/// <summary>
        /// Creates a <see cref="IObserver{WorkDoneProgressReport}" /> that will send all of its progress information to the same source.
        /// The other side can cancel this, so the <see cref="CancellationToken" /> should be respected.
        /// </summary>
        public async Task <IWorkDoneObserver> Create(ProgressToken progressToken, WorkDoneProgressBegin begin,
                                                     Func <Exception, WorkDoneProgressEnd> onError = null, Func <WorkDoneProgressEnd> onComplete = null, CancellationToken cancellationToken = default)
        {
            if (!_supported)
            {
                return(NoopWorkDoneObserver.Instance);
            }

            if (_activeObservers.TryGetValue(progressToken, out var item))
            {
                return(item);
            }

            await _router.SendRequest(new WorkDoneProgressCreateParams()
            {
                Token = progressToken
            }, cancellationToken);

            onError ??= error => new WorkDoneProgressEnd()
            {
                Message = error.ToString()
            };

            onComplete ??= () => new WorkDoneProgressEnd();

            var cts      = new CancellationTokenSource();
            var observer = new WorkDoneObserver(
                progressToken,
                _router,
                _serializer,
                begin,
                onError,
                onComplete,
                cts.Token
                );

            _activeObservers.TryAdd(observer.WorkDoneToken, observer);
            _activeObserverTokens.TryAdd(observer.WorkDoneToken, cts);

            return(observer);
        }
        /// <summary>
        /// Creates a <see cref="IWorkDoneObserver" /> that will send all of its progress information to the same source.
        /// </summary>
        public IWorkDoneObserver For(
            IWorkDoneProgressParams request,
            WorkDoneProgressBegin begin, Func <Exception, WorkDoneProgressEnd> onError = null,
            Func <WorkDoneProgressEnd> onComplete = null
            )
        {
            if (!IsSupported || request.WorkDoneToken == null)
            {
                return(NoopWorkDoneObserver.Instance);
            }

            if (_activeObservers.TryGetValue(request.WorkDoneToken, out var item))
            {
                return(item);
            }

            onError ??= error => new WorkDoneProgressEnd {
                Message = error.ToString()
            };

            onComplete ??= () => new WorkDoneProgressEnd();
            var cts      = new CancellationTokenSource();
            var observer = new WorkDoneObserver(
                request.WorkDoneToken,
                _router,
                _serializer,
                begin,
                onError,
                onComplete,
                cts.Token
                );

            _activeObservers.TryAdd(observer.WorkDoneToken, observer);
            _activeObserverTokens.TryAdd(observer.WorkDoneToken, cts);

            return(observer);
        }