/// <summary>
        ///     Initializes a new instance of the <see cref="TcpChannel" /> class.
        /// </summary>
        /// <param name="readBuffer">Buffer used for our reading.</param>
        /// <param name="encoder">Used to encode messages before they are put in the MicroMessage body of outbound messages.</param>
        /// <param name="decoder">
        ///     Used to decode the body of incoming MicroMessages. The <c>MessageReceived</c> delegate will be
        ///     overridden by this class.
        /// </param>
        public TcpChannel(IBufferSlice readBuffer, IMessageEncoder encoder, IMessageDecoder decoder) {
            if (readBuffer == null) throw new ArgumentNullException("readBuffer");
            if (encoder == null) throw new ArgumentNullException("encoder");
            if (decoder == null) throw new ArgumentNullException("decoder");

            _readArgs = new SocketAsyncEventArgs();
            _readArgs.SetBuffer(readBuffer.Buffer, readBuffer.Offset, readBuffer.Capacity);
            _readArgs.Completed += OnReadCompleted;
            _readArgsWrapper = new SocketAsyncEventArgsWrapper(_readArgs);

            _encoder = encoder;
            _decoder = decoder;
            _decoder.MessageReceived = OnMessageReceived;

            _writeArgs = new SocketAsyncEventArgs();
            _writeArgs.Completed += OnSendCompleted;
            _writeArgsWrapper = new SocketAsyncEventArgsWrapper(_writeArgs);

            _sendCompleteAction = (channel, message) => { };
            _disconnectAction = (channel, exception) => { };
            ChannelFailure = (channel, error) => HandleDisconnect(SocketError.ProtocolNotSupported);

            RemoteEndpoint = EmptyEndpoint.Instance;
            ChannelId = GuidFactory.Create().ToString();
            Data = new ChannelData();
        }
        /// <summary>
        /// </summary>
        /// <param name="readBuffer"></param>
        /// <param name="encoder"></param>
        /// <param name="decoder"></param>
        /// <param name="sslStreamBuilder">Used to wrap the socket with a SSL stream</param>
        public SecureTcpChannel(IBufferSlice readBuffer, IMessageEncoder encoder, IMessageDecoder decoder, ISslStreamBuilder sslStreamBuilder) {
            if (readBuffer == null) throw new ArgumentNullException("readBuffer");
            if (encoder == null) throw new ArgumentNullException("encoder");
            if (decoder == null) throw new ArgumentNullException("decoder");
            if (sslStreamBuilder == null) throw new ArgumentNullException("sslStreamBuilder");

            _encoder = encoder;
            _decoder = decoder;
            _sslStreamBuilder = sslStreamBuilder;
            _decoder.MessageReceived = OnMessageReceived;

            _sendCompleteAction = (channel, message) => { };
            _disconnectAction = (channel, exception) => { };
            ChannelFailure = (channel, error) => HandleDisconnect(SocketError.ProtocolNotSupported);

            RemoteEndpoint = EmptyEndpoint.Instance;

            _readBuffer = new SocketBuffer(readBuffer);
            _writeBuffer = new SocketBuffer();
            ChannelId = GuidFactory.Create().ToString();
            Data = new ChannelData();
        }
        /// <summary>
        ///     Initializes a new instance of the <see cref="TcpChannel" /> class.
        /// </summary>
        /// <param name="readBuffer">Buffer used for our reading.</param>
        /// <param name="encoder">Used to encode messages before they are put in the MicroMessage body of outbound messages.</param>
        /// <param name="decoder">
        ///     Used to decode the body of incoming MicroMessages. The <c>MessageReceived</c> delegate will be
        ///     overridden by this class.
        /// </param>
        public TcpChannel(IBufferSlice readBuffer, IMessageEncoder encoder, IMessageDecoder decoder)
        {
            if (readBuffer == null)
            {
                throw new ArgumentNullException("readBuffer");
            }
            if (encoder == null)
            {
                throw new ArgumentNullException("encoder");
            }
            if (decoder == null)
            {
                throw new ArgumentNullException("decoder");
            }

            _readArgs = new SocketAsyncEventArgs();
            _readArgs.SetBuffer(readBuffer.Buffer, readBuffer.Offset, readBuffer.Capacity);
            _readArgs.Completed += OnReadCompleted;
            _readArgsWrapper     = new SocketAsyncEventArgsWrapper(_readArgs);

            _encoder = encoder;
            _decoder = decoder;
            _decoder.MessageReceived = OnMessageReceived;

            _writeArgs            = new SocketAsyncEventArgs();
            _writeArgs.Completed += OnSendCompleted;
            _writeArgsWrapper     = new SocketAsyncEventArgsWrapper(_writeArgs);

            _sendCompleteAction = (channel, message) => { };
            _disconnectAction   = (channel, exception) => { };
            ChannelFailure      = (channel, error) => HandleDisconnect(SocketError.ProtocolNotSupported);

            RemoteEndpoint = EmptyEndpoint.Instance;
            ChannelId      = GuidFactory.Create().ToString();
            Data           = new ChannelData();
        }