/// <summary>
        /// Unpacks this file<paramref name="source"/>.
        /// </summary>
        /// <param name="source">Binary file (.uop source).</param>
        /// <returns>Binary data from this file.</returns>
        public byte[] Unpack(BinaryReader source)
        {
            source.BaseStream.Seek(m_DataBlockAddress + m_DataBlockLength, SeekOrigin.Begin);

            byte[] sourceData = new byte[m_CompressedSize];

            if (source.Read(sourceData, 0, m_CompressedSize) != m_CompressedSize)
            {
                throw new StreamSourceException();
            }

            switch (m_Compression)
            {
            case CompressionFlag.Zlib:
            {
                byte[]    destData   = new byte[m_DecompressedSize];
                int       destLength = m_DecompressedSize;
                ZLibError error      = Zlib.Decompress(destData, ref destLength, sourceData, m_CompressedSize);

                if (error != ZLibError.Okay)
                {
                    throw new CompressionException(error);
                }

                return(destData);
            }

            case CompressionFlag.None:
            {
                return(sourceData);
            }
            }

            return(null);
        }
        /// <summary>
        /// Updates <see cref="Mythic.Package.MythicPackageFile.DataBlockAddress"/> within .uop file,
        /// <see cref="Mythic.Package.MythicPackageFile.CompressedSize"/> and <see cref="Mythic.Package.MythicPackageFile.DecompressedSize"/>.
        /// </summary>
        /// <param name="pointer">Address of <see cref="Mythic.Package.MythicPackageFile.DataBlockAddress"/>.</param>
        public void UpdateOffsets(ref long pointer)
        {
            m_DataBlockAddress = pointer;
            m_DataBlockLength  = 0;            // Custom .uop files don't need data header.

            if (m_Added || m_Modified)
            {
                if (!File.Exists(m_SourceFileName))
                {
                    throw new FileNotFoundException();
                }

                FileInfo info = new FileInfo(m_SourceFileName);

                m_CompressedSize   = (int)info.Length;
                m_DecompressedSize = (int)info.Length;

                byte[] sourceBuffer;

                using (BinaryReader reader = new BinaryReader(info.OpenRead()))
                {
                    sourceBuffer = reader.ReadBytes(m_DecompressedSize);
                }

                if (sourceBuffer.Length < 4)
                {
                    m_Compression = CompressionFlag.None;
                }

                switch (m_Compression)
                {
                case CompressionFlag.Zlib:
                {
                    m_SourceBuffer = new byte[m_CompressedSize];
                    ZLibError error = Zlib.Compress(m_SourceBuffer, ref m_CompressedSize, sourceBuffer, m_DecompressedSize, ZLibQuality.Speed);

                    if (error != ZLibError.Okay)
                    {
                        throw new CompressionException(error);
                    }

                    break;
                }

                case CompressionFlag.None:
                {
                    m_SourceBuffer = sourceBuffer;
                    break;
                }
                }
            }
            else
            {
                m_SourceBuffer = null;
            }

            pointer += m_DataBlockLength + m_CompressedSize;
        }