public static byte[] Reader(DataFrameReader reader, int start, int unsyncedLength)
        {
            var result = new byte[unsyncedLength];
            var n      = start;

            for (var i = 0; i < result.Length; i++)
            {
                var b = reader.ReadByte(n++);
                if (b != 0xFF)
                {
                    result[i] = b;
                }
                else
                {
                    result[i] = reader.ReadByte(n++);
                }
            }
            return(result);
        }
        /// <summary>
        /// Reads a frame (check <see cref="State"/> before usage).
        /// </summary>
        /// <returns>Returns a frame if one left or null otherwise.</returns>
        public bool ReadFrame(out ID3v2Frame frame)
        {
            if (State != ID3v2ReaderState.ReadFrames)
            {
                throw new InvalidOperationException(string.Format("Cannot read frame at state {0}", State));
            }

            frame = null;
            if (m_Reader.BufferStartPosition >= m_BodyBytes)
            {
                if ((m_Header.Flags & ID3v2HeaderFlags.Footer) == 0)
                {
                    // no footer, end of tag
                    State = ID3v2ReaderState.ReadEnd;
                    return(true);
                }
                State = ID3v2ReaderState.ReadFooter;
                return(true);
            }

            if (m_Reader.ReadByte(0) == 0)
            {
                // check padding with zero bytes
                byte[] data;
                switch (m_Header.Version)
                {
                case 2:
                {
                    var read = m_BodyBytes - m_Reader.BufferStartPosition;
                    data  = m_Reader.GetBuffer((int)read);
                    State = ID3v2ReaderState.ReadEnd;
                    frame = null;
                    break;
                }

                case 3:
                case 4:
                {
                    // null frame, used by some encoders to implement padding, this is not allowed if footer present
                    if ((m_Header.Flags & ID3v2HeaderFlags.Footer) != 0)
                    {
                        throw new InvalidDataException(string.Format("Invalid padding frames inside of tag with footer!"));
                    }

                    // load padding bytes
                    var read = m_BodyBytes - m_Reader.BufferStartPosition;
                    data  = m_Reader.GetBuffer((int)read);
                    State = ID3v2ReaderState.ReadEnd;
                    frame = null;
                }
                break;

                default: return(false);
                }
                for (var i = 0; i < data.Length; i++)
                {
                    if (data[i] != 0)
                    {
                        Trace.TraceError("Additional garbage in padding of ID3v2 tag!");
                        break;
                    }
                }
                return(false);
            }

            try
            {
                frame = new ID3v2Frame(m_Header, m_Reader);
            }
            catch (Exception ex)
            {
                Trace.TraceError("Error parsing id3 frame.");
                Trace.TraceError(ex.ToString());
                return(false);
            }
            return(true);
        }