Buggy code:
private final SolrIndexSearcher searcher ; private final QueryResult qr ; private final QueryCommand cmd ; private final List < Grouping . Command > commands = new ArrayList < Grouping . Command > ( ) ; private final boolean main ; private final boolean cacheSecondPassSearch ; private final int maxDocsPercentageToCache ; private Sort sort ; private Sort groupSort ; private int limitDefault ; private int docsPerGroupDefault ; private int groupOffsetDefault ; private Grouping . Format defaultFormat ; private Grouping . TotalCount defaultTotalCount ; private int maxDoc ; private boolean needScores ; private boolean getDocSet ; private boolean getGroupedDocSet ; private boolean getDocList ; private Query query ; private DocSet filter ; private Filter luceneFilter ; private NamedList grouped = new SimpleOrderedMap ( ) ; private Set < Integer > idSet = new LinkedHashSet < Integer > ( ) ; private int maxMatches ; private float maxScore = Float . NEGATIVE_INFINITY ; private boolean signalCacheWarning = false ; private TimeLimitingCollector timeLimitingCollector ; public DocList mainResult ; public Grouping ( SolrIndexSearcher searcher , SolrIndexSearcher . QueryResult qr , SolrIndexSearcher . QueryCommand cmd , boolean cacheSecondPassSearch , int maxDocsPercentageToCache , boolean main ) { } public void add ( Grouping . Command groupingCommand ) { } public void addFieldCommand ( String field , SolrQueryRequest request ) throws ParseException { } public void addQueryCommand ( String groupByStr , SolrQueryRequest request ) throws ParseException { } public Grouping setSort ( Sort sort ) { } public Grouping setGroupSort ( Sort groupSort ) { } public Grouping setLimitDefault ( int limitDefault ) { } public Grouping setDocsPerGroupDefault ( int docsPerGroupDefault ) { } public Grouping setGroupOffsetDefault ( int groupOffsetDefault ) { } public Grouping setDefaultFormat ( Grouping . Format defaultFormat ) { } public Grouping setDefaultTotalCount ( Grouping . TotalCount defaultTotalCount ) { } public Grouping setGetGroupedDocSet ( boolean getGroupedDocSet ) { } public List < Grouping . Command > getCommands ( ) { } public void execute ( ) throws IOException { } private void searchWithTimeLimiter ( final Filter luceneFilter , Collector collector ) throws IOException { } int getMax ( int offset , int len , int max ) { } public boolean isSignalCacheWarning ( ) { } public static enum Format { grouped , simple ; } public static enum TotalCount { grouped , ungrouped ; } public abstract class Command < GROUP_VALUE_TYPE > { public String key ; public Sort groupSort ; public Sort sort ; public int docsPerGroup ; public int groupOffset ; public int numGroups ; int actualGroupsToFind ; public int offset ; public Grouping . Format format ; public boolean main ; public Grouping . TotalCount totalCount = Grouping . TotalCount . ungrouped ; TopGroups < GROUP_VALUE_TYPE > result ; protected abstract void prepare ( ) throws IOException { } protected abstract Collector createFirstPassCollector ( ) throws IOException { } protected Collector createSecondPassCollector ( ) throws IOException { } public AbstractAllGroupHeadsCollector < ? > createAllGroupCollector ( ) throws IOException { } protected abstract void finish ( ) throws IOException { } public abstract int getMatches ( ) { } protected Integer getNumberOfGroups ( ) { } protected NamedList commonResponse ( ) { } protected DocList getDocList ( GroupDocs groups ) { } protected void addDocList ( NamedList rsp , GroupDocs groups ) { } protected DocList createSimpleResponse ( ) { GroupDocs [ ] groups = ( ( result ) != null ) ? result . groups : new GroupDocs [ 0 ] ; List < Integer > ids = new ArrayList < Integer > ( ) ; List < Float > scores = new ArrayList < Float > ( ) ; int docsToGather = getMax ( offset , numGroups , maxDoc ) ; int docsGathered = 0 ; float maxScore = Float . NEGATIVE_INFINITY ; outer : for ( GroupDocs group : groups ) { if ( ( group . maxScore ) > maxScore ) { maxScore = group . maxScore ; } for ( ScoreDoc scoreDoc : group . scoreDocs ) { if ( docsGathered >= docsToGather ) { break outer ; } ids . add ( scoreDoc . doc ) ; scores . add ( scoreDoc . score ) ; docsGathered ++ ; } } <START_BUG> int len = docsGathered - ( offset ) ; <END_BUG> int [ ] docs = ArrayUtils . toPrimitive ( ids . toArray ( new Integer [ ids . size ( ) ] ) ) ; float [ ] docScores = ArrayUtils . toPrimitive ( scores . toArray ( new Float [ scores . size ( ) ] ) ) ; DocSlice docSlice = new DocSlice ( offset , len , docs , docScores , getMatches ( ) , maxScore ) ; if ( getDocList ) { for ( int i = offset ; i < ( docs . length ) ; i ++ ) { idSet . add ( docs [ i ] ) ; } } return docSlice ; } } public class CommandField extends Grouping . Command < String > { public String groupBy ; TermFirstPassGroupingCollector firstPass ; TermSecondPassGroupingCollector secondPass ; TermAllGroupsCollector allGroupsCollector ; TotalHitCountCollector fallBackCollector ; Collection < SearchGroup < String > > topGroups ; protected void prepare ( ) throws IOException { } protected Collector createFirstPassCollector ( ) throws IOException { } protected Collector createSecondPassCollector ( ) throws IOException { } @ Override public AbstractAllGroupHeadsCollector < ? > createAllGroupCollector ( ) throws IOException { } protected void finish ( ) throws IOException { } public int getMatches ( ) { } protected Integer getNumberOfGroups ( ) { } } public class CommandQuery extends Grouping . Command { public Query query ; TopDocsCollector topCollector ; FilterCollector collector ; protected void prepare ( ) throws IOException { } protected Collector createFirstPassCollector ( ) throws IOException { } TopDocsCollector newCollector ( Sort sort , boolean needScores ) throws IOException { } protected void finish ( ) throws IOException { } public int getMatches ( ) { } } }

Fix:
int len = ( docsGathered > ( offset ) ) ? docsGathered - ( offset ) : 0 ;