private void ProcessNetworkMessages()
        {
            NetIncomingMessage im;

            while ((im = this.networkManager.ReadMessage()) != null)
            {
                switch (im.MessageType)
                {
                case NetIncomingMessageType.VerboseDebugMessage:
                case NetIncomingMessageType.DebugMessage:
                case NetIncomingMessageType.WarningMessage:
                case NetIncomingMessageType.ErrorMessage:
                    Console.WriteLine(im.ReadString());
                    break;

                case NetIncomingMessageType.StatusChanged:
                    switch ((NetConnectionStatus)im.ReadByte())
                    {
                    case NetConnectionStatus.Connected:
                        if (!this.IsHost)
                        {
                            var message = new UpdatePlayerStateMessage(im.SenderConnection.RemoteHailMessage);
                            this.playerManager.AddPlayer(message.Id, message.Position, message.Velocity, true);
                            Console.WriteLine("Connected to {0}", im.SenderEndpoint);
                        }
                        else
                        {
                            Console.WriteLine("{0} Connected", im.SenderEndpoint);
                        }
                        break;

                    case NetConnectionStatus.Disconnected:
                        Console.WriteLine(this.IsHost ? "{0} Disconnected" : "Disconnected from {0}", im.SenderEndpoint);
                        break;

                    case NetConnectionStatus.RespondedAwaitingApproval:
                        NetOutgoingMessage hailMessage = this.networkManager.CreateMessage();
                        new UpdatePlayerStateMessage(this.playerManager.AddPlayer(false)).Encode(hailMessage);
                        im.SenderConnection.Approve(hailMessage);
                        break;
                    }
                    break;

                case NetIncomingMessageType.Data:
                    var gameMessageType = (GameMessageTypes)im.ReadByte();
                    switch (gameMessageType)
                    {
                    case GameMessageTypes.UpdatePlayerState:
                        this.HandleUpdatePlayerStateMessage(im);
                        break;
                    }
                    break;
                }
                this.networkManager.Recycle(im);
            }
        }
        private void HandleUpdatePlayerStateMessage(NetIncomingMessage im)
        {
            var message = new UpdatePlayerStateMessage(im);

            var timeDelay = (float)(NetTime.Now - im.SenderConnection.GetLocalTime(message.MessageTime));

            Player player = this.playerManager.GetPlayer(message.Id)
                            ??
                            this.playerManager.AddPlayer(
                message.Id, message.Position, message.Velocity, false);

            if (player.LastUpdateTime < message.MessageTime)
            {
                player.SimulationState.Position = message.Position += message.Velocity * timeDelay;
                player.SimulationState.Velocity = message.Velocity;

                player.LastUpdateTime = message.MessageTime;
            }
        }