Implements "forwarded-tcpip" SSH channel.
Inheritance: ServerChannel, IChannelForwardedTcpip
        public void CleanUp()
        {
            if (_remoteListener != null)
            {
                _remoteListener.Stop();
                _remoteListener = null;
            }

            if (_channelThread != null)
            {
                if (_channelThread.IsAlive)
                    _channelThread.Abort();
                _channelThread = null;
            }
            if (_channel != null)
            {
                _channel.Dispose();
                _channel = null;
            }
        }
        private void Arrange()
        {
            var random = new Random();
            _localChannelNumber = (uint) random.Next(0, int.MaxValue);
            _localWindowSize = (uint) random.Next(2000, 3000);
            _localPacketSize = (uint) random.Next(1000, 2000);
            _remoteChannelNumber = (uint) random.Next(0, int.MaxValue);
            _remoteWindowSize = (uint) random.Next(0, int.MaxValue);
            _remotePacketSize = (uint) random.Next(100, 200);
            _channelBindFinishedWaitHandle = new ManualResetEvent(false);
            _channelException = null;
            _connectedRegister = new List<Socket>();
            _disconnectedRegister = new List<Socket>();
            _connectionInfoTimeout = TimeSpan.FromSeconds(5);

            _remoteEndpoint = new IPEndPoint(IPAddress.Loopback, 8122);

            _sessionMock = new Mock<ISession>(MockBehavior.Strict);
            _connectionInfoMock = new Mock<IConnectionInfo>(MockBehavior.Strict);
            _forwardedPortMock = new Mock<IForwardedPort>(MockBehavior.Strict);

            var sequence = new MockSequence();
            _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true);
            _sessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object);
            _connectionInfoMock.InSequence(sequence).Setup(p => p.Timeout).Returns(_connectionInfoTimeout);
            _sessionMock.InSequence(sequence).Setup(
                p => p.SendMessage(
                    It.Is<ChannelOpenConfirmationMessage>(
                        m => m.LocalChannelNumber == _remoteChannelNumber
                             &&
                             m.InitialWindowSize == _localWindowSize
                             &&
                             m.MaximumPacketSize == _localPacketSize
                             &&
                             m.RemoteChannelNumber == _localChannelNumber)
                    ));
            _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true);
            _sessionMock.InSequence(sequence)
                .Setup(
                    p => p.TrySendMessage(It.Is<ChannelEofMessage>(m => m.LocalChannelNumber == _remoteChannelNumber)))
                .Returns(true);
            _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true);
            _sessionMock.InSequence(sequence)
                .Setup(
                    p => p.TrySendMessage(It.Is<ChannelCloseMessage>(m => m.LocalChannelNumber == _remoteChannelNumber)))
                .Returns(true);
            _sessionMock.InSequence(sequence)
                .Setup(p => p.WaitOnHandle(It.IsNotNull<WaitHandle>()))
                .Callback<WaitHandle>(
                    w =>
                        {
                            _sessionMock.Raise(
                                s => s.ChannelCloseReceived += null,
                                new MessageEventArgs<ChannelCloseMessage>(new ChannelCloseMessage(_localChannelNumber)));
                            w.WaitOne();
                        });

            _remoteListener = new AsyncSocketListener(_remoteEndpoint);
            _remoteListener.Connected += socket => _connectedRegister.Add(socket);
            _remoteListener.Disconnected += socket => _disconnectedRegister.Add(socket);
            _remoteListener.Start();

            _channel = new ChannelForwardedTcpip(
                _sessionMock.Object,
                _localChannelNumber,
                _localWindowSize,
                _localPacketSize,
                _remoteChannelNumber,
                _remoteWindowSize,
                _remotePacketSize);

            _channelThread = new Thread(() =>
                {
                    try
                    {
                        _channel.Bind(_remoteEndpoint, _forwardedPortMock.Object);
                    }
                    catch (Exception ex)
                    {
                        _channelException = ex;
                    }
                    finally
                    {
                        _channelBindFinishedWaitHandle.Set();
                    }
                });
            _channelThread.Start();

            // give channel time to bind to remote endpoint
            Thread.Sleep(100);
        }