void snapshot(final PendingServiceMessageTracker tracker, final ErrorHandler errorHandler)
    {
        final int length = MessageHeaderEncoder.ENCODED_LENGTH + PendingMessageTrackerEncoder.BLOCK_LENGTH;
        final long nextServiceSessionId = correctNextServiceSessionId(tracker, errorHandler);

        idleStrategy.reset();
        while (true)
        {
            final long result = publication.tryClaim(length, bufferClaim);
            if (result > 0)
            {
                pendingMessageTrackerEncoder
                    .wrapAndApplyHeader(bufferClaim.buffer(), bufferClaim.offset(), messageHeaderEncoder)
                    .nextServiceSessionId(nextServiceSessionId)
                    .logServiceSessionId(tracker.logServiceSessionId())
                    .pendingMessageCapacity(tracker.pendingMessages().size())
                    .serviceId(tracker.serviceId());
                bufferClaim.commit();
                break;
            }

            checkResultAndIdle(result);
        }

        tracker.pendingMessages().forEach(this, Integer.MAX_VALUE);
    }
@Test
    void snapshotPendingServiceMessageTrackerWithServiceMessagesMissedByFollower()
    {
        final int serviceId = 6;
        final PendingServiceMessageTracker pendingServiceMessageTracker = new PendingServiceMessageTracker(
            serviceId, mock(Counter.class), mock(LogPublisher.class), mock(ClusterClock.class));
        final AtomicBuffer headerMessageBuffer = new UnsafeBuffer(new byte[1024]);

        final long expectedLogServiceSessionId = pendingServiceMessageTracker.logServiceSessionId() + 1;
        final long expectedNextServiceSessionId = expectedLogServiceSessionId + 1;
        when(publication.tryClaim(anyInt(), any())).thenAnswer(
            (invocation) ->
            {
                final int length = invocation.getArgument(0, Integer.class);
                final BufferClaim bufferClaim = invocation.getArgument(1, BufferClaim.class);

                bufferClaim.wrap(headerMessageBuffer, 0, length + 32);
                return (long)length;
            });

        pendingServiceMessageTracker.sweepFollowerMessages(expectedLogServiceSessionId);

        snapshotTaker.snapshot(pendingServiceMessageTracker, mock(ErrorHandler.class));

        pendingMessageTrackerDecoder.wrapAndApplyHeader(headerMessageBuffer, HEADER_LENGTH, messageHeaderDecoder);
        assertEquals(expectedNextServiceSessionId, pendingMessageTrackerDecoder.nextServiceSessionId());
        assertEquals(expectedLogServiceSessionId, pendingMessageTrackerDecoder.logServiceSessionId());
    }