private static void find(COSBase cosBase, Set<COSName> types, int depth, int maxDepth,
                             Set<COSBase> seen, List<COSDictionary> found) {
        if (seen.contains(cosBase)) {
            return;
        }
        if (depth >= maxDepth) {
            return;
        }
        seen.add(cosBase);
        if (cosBase instanceof COSObject) {
            COSBase dereferencedBase = ((COSObject)cosBase).getObject();
            find(dereferencedBase, types, depth + 1, maxDepth, seen, found);
        } else if (cosBase instanceof COSDictionary) {
            COSDictionary dict = (COSDictionary)cosBase;
            COSName value = dict.getCOSName(COSName.TYPE);
            if (value != null && types.contains(value)) {
                found.add(dict);
            } else if (value != null && (value.equals(COSName.P) || value.equals(COSName.PAGE)
                    || value.equals(COSName.PARENT))) {
                //don't descend page, p, or parent
                return;
            } else {
                for (Map.Entry<COSName, COSBase> e : dict.entrySet()) {
                    find(e.getValue(), types, depth + 1, maxDepth, seen, found);
                }
            }
        } else if (cosBase instanceof COSArray) {
            for (COSBase item : ((COSArray)cosBase)) {
                find(item, types, depth + 1, maxDepth, seen, found);
            }
        }
    }
This recursively looks through cosBase for cosdictionary's that have
a type key in the types set. It intentionally does not follow /p, /parent, /page
dictionaries.

@param cosBase
@param types
@param maxDepth
@return
tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-pdf-module/src/main/java/org/apache/tika/parser/pdf/PDFDOMUtil.java