void ParseAndProcess(NetPacket np)
    {
        INet parsedMsg = Messages.Parse(np.message_type, np.Content());

        // Read from message queue and process!
        // Send updates to each object.
        switch ((MsgType)np.message_type)
        {
        case MsgType.Multipart:
            Multipart mpmsg = (Multipart)parsedMsg;
            // 1. If this group doesn't exist, create it
            if (!this.multipart_cache.ContainsKey(mpmsg.GroupID))
            {
                this.multipart_cache[mpmsg.GroupID] = new Multipart[mpmsg.NumParts];
            }
            // 2. Insert message into group
            this.multipart_cache[mpmsg.GroupID][mpmsg.ID] = mpmsg;
            // 3. Check if all messages exist
            bool complete     = true;
            int  totalContent = 0;
            foreach (Multipart m in this.multipart_cache[mpmsg.GroupID])
            {
                if (m == null)
                {
                    complete = false;
                    break;
                }
                totalContent += m.Content.Length;
            }
            // 4. if so, group up bytes and call 'messages.parse' on the content
            if (complete)
            {
                byte[] content = new byte[totalContent];
                int    co      = 0;
                foreach (Multipart m in this.multipart_cache[mpmsg.GroupID])
                {
                    System.Buffer.BlockCopy(m.Content, 0, content, co, m.Content.Length);
                    co += m.Content.Length;
                }
                NetPacket newpacket = NetPacket.fromBytes(content);
                if (newpacket == null)
                {
                    Debug.LogError("Multipart message content parsing failed... we done goofed");
                }
                this.ParseAndProcess(newpacket);
            }
            // 5. clean up!
            break;

        case MsgType.LoginResp:
            LoginResp lr = ((LoginResp)parsedMsg);
            characters.Add(lr.Character);
            accounts.Add(lr.AccountID);
            break;

        case MsgType.CreateAcctResp:
            CreateAcctResp car = ((CreateAcctResp)parsedMsg);
            accounts.Add(car.AccountID);
            characters.Add(car.Character);
            break;

        case MsgType.ListGamesResp:
            ListGamesResp resp = ((ListGamesResp)parsedMsg);
            for (int j = 0; j < resp.IDs.Length; j++)
            {
                GameInstance ni = new GameInstance();
                ni.ID   = resp.IDs[j];
                ni.Name = resp.Names[j];
            }
            break;

        case MsgType.GameConnected:
            GameConnected gc = ((GameConnected)parsedMsg);
            // TODO: handle connecting to a game!
            break;

        case MsgType.CreateGameResp:
            CreateGameResp cgr = ((CreateGameResp)parsedMsg);
            GameInstance   gi  = new GameInstance();
            gi.Name     = cgr.Name;
            gi.ID       = cgr.Game.ID;
            gi.entities = cgr.Game.Entities;
            games.Add(gi);
            Debug.Log("Added game: " + gi.Name);
            break;

        case MsgType.GameMasterFrame:
            GameMasterFrame gmf = ((GameMasterFrame)parsedMsg);
            Debug.Log("masterframe for gameID:" + gmf.ID.ToString());
            for (int i = 0; i < games.Count; i++)
            {
                if (games[i].ID == gmf.ID)
                {
                    Debug.Log("Updating game entities");
                    games[i].entities = gmf.Entities;
                }
            }
            break;
        }
    }