public async Task It_refreshes_state_when_constraint_violation_is_detected()
    {
        using (var conn = CreateConnection())
        {
            await conn.OpenAsync().ConfigureAwait(false);

            await persister.Initialize(3, 6, 0, 3, conn).ConfigureAwait(false);

            var slowPersister = new InboxPersister("S", "D", CreateConnection);
            await slowPersister.Prepare();

            await persister.Deduplicate("M1", 0, conn, null).ConfigureAwait(false);

            await persister.Deduplicate("M2", 1, conn, null).ConfigureAwait(false);

            await persister.Deduplicate("M3", 2, conn, null).ConfigureAwait(false);

            await persister.Deduplicate("M4", 3, conn, null).ConfigureAwait(false);

            await persister.Deduplicate("M5", 4, conn, null).ConfigureAwait(false);

            await persister.Advance(2, 6, 9, conn);

            var result = await slowPersister.Deduplicate("M2", 1, conn, null);

            Assert.AreEqual(DeduplicationResult.Duplicate, result);
        }
    }
    public async Task It_refreshes_state_if_stale_state_is_detected()
    {
        using (var conn = CreateConnection())
        {
            await conn.OpenAsync().ConfigureAwait(false);

            await persister.Initialize(3, 6, 0, 3, conn).ConfigureAwait(false);

            var slowPersister = new InboxPersister("S", "D", CreateConnection);
            await slowPersister.Prepare();

            await persister.Deduplicate("M1", 0, conn, null).ConfigureAwait(false);

            await persister.Deduplicate("M2", 1, conn, null).ConfigureAwait(false);

            await persister.Deduplicate("M3", 2, conn, null).ConfigureAwait(false);

            await persister.Deduplicate("M4", 3, conn, null).ConfigureAwait(false);

            await persister.Deduplicate("M5", 4, conn, null).ConfigureAwait(false);

            await persister.Advance(2, 6, 9, conn);

            await slowPersister.Deduplicate("M7", 6, conn, null);
        }
    }
    public async Task It_uses_refreshed_state_to_detect_duplicates()
    {
        using (var conn = CreateConnection())
        {
            await conn.OpenAsync().ConfigureAwait(false);

            await persister.Initialize(3, 6, 0, 3, conn).ConfigureAwait(false);

            var slowPersister = new InboxPersister("S", "D", CreateConnection);
            await slowPersister.Prepare();

            await persister.Deduplicate("M0", 0, conn, null).ConfigureAwait(false);

            await persister.Deduplicate("M0", 1, conn, null).ConfigureAwait(false);

            await persister.Deduplicate("M0", 2, conn, null).ConfigureAwait(false);

            await persister.Deduplicate("M0", 3, conn, null).ConfigureAwait(false);

            await persister.Deduplicate("M0", 4, conn, null).ConfigureAwait(false);

            await persister.Advance(2, 6, 9, conn);

            await persister.Deduplicate("M5", 5, conn, null).ConfigureAwait(false);

            await persister.Deduplicate("M6", 6, conn, null).ConfigureAwait(false);

            await persister.Deduplicate("M7", 7, conn, null).ConfigureAwait(false);

            await persister.Advance(3, 9, 12, conn);

            await persister.Deduplicate("M8", 8, conn, null).ConfigureAwait(false);

            await persister.Deduplicate("M9", 9, conn, null).ConfigureAwait(false);

            await persister.Deduplicate("M10", 10, conn, null).ConfigureAwait(false);

            await persister.Advance(4, 12, 15, conn);

            var result = await slowPersister.Deduplicate("M6", 6, conn, null);

            Assert.AreEqual(DeduplicationResult.Duplicate, result);
        }
    }
    public async Task It_does_not_advance_if_new_epoch_is_higher_then_expected()
    {
        using (var conn = CreateConnection())
        {
            await conn.OpenAsync().ConfigureAwait(false);

            await persister.Initialize(3, 6, 0, 3, conn).ConfigureAwait(false);

            await persister.Deduplicate("M1", 0, conn, null).ConfigureAwait(false);

            await persister.Deduplicate("M2", 1, conn, null).ConfigureAwait(false);

            try
            {
                await persister.Advance(3, 6, 9, conn).ConfigureAwait(false);

                Assert.Fail("Expected exception");
            }
            catch (ProcessCurrentMessageLaterException e)
            {
                Assert.AreEqual("The link state is at epoch 1 and is not ready to transition to epoch 3.", e.Message);
            }
        }
    }