/// <summary>
        /// Sends SSH_MSG_CHANNEL_REQUEST "exec"
        /// </summary>
        private void SendExecRequest()
        {
            lock (_stateSync) {
                if (_state != MinorState.NotReady) {
                    return;
                }
                _state = MinorState.WaitExecConfirmation;
            }

            var reqTask =
                SendRequestAndWaitResponseAsync(
                    new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_REQUEST)
                        .WriteUInt32(RemoteChannel)
                        .WriteString("exec")
                        .WriteBool(true)
                        .WriteString(_command)
                );

            Trace("CH[{0}] exec : command={1}", LocalChannel, _command);

            var result = reqTask.Result;

            lock (_stateSync) {
                if (_state != MinorState.WaitExecConfirmation) {
                    return;
                }
                if (result == ChannelRequestResult.Success) {
                    _state = MinorState.Ready;
                    goto SetStateReady;
                }
                else {
                    _state = MinorState.NotReady;
                    goto RequestFailed;
                }
            }

            SetStateReady:
            SetStateReady();
            return;

            RequestFailed:
            RequestFailed();
            return;
        }
        /// <summary>
        /// Sends SSH_MSG_CHANNEL_REQUEST "x11-req"
        /// </summary>
        private bool SendX11Request()
        {
            if (_param.X11ForwardingParams == null || _x11ConnectionManager == null) {
                return true;    // do the next task
            }

            lock (_stateSync) {
                _state = MinorState.WaitX11ReqConfirmation;
            }

            var reqTask =
                SendRequestAndWaitResponseAsync(
                    new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_REQUEST)
                        .WriteUInt32(RemoteChannel)
                        .WriteString("x11-req")
                        .WriteBool(true)
                        .WriteBool(false)   // not single-connection
                        .WriteString(_x11ConnectionManager.SpoofedAuthProtocolName)
                        .WriteString(_x11ConnectionManager.SpoofedAuthProtocolDataHex)
                        .WriteUInt32((uint)_x11ConnectionManager.Params.Screen) // screen number
                );

            Trace("CH[{0}] x11-req", LocalChannel);

            var result = reqTask.Result;

            lock (_stateSync) {
                if (_state != MinorState.WaitX11ReqConfirmation) {
                    return false;
                }
                if (result == ChannelRequestResult.Success) {
                    Trace("CH[{0}] the request of the X11 forwarding has been accepted.", LocalChannel);
                    return true;    // do the next task
                }
                else {
                    Trace("CH[{0}] the request of the X11 forwarding has been rejected.", LocalChannel);
                    _state = MinorState.NotReady;
                    goto RequestFailed;
                }
            }

            RequestFailed:
            RequestFailed();
            return false;
        }
        /// <summary>
        /// Sends SSH_MSG_CHANNEL_REQUEST "pty-req"
        /// </summary>
        private bool SendPtyRequest()
        {
            lock (_stateSync) {
                if (_state != MinorState.NotReady) {
                    return false;
                }
                _state = MinorState.WaitPtyReqConfirmation;
            }

            var reqTask =
                SendRequestAndWaitResponseAsync(
                    new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_REQUEST)
                        .WriteUInt32(RemoteChannel)
                        .WriteString("pty-req")
                        .WriteBool(true)
                        .WriteString(_param.TerminalName)
                        .WriteInt32(_param.TerminalWidth)
                        .WriteInt32(_param.TerminalHeight)
                        .WriteInt32(_param.TerminalPixelWidth)
                        .WriteInt32(_param.TerminalPixelHeight)
                        .WriteAsString(new byte[0])
                );

            Trace("CH[{0}] pty-req : term={1} width={2} height={3} pixelWidth={4} pixelHeight={5}",
                LocalChannel, _param.TerminalName,
                _param.TerminalWidth, _param.TerminalHeight,
                _param.TerminalPixelWidth, _param.TerminalPixelHeight);

            var result = reqTask.Result;

            lock (_stateSync) {
                if (_state != MinorState.WaitPtyReqConfirmation) {
                    return false;
                }
                if (result == ChannelRequestResult.Success) {
                    return true;    // do the next task
                }
                else {
                    _state = MinorState.NotReady;
                    goto RequestFailed;
                }
            }

            RequestFailed:
            RequestFailed();
            return false;
        }
        /// <summary>
        /// Sends SSH_MSG_CHANNEL_REQUEST "shell"
        /// </summary>
        private bool SendShellRequest()
        {
            lock (_stateSync) {
                _state = MinorState.WaitShellConfirmation;
            }

            var reqTask =
                SendRequestAndWaitResponseAsync(
                    new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_REQUEST)
                        .WriteUInt32(RemoteChannel)
                        .WriteString("shell")
                        .WriteBool(true)
                );

            Trace("CH[{0}] shell", LocalChannel);

            var result = reqTask.Result;

            lock (_stateSync) {
                if (_state != MinorState.WaitShellConfirmation) {
                    return false;
                }
                if (result == ChannelRequestResult.Success) {
                    _state = MinorState.Ready;
                    goto SetStateReady;
                }
                else {
                    _state = MinorState.NotReady;
                    goto RequestFailed;
                }
            }

            SetStateReady:
            SetStateReady();
            return true;

            RequestFailed:
            RequestFailed();
            return false;
        }
        /// <summary>
        /// Sends SSH_MSG_CHANNEL_REQUEST "*****@*****.**"
        /// </summary>
        private bool SendAuthAgentRequest()
        {
            if (_param.AgentForwardingAuthKeyProvider == null) {
                return true;    // do the next task
            }

            lock (_stateSync) {
                _state = MinorState.WaitAuthAgentReqConfirmation;
            }

            var reqTask =
                SendRequestAndWaitResponseAsync(
                    new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_REQUEST)
                        .WriteUInt32(RemoteChannel)
                        .WriteString("*****@*****.**")
                        .WriteBool(true)
                );

            Trace("CH[{0}] [email protected]", LocalChannel);

            var result = reqTask.Result;

            lock (_stateSync) {
                if (_state != MinorState.WaitAuthAgentReqConfirmation) {
                    return false;
                }
                if (result == ChannelRequestResult.Success) {
                    Trace("CH[{0}] the request of the agent forwarding has been accepted.", LocalChannel);
                    return true;    // do the next task
                }
                else {
                    Trace("CH[{0}] the request of the agent forwarding has been rejected.", LocalChannel);
                    _state = MinorState.NotReady;
                    goto RequestFailed;
                }
            }

            RequestFailed:
            RequestFailed();
            return false;
        }