@Override
    public Result search(com.yahoo.search.Query query, Execution execution) {
        String collapseFieldParam = query.properties().getString(collapseField);
        if (collapseFieldParam == null) return execution.search(query);

        String[] collapseFields = collapseFieldParam.split(separator);
        int globalCollapseSize = query.properties().getInteger(collapseSize, defaultCollapseSize);
        query.properties().set(collapse, "0");

        int wantedHits = query.getOffset() + query.getHits();
        int hitsToRequest = query.getHits() != 0 ? (int) Math.ceil((wantedHits + 1) * extraFactor) : 0;
        int nextOffset = 0;
        int hitsAfterCollapse = 0;
        boolean moreHitsAvailable = true;
        Map<String, Integer> knownCollapses = new java.util.HashMap<>();
        Result result = new Result(query);
        int performedQueries = 0;
        Result resultSource;
        String collapseSummary = query.properties().getString(collapseSummaryName);
        String summaryClass = (collapseSummary == null)
                              ? query.getPresentation().getSummary() : collapseSummary;
        query.trace("Collapsing by '" + Arrays.toString(collapseFields) + "' using summary '" + collapseSummary + "'", 2);
        boolean wantAnotherQuery;
        do {
            if (performedQueries > 0) {
                query.trace("Collapsing: retry " + performedQueries + ", only has " + hitsAfterCollapse + " hits, wanted " + wantedHits, 2);
            }
            resultSource = search(query.clone(), execution, nextOffset, hitsToRequest);
            fill(resultSource, summaryClass, execution);

            collapse(result, knownCollapses, resultSource, collapseFields, query.properties(), globalCollapseSize);

            hitsAfterCollapse = result.getHitCount();
            if (resultSource.getTotalHitCount() < (hitsToRequest + nextOffset)) {
                // the searcher downstream has no more hits
                moreHitsAvailable = false;
            }
            nextOffset += hitsToRequest;
            if (hitsAfterCollapse < wantedHits) {
                hitsToRequest = (int) Math.ceil(hitsToRequest * extraFactor);
            }
            ++performedQueries;
            wantAnotherQuery = (hitsToRequest != 0
                                && (hitsAfterCollapse < wantedHits)
                                && moreHitsAvailable);
        } while (wantAnotherQuery && (performedQueries <= maxQueries));
        // failure?
        if (wantAnotherQuery) {
            query.trace("Collapsing: giving up after " + performedQueries + " performed queries, collapsing removed too many hits", 1);
        }
        // Set correct meta information
        result.mergeWith(resultSource);
        // Keep only (offset ... offset+hits) hits
        result.hits().trim(query.getOffset(), query.getHits());
        // Mark query as query with collapsing
        query.properties().set(collapse, "1");
        return result;
    }
First fetch result from the next searcher in the chain.
If collapse is active, do collapsing.
Otherwise, act as a simple pass through
container-search/src/main/java/com/yahoo/prelude/searcher/FieldCollapsingSearcher.java