class ASCII85OutputStream extends FilterOutputStream
{

    private int lineBreak;
    private int count;

    private byte[] indata;
    private byte[] outdata;

    /**
     * Function produces five ASCII printing characters from
     * four bytes of binary data.
     */
    private int maxline;
    private boolean flushed;
    private char terminator;
    private static final char OFFSET = '!';
    private static final char NEWLINE = '\n';
    private static final char Z = 'z';

    /**
     * Constructor.
     *
     * @param out The output stream to write to.
     */
    ASCII85OutputStream(OutputStream out)
    {
        super(out);
        lineBreak = 36 * 2;
        maxline = 36 * 2;
        count = 0;
        indata = new byte[4];
        outdata = new byte[5];
        flushed = true;
        terminator = '~';
    }

    /**
     * This will set the terminating character.
     *
     * @param term The terminating character.
     */
    public void setTerminator(char term)
    {<FILL_FUNCTION_BODY>}

    /**
     * This will get the terminating character.
     *
     * @return The terminating character.
     */
    public char getTerminator()
    {
        return terminator;
    }

    /**
     * This will set the line length that will be used.
     *
     * @param l The length of the line to use.
     */
    public void setLineLength(int l)
    {
        if (lineBreak > l)
        {
            lineBreak = l;
        }
        maxline = l;
    }

    /**
     * This will get the length of the line.
     *
     * @return The line length attribute.
     */
    public int getLineLength()
    {
        return maxline;
    }

    /**
     * This will transform the next four ascii bytes.
     */
    private void transformASCII85()
    {
        long word = ((((indata[0] << 8) | (indata[1] & 0xFF)) << 16) | ((indata[2] & 0xFF) << 8) | (indata[3] & 0xFF)) & 0xFFFFFFFFL;

        if (word == 0)
        {
            outdata[0] = (byte) Z;
            outdata[1] = 0;
            return;
        }
        long x;
        x = word / (85L * 85L * 85L * 85L);
        outdata[0] = (byte) (x + OFFSET);
        word -= x * 85L * 85L * 85L * 85L;

        x = word / (85L * 85L * 85L);
        outdata[1] = (byte) (x + OFFSET);
        word -= x * 85L * 85L * 85L;

        x = word / (85L * 85L);
        outdata[2] = (byte) (x + OFFSET);
        word -= x * 85L * 85L;

        x = word / 85L;
        outdata[3] = (byte) (x + OFFSET);

        outdata[4] = (byte) ((word % 85L) + OFFSET);
    }

    /**
     * This will write a single byte.
     *
     * @param b The byte to write.
     *
     * @throws IOException If there is an error writing to the stream.
     */
    @Override
    public void write(int b) throws IOException
    {
        flushed = false;
        indata[count++] = (byte) b;
        if (count < 4)
        {
            return;
        }
        transformASCII85();
        for (int i = 0; i < 5; i++)
        {
            if (outdata[i] == 0)
            {
                break;
            }
            out.write(outdata[i]);
            if (--lineBreak == 0)
            {
                out.write(NEWLINE);
                lineBreak = maxline;
            }
        }
        count = 0;
    }

    /**
     * This will flush the data to the stream.
     *
     * @throws IOException If there is an error writing the data to the stream.
     */
    @Override
    public void flush() throws IOException
    {
        if (flushed)
        {
            return;
        }
        if (count > 0)
        {
            for (int i = count; i < 4; i++)
            {
                indata[i] = 0;
            }
            transformASCII85();
            if (outdata[0] == Z)
            {
                for (int i = 0; i < 5; i++) // expand 'z',
                {
                    outdata[i] = (byte) OFFSET;
                }
            }
            for (int i = 0; i < count + 1; i++)
            {
                out.write(outdata[i]);
                if (--lineBreak == 0)
                {
                    out.write(NEWLINE);
                    lineBreak = maxline;
                }
            }
        }
        if (--lineBreak == 0)
        {
            out.write(NEWLINE);
        }
        out.write(terminator);
        out.write('>');
        out.write(NEWLINE);
        count = 0;
        lineBreak = maxline;
        flushed = true;
        super.flush();
    }

    /**
     * This will close the stream.
     *
     * @throws IOException If there is an error closing the wrapped stream.
     */
    @Override
    public void close() throws IOException
    {
        try
        {
            flush();
            super.close();
        }
        finally
        {
            indata = outdata = null;
        }
    }
}

        if (term < 118 || term > 126 || term == Z)
        {
            throw new IllegalArgumentException("Terminator must be 118-126 excluding z");
        }
        terminator = term;
    
<methods>public void <init>(java.io.OutputStream) ,public void close() throws java.io.IOException,public void flush() throws java.io.IOException,public void write(int) throws java.io.IOException,public void write(byte[]) throws java.io.IOException,public void write(byte[], int, int) throws java.io.IOException<variables>private final java.lang.Object closeLock,private volatile boolean closed,protected java.io.OutputStream out