Handshake concentrates all SRPFunctions and SRPPacketData objects
        /// <summary>
        /// Authenticates the connection
        /// </summary>
        /// <param name="connection">Connection to authenticate</param>
        /// <param name="username">Username</param>
        /// <param name="password">Password</param>
        /// <param name="data">Additional data to send</param>
        public static void Authenticate(NetConnection connection, String username, String password, Byte[] data = null)
        {
            var handshake = new Handshake(true, KeySize);
            var request = handshake.GenerateSRPRequest(username, password, data ?? new Byte[0]);

            var result = Create(connection, Handshake.Contents.Username, request.ByteSize);
            handshake.WriteSRPRequest(result);

            connection.SendMessage(result, NetDeliveryMethod.ReliableUnordered, 0);
            connection.Tag = handshake;

            #if DEBUG
            Console.WriteLine(">> Autenticating with user:{0} and pass:{1} <<", username, password);
            #endif
        }
        /// <summary>
        /// Receives authentication
        /// </summary>
        /// <param name="message">Message with authentication</param>
        internal static void ReceiveAuthenticate(NetIncomingMessage message)
        {
            try
            {
                var handshake = new Handshake(false, KeySize, LogonManager);
                message.SenderConnection.Tag = handshake;
                var response = Handshake.HandshakeFromActive(message);
                var result = Create(message.SenderConnection, Handshake.Contents.Password, response.ByteSize);
                handshake.WriteSRPResponse(result);

                message.SenderConnection.SendMessage(result, NetDeliveryMethod.ReliableUnordered, 0);
                
                #if DEBUG
                Console.WriteLine(">> Authentication received with userdata: {0} <<", handshake.Username ?? handshake.UserData);
                #endif
            }
            catch (Lidgren.Network.Authentication.NetSRP.HandShakeException ex)
            {
                ExceptionHandle(message, ex.Message);
                return;
            }

            
        }
        /// <summary>
        /// Disconnects client and resets connecting status
        /// </summary>
        /// <param name="message">message to disconnect with</param>
        public void Disconnect(String message)
        {
            if (_client != null)
            {
                if (_client.ServerConnection != null && _client.ServerConnection.Status != NetConnectionStatus.Disconnected)
                    _client.Disconnect(message);
            }

            _serverEP = null;
            _handshake = null;
            _connection = null;
            SetStep(AuthenticationStatus.None);
        }
 /// <summary>
 /// Creates a new message
 /// </summary>
 /// <param name="connection"></param>
 /// <param name="reason"></param>
 /// <param name="size"></param>
 /// <returns></returns>
 private static NetOutgoingMessage Create(NetConnection connection, Handshake.Contents reason, Int32 size = 4)
 {
     var message = connection.Peer.CreateMessage(size);
     message.Write((Byte)reason);
     return message;
 }
        /// <summary>
        /// Starts authenticating the user
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="username"></param>
        /// <param name="password"></param>
        public void Authenticate(NetConnection connection, String username, String password)
        {
            // Hey we can't yet, connect first
            if (!IsConnected)
            {
                Connect(_serverEP);
                return;
            }

            SetStep(AuthenticationStatus.ServerConnection);

            NetLobby.Authenticate(connection, username, password);
            _handshake = connection.Tag as Handshake;

            SetStep(AuthenticationStatus.HandshakeData);
        }