void extract(InputStream xfaIs, XHTMLContentHandler xhtml, Metadata m, ParseContext context)
            throws XMLStreamException, SAXException {
        xhtml.startElement("div", "class", "xfa_content");

        //TODO - replace this with multivalued map? This isn't
        //actually metadata, just a handy data structure.
        Metadata pdfObjRToValues = new Metadata();

        //for now, store and dump the fields in insertion order
        Map<String, XFAField> namedFields = new LinkedHashMap<>();

        //The strategy is to cache the fields in fields
        //and cache the values in pdfObjRToValues while
        //handling the text etc along the way.
        //
        //As a final step, dump the merged fields and the values.

        XMLStreamReader reader = XMLReaderUtils.getXMLInputFactory(context).createXMLStreamReader(xfaIs);
        while (reader.hasNext()) {
            switch (reader.next()) {
                case XMLStreamConstants.START_ELEMENT:
                    QName name = reader.getName();
                    String localName = name.getLocalPart();
                    if (xfaTemplateMatcher.reset(name.getNamespaceURI()).find() &&
                            FIELD_LN.equals(name.getLocalPart())) {
                        handleField(reader, namedFields);
                    } else if (XFA_DATA.equals(name)) { //full qname match is important!
                        loadData(reader, pdfObjRToValues);
                    } else if (textMatcher.reset(localName).find()) {
                        scrapeTextUntil(reader, xhtml, name);
                    }
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    break;
            }
        }

        if (namedFields.size() == 0) {
            xhtml.endElement("div");
            return;
        }
        //now dump fields and values
        xhtml.startElement("div", "class", "xfa_form");
        xhtml.startElement("ol");
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, XFAField> e : namedFields.entrySet()) {
            String fieldName = e.getKey();
            XFAField field = e.getValue();
            String displayFieldName =
                    (field.toolTip == null || field.toolTip.isBlank()) ? fieldName :
                            field.toolTip;
            String[] fieldValues = pdfObjRToValues.getValues(fieldName);
            if (fieldValues.length == 0) {
                fieldValues = new String[]{""};
            }
            for (String fieldValue : fieldValues) {
                AttributesImpl attrs = new AttributesImpl();
                attrs.addAttribute("", "fieldName", "fieldName", "CDATA", fieldName);

                sb.append(displayFieldName).append(": ");
                if (fieldValue != null) {
                    sb.append(fieldValue);
                }

                xhtml.startElement("li", attrs);
                xhtml.characters(sb.toString());
                xhtml.endElement("li");
                sb.setLength(0);
            }
        }
        xhtml.endElement("ol");
        xhtml.endElement("div");
        xhtml.endElement("div");
    }
This class offers an initial capability to
scrape text containing elements out of XFA, and
it tries to link fields with values.
<p>
Some areas for improvement:
<ol>
    <li>convert this to 2 lines of XPath</li>
    <li>handle metadata stored in &lt;desc&gt; section (govdocs1: 754282.pdf, 982106.pdf)</li>
    <li>handle pdf metadata (access permissions, etc.) in &lt;pdf&gt; element</li>
    <li>extract different types of uris as metadata</li>
    <li>add extraction of &lt;image&gt; data (govdocs1: 754282.pdf)</li>
    <li>add computation of traversal order for fields</li>
    <li>figure out when text extracted from xfa fields is duplicative of that
    extracted from the rest of the pdf...and do this efficiently and quickly</li>
    <li>avoid duplication with &lt;speak&gt; and &lt;tooltip&gt; elements</li>
</ol>
tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/XFAExtractor.java