aeron-driver/src/main/java/io/aeron/driver/PublicationImage.java
final void trackRebuild(final long nowNs, final long statusMessageTimeoutNs)
    {
        long minSubscriberPosition = Long.MAX_VALUE;
        long maxSubscriberPosition = Long.MIN_VALUE;

        for (final ReadablePosition subscriberPosition : subscriberPositions)
        {
            final long position = subscriberPosition.getVolatile();
            minSubscriberPosition = Math.min(minSubscriberPosition, position);
            maxSubscriberPosition = Math.max(maxSubscriberPosition, position);
        }

        final long rebuildPosition = Math.max(this.rebuildPosition.get(), maxSubscriberPosition);
        final long hwmPosition = this.hwmPosition.getVolatile();

        final long scanOutcome = lossDetector.scan(
            termBuffers[indexByPosition(rebuildPosition, positionBitsToShift)],
            rebuildPosition,
            hwmPosition,
            nowNs,
            termLengthMask,
            positionBitsToShift,
            initialTermId);

        final int rebuildTermOffset = (int)rebuildPosition & termLengthMask;
        final long newRebuildPosition = (rebuildPosition - rebuildTermOffset) + rebuildOffset(scanOutcome);
        this.rebuildPosition.proposeMaxOrdered(newRebuildPosition);

        final long ccOutcome = congestionControl.onTrackRebuild(
            nowNs,
            minSubscriberPosition,
            nextSmPosition,
            hwmPosition,
            rebuildPosition,
            newRebuildPosition,
            lossFound(scanOutcome));

        final int windowLength = CongestionControl.receiverWindowLength(ccOutcome);
        final int threshold = CongestionControl.threshold(windowLength);

        if (CongestionControl.shouldForceStatusMessage(ccOutcome) ||
            ((timeOfLastStatusMessageScheduleNs + statusMessageTimeoutNs) - nowNs < 0) ||
            (minSubscriberPosition > (nextSmPosition + threshold)))
        {
            scheduleStatusMessage(nowNs, minSubscriberPosition, windowLength);
            cleanBufferTo(minSubscriberPosition - (termLengthMask + 1));
        }
    }
final void trackRebuild(final long nowNs, final long statusMessageTimeoutNs)
    {
        long minSubscriberPosition = Long.MAX_VALUE;
        long maxSubscriberPosition = Long.MIN_VALUE;

        for (final ReadablePosition subscriberPosition : subscriberPositions)
        {
            final long position = subscriberPosition.getVolatile();
            minSubscriberPosition = Math.min(minSubscriberPosition, position);
            maxSubscriberPosition = Math.max(maxSubscriberPosition, position);
        }

        final long rebuildPosition = Math.max(this.rebuildPosition.get(), maxSubscriberPosition);
        final long hwmPosition = this.hwmPosition.getVolatile();

        final long scanOutcome = lossDetector.scan(
            termBuffers[indexByPosition(rebuildPosition, positionBitsToShift)],
            rebuildPosition,
            hwmPosition,
            nowNs,
            termLengthMask,
            positionBitsToShift,
            initialTermId);

        final int rebuildTermOffset = (int)rebuildPosition & termLengthMask;
        final long newRebuildPosition = (rebuildPosition - rebuildTermOffset) + rebuildOffset(scanOutcome);
        this.rebuildPosition.proposeMaxOrdered(newRebuildPosition);

        final long ccOutcome = congestionControl.onTrackRebuild(
            nowNs,
            minSubscriberPosition,
            nextSmPosition,
            hwmPosition,
            rebuildPosition,
            newRebuildPosition,
            lossFound(scanOutcome));

        final int windowLength = CongestionControl.receiverWindowLength(ccOutcome);
        final int threshold = CongestionControl.threshold(windowLength);

        if (CongestionControl.shouldForceStatusMessage(ccOutcome) ||
            ((timeOfLastStatusMessageScheduleNs + statusMessageTimeoutNs) - nowNs < 0) ||
            (minSubscriberPosition > (nextSmPosition + threshold)))
        {
            scheduleStatusMessage(nowNs, minSubscriberPosition, windowLength);
            cleanBufferTo(minSubscriberPosition - (termLengthMask + 1));
        }
    }
Called from the {@link DriverConductor}.

@param nowNs                  in nanoseconds
@param statusMessageTimeoutNs for sending of Status Messages.