/// <summary>
        /// Called when the client wants to send a user defined message to the server.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SendButton_Click(object sender, RoutedEventArgs e)
        {
            LogToTextBox("Attempting to send UserDefined message");

            Message m = new Message();
            m.mID = IDTextBox.Text;
            m.mType = MessageType.UserDefined;
            m.mValues.Add("Payload", PayloadTextBox.Text);

            SendInfo sendInfo;
            sendInfo.client = mClient;
            sendInfo.data = m.ToString();

            Thread t = new Thread(NewSendThread);
            t.Start(sendInfo);
        }
        /// <summary>
        /// Set up an unsubscribe message to the server.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UnsubscribeButton_Click(object sender, RoutedEventArgs e)
        {
            LogToTextBox("Attempting to send Unsubscribe message");

            Message m = new Message();
            m.mID = SubscribeIDTextBox.Text;
            m.mType = MessageType.Unsubscribe;

            SendInfo sendInfo;
            sendInfo.client = mClient;
            sendInfo.data = m.ToString();

            Thread t = new Thread(NewSendThread);
            t.Start(sendInfo);
        }
        /// <summary>
        /// Called when the server gets a callback from BeginReceive
        /// </summary>
        /// <param name="ar">Holds state information like the client socket and buffer size</param>
        private void ReadCallback(IAsyncResult ar)
        {
            // Unblock any previous read calls
            mWindowClosing.Set();

            // Set up state data
            String content = String.Empty;
            StateObject state = (StateObject)ar.AsyncState;
            Socket handler = state.workSocket;

            try
            {
                int bytesRead = handler.EndReceive(ar);

                if (bytesRead > 0)
                {
                    // Get the data that was read
                    state.sb.Clear();
                    state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
                    content = state.sb.ToString();
                    LogToTextBox("Received message: " + content);

                    // Construct a new message from the received data
                    Message m = new Message(content);
                    if (m.mType == MessageType.Subscribe)
                    {
                        // If subscribe, just add the client to the subscribers list
                        if (mIDToSubscribers.ContainsKey(m.mID))
                        {
                            mIDToSubscribers[m.mID].Add(handler);
                        }
                        else
                        {
                            List<Socket> clients = new List<Socket>();
                            clients.Add(handler);
                            mIDToSubscribers.Add(m.mID, clients);
                        }
                    }
                    if (m.mType == MessageType.Unsubscribe)
                    {
                        // If unsubscribe, just remove the client from the subscribers list.
                        if (mIDToSubscribers.ContainsKey(m.mID))
                        {
                            mIDToSubscribers[m.mID].Remove(handler);
                        }
                    }
                    if (m.mType == MessageType.UserDefined)
                    {
                        // If Userdefined, distribute it to all client subscribers
                        if (mIDToSubscribers.ContainsKey(m.mID))
                        {
                            List<Socket> socketsToRemove = new List<Socket>();

                            foreach (Socket client in mIDToSubscribers[m.mID])
                            {
                                byte[] byteData = Encoding.ASCII.GetBytes(content);
                                try
                                {
                                    client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);
                                }
                                catch (Exception ex)
                                {
                                    LogToTextBox(ex.ToString());
                                    socketsToRemove.Add(client);
                                }
                            }
                            foreach (Socket client in socketsToRemove)
                            {
                                foreach (KeyValuePair<string, List<Socket>> pair in mIDToSubscribers)
                                {
                                    pair.Value.Remove(client);
                                }

                                mClients.Remove(client);
                            }

                            socketsToRemove.Clear();
                        }
                    }
                }

                // Start another read
                mWindowClosing.Reset();
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
                mWindowClosing.WaitOne();
            }
            catch (Exception ex)
            {
                LogToTextBox(ex.ToString());
            }
        }