protected void ReceiveCallback(object sender, SocketAsyncEventArgs receiveEventArgs)
        {
            if (_receiveTimeoutScheduleId > 0)
                _server.Scheduler.Remove(_receiveTimeoutScheduleId);

            if (receiveEventArgs.BytesTransferred > 0 && receiveEventArgs.SocketError == SocketError.Success)
            {
                _message.WriterIndex += receiveEventArgs.BytesTransferred;

                var receiveType = (ReceiveType)receiveEventArgs.UserToken;

                if (receiveType == ReceiveType.Head && receiveEventArgs.BytesTransferred != 2)
                {
                    //Error, we could not retrive the message length.
                    OnExceptionCaught(new Exception("Unable to receive message length."));
                }
                else
                {
                    var length = _message.PeekUShort() + 2;

                    if (length > _message.Capacity)
                    {
                        OnExceptionCaught(new Exception("The message length is larger then the buffer."));
                    }
                    else if (length == _message.ReadableBytes)
                    {
                        _message.GetUShort();

                        if (!_firstMessageReceived)
                        {
                            _firstMessageReceived = true;

                            _message.MarkReaderIndex();
                            var hasChecksum = _message.GetUInt() == Adler.Generate(_message);
                            if (!hasChecksum)
                                _message.ResetReaderIndex();

                            if (_protocol == null)
                            {
                                _protocol = _servicePort.CreateProtocol(_message, hasChecksum);

                                if (_protocol == null)
                                {
                                    Logger.Error("No protocol found. Closing connection.");
                                    Close();
                                    return;
                                }

                                _protocol.Connection = this;
                            }
                            else
                            {
                                _message.GetByte(); //remove the protocol byte.
                            }

                            OnReceiveFirstMessage();
                        }
                        else
                        {
                            OnReceiveMessage();
                        }

                        Receive(receiveEventArgs);
                    }
                    else
                    {
                        //incomplete message
                        receiveEventArgs.SetBuffer(_message.Buffer, _message.WriterIndex, length - _message.ReadableBytes);
                        receiveEventArgs.UserToken = ReceiveType.Body;

                        if (_receiveTimeout > 0)
                            _receiveTimeoutScheduleId = _server.Scheduler.Add(_receiveTimeout, OnMessageReceiveTimeout);

                        if (!_socket.ReceiveAsync(receiveEventArgs))
                            ReceiveCallback(this, receiveEventArgs);
                    }
                }
            }
            else
            {
                Close();
            }
        }
        public void Accept(Protocol protocol)
        {
            if (protocol != null)
            {
                _protocol = protocol;
                _protocol.Connection = this;

                OnOpen();
            }

            Receive(null);
        }