@Test
public void shouldReturnLogEntriesInResponseToRepeatedGetNextCommittedCallsWithInitialIndexToSearchFromNonZeroAndOverlapBetweenLogAndSnapshot() throws Exception {

    // we have a snapshot that contains data to index 9 (inclusive)
    long lastAppliedIndex = 9;
    SnapshotsStore.ExtendedSnapshot storedSnapshot = new UnitTestSnapshot(lastAppliedIndex, 2);
    // we have a log that contains entries from index 7 onwards
    LogEntry unappliedEntry0 = CLIENT(11, 3, new UnitTestCommand());
    final LogEntry[] entries = new LogEntry[] {
            CLIENT(7, 2, new UnitTestCommand()),
            NOOP(8, 2),
            NOOP(9, 3),
            CLIENT(10, 3, new UnitTestCommand()),
            unappliedEntry0, // <------ we've committed up to here
            CLIENT(12, 3, new UnitTestCommand())
    };
    clearLog(); // clear out the log completely - we don't even want the sentinel
    insertIntoLog(entries);
    // set the current term
    long currentTerm = 3;
    store.setCurrentTerm(currentTerm);
    // set the committed index
    long commitIndex = 11;
    store.setCommitIndex(commitIndex);
    // have the snapshot store return the snapshot
    when(snapshotsStore.getLatestSnapshot()).thenReturn(storedSnapshot);
    //
    // situation is as follows:
    //
    //                                             +----------- COMMITTED
    //                                             V
    //                       ------------------------------
    //    .... EMPTY ....   | 07 | 08 | 09 | 10 | 11 | 12 | (LOG)
    //                      ------------------------------
    //  ------------------------------------
    // |         LAST APPLIED = 9          | (SNAPSHOT)
    // ------------------------------------
    //                                      ^
    //                                      +----------- INDEX TO SEARCH FROM = 10
    //
    Committed committed;
    // OK, now, let's start by saying that the last index we applied was 10
    // we should get the only remaining committed unapplied entry back
    committed = algorithm.getNextCommitted(10);
    checkMatchingCommittedLogEntry(committed, unappliedEntry0);
    // if we make one more call we should get nothing
    committed = algorithm.getNextCommitted(committed.getIndex()); // index = 11
    assertThat(committed, nullValue());
    // we haven't changed the state at all
    assertThatLogContains(entries);
    assertThatTermAndCommitIndexHaveValues(currentTerm, commitIndex);
}