/// <summary>
        ///   Asynchronously initialize the server side of this connection
        /// </summary>
        /// <param name="serverEndPoint"> Information of the new server this connection should connect to. </param>
        /// <returns> A task which returns the LogOnPacket or DisconnectPacket of the established connection. </returns>
        public async Task<Packet> InitializeServerAsync(RemoteServerInfo serverEndPoint)
        {
            ProxyEndPoint server = null;
            try
            {
                UnregisterServer ();
                _serverEndPoint = null;

                if (!string.IsNullOrEmpty(serverEndPoint.KickMessage))
                {
                    await KickUserAsync(serverEndPoint.KickMessage);
                    throw new OperationCanceledException("User got kicked.");
                }

                if (serverEndPoint.MinecraftVersion == 0)
                    _server.GetServerVersion(this, serverEndPoint);
                if (serverEndPoint.MinecraftVersion == null)
                {
                    var information =await  MinecraftPinger.GetServerInformationAsync(serverEndPoint.EndPoint);
                    if((serverEndPoint.MinecraftVersion = information.ProtocolVersion) == null)
                        throw new InvalidOperationException("Could not auto detect server version");
                    
                }

                var socket = new Socket(serverEndPoint.EndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
                                 {
                                     ReceiveBufferSize = 1024*1024
                                 };

                await socket.ConnectTaskAsync(serverEndPoint.EndPoint);
                server =
                    new ProxyEndPoint(
                        ServerRemoteInterface.Create(new NetworkStream(socket), (int)serverEndPoint.MinecraftVersion),
                        (int)serverEndPoint.MinecraftVersion);
                server.RemoteEndPoint = (IPEndPoint) socket.RemoteEndPoint;
                var handshakeRequest = new HandshakeRequest
                                           {
                                               UserName = Username,
                                               Host = Host,
                                               ProtocolVersion = (byte) serverEndPoint.MinecraftVersion
                                           };
                await server.SendPacketAsync(handshakeRequest);

                Packet tp = await server.ReceivePacketAsync ();

                if (tp is DisconnectPacket)
                {
                    throw new OperationCanceledException((tp as DisconnectPacket).Reason);
                }

                var encryptionKeyRequest = tp as EncryptionKeyRequest;

                server.ConnectionKey = ProtocolSecurity.GenerateAes128Key ();
                byte[] key = ProtocolSecurity.RsaEncrypt(server.ConnectionKey, encryptionKeyRequest.PublicKey.ToArray (),
                                                         false);
                byte[] verifyToken = ProtocolSecurity.RsaEncrypt(encryptionKeyRequest.VerifyToken.ToArray (),
                                                                 encryptionKeyRequest.PublicKey.ToArray (), false);

                var encryptionKeyResponse = new EncryptionKeyResponse
                                                {
                                                    SharedKey = key,
                                                    VerifyToken = verifyToken
                                                };
                await server.SendPacketAsync(encryptionKeyResponse);

                Packet p = await server.ReceivePacketAsync ();

                server.EnableAes ();

                await server.SendPacketAsync(new RespawnRequestPacket ());

                return await server.ReceivePacketAsync ();
            }
            catch (Exception ex)
            {
                _quitMessagePosted = true;
                _logger.Error("Could not connect to remote server", ex);
                throw;
            }
            finally
            {
                _serverEndPoint = server;
            }
        }