/// <summary>
        /// Creates an ID3v2 frame for the given key-value pair.
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        static byte[] CreateId3v2Frame(string key, string value)
        {
            if (string.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException("key");
            }

            if (string.IsNullOrEmpty(value))
            {
                throw new ArgumentNullException("value");
            }

            if (key.Length != 4)
            {
                throw new ArgumentOutOfRangeException("key", "key " + key + " must be 4 characters long");
            }

            const byte UnicodeEncoding = 01;                     // encode text in Unicode

            byte[] UnicodeOrder     = new byte[] { 0xff, 0xfe }; // Unicode byte order mark
            byte[] language         = new byte[] { 0, 0, 0 };    // language is empty (only used in COMM -> comment)
            byte[] shortDescription = new byte[] { 0, 0 };       // short description is empty (only used in COMM -> comment)

            byte[] body;
            if (key == "COMM") // comment
            {
                body = ByteArrayExtensions.Concat(
                    new byte[] { UnicodeEncoding },
                    language,
                    shortDescription,
                    UnicodeOrder,
                    Encoding.Unicode.GetBytes(value));
            }
            else
            {
                body = ByteArrayExtensions.Concat(
                    new byte[] { UnicodeEncoding },
                    UnicodeOrder,
                    Encoding.Unicode.GetBytes(value));
            }

            return(ByteArrayExtensions.Concat(
                       // needs review - have converted to UTF8 as Win 8 has no Encoding.ASCII,
                       // need to check what the rules are for ID3v2 tag identifiers
                       Encoding.UTF8.GetBytes(key),
                       FrameSizeToBytes(body.Length),
                       new byte[] { 0, 0 }, // flags
                       body));
        }
        /// <summary>
        /// Creates the Id3v2 tag header and returns is as a byte array.
        /// </summary>
        /// <param name="frames">The Id3v2 frames that will be included in the file. This is used to calculate the ID3v2 tag size.</param>
        /// <returns></returns>
        static byte[] CreateId3v2TagHeader(IEnumerable <byte[]> frames)
        {
            int size = 0;

            foreach (byte[] frame in frames)
            {
                size += frame.Length;
            }

            byte[] tagHeader = ByteArrayExtensions.Concat(
                Encoding.UTF8.GetBytes("ID3"),
                new byte[] { 3, 0 }, // version
                new byte[] { 0 },    // flags
                GetId3TagHeaderSize(size));
            return(tagHeader);
        }