class CreateSignedTimeStamp implements SignatureInterface
{
    private static final Logger LOG = LogManager.getLogger(CreateSignedTimeStamp.class);
    
    private final String tsaUrl;

    /**
     * Initialize the signed timestamp creator
     * 
     * @param tsaUrl The url where TS-Request will be done.
     */
    public CreateSignedTimeStamp(String tsaUrl)
    {
        this.tsaUrl = tsaUrl;
    }

    /**
     * Signs the given PDF file. Alters the original file on disk.
     * 
     * @param file the PDF file to sign
     * @throws IOException if the file could not be read or written
     */
    public void signDetached(File file) throws IOException
    {
        signDetached(file, file);
    }

    /**
     * Signs the given PDF file.
     * 
     * @param inFile input PDF file
     * @param outFile output PDF file
     * @throws IOException if the input file could not be read
     */
    public void signDetached(File inFile, File outFile) throws IOException
    {
        if (inFile == null || !inFile.exists())
        {
            throw new FileNotFoundException("Document for signing does not exist");
        }

        // sign
        try (PDDocument doc = Loader.loadPDF(inFile);
             FileOutputStream fos = new FileOutputStream(outFile))
        {
            signDetached(doc, fos);
        }
    }

    /**
     * Prepares the TimeStamp-Signature and starts the saving-process.
     * 
     * @param document given Pdf
     * @param output Where the file will be written
     * @throws IOException
     */
    public void signDetached(PDDocument document, OutputStream output) throws IOException
    {
        int accessPermissions = SigUtils.getMDPPermission(document);
        if (accessPermissions == 1)
        {
            throw new IllegalStateException(
                    "No changes to the document are permitted due to DocMDP transform parameters dictionary");
        }

        // create signature dictionary
        PDSignature signature = new PDSignature();
        signature.setType(COSName.DOC_TIME_STAMP);
        signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
        signature.setSubFilter(COSName.getPDFName("ETSI.RFC3161"));

        // No certification allowed because /Reference not allowed in signature directory
        // see ETSI EN 319 142-1 Part 1 and ETSI TS 102 778-4
        // http://www.etsi.org/deliver/etsi_en%5C319100_319199%5C31914201%5C01.01.00_30%5Cen_31914201v010100v.pdf
        // http://www.etsi.org/deliver/etsi_ts/102700_102799/10277804/01.01.01_60/ts_10277804v010101p.pdf

        // register signature dictionary and sign interface
        document.addSignature(signature, this);

        // write incremental (only for signing purpose)
        document.saveIncremental(output);
    }

    @Override
    public byte[] sign(InputStream content) throws IOException
    {
        ValidationTimeStamp validation;
        try
        {
            validation = new ValidationTimeStamp(tsaUrl);
            return validation.getTimeStampToken(content);
        }
        catch (NoSuchAlgorithmException | URISyntaxException e)
        {
            LOG.error("Hashing-Algorithm not found for TimeStamping", e);
        }
        return new byte[] {};
    }

    public static void main(String[] args) throws IOException
    {<FILL_FUNCTION_BODY>}

    private static void usage()
    {
        System.err.println("usage: java " + CreateSignedTimeStamp.class.getName() + " "
                + "<pdf_to_sign>\n" + "mandatory options:\n"
                + "  -tsa <url>    sign timestamp using the given TSA server\n");
    }
}

        if (args.length != 3)
        {
            usage();
            System.exit(1);
        }

        String tsaUrl = null;
        if ("-tsa".equals(args[1]))
        {
            tsaUrl = args[2];
        }
        else
        {
            usage();
            System.exit(1);
        }

        // sign PDF
        CreateSignedTimeStamp signing = new CreateSignedTimeStamp(tsaUrl);

        File inFile = new File(args[0]);
        String name = inFile.getName();
        String substring = name.substring(0, name.lastIndexOf('.'));

        File outFile = new File(inFile.getParent(), substring + "_timestamped.pdf");
        signing.signDetached(inFile, outFile);
    
<no_super_class>