class ScoreDocRowFunction implements Function<ScoreDoc, Row> {

    private final List<OrderByCollectorExpression> orderByCollectorExpressions = new ArrayList<>();
    private final IndexReader indexReader;
    private final LuceneCollectorExpression[] expressions;
    private final DummyScorer scorer;
    private final InputRow inputRow;
    private final Runnable onScoreDoc;
    private final ReaderContext[] readerContexts;

    ScoreDocRowFunction(IndexReader indexReader,
                        List<? extends Input<?>> inputs,
                        Collection<? extends LuceneCollectorExpression<?>> expressions,
                        DummyScorer scorer,
                        Runnable onScoreDoc) {
        this.indexReader = indexReader;
        this.expressions = expressions.toArray(new LuceneCollectorExpression[0]);
        this.scorer = scorer;
        this.inputRow = new InputRow(inputs);
        this.onScoreDoc = onScoreDoc;
        for (LuceneCollectorExpression<?> expression : this.expressions) {
            if (expression instanceof OrderByCollectorExpression orderByExpr) {
                orderByCollectorExpressions.add(orderByExpr);
            }
        }
        List<LeafReaderContext> leaves = indexReader.leaves();
        readerContexts = new ReaderContext[leaves.size()];
        try {
            for (int i = 0; i < readerContexts.length; i++) {
                readerContexts[i] = new ReaderContext(leaves.get(i));
            }
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    @Nullable
    @Override
    public Row apply(@Nullable ScoreDoc input) {<FILL_FUNCTION_BODY>}
}

        onScoreDoc.run();
        if (input == null) {
            return null;
        }
        FieldDoc fieldDoc = (FieldDoc) input;
        scorer.score(fieldDoc.score);
        for (int i = 0; i < orderByCollectorExpressions.size(); i++) {
            orderByCollectorExpressions.get(i).setNextFieldDoc(fieldDoc);
        }
        List<LeafReaderContext> leaves = indexReader.leaves();
        int readerIndex = ReaderUtil.subIndex(fieldDoc.doc, leaves);
        LeafReaderContext subReaderContext = leaves.get(readerIndex);
        var readerContext = readerContexts[readerIndex];
        int subDoc = fieldDoc.doc - subReaderContext.docBase;
        try {
            for (LuceneCollectorExpression<?> expression : expressions) {
                expression.setNextReader(readerContext);
                expression.setNextDocId(subDoc);
            }
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
        return inputRow;
    
<no_super_class>