void OnReceived(object sender, ReceiveEventArgs data)
        {
            try
            {
                byte[] buff = (byte[])data.Data;
                string str = Gurux.Common.GXCommon.ToHex(buff, true);
                foreach (GXClient cl in Clients)
                {
                    cl.NotifyVerbose(sender, Gurux.Common.TraceTypes.Received, str);
                }
                GXClient client = null;
                lock (Clients.SyncRoot)
                {
                    if (Clients.Count == 0)
                    {
                        return;
                    }
                    client = Clients[0] as GXClient;
                }
                GXReceiveDataEventArgs args = new GXReceiveDataEventArgs(buff, data.SenderInfo);
                client.NotifyReceiveData(args);
                //If data is not accepted ignore it.
                if (!args.Accept)
                {
					if (this.m_Media.Trace >= System.Diagnostics.TraceLevel.Info)
					{
                        client.NotifyVerbose(client, Resources.ClientToNotAcceptData + BitConverter.ToString(buff).Replace('-', ' '));
					}
                    return;
                }
                int cnt = 0;
                //Add received data to the buffer.
                lock (m_syncRoot)
                {
                    m_replyBuffer.AddRange(buff);
                    cnt = m_replyBuffer.Count;
                }
                while (cnt != 0)
                {
                    m_ReplyPacket.ClearData();
                    m_ReplyPacket.Status = PacketStates.Ok;
                    //If end applications are parsing data itself.
                    if (m_bParseReceivedPacket)
                    {
                        GXParsePacketEventArgs e;
                        lock (m_syncRoot)
                        {
                            e = new GXParsePacketEventArgs(m_replyBuffer.ToArray(), m_ReplyPacket);
                        }
                        client.NotifyParsePacketFromData(e);
                        //If packet is not ready yet.
                        if (e.PacketSize == 0)
                        {
                            return;
                        }
                        //Remove parsed data.
                        lock (m_syncRoot)
                        {
                            m_replyBuffer.RemoveRange(0, e.PacketSize);
                        }
                    }
                    else
                    {
                        int start;
                        byte[] tmp;
                        int packetSize = 0;
                        lock (m_syncRoot)
                        {
                            tmp = m_replyBuffer.ToArray();
                        }
                        try
                        {
                            m_ReplyPacket.Sender = client;
                            m_ReplyPacket.ParsePacket(tmp, out start, out packetSize);
                        }
                        finally
                        {
                            m_ReplyPacket.Sender = null;
                        }
                        //If packet is not ready yet.
                        if (packetSize == 0)
                        {
                            return;
                        }
                        GXVerifyPacketEventArgs e = new GXVerifyPacketEventArgs(tmp, m_ReplyPacket);
                        client.NotifyVerifyPacket(e);
                        do
                        {
                            if (e.State == ParseStatus.CorruptData)
                            {
                                //Remove parsed data.
                                lock (m_syncRoot)
                                {
                                    m_replyBuffer.Clear();
                                }
                                client.NotifyVerbose(client, Resources.CorruptedData);
                                Gurux.Common.GXCommon.TraceWriteLine(Resources.CorruptedData);
                                return;
                            }
                            else if (e.State == ParseStatus.Incomplete)
                            {
                                m_ReplyPacket.ParsePacket(tmp, out start, out packetSize);
                                e = new GXVerifyPacketEventArgs(tmp, m_ReplyPacket);
                                client.NotifyVerifyPacket(e);
                            }
                        }
                        while (e.State != ParseStatus.Complete);
                        //Remove parsed data.
                        lock (m_syncRoot)
                        {
                            m_replyBuffer.RemoveRange(0, packetSize);
                        }
                    }
                    lock (m_syncRoot)
                    {
                        cnt = m_replyBuffer.Count;
                    }
                    //Data parsing succeeded. Handle reply.
                    //Clear transaction time flag.                                
                    m_ReplyPacket.Status &= ~PacketStates.TransactionTimeReset;
                    bool acceptPacket = true;
                    GXPacket replyPacket = null;
                    lock (m_SendPackets.SyncRoot)
                    {
                        // Find the send packet from the send list
                        foreach (GXPacket it in m_SendPackets)
                        {
							lock (it.SyncRoot)
							{
								//If packet is send as a broadcast message.
								if (it.ResendCount == -1)
								{
									continue;
								}
								GXReplyPacketEventArgs e = new GXReplyPacketEventArgs(it, m_ReplyPacket);
								try
								{
									client.NotifyIsReplyPacket(e);
								}
								catch (Exception ex)
								{
									it.Status = PacketStates.SendFailed;
									it.SenderInfo = ex.Message;
									acceptPacket = true;
									replyPacket = it;
									break;
								}
								acceptPacket = e.Accept;
								if (!acceptPacket)
								{
									if (this.m_Media.Trace >= System.Diagnostics.TraceLevel.Info)
									{
                                        if (!string.IsNullOrEmpty(e.Description))
                                        {
                                            client.NotifyVerbose(client, e.Description);                                            
                                        }
                                        else
                                        {
                                            client.NotifyVerbose(client, Resources.ReceivedPacketIsNotAccepted + 
                                                " " + m_ReplyPacket.ToString());                                            
                                        }
									}
									break;
								}
								//If the packet is old, don't do anything
								if ((it.Status & PacketStates.Timeout) != 0)
								{
									continue;
								}
								//Mark the packet as received so the sender do not remove it.
								it.Status = PacketStates.Received;
								//Copy content if the received packet is a reply packet...
								it.ClearData();
								it.AppendData(m_ReplyPacket.ExtractData(typeof(byte[]), 0, -1));
								it.Bop = m_ReplyPacket.Bop;
								it.Eop = m_ReplyPacket.Eop;
								it.ChecksumSettings.Copy(m_ReplyPacket.ChecksumSettings);
							}
                            replyPacket = it;
                        }
                    }
                    if (acceptPacket)
                    {
                        ///////////////////////////////////////////////////////////////
                        //If packet sender not found, send packet to all clients.
                        if (replyPacket == null)
                        {
                            GXReplyPacketEventArgs e;
                            lock (Handlers)
                            {
                                GXNotifyEventArgs fc = new GXNotifyEventArgs(m_ReplyPacket, data.SenderInfo);
                                foreach (var it in Handlers)
                                {
                                    it.Key.NorifyEvent(fc);
                                    if (fc.Handled)
                                    {
                                        if (fc.Client != null)
                                        {
                                            e = new GXReplyPacketEventArgs(null, m_ReplyPacket);
                                            fc.Client.NotifyAcceptNotify(e);
                                            if (!e.Accept)
                                            {
                                                return;
                                            }
                                            fc.Client.NotifyReceived(new GXReceivedPacketEventArgs(m_ReplyPacket, false));
                                        }
                                        m_ReplyPacket.ClearData();
                                        if (fc.Reply != null)
                                        {
                                            Send(fc.Reply);
                                        }
                                        return;
                                    }
                                }
                            }
                            e = new GXReplyPacketEventArgs(null, m_ReplyPacket);
                            client.NotifyAcceptNotify(e);
                            if (!e.Accept)
                            {
                                continue;
                            }
                            foreach (GXClient it in Clients)
                            {
                                it.NotifyReceived(new GXReceivedPacketEventArgs(m_ReplyPacket, false));
                            }
                        }
                        else //Sender found.
                        {
							System.Diagnostics.Debug.Assert((replyPacket.Status & PacketStates.Sent) == 0);
                            AddPacketToReceivedBuffer(replyPacket);
                        }
                    }
                }
            }
            catch (Exception Ex)
            {
                foreach (GXClient it in Clients)
                {
					it.NotifyError(m_ReplyPacket, Ex);
                }
            }
        }   
 internal void NotifyVerifyPacket(GXVerifyPacketEventArgs e)
 {
     if (PacketParser != null)
     {
         PacketParser.VerifyPacket(this, e);
     }
     else if (OnVerifyPacket != null)
     {
         OnVerifyPacket(this, e);
     }
 }
		public void VerifyPacket(object sender, GXVerifyPacketEventArgs e)
		{
			//throw new NotImplementedException();
		}
        public void VerifyPacket(object sender, GXVerifyPacketEventArgs e)
        {

        }
        void IGXPacketParser.VerifyPacket(object sender, GXVerifyPacketEventArgs e)
        {

        }