@Test
public void shouldReturnLogEntriesInResponseToRepeatedGetNextCommittedCallsWithInitialIndexToSearchFromNonZeroAndAfterTheLastAppliedIndexInTheSnapshot() throws Exception {

    // we have a snapshot that contains data to index 6 (inclusive)
    SnapshotsStore.ExtendedSnapshot storedSnapshot = new UnitTestSnapshot(6L, 2);
    // we have a log that contains entries from index 7 onwards
    LogEntry unappliedEntry0 = NOOP(8, 2);
    LogEntry unappliedEntry1 = CLIENT(9, 2, new UnitTestCommand());
    final LogEntry[] entries = new LogEntry[] {
            CLIENT(7, 2, new UnitTestCommand()),
            unappliedEntry0,
            unappliedEntry1, // <------ we've committed up to here
            CLIENT(10, 3, new UnitTestCommand()),
            CLIENT(11, 3, new UnitTestCommand()),
            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 = 9;
    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 = 6   | (SNAPSHOT)
    //  ---------------------
    //                         ^
    //                         +----------- INDEX TO SEARCH FROM = 7
    //
    Committed committed;
    // OK, now, let's start by saying that the last index we applied was '7'
    committed = algorithm.getNextCommitted(7);
    checkMatchingCommittedLogEntry(committed, unappliedEntry0);
    // second call (should get back the client entry)
    committed = algorithm.getNextCommitted(committed.getIndex()); // index = 8
    checkMatchingCommittedLogEntry(committed, unappliedEntry1);
    // a final call (should get nothing)
    committed = algorithm.getNextCommitted(committed.getIndex()); // index = 9
    assertThat(committed, nullValue());
    // we should not have changed our internal state
    assertThatLogContains(entries);
    assertThatTermAndCommitIndexHaveValues(currentTerm, commitIndex);
}