public void recordHits(Hits hits, long groupId, boolean privateLayout, int start, int end)
      throws Exception {

    // This can later be optimized according to LEP-915.

    List<Document> docs = new ArrayList<Document>();
    List<Float> scores = new ArrayList<Float>();

    Document[] docsArray = hits.getDocs();

    for (int i = 0; i < docsArray.length; i++) {
      Document doc = hits.doc(i);

      String articleId = doc.get(Field.ARTICLE_ID);
      long articleGroupId = GetterUtil.getLong(doc.get(Field.GROUP_ID));

      int layoutIdsCount =
          JournalContentSearchLocalServiceUtil.getLayoutIdsCount(groupId, privateLayout, articleId);

      if ((layoutIdsCount > 0) || (!isShowListed() && (articleGroupId == groupId))) {

        docs.add(hits.doc(i));
        scores.add(hits.score(i));
      }
    }

    int length = docs.size();

    hits.setLength(length);

    if (end > length) {
      end = length;
    }

    docs = docs.subList(start, end);
    scores = scores.subList(start, end);

    hits.setDocs(docs.toArray(new Document[docs.size()]));
    hits.setScores(ArrayUtil.toFloatArray(scores));

    hits.setSearchTime((float) (System.currentTimeMillis() - hits.getStart()) / Time.SECOND);
  }
  @Override
  public Hits search(SearchContext searchContext, Query query) throws SearchException {

    long startTime = System.currentTimeMillis();

    List<ExtRepositorySearchResult<?>> extRepositorySearchResults = null;

    try {
      extRepositorySearchResults =
          _extRepository.search(searchContext, query, new ExtRepositoryQueryMapperImpl(this));
    } catch (PortalException | SystemException e) {
      throw new SearchException("Unable to perform search", e);
    }

    QueryConfig queryConfig = searchContext.getQueryConfig();

    List<Document> documents = new ArrayList<>();
    List<String> snippets = new ArrayList<>();
    List<Float> scores = new ArrayList<>();

    int total = 0;

    for (ExtRepositorySearchResult<?> extRepositorySearchResult : extRepositorySearchResults) {

      try {
        ExtRepositoryObjectAdapter<?> extRepositoryEntryAdapter =
            _toExtRepositoryObjectAdapter(
                ExtRepositoryObjectAdapterType.OBJECT, extRepositorySearchResult.getObject());

        Document document = new DocumentImpl();

        document.addKeyword(Field.ENTRY_CLASS_NAME, extRepositoryEntryAdapter.getModelClassName());
        document.addKeyword(Field.ENTRY_CLASS_PK, extRepositoryEntryAdapter.getPrimaryKey());
        document.addKeyword(Field.TITLE, extRepositoryEntryAdapter.getName());

        documents.add(document);

        if (queryConfig.isScoreEnabled()) {
          scores.add(extRepositorySearchResult.getScore());
        } else {
          scores.add(1.0F);
        }

        snippets.add(extRepositorySearchResult.getSnippet());

        total++;
      } catch (PortalException | SystemException e) {
        if (_log.isWarnEnabled()) {
          _log.warn("Invalid entry returned from search", e);
        }
      }
    }

    float searchTime = (float) (System.currentTimeMillis() - startTime) / Time.SECOND;

    Hits hits = new HitsImpl();

    hits.setDocs(documents.toArray(new Document[documents.size()]));
    hits.setLength(total);
    hits.setQueryTerms(new String[0]);
    hits.setScores(ArrayUtil.toFloatArray(scores));
    hits.setSearchTime(searchTime);
    hits.setSnippets(snippets.toArray(new String[snippets.size()]));
    hits.setStart(startTime);

    return hits;
  }