public static byte[] decompress(byte[] source)
    {
        int len;
        len = (source[1] & 0xFF) | ((source[2] & 0xFF) << 8) | ((source[3] & 0xFF) << 16);
        byte[] dest = new byte[len];
        int i, j, xin, xout;
        xin = 4;
        xout = 0;
        int length, offset, windowOffset, data;
        byte d;
        while (len > 0)
        {
            d = source[xin++];
            if (d != 0)
                for (i = 0; i < 8; i++)
                {
                    if ((d & 0x80) != 0)
                    {
                        data = (((source[xin] & 0xFF) << 8) | (source[xin + 1] & 0xFF));
                        xin += 2;
                        length = (data >> 12) + 3;
                        offset = data & 0xFFF;
                        windowOffset = xout - offset - 1;
                        for (j = 0; j < length; j++)
                        {
                            dest[xout++] = dest[windowOffset++];
                            len--;
                            if (len == 0)
                                return dest;
                        }
                    } else
                    {
                        dest[xout++] = source[xin++];
                        len--;
                        if (len == 0)
                            return dest;
                    }
                    d <<= 1;
                }
            else
                for (i = 0; i < 8; i++)
                {
                    dest[xout++] = source[xin++];
                    len--;
                    if (len == 0)
                        return dest;
                }
        }
        return dest;
    }