/// <summary>
        /// decompress CLAIMS_SET
        /// </summary>
        /// <param name="option"></param>
        /// <param name="compressedData"></param>
        /// <param name="decompressedSize"></param>
        /// <returns>Decompressed data</returns>
        public static byte[] Decompress(CLAIMS_COMPRESSION_FORMAT option, byte[] compressedData, int decompressedSize)
        {
            XcaDecompressor decompressor;

            switch (option)
            {
            case CLAIMS_COMPRESSION_FORMAT.COMPRESSION_FORMAT_LZNT1:
                decompressor = new LZNT1Decompressor();
                break;

            case CLAIMS_COMPRESSION_FORMAT.COMPRESSION_FORMAT_XPRESS:
                decompressor = new PlainLZ77Decompressor();
                break;

            case CLAIMS_COMPRESSION_FORMAT.COMPRESSION_FORMAT_XPRESS_HUFF:
                decompressor = new LZ77HuffmanDecompressor();
                break;

            default:
                throw new NotSupportedException($"{option} is not supported.");
            }

            byte[] ret = decompressor.Decompress(compressedData);
            if (ret.Length != decompressedSize)
            {
                throw new Exception($"Size of decompressed data ({ret.Length}) is different from decompressedSize ({decompressedSize}).");
            }

            return(ret);
        }
        /// <summary>
        /// decompress CLAIMS_SET
        /// </summary>
        /// <param name="option"></param>
        /// <param name="compressedData"></param>
        /// <param name="decompressedSize"></param>
        /// <param name="finalDecompressed"></param>
        /// <returns></returns>
        public static uint Decompress(CLAIMS_COMPRESSION_FORMAT option, byte[] compressedData, int decompressedSize, out byte[] finalDecompressed)
        {
            finalDecompressed = null;
            uint ret = 0;
            int compressWorkSpaceSize = 0, decompressWorkSpaceSize = 0;
            ret = RtlGetCompressionWorkSpaceSize((uint)option, ref compressWorkSpaceSize, ref decompressWorkSpaceSize);
            if (ret != 0)
                return ret;

            IntPtr workspace = Marshal.AllocHGlobal(decompressWorkSpaceSize);

            IntPtr compressedPtr = Marshal.AllocHGlobal(compressedData.Length);
            for (int i = 0; i < compressedData.Length; i++)
            {
                Marshal.WriteByte(compressedPtr, i, compressedData[i]);
            }
            IntPtr decompressedBuf = Marshal.AllocHGlobal(decompressedSize);
            int finalSize = 0;
            ret = RtlDecompressBufferEx((uint)option, decompressedBuf, decompressedSize, compressedPtr, compressedData.Length, ref finalSize, workspace);
            if (ret != 0)
                return ret;

            finalDecompressed = new byte[finalSize];
            for (int i = 0; i < finalSize; i++)
            {
                finalDecompressed[i] = Marshal.ReadByte(decompressedBuf, i);
            }

            return ret;
        }
        /// <summary>
        /// decompress CLAIMS_SET
        /// </summary>
        /// <param name="option"></param>
        /// <param name="compressedData"></param>
        /// <param name="decompressedSize"></param>
        /// <param name="finalDecompressed"></param>
        /// <returns></returns>
        public static uint Decompress(CLAIMS_COMPRESSION_FORMAT option, byte[] compressedData, int decompressedSize, out byte[] finalDecompressed)
        {
            finalDecompressed = null;
            uint ret = 0;
            int  compressWorkSpaceSize = 0, decompressWorkSpaceSize = 0;

            ret = RtlGetCompressionWorkSpaceSize((uint)option, ref compressWorkSpaceSize, ref decompressWorkSpaceSize);
            if (ret != 0)
            {
                return(ret);
            }

            IntPtr workspace = Marshal.AllocHGlobal(decompressWorkSpaceSize);

            IntPtr compressedPtr = Marshal.AllocHGlobal(compressedData.Length);

            for (int i = 0; i < compressedData.Length; i++)
            {
                Marshal.WriteByte(compressedPtr, i, compressedData[i]);
            }
            IntPtr decompressedBuf = Marshal.AllocHGlobal(decompressedSize);
            int    finalSize       = 0;

            ret = RtlDecompressBufferEx((uint)option, decompressedBuf, decompressedSize, compressedPtr, compressedData.Length, ref finalSize, workspace);
            if (ret != 0)
            {
                return(ret);
            }

            finalDecompressed = new byte[finalSize];
            for (int i = 0; i < finalSize; i++)
            {
                finalDecompressed[i] = Marshal.ReadByte(decompressedBuf, i);
            }

            return(ret);
        }