docs: private static void createGroup(List<ComponentGroup> groupList,
        Map<MtasSpanQuery, Map<Integer, List<Match>>> spansMatchData,
        List<Integer> docSet, FieldInfo fieldInfo, String field, int docBase,
        CodecInfo mtasCodecInfo, IndexSearcher searcher, LeafReaderContext lrc,
        Status status) throws IOException {
  
      if (mtasCodecInfo != null && groupList != null) {
        List<Match> matchList;
        Map<Integer, List<Match>> matchData;
        for (ComponentGroup group : groupList) {
          group.dataCollector.setWithTotal();
          if (!group.prefixes.isEmpty()) {
            matchData = spansMatchData.get(group.spanQuery);
            Set<String> knownPrefixes = collectKnownPrefixes(fieldInfo);
            Set<String> intersectionPrefixes = collectIntersectionPrefixes(
                fieldInfo);
            boolean intersectionGroupPrefixes = intersectionPrefixes(group,
                intersectionPrefixes);
            boolean availablePrefixes = availablePrefixes(group, knownPrefixes);
            // sort match lists
            if (!intersectionGroupPrefixes) {
              for (Entry<Integer, List<Match>> entry : matchData.entrySet()) {
                sortMatchList(entry.getValue());
              }
            }
            // init
            group.dataCollector.initNewList(1);
            int docId;
  
            Map<GroupHit, Long> occurencesSum = new HashMap<>();
            Map<GroupHit, Integer> occurencesN = new HashMap<>();
            Set<GroupHit> occurencesInCurrentDocument = new HashSet<>();
  
            if (!availablePrefixes) {
              HashMap<Integer, GroupHit> hits = new HashMap<>();
              for (int docCounter = 0; docCounter < docSet.size(); docCounter++) {
                occurencesInCurrentDocument.clear();
                docId = docSet.get(docCounter);
                GroupHit hit;
                GroupHit hitKey;
                if (matchData != null
                    && (matchList = matchData.get(docId)) != null
                    && !matchList.isEmpty()) {
                  Iterator<Match> it = matchList.listIterator();
                  while (it.hasNext()) {
                    Match m = it.next();
                    IntervalTreeNodeData<String> positionHit = createPositionHit(
                        m, group);
                    int length = m.endPosition - m.startPosition;
                    hitKey = null;
                    if (!hits.containsKey(length)) {
                      hit = new GroupHit(positionHit.list, positionHit.start,
                          positionHit.end, positionHit.hitStart,
                          positionHit.hitEnd, group, knownPrefixes);
                      hits.put(length, hit);
                    } else {
                      hit = hits.get(length);
                      for (GroupHit hitKeyItem : occurencesSum.keySet()) {
                        if (hitKeyItem.equals(hit)) {
                          hitKey = hitKeyItem;
                          break;
                        }
                      }
                    }
                    if (hitKey == null) {
                      occurencesSum.put(hit, Long.valueOf(1));
                      occurencesN.put(hit, 1);
                      occurencesInCurrentDocument.add(hit);
                    } else {
                      occurencesSum.put(hitKey, occurencesSum.get(hitKey) + 1);
                      if (!occurencesInCurrentDocument.contains(hitKey)) {
                        if (occurencesN.containsKey(hitKey)) {
                          occurencesN.put(hitKey, occurencesN.get(hitKey) + 1);
                        } else {
                          occurencesN.put(hitKey, 1);
                        }
                        occurencesInCurrentDocument.add(hitKey);
                      }
                    }
                  }
                }
              }
            } else {
              int maximumNumberOfDocuments = 0;
              int boundaryMinimumNumberOfDocuments = 1;
              int boundaryMaximumNumberOfDocuments = 5;
              Set<GroupHit> administrationOccurrences = new HashSet<>();
              for (int docCounter = 0; docCounter < docSet.size(); docCounter++) {
                occurencesInCurrentDocument.clear();
                docId = docSet.get(docCounter);
                if (matchData != null
                    && (matchList = matchData.get(docId)) != null
                    && !matchList.isEmpty()) {
                  // loop over matches
                  Iterator<Match> it = matchList.listIterator();
                  ArrayList<IntervalTreeNodeData<String>> positionsHits = new ArrayList<>();
                  while (it.hasNext()) {
                    Match m = it.next();
                    positionsHits.add(createPositionHit(m, group));
                  }
                  mtasCodecInfo.collectTermsByPrefixesForListOfHitPositions(field,
                      (docId - docBase), group.prefixes, positionsHits);
                  // administration
                  for (IntervalTreeNodeData<String> positionHit : positionsHits) {
                    GroupHit hit = new GroupHit(positionHit.list,
                        positionHit.start, positionHit.end, positionHit.hitStart,
                        positionHit.hitEnd, group, knownPrefixes);
                    GroupHit hitKey = null;
                    for (GroupHit hitKeyItem : occurencesSum.keySet()) {
                      if (hitKeyItem.equals(hit)) {
                        hitKey = hitKeyItem;
                        break;
                      }
                    }
                    if (hitKey == null) {
                      occurencesSum.put(hit, Long.valueOf(1));
                      occurencesN.put(hit, 1);
                      occurencesInCurrentDocument.add(hit);
                    } else {
                      occurencesSum.put(hitKey, occurencesSum.get(hitKey) + 1);
                      if (!occurencesInCurrentDocument.contains(hitKey)) {
                        if (occurencesN.containsKey(hitKey)) {
                          occurencesN.put(hitKey, occurencesN.get(hitKey) + 1);
                        } else {
                          occurencesN.put(hitKey, 1);
                        }
                        occurencesInCurrentDocument.add(hitKey);
                      }
                    }
                  }
                  if (!intersectionGroupPrefixes) {
                    for (GroupHit groupHit : occurencesInCurrentDocument) {
                      int tmpNumber = occurencesN.get(groupHit);
                      maximumNumberOfDocuments = Math
                          .max(maximumNumberOfDocuments, tmpNumber);
                      if (tmpNumber > boundaryMinimumNumberOfDocuments) {
                        administrationOccurrences.add(groupHit);
                      }
                    }
                    // collect spans
                    if (maximumNumberOfDocuments > boundaryMaximumNumberOfDocuments) {
                      if (!administrationOccurrences.isEmpty()) {
                        Map<GroupHit, Spans> list = collectSpansForOccurences(
                            administrationOccurrences, knownPrefixes, field,
                            searcher, lrc);
                        if (list.size() > 0) {
                          collectGroupUsingSpans(list, docSet, docBase,
                              docCounter, matchData, occurencesSum, occurencesN);
                        }
                      }
                      administrationOccurrences.clear();
                      maximumNumberOfDocuments = 0;
                      boundaryMinimumNumberOfDocuments = (int) Math
                          .ceil(boundaryMinimumNumberOfDocuments * 1.2);
                      boundaryMaximumNumberOfDocuments = (int) Math
                          .ceil(boundaryMaximumNumberOfDocuments * 1.2);
                    }
                  }
                }
              }
            }
  
            for (Entry<GroupHit, Long> entry : occurencesSum.entrySet()) {
              group.dataCollector.add(entry.getKey().toString(), entry.getValue(),
                  occurencesN.get(entry.getKey()));
            }
            group.dataCollector.closeNewList();
          }
        }
      }
    }