/// <summary>Create a new instance.</summary>
        /// <param name="connection">The <see cref="IHttp2Connection"/> associated with this decoder.</param>
        /// <param name="encoder">The <see cref="IHttp2ConnectionEncoder"/> associated with this decoder.</param>
        /// <param name="frameReader">Responsible for reading/parsing the raw frames. As opposed to this object which applies
        /// h2 semantics on top of the frames.</param>
        /// <param name="requestVerifier">Determines if push promised streams are valid.</param>
        /// <param name="autoAckSettings"><c>false</c> to disable automatically applying and sending settings acknowledge frame.
        /// The <paramref name="encoder"/> is expected to be an instance of
        /// <see cref="IHttp2SettingsReceivedConsumer"/> and will apply the earliest received but not yet
        /// ACKed SETTINGS when writing the SETTINGS ACKs. <c>true</c> to enable automatically
        /// applying and sending settings acknowledge frame.</param>
        /// <param name="autoAckPing"><c>false</c> to disable automatically sending ping acknowledge frame. <c>true</c> to enable
        /// automatically sending ping ack frame.</param>
        public DefaultHttp2ConnectionDecoder(IHttp2Connection connection,
                                             IHttp2ConnectionEncoder encoder, IHttp2FrameReader frameReader, IHttp2PromisedRequestVerifier requestVerifier,
                                             bool autoAckSettings, bool autoAckPing)
        {
            if (connection is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.connection);
            }
            if (frameReader is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.frameReader);
            }
            if (encoder is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.encoder);
            }
            if (requestVerifier is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.requestVerifier);
            }

            _autoAckPing = autoAckPing;
            if (autoAckSettings)
            {
                _settingsReceivedConsumer = null;
            }
            else
            {
                var receivedConsumer = encoder as IHttp2SettingsReceivedConsumer;
                if (receivedConsumer is null)
                {
                    ThrowHelper.ThrowInvalidOperationException_disabling_autoAckSettings_requires_encoder_IHttp2SettingsReceivedConsumer();
                }
                _settingsReceivedConsumer = receivedConsumer;
            }
            _connection      = connection;
            _frameReader     = frameReader;
            _encoder         = encoder;
            _requestVerifier = requestVerifier;
            var connLocal = connection.Local;

            if (connLocal.FlowController is null)
            {
                connLocal.FlowController = new DefaultHttp2LocalFlowController(connection);
            }
            _ = connLocal.FlowController.FrameWriter(encoder.FrameWriter);

            _internalFrameListener = new PrefaceFrameListener(this);
        }
 /// <summary>Create a new instance.</summary>
 /// <param name="connection">The <see cref="IHttp2Connection"/> associated with this decoder.</param>
 /// <param name="encoder">The <see cref="IHttp2ConnectionEncoder"/> associated with this decoder.</param>
 /// <param name="frameReader">Responsible for reading/parsing the raw frames. As opposed to this object which applies
 /// h2 semantics on top of the frames.</param>
 /// <param name="requestVerifier">Determines if push promised streams are valid.</param>
 /// <param name="autoAckSettings"><c>false</c> to disable automatically applying and sending settings acknowledge frame.
 /// The <paramref name="encoder"/> is expected to be an instance of
 /// <see cref="IHttp2SettingsReceivedConsumer"/> and will apply the earliest received but not yet
 /// ACKed SETTINGS when writing the SETTINGS ACKs. <c>true</c> to enable automatically
 /// applying and sending settings acknowledge frame.</param>
 public DefaultHttp2ConnectionDecoder(IHttp2Connection connection,
                                      IHttp2ConnectionEncoder encoder, IHttp2FrameReader frameReader, IHttp2PromisedRequestVerifier requestVerifier, bool autoAckSettings)
     : this(connection, encoder, frameReader, requestVerifier, autoAckSettings, true)
 {
 }
 /// <summary>Create a new instance.</summary>
 /// <param name="connection">The <see cref="IHttp2Connection"/> associated with this decoder.</param>
 /// <param name="encoder">The <see cref="IHttp2ConnectionEncoder"/> associated with this decoder.</param>
 /// <param name="frameReader">Responsible for reading/parsing the raw frames. As opposed to this object which applies
 /// h2 semantics on top of the frames.</param>
 /// <param name="requestVerifier">Determines if push promised streams are valid.</param>
 public DefaultHttp2ConnectionDecoder(IHttp2Connection connection,
                                      IHttp2ConnectionEncoder encoder, IHttp2FrameReader frameReader, IHttp2PromisedRequestVerifier requestVerifier)
     : this(connection, encoder, frameReader, requestVerifier, true, true)
 {
 }