/// <summary>
        /// Finds an already-existing instance of the given saga data type that has a property with the given <paramref name="propertyName"/>
        /// whose value matches <paramref name="propertyValue"/>. Returns null if no such instance could be found
        /// </summary>
        public async Task <ISagaData> Find(Type sagaDataType, string propertyName, object propertyValue)
        {
            using (var session = _documentStore.OpenAsyncSession())
            {
                string sagaDataDocumentId;

                if (propertyName == _sagaDataIdPropertyName)
                {
                    sagaDataDocumentId = SagaDataDocument.GetIdFromGuid((Guid)propertyValue);
                }
                else
                {
                    var sagaCorrelationPropertyDocumentId =
                        SagaCorrelationPropertyDocument.GetIdForCorrelationProperty(sagaDataType, propertyName,
                                                                                    propertyValue);

                    var existingSagaCorrelationPropertyDocument =
                        await session.LoadAsync <SagaCorrelationPropertyDocument>(sagaCorrelationPropertyDocumentId);

                    sagaDataDocumentId = existingSagaCorrelationPropertyDocument?.SagaDataDocumentId;
                }

                if (sagaDataDocumentId == null)
                {
                    return(null);
                }

                var existingSagaDataDocument = await session.LoadAsync <SagaDataDocument>(sagaDataDocumentId);

                return(existingSagaDataDocument?.SagaData);
            }
        }
        async Task <IEnumerable <string> > SaveCorrelationProperties(IAsyncDocumentSession session, ISagaData sagaData, IEnumerable <ISagaCorrelationProperty> correlationProperties, string sagaDataDocumentId)
        {
            var documentIds = new List <string>();

            foreach (var correlationProperty in correlationProperties)
            {
                var propertyName = correlationProperty.PropertyName;
                var value        = sagaData.GetType().GetProperty(propertyName).GetValue(sagaData).ToString();

                var documentId = SagaCorrelationPropertyDocument.GetIdForCorrelationProperty(correlationProperty.SagaDataType, propertyName,
                                                                                             value);

                var existingSagaCorrelationPropertyDocument =
                    await session.LoadAsync <SagaCorrelationPropertyDocument>(documentId);

                if (existingSagaCorrelationPropertyDocument != null)
                {
                    if (existingSagaCorrelationPropertyDocument.SagaDataDocumentId != sagaDataDocumentId)
                    {
                        throw new ConcurrencyException(
                                  $"Could not save correlation properties. The following correlation property already exists with the same value for another saga: {propertyName} - {value}");
                    }
                }
                else
                {
                    var sagaCorrelationPropertyDocument = new SagaCorrelationPropertyDocument(correlationProperty.SagaDataType, propertyName, value, sagaDataDocumentId);

                    await session.StoreAsync(sagaCorrelationPropertyDocument, documentId);
                }

                documentIds.Add(documentId);
            }

            return(documentIds);
        }
        async Task<IEnumerable<string>> SaveCorrelationProperties(IAsyncDocumentSession session, ISagaData sagaData, IEnumerable<ISagaCorrelationProperty> correlationProperties, string sagaDataDocumentId)
        {
            var documentIds = new List<string>();

            foreach (var correlationProperty in correlationProperties)
            {
                var propertyName = correlationProperty.PropertyName;
                var value = sagaData.GetType().GetProperty(propertyName).GetValue(sagaData).ToString();

                var documentId = SagaCorrelationPropertyDocument.GetIdForCorrelationProperty(correlationProperty.SagaDataType, propertyName,
                    value);

                var existingSagaCorrelationPropertyDocument =
                    await session.LoadAsync<SagaCorrelationPropertyDocument>(documentId);

                if (existingSagaCorrelationPropertyDocument != null)
                {
                    if (existingSagaCorrelationPropertyDocument.SagaDataDocumentId != sagaDataDocumentId)
                    {
                        throw new ConcurrencyException(
                            $"Could not save correlation properties. The following correlation property already exists with the same value for another saga: {propertyName} - {value}");
                    }
                }
                else
                {
                    var sagaCorrelationPropertyDocument = new SagaCorrelationPropertyDocument(correlationProperty.SagaDataType, propertyName, value, sagaDataDocumentId);

                    await session.StoreAsync(sagaCorrelationPropertyDocument, documentId);
                }
                
                documentIds.Add(documentId);
            }

            return documentIds;
        }