/// <summary>
        /// Decodes the message.
        /// </summary>
        /// <param name="buffer">The buffer.</param>
        /// <param name="offset">The offset.</param>
        /// <param name="message">The message.</param>
        /// <returns>
        /// True if decoding was successful; false otherwise.
        /// </returns>
        public static bool TryDecode(byte[] buffer, int offset, out ScrapeMessage message)
        {
            long          connectionId;
            int           action;
            int           transactionId;
            List <string> infoHashes = new List <string>();

            message = null;

            if (buffer != null &&
                buffer.Length >= offset + ConnectionIdLength + ActionLength + TransactionIdLength &&
                offset >= 0)
            {
                connectionId  = Message.ReadLong(buffer, ref offset);
                action        = Message.ReadInt(buffer, ref offset);
                transactionId = Message.ReadInt(buffer, ref offset);

                if (connectionId >= 0 &&
                    action == (int)TrackingAction.Scrape &&
                    transactionId >= 0)
                {
                    while (offset <= buffer.Length - InfoHashLength)
                    {
                        infoHashes.Add(Message.ReadBytes(buffer, ref offset, InfoHashLength).ToHexaDecimalString());
                    }

                    message = new ScrapeMessage(connectionId, transactionId, infoHashes);
                }
            }

            return(message != null);
        }
        /// <summary>
        /// Tries to decode the message.
        /// </summary>
        /// <param name="buffer">The buffer.</param>
        /// <param name="offset">The offset.</param>
        /// <param name="messageType">Type of the message.</param>
        /// <param name="message">The decoded message.</param>
        /// <returns>
        /// True if message was successfully decoded; false otherwise.
        /// </returns>
        public static bool TryDecode(byte[] buffer, int offset, MessageType messageType, out TrackerMessage message)
        {
            int action;

            message = null;

            if (buffer.IsNotNullOrEmpty())
            {
                action = messageType == MessageType.Request ? Message.ReadInt(buffer, ref offset) : Message.ReadInt(buffer, ref offset);
                offset = 0;

                if (action == (int)TrackingAction.Connect)
                {
                    if (messageType == MessageType.Request)
                    {
                        ConnectMessage message2;
                        ConnectMessage.TryDecode(buffer, offset, out message2);

                        message = message2;
                    }
                    else
                    {
                        ConnectResponseMessage message2;
                        ConnectResponseMessage.TryDecode(buffer, offset, out message2);

                        message = message2;
                    }
                }
                else if (action == (int)TrackingAction.Announce)
                {
                    if (messageType == MessageType.Request)
                    {
                        AnnounceMessage message2;
                        AnnounceMessage.TryDecode(buffer, offset, out message2);

                        message = message2;
                    }
                    else
                    {
                        AnnounceResponseMessage message2;
                        AnnounceResponseMessage.TryDecode(buffer, offset, out message2);

                        message = message2;
                    }
                }
                else if (action == (int)TrackingAction.Scrape)
                {
                    if (messageType == MessageType.Request)
                    {
                        ScrapeMessage message2;
                        ScrapeMessage.TryDecode(buffer, offset, out message2);

                        message = message2;
                    }
                    else
                    {
                        ScrapeResponseMessage message2;
                        ScrapeResponseMessage.TryDecode(buffer, offset, out message2);

                        message = message2;
                    }
                }
                else if (action == (int)TrackingAction.Error)
                {
                    ErrorMessage message2;
                    ErrorMessage.TryDecode(buffer, offset, out message2);

                    message = message2;
                }
                else
                {
                    // could not decode UDP message
                }
            }

            return(message != null);
        }