public void run()
    {
        try
        {
            long outSize = 0;
            if (LzmaOutputStream.LZMA_HEADER)
            {
                final int n = in.read(props, 0, propSize);
                if (n != propSize)
                {
                    throw new IOException("input .lzma file is too short");
                }
                dec.SetDecoderProperties(props);
                for (int i = 0; i < 8; i++)
                {
                    final int v = in.read();
                    if (v < 0)
                    {
                        throw new IOException("Can't read stream size");
                    }
                    outSize |= (long) v << 8 * i;
                }
            }
            else
            {
                outSize = -1;
                dec.SetDecoderProperties(props);
            }
            if (DEBUG)
            {
                dbg.printf("%s begins%n", this);
            }
            dec.Code(in, out, outSize);
            if (DEBUG)
            {
                dbg.printf("%s ends%n", this);
            }
            in.close(); // ?
        }
        catch (final IOException _exn)
        {
            exn = _exn;
            if (DEBUG)
            {
                dbg.printf("%s exception: %s%n", this, exn.getMessage());
            }
        }
        // close either way, so listener can unblock
        try
        {
            out.close();
        }
        catch (final IOException _exn)
        {
        }
    }