@SuppressWarnings("MethodLength")
    static void dissectControlRequest(
        final ArchiveEventCode eventCode,
        final MutableDirectBuffer buffer,
        final int offset,
        final StringBuilder builder)
    {
        int encodedLength = dissectLogHeader(CONTEXT, eventCode, buffer, offset, builder);

        HEADER_DECODER.wrap(buffer, offset + encodedLength);
        encodedLength += MessageHeaderDecoder.ENCODED_LENGTH;

        switch (eventCode)
        {
            case CMD_IN_CONNECT:
                CONNECT_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendConnect(builder);
                break;

            case CMD_IN_CLOSE_SESSION:
                CLOSE_SESSION_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendCloseSession(builder);
                break;

            case CMD_IN_START_RECORDING:
                START_RECORDING_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendStartRecording(builder);
                break;

            case CMD_IN_STOP_RECORDING:
                STOP_RECORDING_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendStopRecording(builder);
                break;

            case CMD_IN_REPLAY:
                REPLAY_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendReplay(builder);
                break;

            case CMD_IN_STOP_REPLAY:
                STOP_REPLAY_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendStopReplay(builder);
                break;

            case CMD_IN_LIST_RECORDINGS:
                LIST_RECORDINGS_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendListRecordings(builder);
                break;

            case CMD_IN_LIST_RECORDINGS_FOR_URI:
                LIST_RECORDINGS_FOR_URI_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendListRecordingsForUri(builder);
                break;

            case CMD_IN_LIST_RECORDING:
                LIST_RECORDING_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendListRecording(builder);
                break;

            case CMD_IN_EXTEND_RECORDING:
                EXTEND_RECORDING_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendExtendRecording(builder);
                break;

            case CMD_IN_RECORDING_POSITION:
                RECORDING_POSITION_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendRecordingPosition(builder);
                break;

            case CMD_IN_TRUNCATE_RECORDING:
                TRUNCATE_RECORDING_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendTruncateRecording(builder);
                break;

            case CMD_IN_STOP_RECORDING_SUBSCRIPTION:
                STOP_RECORDING_SUBSCRIPTION_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendStopRecordingSubscription(builder);
                break;

            case CMD_IN_STOP_POSITION:
                STOP_POSITION_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendStopPosition(builder);
                break;

            case CMD_IN_FIND_LAST_MATCHING_RECORD:
                FIND_LAST_MATCHING_RECORDING_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendFindLastMatchingRecord(builder);
                break;

            case CMD_IN_LIST_RECORDING_SUBSCRIPTIONS:
                LIST_RECORDING_SUBSCRIPTIONS_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendListRecordingSubscriptions(builder);
                break;

            case CMD_IN_START_BOUNDED_REPLAY:
                BOUNDED_REPLAY_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendStartBoundedReplay(builder);
                break;

            case CMD_IN_STOP_ALL_REPLAYS:
                STOP_ALL_REPLAYS_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendStopAllReplays(builder);
                break;

            case CMD_IN_REPLICATE:
                REPLICATE_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendReplicate(builder);
                break;

            case CMD_IN_STOP_REPLICATION:
                STOP_REPLICATION_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendStopReplication(builder);
                break;

            case CMD_IN_START_POSITION:
                START_POSITION_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendStartPosition(builder);
                break;

            case CMD_IN_DETACH_SEGMENTS:
                DETACH_SEGMENTS_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendDetachSegments(builder);
                break;

            case CMD_IN_DELETE_DETACHED_SEGMENTS:
                DELETE_DETACHED_SEGMENTS_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendDeleteDetachedSegments(builder);
                break;

            case CMD_IN_PURGE_SEGMENTS:
                PURGE_SEGMENTS_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendPurgeSegments(builder);
                break;

            case CMD_IN_ATTACH_SEGMENTS:
                ATTACH_SEGMENTS_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendAttachSegments(builder);
                break;

            case CMD_IN_MIGRATE_SEGMENTS:
                MIGRATE_SEGMENTS_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendMigrateSegments(builder);
                break;

            case CMD_IN_AUTH_CONNECT:
                AUTH_CONNECT_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendAuthConnect(builder);
                break;

            case CMD_IN_KEEP_ALIVE:
                KEEP_ALIVE_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendKeepAlive(builder);
                break;

            case CMD_IN_TAGGED_REPLICATE:
                TAGGED_REPLICATE_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendTaggedReplicate(builder);
                break;

            case CMD_IN_START_RECORDING2:
                START_RECORDING_REQUEST2_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendStartRecording2(builder);
                break;

            case CMD_IN_EXTEND_RECORDING2:
                EXTEND_RECORDING_REQUEST2_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendExtendRecording2(builder);
                break;

            case CMD_IN_STOP_RECORDING_BY_IDENTITY:
                STOP_RECORDING_BY_IDENTITY_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendStopRecordingByIdentity(builder);
                break;

            case CMD_IN_PURGE_RECORDING:
                PURGE_RECORDING_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendPurgeRecording(builder);
                break;

            case CMD_IN_REPLICATE2:
                REPLICATE_REQUEST2_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendReplicate2(builder);
                break;

            case CMD_IN_REQUEST_REPLAY_TOKEN:
                REPLAY_TOKEN_REQUEST_DECODER.wrap(
                    buffer,
                    offset + encodedLength,
                    HEADER_DECODER.blockLength(),
                    HEADER_DECODER.version());
                appendReplayToken(builder);
                break;

            default:
                builder.append(": unknown command");
        }
    }
@Test
    void controlRequestListRecordings()
    {
        internalEncodeLogHeader(buffer, 0, 32, 32, () -> 100_000_000L);
        final ListRecordingsRequestEncoder requestEncoder = new ListRecordingsRequestEncoder();
        requestEncoder.wrapAndApplyHeader(buffer, LOG_HEADER_LENGTH, headerEncoder)
            .controlSessionId(9)
            .correlationId(78)
            .fromRecordingId(45)
            .recordCount(10);

        dissectControlRequest(CMD_IN_LIST_RECORDINGS, buffer, 0, builder);

        assertEquals("[0.100000000] " + CONTEXT + ": " + CMD_IN_LIST_RECORDINGS.name() + " [32/32]:" +
            " controlSessionId=9" +
            " correlationId=78" +
            " fromRecordingId=45" +
            " recordCount=10",
            builder.toString());
    }