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 snapshotPendingServiceMessageTracker()
    {
        final int offset = 108;
        final int length = MessageHeaderEncoder.ENCODED_LENGTH + PendingMessageTrackerEncoder.BLOCK_LENGTH;
        final int serviceId = 6;
        final PendingServiceMessageTracker pendingServiceMessageTracker = new PendingServiceMessageTracker(
            serviceId, mock(Counter.class), mock(LogPublisher.class), mock(ClusterClock.class));
        pendingServiceMessageTracker.enqueueMessage(buffer, 32, 0);
        final int capacity = pendingServiceMessageTracker.size();
        when(publication.tryClaim(eq(length), any()))
            .thenReturn(ADMIN_ACTION)
            .thenAnswer(mockTryClaim(offset));
        when(publication.offer(any(), anyInt(), anyInt()))
            .thenReturn(BACK_PRESSURED, 9L);

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

        final InOrder inOrder = inOrder(idleStrategy, publication);
        inOrder.verify(idleStrategy).reset();
        inOrder.verify(publication).tryClaim(anyInt(), any());
        inOrder.verify(idleStrategy).idle();
        inOrder.verify(publication).tryClaim(anyInt(), any());
        inOrder.verify(idleStrategy).reset();
        inOrder.verify(publication).offer(any(), anyInt(), anyInt());
        inOrder.verify(idleStrategy).idle();
        inOrder.verify(publication).offer(any(), anyInt(), anyInt());
        inOrder.verifyNoMoreInteractions();

        pendingMessageTrackerDecoder.wrapAndApplyHeader(buffer, offset + HEADER_LENGTH, messageHeaderDecoder);
        assertEquals(-8791026472627208190L, pendingMessageTrackerDecoder.nextServiceSessionId());
        assertEquals(-8791026472627208192L, pendingMessageTrackerDecoder.logServiceSessionId());
        assertEquals(capacity, pendingMessageTrackerDecoder.pendingMessageCapacity());
        assertEquals(serviceId, pendingMessageTrackerDecoder.serviceId());
    }