/////////////////////////////////////////////////////////////////////////////
        // Check is received packet's checksum corrent.
        /////////////////////////////////////////////////////////////////////////////
        bool IsReplyChecksumOK(byte[] data, int index, int crcSize)
        {
            object crc = null;
            if (this.m_ChecksumSettings.Type == ChecksumType.Own)
            {
                this.Checksum = null;
                GXChecksumEventArgs e = new GXChecksumEventArgs(this);
                NotifyCountChecksum(e);
                crc = e.Checksum;
            }
            else
            {
                crc = CountChecksum(this.m_ChecksumSettings.Start, this.m_ChecksumSettings.Count);
            }
            byte[] chksumCount = GXConverter.GetBytes(crc, ShouldSwap());
            byte[] chksumRead = new byte[crcSize];
            Array.Copy(data, index, chksumRead, 0, crcSize);
            if (Gurux.Common.GXCommon.IndexOf(chksumCount, chksumRead, 0, crcSize) != 0)
            {
				if (this.Sender != null && this.Sender.Trace >= System.Diagnostics.TraceLevel.Error)
				{
                    Gurux.Common.GXCommon.TraceWriteLine("GXPacket -- Checksum count failed. CRCs are not same + " + BitConverter.ToString(chksumCount).Replace('-', ' ') + " / " + BitConverter.ToString(chksumRead).Replace('-', ' '));
				}
                this.Checksum = null;
                m_DataAdded = true;
                return false;
            }
            this.Checksum = crc;
            return true;
        }
 /// <summary>
 /// Computes the checksum for the contents of the packet.
 /// </summary>
 /// <remarks>
 /// The checksum is computed from the data of the GXPacket object. This method should not be called directly. 
 /// GXClient calls this method automatically, when checksum is computed.
 /// </remarks>
 /// <param name="start">Position where to start counting CRC.</param>
 /// <param name="count">How many bytes are counted. If all, set to -1.</param>
 /// <returns>Counted checksum.</returns>       
 public object CountChecksum(int start, int count)
 {            
     this.m_Checksum = null;
     if (this.ChecksumSettings.Type == ChecksumType.Own)
     {
         GXChecksumEventArgs e = new GXChecksumEventArgs(this);
         NotifyCountChecksum(e);
         return e.Checksum;
     }
     byte[] data = ExtractPacket(true);
     if (count < 0)
     {
         count = data.Length + count + 1 - start;
     }
     object crc = null;
     if (this.ChecksumSettings.Type == ChecksumType.Adler32)
     {
         crc = CRCCTemplate.CountAdler32Checksum(data, start, count);
     }                
     else if (this.ChecksumSettings.Type == ChecksumType.Sum8Bit)
     {
         int val = 0;
         for (int pos = 0; pos != count; ++pos)
         {
             val = (val + data[start + pos]) & 0xFF;
         }
         crc = (byte)val;
     }
     else if (this.ChecksumSettings.Type == ChecksumType.Sum16Bit)
     {
         int val = 0;
         for (int pos = 0; pos != count; ++pos)
         {
             val = (val + data[start + pos]) & 0xFF;
         }
         crc = (UInt16)val;
     }
     else if (this.ChecksumSettings.Type == ChecksumType.Sum32Bit)
     {
         UInt32 val = 0;
         for (int pos = 0; pos != count; ++pos)
         {
             val = (val + data[start + pos]) & 0xFF;
         }
         crc = (UInt32)val;
     }
     else
     {
         if (m_crc == null || this.ChecksumSettings.Dirty)
         {
             if (this.ChecksumSettings.Size != 8 && this.ChecksumSettings.Size != 16 && this.ChecksumSettings.Size != 24 && this.ChecksumSettings.Size != 32)
             {
                 throw new Exception(Resources.ChecksumSizeIsInvalid);
             }
             m_crc = new CRCCTemplate(this.ChecksumSettings.Size, this.ChecksumSettings.Polynomial, this.ChecksumSettings.InitialValue, this.ChecksumSettings.FinalXOR, this.ChecksumSettings.ReverseData, this.ChecksumSettings.Reflection);
             this.ChecksumSettings.Dirty = false;
         }
         crc = m_crc.CountCRC(data, start, count);
         if (this.ShouldSwap() || this.ChecksumSettings.ReversedChecksum)
         {
             if (crc is UInt16)
             {
                 crc = CRCCTemplate.Swap((UInt16)crc);
             }
             else if (crc is UInt32)
             {
                 crc = CRCCTemplate.Swap((UInt32)crc);
             }
         }
     }
     return crc;
 }       
 internal void NotifyCountChecksum(GXChecksumEventArgs e)
 {
     if (OnCountChecksum != null)
     {
         OnCountChecksum(this, e);
     }
     //GXCom server is asking packet to count checksum. Packet asks client to count it.
     else if (Sender != null)
     {
         Sender.NotifyCountChecksum(e);
     }
 }
 internal void NotifyCountChecksum(GXChecksumEventArgs e)
 {
     if (PacketParser != null)
     {
         PacketParser.CountChecksum(this, e);
     }
     else if (OnCountChecksum != null)
     {
         OnCountChecksum(this, e);
     }
 }
		public void CountChecksum(object sender, GXChecksumEventArgs e)
		{	
		}
 void IGXPacketParser.CountChecksum(object sender, GXChecksumEventArgs e)
 {
     throw new NotImplementedException();
 }