/// <summary>
        /// Loop thread that processes messages received from UDP receiver. 
        /// </summary>
        /// <param name="data"></param>
        private void UdpReceiverListenerThreadImpl(object data)
        {
            _threadStatus.IsThreadActive = true;
            logger.Info("[" + _description + "-T] UdpReceiverListener active");

            while (_threadStatus.IsThreadEnabled)
            {
                try
                {
                    _threadStatus.ThreadHealthDate = DateTime.Now;

                    //check if there are any messages
                    if (_udpReceiver.CountMessagesInBuffer() > 0)
                    {
                        //dequeue message
                        NiawaNetDatagram message = _udpReceiver.GetNextMessageFromBuffer();

                        /*when receive UDP handshake, pass session data to TCP session manager*/

                         //check for handshake message
                        if (message.MessageType == MessageContent.HandshakeMessageContent.MESSAGE_CONTENT_TYPE)
                        {
                            //handshake message

                            MessageContent.HandshakeMessageContent remoteServerData = new MessageContent.HandshakeMessageContent(message.MessageContents);

                            logger.Info("[" + _description + "-T] Received handshake message from [" + remoteServerData.IpAddress + "]");
                            _evtRaiser.RaiseEvent("Session", "Received handshake message from [" + remoteServerData.IpAddress + "]", null, _threadStatus.NodeID, _threadStatus.ParentNodeID);

                            //find session
                            if (_tcpSessionManager.TcpSessions.ContainsKey(remoteServerData.IpAddress))
                            {
                                //we already have something relating to this session data
                                logger.Warn("[" + _description + "-T] UdpReceiverListener received a handshake message for existing session [" + remoteServerData.IpAddress + "]");

                                //check if any of the information has changed
                                TcpSession existingSession = _tcpSessionManager.TcpSessions[remoteServerData.IpAddress];
                                bool invalidateSession = false;

                                //check this existing session for any reasons that would invalidate the session
                                invalidateSession = ReceivedHandshakeExistingSessionValidations(existingSession, remoteServerData);

                                if (invalidateSession)
                                {
                                    //invalidate session and create new one

                                    logger.Info("[" + _description + "-T] UdpReceiverListener removing invalidated session before creating a new session for [" + remoteServerData.IpAddress + "]");
                                    _evtRaiser.RaiseEvent("Session", "Removing invalidated session before creating a new session for [" + remoteServerData.IpAddress + "]", null, _threadStatus.NodeID, _threadStatus.ParentNodeID);

                                    //remove old session
                                    _tcpSessionManager.RemoveSession(remoteServerData.IpAddress, false);

                                    //create a session with the remote session data, and then receive the session initialization from the remote
                                    MessageContent.SessionInitMessageContent localSession = _tcpSessionManager.CreateNewSession(remoteServerData.IpAddress, remoteServerData.Hostname, remoteServerData.HandshakePort);

                                    //transmit session initialization to the remote
                                    _tcpSessionManager.TransmitSessionInitialization(remoteServerData.IpAddress, remoteServerData.HandshakePort, remoteServerData.Hostname, localSession);
                                }
                                else
                                {
                                    //existing session is still valid; don't do anything
                                    logger.Info("[" + _description + "-T] UdpReceiverListener ignoring handshake message for existing session [" + remoteServerData.IpAddress + "]");
                                    _evtRaiser.RaiseEvent("Session", "Ignoring handshake message for existing session [" + remoteServerData.IpAddress + "]", null, _threadStatus.NodeID, _threadStatus.ParentNodeID);
                                }

                            }
                            else
                            {
                                /*we don't have anything relating to this sesion data yet*/

                                //create a session with the remote session data, and then receive the session initialization from the remote
                                MessageContent.SessionInitMessageContent localSession = _tcpSessionManager.CreateNewSession(remoteServerData.IpAddress, remoteServerData.Hostname, remoteServerData.HandshakePort);

                                //transmit session initialization to the remote
                                _tcpSessionManager.TransmitSessionInitialization(remoteServerData.IpAddress, remoteServerData.HandshakePort, remoteServerData.Hostname, localSession);
                            }

                        }
                        else if (message.MessageType == MessageContent.PingMessageContent.MESSAGE_CONTENT_TYPE_PING)
                        {
                            //ping message
                            MessageContent.PingMessageContent pingData = new MessageContent.PingMessageContent(message.MessageContents);

                            logger.Info("[" + _description + "-T] Received ping message from [" + pingData.IpAddress + "]");
                            _evtRaiser.RaiseEvent("Message", "Received ping message from [" + pingData.IpAddress + "]", null, _threadStatus.NodeID, _threadStatus.ParentNodeID);

                            //send a reply
                            TransmitPingMessage(true, message.SerialID.ToString());

                        }
                        else if (message.MessageType == MessageContent.PingMessageContent.MESSAGE_CONTENT_TYPE_PINGREPLY)
                        {
                            //ping message
                            MessageContent.PingMessageContent pingData = new MessageContent.PingMessageContent(message.MessageContents);

                            logger.Info("[" + _description + "-T] Received ping reply message from [" + pingData.IpAddress + "] for ping SerialID [" + pingData.ReplySerialID + "]");
                            _evtRaiser.RaiseEvent("Message", "Received ping reply from [" + pingData.IpAddress + "] for ping SerialID [" + pingData.ReplySerialID + "]", null, _threadStatus.NodeID, _threadStatus.ParentNodeID);

                        }
                        else
                        {
                            //message is not valid - not a handshake message

                            //throw away other data
                            logger.Warn("[" + _description + "-T] UdpReceiverListener ignoring unexpected message type [" + message.MessageType + "]");
                            _evtRaiser.RaiseEvent("Error", "UdpReceiverListener: Ignoring unexpected message type [" + message.MessageType + "]", null, _threadStatus.NodeID, _threadStatus.ParentNodeID);

                        }
                    }
                    else
                    {
                        //there are no messages
                    }

                }
                catch (System.Threading.ThreadAbortException) // ex1)
                {
                    //thread was aborted
                    logger.Debug("[" + _description + "-T] Thread aborted");
                    break;
                }
                catch (System.Threading.ThreadInterruptedException) // ex1)
                {
                    //thread was interrupted
                    logger.Debug("[" + _description + "-T] Thread interrupted");
                    break;
                }
                catch (Exception ex)
                {
                    //exception
                    logger.Error("[" + _description + "-T] Error while listening to UdpReceiver: " + ex.Message + "]", ex);
                    //ipcLoggerMsg.Write("ReceiveMessageError", "[" + _logInstanceName + "]: " + "Error: " + ex.Message);
                    _evtRaiser.RaiseEvent("Error", "Error while listening to UdpReceiver [" + ex.Message + "]", null, _threadStatus.NodeID, _threadStatus.ParentNodeID);
                    _threadStatus.ErrorCount += 1;
                    System.Threading.Thread.Sleep(100);
                }

                System.Threading.Thread.Sleep(50);

            }
            //done working
            _threadStatus.IsThreadActive = false;
        }
        /// <summary>
        /// Transmits the UDP ping or ping reply message configured for this instance of NiawaAdHocNetworkAdapter.
        /// </summary>
        /// <param name="isReplyMessage">True if ping reply message; False if ping message</param>
        public void TransmitPingMessage(bool isReplyMessage, string replySerialID)
        {
            try
            {
                if(!isReplyMessage )
                {
                    logger.Info("[" + _description + "-M] Transmitting ping message");

                    //send message
                    _evtRaiser.RaiseEvent("Message", "Transmitting ping message", null, _threadStatus.NodeID, _threadStatus.ParentNodeID);
                    _threadStatus.MessageCount += 1;

                    /*broadcast UDP ping when requested by implementor*/
                    if (!_started) throw new Exception("[" + _description + "-M] Could not transmit ping message: NiawaAdHocNetworkAdapter is not started");

                    if (_tcpHandshakePort == 0) throw new Exception("[" + _description + "-M] Could not transmit ping message: HandshakePort [" + _tcpHandshakePort + "] is not valid.");

                    //create message
                    MessageContent.PingMessageContent pingMessage = new MessageContent.PingMessageContent(_ipAddress, _hostname, string.Empty);

                    NiawaNetDatagram message = new NiawaNetDatagram(_ipAddress, _udpPort, Guid.NewGuid(), _hostname, _applicationName, MessageContent.PingMessageContent.MESSAGE_CONTENT_TYPE_PING, pingMessage.ToJson());

                    //send message
                    _udpTransmitter.SendMessage(message);

                }

                else
                {
                    logger.Info("[" + _description + "-M] Transmitting ping reply message");

                    //send message
                    _evtRaiser.RaiseEvent("Message", "Transmitting ping reply message", null, _threadStatus.NodeID, _threadStatus.ParentNodeID);
                    _threadStatus.MessageCount += 1;

                    /*broadcast UDP ping reply when requested by implementor*/
                    if (!_started) throw new Exception("[" + _description + "-M] Could not transmit ping reply message: NiawaAdHocNetworkAdapter is not started");

                    if (_tcpHandshakePort == 0) throw new Exception("[" + _description + "-M] Could not transmit ping reply message: HandshakePort [" + _tcpHandshakePort + "] is not valid.");

                    //create message
                    MessageContent.PingMessageContent pingMessage = new MessageContent.PingMessageContent(_ipAddress, _hostname, replySerialID);

                    NiawaNetDatagram message = new NiawaNetDatagram(_ipAddress, _udpPort, Guid.NewGuid(), _hostname, _applicationName, MessageContent.PingMessageContent.MESSAGE_CONTENT_TYPE_PINGREPLY, pingMessage.ToJson());

                    //send message
                    _udpTransmitter.SendMessage(message);

                }

            }
            catch (Exception ex)
            {
                logger.Error("[" + _description + "-M] Error while transmitting ping/ping reply message: " + ex.Message, ex);
                throw ex;
            }
        }