public async Task <TSagaData> Get <TSagaData>(Guid sagaId, SynchronizedStorageSession session, ContextBag context) where TSagaData : IContainSagaData
        {
            var operations      = new SagaPersisterAtomicOperations(session);
            var incomingMessage = context.Get <IncomingMessage>();
            var messageId       = incomingMessage.MessageId;
            var indexStream     = BuildSagaByIdStreamName(typeof(TSagaData), sagaId);
            var slice           = await session.ReadStreamEventsBackwardAsync(indexStream, -1, 1, true).ConfigureAwait(false);

            if (slice.Status != SliceReadStatus.Success)
            {
                return(default(TSagaData));
            }
            if (slice.Events[0].Event.EventType != SagaIndexEventType)
            {
                return(await operations.ReadSagaData <TSagaData>(indexStream, slice.Events[0], messageId));
            }
            var indexEntry = slice.Events[0].Event.Data.ParseJson <SagaIndexEvent>();
            var dataStream = indexEntry.DataStreamName;

            slice = await session.ReadStreamEventsBackwardAsync(dataStream, -1, 1, true).ConfigureAwait(false);

            if (slice.Status != SliceReadStatus.Success)
            {
                return(default(TSagaData));
            }
            var sagaData = await operations.ReadSagaData <TSagaData>(dataStream, slice.Events[0], messageId);

            // ReSharper disable once CompareNonConstrainedGenericWithNull
            if (sagaData != null)
            {
                return(sagaData);
            }
            throw new Exception($"Either the saga has not yet been created successfully or saga ID {sagaId} has been sent out in a ghost message.");
        }
        public async Task <TSagaData> Get <TSagaData>(string propertyName, object propertyValue, SynchronizedStorageSession session, ContextBag context) where TSagaData : IContainSagaData
        {
            var operations      = new SagaPersisterAtomicOperations(session);
            var incomingMessage = context.Get <IncomingMessage>();
            var messageId       = incomingMessage.MessageId;
            var streamName      = BuildSagaDataStreamName(typeof(TSagaData), propertyValue);
            var slice           = await session.ReadStreamEventsBackwardAsync(streamName, -1, 1, true).ConfigureAwait(false);

            if (slice.Status != SliceReadStatus.Success)
            {
                return(default(TSagaData));
            }
            return(await operations.ReadSagaData <TSagaData>(streamName, slice.Events[0], messageId));
        }
        public async Task Complete(IContainSagaData sagaData, SynchronizedStorageSession session, ContextBag context)
        {
            var indexStream = BuildSagaByIdStreamName(sagaData.GetType(), sagaData.Id);
            var slice       = await session.ReadStreamEventsBackwardAsync(indexStream, -1, 1, false).ConfigureAwait(false);

            if (slice.Status != SliceReadStatus.Success)
            {
                return;
            }
            if (slice.Events[0].Event.EventType != SagaIndexEventType)
            {
                await session.DeleteStreamAsync(indexStream, ExpectedVersion.Any, true).ConfigureAwait(false);

                return;
            }
            var indexEntry = slice.Events[0].Event.Data.ParseJson <SagaIndexEvent>();
            var dataStream = indexEntry.DataStreamName;
            await session.DeleteStreamAsync(dataStream, ExpectedVersion.Any, true).ConfigureAwait(false);

            await session.DeleteStreamAsync(indexStream, ExpectedVersion.Any, true).ConfigureAwait(false);
        }