/// <summary>
        /// Calculate the MD5 of the message attributes
        /// </summary>
        /// <param name="attributes"></param>
        /// <returns></returns>
        public static string CalculateMD5(Dictionary <string, MessageAttributeValue> attributes)
        {
            List <KeyValuePair <string, MessageAttributeValue> > orderedAttributes = new List <KeyValuePair <string, MessageAttributeValue> >();

            foreach (var kvp in attributes)
            {
                orderedAttributes.Add(kvp);
            }
            orderedAttributes.Sort(delegate(KeyValuePair <string, MessageAttributeValue> kvp1, KeyValuePair <string, MessageAttributeValue> kvp2)
            {
                return(string.CompareOrdinal(kvp1.Key, kvp2.Key));
            });
            var ms = new MemoryStream();

            using (var writer = new SQSWriter(ms))
            {
                foreach (var kvp in orderedAttributes)
                {
                    var name  = kvp.Key;
                    var value = kvp.Value;
                    writer.Write(name);
                    writer.Write(value.DataType);

                    if (value.StringValue != null)
                    {
                        writer.Write(STRING_TYPE);
                        writer.Write(value.StringValue);
                    }
                    else if (value.BinaryValue != null)
                    {
                        writer.Write(BINARY_TYPE);
                        writer.Write(value.BinaryValue);
                    }
                    else if (value.StringListValues != null)
                    {
                        writer.Write(STRING_LIST_TYPE);
                        foreach (var item in value.StringListValues)
                        {
                            writer.Write(item);
                        }
                    }
                    else if (value.BinaryListValues != null)
                    {
                        writer.Write(BINARY_LIST_TYPE);
                        foreach (var item in value.BinaryListValues)
                        {
                            writer.Write(item);
                        }
                    }
                }
            }

            var bytes = ms.ToArray();

            return(CalculateMD5(bytes));
        }
        /// <summary>
        /// Calculate the MD5 of the message attributes
        /// </summary>
        /// <param name="attributes"></param>
        /// <returns></returns>
        public static string CalculateMD5(Dictionary <string, MessageAttributeValue> attributes)
        {
            var sorted = attributes.OrderBy(kvp => kvp.Key, StringComparer.Ordinal);

            var ms = new MemoryStream();

            using (var writer = new SQSWriter(ms))
            {
                foreach (var kvp in sorted)
                {
                    var name  = kvp.Key;
                    var value = kvp.Value;
                    writer.Write(name);
                    writer.Write(value.DataType);

                    if (value.StringValue != null)
                    {
                        writer.Write(STRING_TYPE);
                        writer.Write(value.StringValue);
                    }
                    else if (value.BinaryValue != null)
                    {
                        writer.Write(BINARY_TYPE);
                        writer.Write(value.BinaryValue);
                    }
                    else if (value.StringListValues != null)
                    {
                        writer.Write(STRING_LIST_TYPE);
                        foreach (var item in value.StringListValues)
                        {
                            writer.Write(item);
                        }
                    }
                    else if (value.BinaryListValues != null)
                    {
                        writer.Write(BINARY_LIST_TYPE);
                        foreach (var item in value.BinaryListValues)
                        {
                            writer.Write(item);
                        }
                    }
                }
            }

            var bytes = ms.ToArray();

            return(CalculateMD5(bytes));
        }
        private static string CalculateMD5(Dictionary<string, MessageAttributeValue> attributes)
        {
            var sorted = attributes.OrderBy(kvp => kvp.Key, StringComparer.OrdinalIgnoreCase);

            var ms = new MemoryStream();
            using (var writer = new SQSWriter(ms))
            {
                foreach (var kvp in sorted)
                {
                    var name = kvp.Key;
                    var value = kvp.Value;
                    writer.Write(name);
                    writer.Write(value.DataType);

                    if (value.StringValue != null)
                    {
                        writer.Write(STRING_TYPE);
                        writer.Write(value.StringValue);
                    }
                    else if (value.BinaryValue != null)
                    {
                        writer.Write(BINARY_TYPE);
                        writer.Write(value.BinaryValue);
                    }
                    else if (value.StringListValues != null)
                    {
                        writer.Write(STRING_LIST_TYPE);
                        foreach (var item in value.StringListValues)
                        {
                            writer.Write(item);
                        }
                    }
                    else if (value.BinaryListValues != null)
                    {
                        writer.Write(BINARY_LIST_TYPE);
                        foreach (var item in value.BinaryListValues)
                        {
                            writer.Write(item);
                        }
                    }
                }
            }

            var bytes = ms.ToArray();
            return CalculateMD5(bytes);
        }