public int OnReceive(byte[] buffer, int length)
        {
            if (length >= Messaging.HEADER_SIZE)
            {
                Messaging.ReadHeader(buffer, out int messageType, out int messageLength, out int messageVersion);

                if (length - Messaging.HEADER_SIZE >= messageLength)
                {
                    byte[] encryptedBytes = new byte[messageLength];
                    byte[] encodingBytes;

                    Buffer.BlockCopy(buffer, Messaging.HEADER_SIZE, encryptedBytes, 0, messageLength);

                    int encodingLength;

                    if (this.m_receiveEncrypter != null)
                    {
                        encodingLength = messageLength - this.m_receiveEncrypter.GetOverheadEncryption();
                        encodingBytes  = new byte[encodingLength];

                        this.DecryptUsingEncrypter(encryptedBytes, encodingBytes, messageLength);
                    }
                    else
                    {
                        if (this.m_pepperState == PepperState.DEFAULT)
                        {
                            if (messageType == ClientHelloMessage.MESSAGE_TYPE)
                            {
                                this.m_pepperState = PepperState.AUTHENTIFICATION;

                                encodingLength = messageLength;
                                encodingBytes  = encryptedBytes;
                            }
                            else if (messageType == LoginMessage.MESSAGE_TYPE)
                            {
                                this.m_pepperState = PepperState.DISABLED;
                                this.InitRC4Encryption(this.GetDefaultNonce());

                                encodingLength = messageLength - this.m_receiveEncrypter.GetOverheadEncryption();
                                encodingBytes  = new byte[encodingLength];

                                this.DecryptUsingEncrypter(encryptedBytes, encodingBytes, messageLength);
                            }
                            else
                            {
                                return(messageLength + Messaging.HEADER_SIZE);
                            }
                        }
                        else if (this.m_pepperState == PepperState.AUTHENTIFICATION_SERVER)
                        {
                            if (messageType != LoginMessage.MESSAGE_TYPE)
                            {
                                return(messageLength + Messaging.HEADER_SIZE);
                            }
                            throw new NotImplementedException();
                        }
                        else
                        {
                            return(messageLength + Messaging.HEADER_SIZE);
                        }
                    }

                    PiranhaMessage piranhaMessage = this.m_messageFactory.CreateMessageByType(messageType);

                    if (piranhaMessage != null)
                    {
                        piranhaMessage.GetByteStream().SetByteArray(encodingBytes, encodingLength);
                        piranhaMessage.SetMessageVersion(messageVersion);

                        try
                        {
                            piranhaMessage.Decode();

                            if (!piranhaMessage.IsServerToClientMessage())
                            {
                                MessageHandler.EnqueueReceive(piranhaMessage, this.m_clientConnection);
                            }
                        }
                        catch (Exception exception)
                        {
                            Logging.Error(string.Format("Messaging::onReceive: error while the decoding of message type {0}, trace: {1}", messageType, exception));
                        }
                    }
                    else
                    {
                        Logging.Warning(string.Format("Messaging::onReceive: ignoring message of unknown type {0}", messageType));
                    }

                    return(messageLength + Messaging.HEADER_SIZE);
                }
                else
                {
                    int httpHeader = buffer[0] << 16 | buffer[1] << 8 | buffer[2];

                    if (httpHeader == 0x474554) // httpHeader == GET
                    {
                        return(-1);
                    }
                }
            }

            return(0);
        }