/// <summary>
        /// Initializes a new instance of the <see cref="MessageFormatterProgressTracker"/> class.
        /// </summary>
        /// <param name="jsonRpc">The <see cref="JsonRpc"/> object that ultimately owns this tracker.</param>
        /// <param name="formatterState">The formatter that owns this tracker.</param>
        public MessageFormatterProgressTracker(JsonRpc jsonRpc, IJsonRpcFormatterState formatterState)
        {
            Requires.NotNull(jsonRpc, nameof(jsonRpc));
            Requires.NotNull(formatterState, nameof(formatterState));

            this.formatterState = formatterState;

            IJsonRpcFormatterCallbacks callbacks = jsonRpc;

            callbacks.RequestTransmissionAborted += (s, e) => this.CleanUpResources(e.RequestId);
            callbacks.ResponseReceived           += (s, e) => this.CleanUpResources(e.RequestId);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="MessageFormatterDuplexPipeTracker"/> class.
        /// </summary>
        /// <param name="jsonRpc">The <see cref="JsonRpc"/> instance that may be used to send or receive RPC messages related to <see cref="IAsyncEnumerable{T}"/>.</param>
        /// <param name="formatterState">The formatter that owns this tracker.</param>
        public MessageFormatterDuplexPipeTracker(JsonRpc jsonRpc, IJsonRpcFormatterState formatterState)
        {
            Requires.NotNull(jsonRpc, nameof(jsonRpc));
            Requires.NotNull(formatterState, nameof(formatterState));

            this.formatterState = formatterState;

            // We don't offer a way to remove these handlers because this object should has a lifetime closely tied to the JsonRpc object anyway.
            IJsonRpcFormatterCallbacks callbacks = jsonRpc;

            callbacks.RequestTransmissionAborted += (s, e) => this.CleanUpOutboundResources(e.RequestId, successful: false);
            callbacks.ResponseReceived           += (s, e) => this.CleanUpOutboundResources(e.RequestId, successful: e.IsSuccessfulResponse);
            callbacks.ResponseSent += (s, e) => this.CleanUpInboundResources(e.RequestId, successful: e.IsSuccessfulResponse);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="MessageFormatterEnumerableTracker"/> class.
        /// </summary>
        /// <param name="jsonRpc">The <see cref="JsonRpc"/> instance that may be used to send or receive RPC messages related to <see cref="IAsyncEnumerable{T}"/>.</param>
        /// <param name="formatterState">The formatter that owns this tracker.</param>
        public MessageFormatterEnumerableTracker(JsonRpc jsonRpc, IJsonRpcFormatterState formatterState)
        {
            Requires.NotNull(jsonRpc, nameof(jsonRpc));
            Requires.NotNull(formatterState, nameof(formatterState));

            this.jsonRpc        = jsonRpc;
            this.formatterState = formatterState;

            jsonRpc.AddLocalRpcMethod(NextMethodName, OnNextAsyncMethodInfo, this);
            jsonRpc.AddLocalRpcMethod(DisposeMethodName, OnDisposeAsyncMethodInfo, this);
            this.formatterState = formatterState;

            // We don't offer a way to remove these handlers because this object should has a lifetime closely tied to the JsonRpc object anyway.
            IJsonRpcFormatterCallbacks callbacks = jsonRpc;

            callbacks.RequestTransmissionAborted += (s, e) => this.CleanUpResources(e.RequestId);
            callbacks.ResponseReceived           += (s, e) => this.CleanUpResources(e.RequestId);
        }