public int read(byte[] b) throws IOException {
    /* We just don't pass read() down, since negotiate() might call other
     * functions and we need transaction points.
     */
        int n;

    /* clear out the rest of the buffer.
     * loop, in case we have negotiations (return 0) and
     * date (return > 0) mixed ... until end of buffer or
     * any data read.
     */
        do {
            n = handler.negotiate(b);
            if (n > 0) {
                return n;
            }
        } while (n == 0);

    /* try reading stuff until we get at least 1 byte of real data or are 
     * at the end of the buffer.
     */
        while (true) {
            n = source.read(b);
            if (n <= 0) {
                return n;
            }

            handler.inputfeed(b, n);
            n = 0;
            while (true) {
                n = handler.negotiate(b);
                if (n > 0) {
                    return n;
                }
                if (n == -1) // buffer empty.
                {
                    break;
                }
            }
            return 0;
        }
    }