static SearchProtocol.SearchRequest convertFromQuery(Query query, int hits, String serverId, double requestTimeout) {
        var builder = SearchProtocol.SearchRequest.newBuilder().setHits(hits).setOffset(query.getOffset())
                .setTimeout((int) (requestTimeout * 1000));

        var documentDb = query.getModel().getDocumentDb();
        if (documentDb != null) {
            builder.setDocumentType(documentDb);
        }
        GrowableByteBuffer scratchPad = threadLocalBuffer.get();
        builder.setQueryTreeBlob(serializeQueryTree(query.getModel().getQueryTree(), scratchPad));

        if (query.getGroupingSessionCache() || query.getRanking().getQueryCache()) {
            // TODO verify that the session key is included whenever rank properties would have been
            builder.setSessionKey(query.getSessionId(serverId).toString());
        }
        if (query.properties().getBoolean(Model.ESTIMATE)) {
            builder.setHits(0);
        }
        if (GroupingExecutor.hasGroupingList(query)) {
            List<Grouping> groupingList = GroupingExecutor.getGroupingList(query);
            scratchPad.clear();
            BufferSerializer gbuf = new BufferSerializer(scratchPad);
            gbuf.putInt(null, groupingList.size());
            for (Grouping g : groupingList) {
                g.serialize(gbuf);
            }
            gbuf.getBuf().flip();
            builder.setGroupingBlob(ByteString.copyFrom(gbuf.getBuf().getByteBuffer()));
        }
        if (query.getGroupingSessionCache()) {
            builder.setCacheGrouping(true);
        }

        int traceLevel = getTraceLevelForBackend(query);
        builder.setTraceLevel(traceLevel);
        builder.setProfileDepth(query.getTrace().getProfileDepth());
        if (traceLevel > 0) {
            mergeToSearchRequestFromProfiling(query.getTrace().getProfiling(), builder);
        }

        mergeToSearchRequestFromRanking(query.getRanking(), scratchPad, builder);

        return builder.build();
    }
@Test
    void profiling_parameters_are_serialized_in_search_request() {
        var q = new Query("?query=test&trace.level=1&" +
                "trace.profiling.matching.depth=3&" +
                "trace.profiling.firstPhaseRanking.depth=5&" +
                "trace.profiling.secondPhaseRanking.depth=-7");
        var req = ProtobufSerialization.convertFromQuery(q, 1, "serverId", 0.5);
        assertEquals(3, req.getProfiling().getMatch().getDepth());
        assertEquals(5, req.getProfiling().getFirstPhase().getDepth());
        assertEquals(-7, req.getProfiling().getSecondPhase().getDepth());
    }