public override async Task Start(CancellationToken cancellationToken)
        {
            if (_nextVersion == StreamVersion.End)
            {
                // Get the last stream version and subscribe from there.
                var eventsPage = await ReadonlyStreamStore.ReadStreamBackwards(
                    _streamId,
                    StreamVersion.End,
                    1,
                    cancellationToken).NotOnCapturedContext();

                //Only new Messages, i.e. the one after the current last one
                _nextVersion = eventsPage.LastStreamVersion + 1;
            }
            await base.Start(cancellationToken);
        }
        public override async Task Start(CancellationToken cancellationToken)
        {
            if (FromPosition == Position.End)
            {
                // Get the last stream version and subscribe from there.
                var eventsPage = await ReadonlyStreamStore.ReadAllBackwards(
                    Position.End,
                    1,
                    cancellationToken).NotOnCapturedContext();

                // If fromPosition = 0, we have empty store, so start from zero, otherwise, the next position is
                // one after the FromPosition.
                _nextPosition = eventsPage.FromPosition == 0 ?  0 : eventsPage.FromPosition + 1;
            }
            await base.Start(cancellationToken).NotOnCapturedContext();
        }
        protected override async Task <bool> DoFetch()
        {
            var allMessagesPage = await ReadonlyStreamStore
                                  .ReadAllForwards(
                _nextPosition,
                PageSize,
                IsDisposed)
                                  .NotOnCapturedContext();

            bool isEnd = allMessagesPage.IsEnd;

            foreach (var streamMessage in allMessagesPage.Messages)
            {
                if (IsDisposed.IsCancellationRequested)
                {
                    return(true);
                }
                try
                {
                    await StreamMessageReceived(streamMessage).NotOnCapturedContext();

                    LastPosition  = streamMessage.Position;
                    _nextPosition = streamMessage.Position + 1;
                }
                catch (Exception ex)
                {
                    try
                    {
                        SubscriptionDropped.Invoke(ex.Message, ex);
                    }
                    catch
                    {
                        //TODO logging
                    }
                    finally
                    {
                        Dispose();
                    }
                }
            }

            return(isEnd);
        }
        protected override async Task <bool> DoFetch()
        {
            var streamMessagesPage = await ReadonlyStreamStore
                                     .ReadStreamForwards(
                _streamId,
                _nextVersion,
                PageSize,
                IsDisposed)
                                     .NotOnCapturedContext();

            bool isEnd = streamMessagesPage.IsEndOfStream;

            foreach (var message in streamMessagesPage.Messages)
            {
                if (IsDisposed.IsCancellationRequested)
                {
                    return(true);
                }
                _nextVersion = message.StreamVersion + 1;
                _lastVersion = message.StreamVersion;
                try
                {
                    await StreamMessageReceived(message).NotOnCapturedContext();
                }
                catch (Exception ex)
                {
                    try
                    {
                        SubscriptionDropped.Invoke(ex.Message, ex);
                    }
                    catch (Exception ex2)
                    {
                        // Need to log this
                    }
                    finally
                    {
                        Dispose();
                    }
                }
            }
            return(isEnd);
        }