public long scan(
        final UnsafeBuffer termBuffer,
        final long rebuildPosition,
        final long hwmPosition,
        final long nowNs,
        final int termLengthMask,
        final int positionBitsToShift,
        final int initialTermId)
    {
        boolean lossFound = false;
        int rebuildOffset = (int)rebuildPosition & termLengthMask;

        if (rebuildPosition < hwmPosition)
        {
            final int rebuildTermCount = (int)(rebuildPosition >>> positionBitsToShift);
            final int hwmTermCount = (int)(hwmPosition >>> positionBitsToShift);

            final int rebuildTermId = initialTermId + rebuildTermCount;
            final int hwmTermOffset = (int)hwmPosition & termLengthMask;
            final int limitOffset = rebuildTermCount == hwmTermCount ? hwmTermOffset : termLengthMask + 1;

            rebuildOffset = scanForGap(termBuffer, rebuildTermId, rebuildOffset, limitOffset, this);
            if (rebuildOffset < limitOffset)
            {
                if (scannedTermOffset != activeTermOffset || scannedTermId != activeTermId)
                {
                    activateGap(nowNs);
                    lossFound = true;
                }

                checkTimerExpiry(nowNs);
            }
        }

        return pack(rebuildOffset, lossFound);
    }
@Test
    void shouldHandleHwmGreaterThanCompletedBuffer()
    {
        lossDetector = getLossHandlerWithLongRetry();

        long rebuildPosition = ACTIVE_TERM_POSITION;
        final long hwmPosition = ACTIVE_TERM_POSITION + TERM_BUFFER_LENGTH + ALIGNED_FRAME_LENGTH;

        insertDataFrame(offsetOfMessage(0));
        rebuildPosition += ALIGNED_FRAME_LENGTH;

        lossDetector.scan(termBuffer, rebuildPosition, hwmPosition, currentTime, MASK, POSITION_BITS_TO_SHIFT, TERM_ID);
        currentTime = TimeUnit.MILLISECONDS.toNanos(40);
        lossDetector.scan(termBuffer, rebuildPosition, hwmPosition, currentTime, MASK, POSITION_BITS_TO_SHIFT, TERM_ID);

        verify(lossHandler).onGapDetected(TERM_ID, offsetOfMessage(1), TERM_BUFFER_LENGTH - (int)rebuildPosition);
    }