/// <summary>
        /// When the local peer list changes, we have to send updates to
        /// the other end of this connection.
        /// </summary>
        /// <param name="newPeerList"></param>
        /// <param name="oldPeerList"></param>
        private void LocalPeerListChangedCallback(NodePeerList newPeerList,
                                                  NodePeerList oldPeerList)
        {
            string s = newPeerList.ToXml(oldPeerList);

            Send(s);
        }
        internal void ThreadStart(Object o)
        {
            SslStream sslStream = o as SslStream;

            if (sslStream != null)
            {
                //Have to send the local peer list to the other end of
                //the connection, and we also need to be notified of any
                //changes to the local peer list.  This has to be done
                //in one operation so a new node can't sneak in between
                //us reading the nodelist, and us registering the event.
                lock (m_OutgoingQueue_Lock) //don't let the callback enqueue a message first
                {
                    NodePeerList localPeerList =
                        CommunicationManager.RegisterLocalPeerListChangedCallback(
                            new CommunicationManager.LocalPeerListChangedHandler(
                                LocalPeerListChangedCallback));
                    Send(localPeerList.ToXml());
                }

                //kick off a read callback chain of threads
                lock (m_ReadCallback_Lock)
                {
                    sslStream.BeginRead(m_newData, 0, m_newData.Length,
                                        new AsyncCallback(ReadCallback), sslStream);
                }

                bool stop = false;
                while (!stop)
                {
                    //send any queued messages
                    int outgoingCount = 0;
                    lock (m_OutgoingQueue_Lock)
                    {
                        outgoingCount = m_OutgoingQueue.Count;
                    }
                    while (outgoingCount > 0)
                    {
                        string data = null;
                        lock (m_OutgoingQueue_Lock)
                        {
                            data = m_OutgoingQueue.Dequeue();
                        }

                        //encode it to base 64 so we don't have to worry about control codes
                        byte[] encbuf      = System.Text.Encoding.Unicode.GetBytes(data);
                        string encodedData = Convert.ToBase64String(encbuf) + "\n"; //terminate in newline to denote the end of the message

                        //convert to a byte array
                        byte[] writebuf = System.Text.Encoding.ASCII.GetBytes(encodedData);

                        sslStream.Write(writebuf);
                        sslStream.Flush();

                        outgoingCount--;
                    }

                    //process any received messages
                    int incomingCount = 0;
                    lock (m_IncomingQueue_Lock)
                    {
                        incomingCount = m_IncomingQueue.Count;
                    }
                    while (incomingCount > 0)
                    {
                        string data = null;
                        lock (m_IncomingQueue_Lock)
                        {
                            data = m_IncomingQueue.Dequeue();
                        }

                        //message is in base 64, so convert back to a string
                        byte[] decbuff = Convert.FromBase64String(data);
                        string message = System.Text.Encoding.Unicode.GetString(decbuff);

                        Receive(message);
                        incomingCount--;
                    }

                    //wait
                    System.Threading.Thread.Sleep(100);

                    lock (m_CloseRequest_Lock)
                    {
                        if (stop == false)
                        {
                            stop = m_CloseRequest;
                        }
                    }
                }

                //See if we closed due to an exception in the reader thread
                Exception readException = null;
                lock (m_readException_Lock)
                {
                    readException = m_readException;
                }
                if (readException != null)
                {
                    //TODO propagate this exception to higher code
                }

                //clean up the stream
                sslStream.Close();
            }
        }