long addNewRecording(
        final long startPosition,
        final long stopPosition,
        final long startTimestamp,
        final long stopTimestamp,
        final int imageInitialTermId,
        final int segmentFileLength,
        final int termBufferLength,
        final int mtuLength,
        final int sessionId,
        final int streamId,
        final String strippedChannel,
        final String originalChannel,
        final String sourceIdentity)
    {
        final int frameLength = recordingDescriptorFrameLength(strippedChannel, originalChannel, sourceIdentity);
        final int recordingDescriptorOffset = nextRecordingDescriptorOffset;

        if (recordingDescriptorOffset + frameLength > capacity)
        {
            growCatalog(MAX_CATALOG_LENGTH, frameLength);
        }

        final long recordingId = nextRecordingId;

        catalogBuffer.wrap(catalogByteBuffer, recordingDescriptorOffset, frameLength);
        descriptorEncoder
            .wrap(catalogBuffer, DESCRIPTOR_HEADER_LENGTH)
            .recordingId(recordingId)
            .startTimestamp(startTimestamp)
            .stopTimestamp(stopTimestamp)
            .startPosition(startPosition)
            .stopPosition(stopPosition)
            .initialTermId(imageInitialTermId)
            .segmentFileLength(segmentFileLength)
            .termBufferLength(termBufferLength)
            .mtuLength(mtuLength)
            .sessionId(sessionId)
            .streamId(streamId)
            .strippedChannel(strippedChannel)
            .originalChannel(originalChannel)
            .sourceIdentity(sourceIdentity);

        final int recordingLength = frameLength - DESCRIPTOR_HEADER_LENGTH;
        descriptorHeaderEncoder
            .wrap(catalogBuffer, 0)
            .length(recordingLength)
            .checksum(computeRecordingDescriptorChecksum(recordingDescriptorOffset, recordingLength))
            .state(VALID);

        catalogHeaderEncoder.nextRecordingId(recordingId + 1);

        forceWrites(catalogChannel);

        nextRecordingId = recordingId + 1;
        nextRecordingDescriptorOffset = recordingDescriptorOffset + frameLength;
        catalogIndex.add(recordingId, recordingDescriptorOffset);

        return recordingId;
    }
@Test
    void shouldAppendToExistingIndex()
    {
        final long newRecordingId;
        try (Catalog catalog = new Catalog(archiveDir, null, 0, CAPACITY, () -> 3L, null, segmentFileBuffer))
        {
            newRecordingId = catalog.addNewRecording(
                32,
                128,
                21,
                42,
                5,
                SEGMENT_LENGTH,
                TERM_LENGTH,
                MTU_LENGTH,
                9,
                4,
                "channelJ",
                "channelJ?tag=f",
                "sourceN");
        }

        try (Catalog catalog = new Catalog(archiveDir, clock))
        {
            verifyRecordingForId(
                catalog,
                recordingOneId,
                160,
                0L,
                0L, // updated from NULL_POSITION when Catalog was created for write
                0L,
                3L, // updated from NULL_TIMESTAMP when Catalog was created for write
                0,
                SEGMENT_LENGTH,
                TERM_LENGTH,
                MTU_LENGTH,
                6,
                1,
                "channelG",
                "channelG?tag=f",
                "sourceA");

            verifyRecordingForId(
                catalog,
                newRecordingId,
                160,
                32,
                128,
                21,
                42,
                5,
                SEGMENT_LENGTH,
                TERM_LENGTH,
                MTU_LENGTH,
                9,
                4,
                "channelJ",
                "channelJ?tag=f",
                "sourceN");
        }
    }