public IDisposable SubscribeToStreamFrom(
            string stream,
            long?lastCheckpoint,
            bool resolveLinkTos,
            Action <Message> eventAppeared,
            Action liveProcessingStarted = null,
            Action <SubscriptionDropReason, Exception> subscriptionDropped = null,
            UserCredentials userCredentials = null,
            int readBatchSize = 500)
        {
            var settings = new CatchUpSubscriptionSettings(10, readBatchSize, false);

            StreamName = stream;
            var sub = _eventStoreConnection.SubscribeToStreamFrom(
                stream,
                lastCheckpoint,
                settings,
                resolvedEvent => {
                Interlocked.Exchange(ref _position, resolvedEvent.EventNumber);
                eventAppeared(_serializer.Deserialize(resolvedEvent) as Message);
            },
                _ => liveProcessingStarted?.Invoke(),
                (reason, exception) => subscriptionDropped?.Invoke(reason, exception),
                userCredentials);

            return(new Disposer(() => { sub.Dispose(); return Unit.Default; }));
        }
        public IDisposable SubscribeToStreamFrom(
            string stream,
            long?lastCheckpoint,
            Action <RecordedEvent> eventAppeared,
            Action liveProcessingStarted = null,
            Action <SubscriptionDropReason, Exception> subscriptionDropped = null,
            UserCredentials userCredentials = null)
        {
            StreamName = stream;
            Action <SubscriptionDropReason, Exception> dropped = (r, e) =>
            {
                _liveLock.Set();
                (subscriptionDropped ?? _subscriptionDropped)?.Invoke(r, e);
            };

            Interlocked.Exchange(ref StreamPosition, lastCheckpoint ?? 0);
            var sub = _streamStoreConnection.SubscribeToStreamFrom(
                stream,
                lastCheckpoint,
                Settings,
                eventAppeared,
                _ => liveProcessingStarted?.Invoke(),
                (reason, exception) => dropped(reason, exception),
                userCredentials);

            return(new Disposer(() => { sub.Dispose(); return Unit.Default; }));
        }