class PDFunctionType4 extends PDFunction
{

    private static final Operators OPERATORS = new Operators();

    private final InstructionSequence instructions;

    /**
     * Constructor.
     *
     * @param functionStream The function stream.
     * @throws IOException if an I/O error occurs while reading the function
     */
    public PDFunctionType4(COSBase functionStream) throws IOException
    {
        super( functionStream );
        byte[] bytes = getPDStream().toByteArray();
        String string = new String(bytes, StandardCharsets.ISO_8859_1);
        this.instructions = InstructionSequenceBuilder.parse(string);
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public int getFunctionType()
    {
        return 4;
    }

    /**
    * {@inheritDoc}
    */
    @Override
    public float[] eval(float[] input) throws IOException
    {<FILL_FUNCTION_BODY>}
}

        //Setup the input values
        ExecutionContext context = new ExecutionContext(OPERATORS);
        for (int i = 0; i < input.length; i++)
        {
            PDRange domain = getDomainForInput(i);
            float value = clipToRange(input[i], domain.getMin(), domain.getMax());
            context.getStack().push(value);
        }

        //Execute the type 4 function.
        instructions.execute(context);

        //Extract the output values
        int numberOfOutputValues = getNumberOfOutputParameters();
        int numberOfActualOutputValues = context.getStack().size();
        if (numberOfActualOutputValues < numberOfOutputValues)
        {
            throw new IllegalStateException("The type 4 function returned "
                    + numberOfActualOutputValues
                    + " values but the Range entry indicates that "
                    + numberOfOutputValues + " values be returned.");
        }
        float[] outputValues = new float[numberOfOutputValues];
        for (int i = numberOfOutputValues - 1; i >= 0; i--)
        {
            PDRange range = getRangeForOutput(i);
            outputValues[i] = context.popReal();
            outputValues[i] = clipToRange(outputValues[i], range.getMin(), range.getMax());
        }

        //Return the resulting array
        return outputValues;
    
<methods>public void <init>(org.apache.pdfbox.cos.COSBase) ,public static org.apache.pdfbox.pdmodel.common.function.PDFunction create(org.apache.pdfbox.cos.COSBase) throws java.io.IOException,public abstract float[] eval(float[]) throws java.io.IOException,public final org.apache.pdfbox.cos.COSDictionary getCOSObject() ,public org.apache.pdfbox.pdmodel.common.PDRange getDomainForInput(int) ,public abstract int getFunctionType() ,public int getNumberOfInputParameters() ,public int getNumberOfOutputParameters() ,public org.apache.pdfbox.pdmodel.common.PDRange getRangeForOutput(int) ,public void setDomainValues(org.apache.pdfbox.cos.COSArray) ,public void setRangeValues(org.apache.pdfbox.cos.COSArray) ,public java.lang.String toString() <variables>private org.apache.pdfbox.cos.COSArray domain,private org.apache.pdfbox.cos.COSDictionary functionDictionary,private org.apache.pdfbox.pdmodel.common.PDStream functionStream,private int numberOfInputValues,private int numberOfOutputValues,private org.apache.pdfbox.cos.COSArray range