// TODO: this probably should get broken up into many smaller functions
        public override void HandleMessage(XmlDocument msg, SocketManager from)
        {
            switch (MessageTypeOf(msg))
            {
            // handle player taking action
            case "gameAction":
                if (state == State.ACTING)
                {
                    // forloop to handle all actions in the message
                    // will handle up-to but not past any illegal actions given
                    XmlDocument resp = NewEmptyMessage("actionDeltas");
                    foreach (XmlElement actionElement in msg.GetElementsByTagName("action"))
                    {
                        PlayerAction a = PlayerAction.FromXml(actionElement, cardLoader, Lane.IdIssuer);
                        if (gameManager.IsLegalAction(player, a))
                        {
                            // using three different for loops to:
                            //  1) send message faster
                            //  2) spend less time in each lock
                            handleDeltas(gameManager.GetActionDeltas(player, a), resp);
                        }
                        else
                        {
                            from.Send("<file type='error'><msg>Illegal game action</msg></file>");
                            break;
                        }
                    }
                    Socket.SendXml(resp);
                }
                else
                {
                    from.Send("<file type='error'><msg>Cannot take game actions now</msg></file>");
                }
                break;

            // handle ending turn
            case "lockInTurn":
                if (state == State.ACTING)
                {
                    // ...
                    // TES
                    Console.WriteLine("Turn locked in...");
                    state = State.WAITING;     // after locking in, the player may makthough maybe I should fixe no more actions
                    eotCallback();
                }
                else
                {
                    from.Send("<file type='error'><msg>You probably sent 'lockInTurn' multiple times</msg></file>");
                }
                break;

            // handle answers to input requests
            case "inputRequestResponse":
                XmlDocument irResp = NewEmptyMessage("turnStart");
                foreach (XmlElement reqElement in msg.GetElementsByTagName("inputRequest"))
                {
                    InputRequest req = InputRequest.FromXml(reqElement);
                    if (player.ContainsInputRequest(req) && req.Made)
                    {
                        // if the player is actually answering an input request they were assigned to
                        handleDeltas(req.GetDeltas(), irResp);
                        player.FinishInputRequest(req);
                    }
                    else
                    {
                        from.Send("<file type='error'<msg>Either: You were not assigned this Input Request, or you did not make a valid choice: "
                                  + reqElement.OuterXml + "</msg></file>");
                    }
                }
                Socket.SendXml(irResp);
                break;

            default:
                base.HandleMessage(msg, from);
                break;
            }
        }