public async Task <IndexResult> AddAsync(string email, Guid userId)
        {
            while (true)
            {
                var maybeEvent = await ReadUserByEmailIndexedEventAsync(email);

                if (maybeEvent.HasValue)
                {
                    return(maybeEvent.ValueOrFailure().UserId == userId
                        ? IndexResult.EmailAccepted
                        : IndexResult.EmailRejected);
                }

                try
                {
                    var userByEmailAdded = new UserIndexedByEmail(userId);
                    var eventData        = _eventSerializer.ToEventData(userByEmailAdded);
                    await _connection.AppendToStreamAsync(
                        StreamBy(email),
                        ExpectedVersion.EmptyStream,
                        eventData);

                    return(IndexResult.EmailAccepted);
                }
                catch (WrongExpectedVersionException)
                {
                }
            }
        }
        public async Task <long> SaveEventsAsync <TEvent>(string streamName, long expectedStreamVersion, IEnumerable <TEvent> events)
        {
            var eventDatas = events.Select(e => _serializer.ToEventData(e));

            var streamVersion = MapStreamVersionToEventStoreStreamVersion(expectedStreamVersion);

            // TODO: Handle failure cases
            var writeResult = await _connection.AppendToStreamAsync(streamName, streamVersion, eventDatas);

            return(writeResult.NextExpectedVersion);
        }