class PDVisibleSigProperties
{
    private String signerName;
    private String signerLocation;
    private String signatureReason;
    private boolean visualSignEnabled;
    private int page;
    private int preferredSize;

    private InputStream visibleSignature;
    private PDVisibleSignDesigner pdVisibleSignature;

    /**
     * start building of visible signature
     *
     * @throws IOException if the output could not be written
     */
    public void buildSignature() throws IOException
    {<FILL_FUNCTION_BODY>}

    /**
     * 
     * @return - signer name
     */
    public String getSignerName()
    {
        return signerName;
    }

    /**
     * Sets signer name
     * 
     * @param signerName the signer name
     * @return the visible signature properties.
     */
    public PDVisibleSigProperties signerName(String signerName)
    {
        this.signerName = signerName;
        return this;
    }

    /**
     * Gets signer location
     * 
     * @return - location
     */
    public String getSignerLocation()
    {
        return signerLocation;
    }

    /**
     * Sets location
     * 
     * @param signerLocation the new signer location
     * @return the visible signature properties.
     */
    public PDVisibleSigProperties signerLocation(String signerLocation)
    {
        this.signerLocation = signerLocation;
        return this;
    }

    /**
     * gets reason of signing
     * @return  the signing reason. 
     */
    public String getSignatureReason()
    {
        return signatureReason;
    }

    /**
     * sets reason of signing
     * 
     * @param signatureReason the reason of signing
     * @return the visible signature properties.
     */
    public PDVisibleSigProperties signatureReason(String signatureReason)
    {
        this.signatureReason = signatureReason;
        return this;
    }

    /**
     * returns your page
     * @return  the page number (1-based).
     */
    public int getPage()
    {
        return page;
    }

    /**
     * sets page number
     * @param page page the signature should be placed on (1-based)
     * @return the visible signature properties.
     */
    public PDVisibleSigProperties page(int page)
    {
        this.page = page;
        return this;
    }

    /**
     * Gets the preferred signature size in bytes.
     *
     * @return the signature's preferred size. A return value of 0 means to use default.
     */
    public int getPreferredSize()
    {
        return preferredSize;
    }

    /**
     * Sets the preferred signature size in bytes.
     *
     * @param preferredSize The preferred signature size in bytes, or 0 to use default.
     * @return the visible signature properties.
     */
    public PDVisibleSigProperties preferredSize(int preferredSize)
    {
        this.preferredSize = preferredSize;
        return this;
    }

    /**
     * checks if we need to add visible signature
     * @return state if visible signature is needed.
     */
    public boolean isVisualSignEnabled()
    {
        return visualSignEnabled;
    }

    /**
     * sets visible signature to be added or not
     * 
     * @param visualSignEnabled if true the visible signature is added
     * @return the visible signature properties.
     */
    public PDVisibleSigProperties visualSignEnabled(boolean visualSignEnabled)
    {
        this.visualSignEnabled = visualSignEnabled;
        return this;
    }

    /**
     * this method gets visible signature configuration object
     * @return the visible signature configuration.
     */
    public PDVisibleSignDesigner getPdVisibleSignature()
    {
        return pdVisibleSignature;
    }

    /**
     * Sets visible signature configuration Object
     * 
     * @param pdVisibleSignature the new visible signature configuration
     * @return the visible signature properties.
     */
    public PDVisibleSigProperties setPdVisibleSignature(PDVisibleSignDesigner pdVisibleSignature)
    {
        this.pdVisibleSignature = pdVisibleSignature;
        return this;
    }

    /**
     * returns visible signature configuration object
     * @return the input stream representing the visible signature.
     */
    public InputStream getVisibleSignature()
    {
        return visibleSignature;
    }

    /**
     * sets configuration object of visible signature
     * 
     * @param visibleSignature the stream of the visible signature
     */
    public void setVisibleSignature(InputStream visibleSignature)
    {
        this.visibleSignature = visibleSignature;
    }
}

        PDFTemplateBuilder builder = new PDVisibleSigBuilder();
        PDFTemplateCreator creator = new PDFTemplateCreator(builder);
        setVisibleSignature(creator.buildPDF(getPdVisibleSignature()));
    
<no_super_class>