public Set<MavenArtifactInfo> search(int indexId, Query query, int maxResult)
      throws MavenServerIndexerException {
    try {
      IndexingContext index = getIndex(indexId);

      TopDocs docs = null;
      try {
        BooleanQuery.setMaxClauseCount(Integer.MAX_VALUE);
        docs = index.getIndexSearcher().search(query, null, maxResult);
      } catch (BooleanQuery.TooManyClauses ignore) {
        // this exception occurs when too wide wildcard is used on too big data.
      }

      if (docs == null || docs.scoreDocs.length == 0) return Collections.emptySet();

      Set<MavenArtifactInfo> result = new THashSet<MavenArtifactInfo>();

      for (int i = 0; i < docs.scoreDocs.length; i++) {
        int docIndex = docs.scoreDocs[i].doc;
        Document doc = index.getIndexReader().document(docIndex);
        ArtifactInfo a = IndexUtils.constructArtifactInfo(doc, index);
        if (a == null) continue;

        a.repository = getRepositoryPathOrUrl(index);
        result.add(Maven2ModelConverter.convertArtifactInfo(a));
      }
      return result;
    } catch (Exception e) {
      throw new MavenServerIndexerException(wrapException(e));
    }
  }
  protected int searchFlat(
      AbstractSearchRequest req,
      Collection<ArtifactInfo> result,
      IndexingContext context,
      Query query,
      int from,
      int aiCount)
      throws IOException {
    Hits hits =
        context
            .getIndexSearcher()
            .search(query, new Sort(new SortField(ArtifactInfo.UINFO, SortField.STRING)));

    if (hits == null || hits.length() == 0) {
      return 0;
    }

    if (req.isHitLimited() && hits.length() > req.getResultHitLimit()) {
      return AbstractSearchResponse.LIMIT_EXCEEDED;
    }

    int hitCount = hits.length();

    int start = 0; // from == FlatSearchRequest.UNDEFINED ? 0 : from;

    // we have to pack the results as long: a) we have found aiCount ones b) we depleted hits
    for (int i = start; i < hits.length(); i++) {
      Document doc = hits.doc(i);

      ArtifactInfo artifactInfo = IndexUtils.constructArtifactInfo(doc, context);

      if (artifactInfo != null) {
        artifactInfo.repository = context.getRepositoryId();

        artifactInfo.context = context.getId();

        result.add(artifactInfo);

        if (req.isHitLimited() && result.size() > req.getResultHitLimit()) {
          // we hit limit, back out now !!
          return AbstractSearchResponse.LIMIT_EXCEEDED;
        }
      }
    }

    return hitCount;
  }
  protected int searchGrouped(
      AbstractSearchRequest req,
      Map<String, ArtifactInfoGroup> result,
      Grouping grouping,
      IndexingContext context,
      Query query)
      throws IOException {
    Hits hits =
        context
            .getIndexSearcher()
            .search(query, new Sort(new SortField(ArtifactInfo.UINFO, SortField.STRING)));

    if (hits != null && hits.length() != 0) {
      int hitCount = hits.length();

      for (int i = 0; i < hits.length(); i++) {
        ArtifactInfo artifactInfo = IndexUtils.constructArtifactInfo(hits.doc(i), context);

        if (artifactInfo != null) {
          artifactInfo.repository = context.getRepositoryId();

          artifactInfo.context = context.getId();

          if (!grouping.addArtifactInfo(result, artifactInfo)) {
            // fix the hitCount accordingly
            hitCount--;
          }
        }
      }

      if (req.isHitLimited() && hits.length() > req.getResultHitLimit()) {
        return AbstractSearchResponse.LIMIT_EXCEEDED;
      }

      return hitCount;
    } else {
      return 0;
    }
  }