Batch group definitions

This reduces our memory consumption
diff --git a/src/com/google/enterprise/adaptor/sharepoint/SharePointAdaptor.java b/src/com/google/enterprise/adaptor/sharepoint/SharePointAdaptor.java
index 5c57a39..11a467a 100644
--- a/src/com/google/enterprise/adaptor/sharepoint/SharePointAdaptor.java
+++ b/src/com/google/enterprise/adaptor/sharepoint/SharePointAdaptor.java
@@ -251,6 +251,7 @@
   private final Callable<ExecutorService> executorFactory;
   private ExecutorService executor;
   private boolean xmlValidation;
+  private int feedMaxUrls;
   private long maxIndexableSize;
   
   private ScheduledThreadPoolExecutor scheduledExecutor 
@@ -346,6 +347,7 @@
         config.getValue("sharepoint.password"));
     xmlValidation = Boolean.parseBoolean(
         config.getValue("sharepoint.xmlValidation"));
+    feedMaxUrls = Integer.parseInt(config.getValue("feed.maxUrls"));
     maxIndexableSize = Integer.parseInt(
         config.getValue("sharepoint.maxIndexableSize"));
     defaultNamespace = config.getValue("adaptor.namespace");
@@ -501,7 +503,16 @@
               siteString);
           continue;
         }
-        defs.putAll(siteAdaptor.computeMembersForGroups(site.getGroups()));
+        Map<GroupPrincipal, Collection<Principal>> siteDefs
+            = siteAdaptor.computeMembersForGroups(site.getGroups());
+        for (Map.Entry<GroupPrincipal, Collection<Principal>> me
+            : siteDefs.entrySet()) {
+          defs.put(me.getKey(), me.getValue());
+          if (defs.size() >= feedMaxUrls) {
+            pusher.pushGroupDefinitions(defs, false);
+            defs.clear();
+          }
+        }
       }
     }
     pusher.pushGroupDefinitions(defs, false);
diff --git a/test/com/google/enterprise/adaptor/sharepoint/SharePointAdaptorTest.java b/test/com/google/enterprise/adaptor/sharepoint/SharePointAdaptorTest.java
index 3b325e3..770c7a7 100644
--- a/test/com/google/enterprise/adaptor/sharepoint/SharePointAdaptorTest.java
+++ b/test/com/google/enterprise/adaptor/sharepoint/SharePointAdaptorTest.java
@@ -1216,6 +1216,8 @@
       goldenGroups = Collections.unmodifiableMap(tmp);
     }
 
+    // Force a full batch of 2 and a final batch of 1.
+    config.overrideKey("feed.maxUrls", "2");
     adaptor = new SharePointAdaptor(MockSoapFactory.blank()
         .endpoint(AUTH_ENDPOINT, new MockAuthenticationSoap())
         .endpoint(VS_ENDPOINT, MockSiteData.blank()