class MergedStream extends InputStream
{
    final private IOContext _ctxt;

    final private InputStream _in;

    private byte[] _b;

    private int _ptr;

    final private int _end;

    public MergedStream(IOContext ctxt, InputStream in, byte[] buf, int start, int end) {
        _ctxt = ctxt;
        _in = in;
        _b = buf;
        _ptr = start;
        _end = end;
    }

    @Override
    public int available() throws IOException {
        if (_b != null) {
            return _end - _ptr;
        }
        return _in.available();
    }

    @Override public void close() throws IOException {
        _free();
        _in.close();
    }

    @Override public synchronized void mark(int readlimit) {
        if (_b == null) { _in.mark(readlimit); }
    }

    @Override public boolean markSupported() {
        // Only supports marks past the initial rewindable section...
        return (_b == null) && _in.markSupported();
    }

    @Override public int read() throws IOException {
        if (_b != null) {
            int c = _b[_ptr++] & 0xFF;
            if (_ptr >= _end) {
                _free();
            }
            return c;
        }
        return _in.read();
    }

    @Override public int read(byte[] b) throws IOException {
        return read(b, 0, b.length);
    }

    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        if (_b != null) {
            int avail = _end - _ptr;
            if (len > avail) {
                len = avail;
            }
            System.arraycopy(_b, _ptr, b, off, len);
            _ptr += len;
            if (_ptr >= _end) {
                _free();
            }
            return len;
        }
        return _in.read(b, off, len);
    }

    @Override
    public synchronized void reset() throws IOException {
        if (_b == null) { _in.reset(); }
    }

    @Override
    public long skip(long n) throws IOException {
        long count = 0L;

        if (_b != null) {
            int amount = _end - _ptr;

            if (amount > n) { // all in pushed back segment?
                _ptr += (int) n;
                return n;
            }
            _free();
            count += amount;
            n -= amount;
        }

        if (n > 0) { count += _in.skip(n); }
        return count;
    }

    private void _free() {<FILL_FUNCTION_BODY>}
}

        byte[] buf = _b;
        if (buf != null) {
            _b = null;
            if (_ctxt != null) {
                _ctxt.releaseReadIOBuffer(buf);
            }
        }
    
<methods>public void <init>() ,public int available() throws java.io.IOException,public void close() throws java.io.IOException,public synchronized void mark(int) ,public boolean markSupported() ,public static java.io.InputStream nullInputStream() ,public abstract int read() throws java.io.IOException,public int read(byte[]) throws java.io.IOException,public int read(byte[], int, int) throws java.io.IOException,public byte[] readAllBytes() throws java.io.IOException,public byte[] readNBytes(int) throws java.io.IOException,public int readNBytes(byte[], int, int) throws java.io.IOException,public synchronized void reset() throws java.io.IOException,public long skip(long) throws java.io.IOException,public void skipNBytes(long) throws java.io.IOException,public long transferTo(java.io.OutputStream) throws java.io.IOException<variables>private static final int DEFAULT_BUFFER_SIZE,private static final int MAX_BUFFER_SIZE,private static final int MAX_SKIP_BUFFER_SIZE