private void extractEmbeddedDocuments(PDDocument document)
            throws IOException, SAXException, TikaException {
        //See 14.13.10 for the 2.0 spec.  Associated files can show up in lots of places...even
        // streams.
        // It would be great to get more context from the /AF info, but we risk missing files
        //if we don't look everywhere.  With the current method, we're at least getting all
        //filespecs at the cost of losing context (to what was this file attached: doc, page,
        // stream, etc?).

        //find all Filespecs TIKA-4012
        List<COSObject> objs = document.getDocument().getObjectsByType(COSName.FILESPEC);
        Set<COSBase> seen = new HashSet<>();
        for (COSObject obj : objs) {
            processDoc("", "", createFileSpecification(obj.getObject()), new AttributesImpl());
            seen.add(obj.getObject());
        }

        //now go through the embedded files names tree to get those rare cases where
        //a file (instead of a filespec) is attached directly to the names tree
        //or where the filespec is a direct object

        if (document.getDocumentCatalog() == null) {
            return;
        }
        if (document.getDocumentCatalog().getNames() == null) {
            return;
        }
        if (document.getDocumentCatalog().getNames().getEmbeddedFiles() == null) {
            return;
        }
        //use a list instead of a name-based map in case there are key collisions
        //that could hide attachments
        List<NameSpecTuple> specs = new ArrayList<>();
        extractFilesfromEFTree(document.getDocumentCatalog().getNames().getEmbeddedFiles(), specs,
                0);
        //this avoids duplication with the above /FileSpec searching, but also in the case
        //where the same underlying file has different names in the EFTree
        for (NameSpecTuple nameSpecTuple : specs) {
            if (seen.contains(nameSpecTuple.getSpec().getCOSObject())) {
                continue;
            }
            processDoc(nameSpecTuple.getName(), "", nameSpecTuple.getSpec(), new AttributesImpl());
            seen.add(nameSpecTuple.getSpec().getCOSObject());
        }
    }
Format used for signature dates
TODO Make this thread-safe
tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/AbstractPDF2XHTML.java