SOLR-13004: Forward compatability by returning integer in usual cases, long in overflown cases
diff --git a/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java b/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java
index 5da1fac..9d4b09a 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java
@@ -63,6 +63,7 @@
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
 import org.apache.solr.common.util.StrUtils;
+import org.apache.solr.common.util.Utils;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.response.BasicResultContext;
 import org.apache.solr.response.ResultContext;
@@ -1320,7 +1321,7 @@
     SearchGroupsResultTransformer serializer = new SearchGroupsResultTransformer(searcher);
 
     rsp.add("firstPhase", commandHandler.processResult(result, serializer));
-    rsp.add("totalHitCount", commandHandler.getTotalHitCount());
+    rsp.add("totalHitCount", Utils.intIfNotOverflown(commandHandler.getTotalHitCount()));
     rb.setResult(result);
   }
 
diff --git a/solr/core/src/java/org/apache/solr/search/grouping/distributed/shardresultserializer/TopGroupsResultTransformer.java b/solr/core/src/java/org/apache/solr/search/grouping/distributed/shardresultserializer/TopGroupsResultTransformer.java
index 13eef04..ae5bd4c 100644
--- a/solr/core/src/java/org/apache/solr/search/grouping/distributed/shardresultserializer/TopGroupsResultTransformer.java
+++ b/solr/core/src/java/org/apache/solr/search/grouping/distributed/shardresultserializer/TopGroupsResultTransformer.java
@@ -36,6 +36,7 @@
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.CharsRefBuilder;
 import org.apache.solr.common.util.NamedList;
+import org.apache.solr.common.util.Utils;
 import org.apache.solr.handler.component.ResponseBuilder;
 import org.apache.solr.handler.component.ShardDoc;
 import org.apache.solr.schema.FieldType;
@@ -95,7 +96,7 @@
     for (Map.Entry<String, NamedList> entry : shardResponse) {
       String key = entry.getKey();
       NamedList commandResult = entry.getValue();
-      Long totalGroupedHitCount = (Long) commandResult.get("totalGroupedHitCount");
+      Long totalGroupedHitCount = commandResult.get("totalGroupedHitCount")==null? null: ((Number) commandResult.get("totalGroupedHitCount")).longValue();
       Number totalHits = (Number) commandResult.get("totalHits"); // previously Integer now Long
       if (totalHits != null) {
         Long matches = (Long) commandResult.get("matches");
@@ -184,10 +185,10 @@
 
   protected NamedList serializeTopGroups(TopGroups<BytesRef> data, SchemaField groupField) throws IOException {
     NamedList<Object> result = new NamedList<>();
-    result.add("totalGroupedHitCount", data.totalGroupedHitCount);
-    result.add("totalHitCount", data.totalHitCount);
+    result.add("totalGroupedHitCount", Utils.intIfNotOverflown(data.totalGroupedHitCount));
+    result.add("totalHitCount", Utils.intIfNotOverflown(data.totalHitCount));
     if (data.totalGroupCount != null) {
-      result.add("totalGroupCount", data.totalGroupCount);
+      result.add("totalGroupCount", Utils.intIfNotOverflown(data.totalGroupCount));
     }
 
     final IndexSchema schema = rb.req.getSearcher().getSchema();
@@ -239,9 +240,10 @@
     return result;
   }
 
+
   protected NamedList serializeTopDocs(QueryCommandResult result) throws IOException {
     NamedList<Object> queryResult = new NamedList<>();
-    queryResult.add("matches", result.getMatches());
+    queryResult.add("matches", Utils.intIfNotOverflown(result.getMatches()));
     TopDocs topDocs = result.getTopDocs();
     assert topDocs.totalHits.relation == TotalHits.Relation.EQUAL_TO;
     queryResult.add("totalHits", topDocs.totalHits.value);
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java b/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java
index 5f60b4f..e242356 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java
@@ -266,11 +266,11 @@
         }
 
         if (oGroups != null) {
-          Long iMatches = (Long) oMatches;
+          Long iMatches = oMatches==null? null: ((Number) oMatches).longValue();
           ArrayList<Object> groupsArr = (ArrayList<Object>) oGroups;
           GroupCommand groupedCommand;
           if (oNGroups != null) {
-            Long iNGroups = (Long) oNGroups;
+            Long iNGroups = oNGroups==null? null: ((Number) oNGroups).longValue();
             groupedCommand = new GroupCommand(fieldName, iMatches, iNGroups);
           } else {
             groupedCommand = new GroupCommand(fieldName, iMatches);
@@ -286,10 +286,10 @@
 
           _groupResponse.add(groupedCommand);
         } else if (queryCommand != null) {
-          Integer iMatches = (Integer) oMatches;
+          Long iMatches = oMatches==null? null: ((Number) oMatches).longValue();
           GroupCommand groupCommand;
           if (oNGroups != null) {
-            Long iNGroups = (Long) oNGroups;
+            Long iNGroups = oMatches==null? null: ((Number) oNGroups).longValue();;
             groupCommand = new GroupCommand(fieldName, iMatches, iNGroups);
           } else {
             groupCommand = new GroupCommand(fieldName, iMatches);
diff --git a/solr/solrj/src/java/org/apache/solr/common/util/Utils.java b/solr/solrj/src/java/org/apache/solr/common/util/Utils.java
index fd5eafa..a8bd3b0 100644
--- a/solr/solrj/src/java/org/apache/solr/common/util/Utils.java
+++ b/solr/solrj/src/java/org/apache/solr/common/util/Utils.java
@@ -210,6 +210,18 @@
     return writer;
   }
 
+  /**
+   * Given long integer, return an integer or a long integer
+   * depending upon whether it overflows the integer range.
+   */
+  static public Number intIfNotOverflown(long n) {
+    if (((int) n) == n){
+      return Integer.valueOf((int)n);
+    } else {
+      return Long.valueOf(n);
+    }
+  }
+
   private static class MapWriterJSONWriter extends JSONWriter {
 
     public MapWriterJSONWriter(CharArr out, int indentSize) {