class FileVaultNameFinder {

    public Set<QName> search(final Archive archive) throws Exception {
        archive.open(false);
        PrivilegeDefinitions defs = archive.getMetaInf().getPrivileges();
        if (defs != null && !defs.getDefinitions().isEmpty()) {
            NamespaceMapping mapping = defs.getNamespaceMapping();
            defs.getDefinitions().forEach(def -> collectPrivilegeDefinition(mapping, def));
        }

        Collection<NodeTypeSet> nodeTypeSets = archive.getMetaInf().getNodeTypes();
        for (NodeTypeSet nodeTypeSet : nodeTypeSets) {
            NamespaceMapping names = nodeTypeSet.getNamespaceMapping();
            nodeTypeSet.getNodeTypes().values().forEach(def -> collectNodeTypeNames(names, def));
        }

        Archive.Entry rootEntry = archive.getJcrRoot();

        if (rootEntry != null) {
            this.search(archive, rootEntry);
        }

        Set<QName> subtracted = new LinkedHashSet<>();

        references.stream()
                .filter(((Predicate<QName>) definitions::contains).negate())
                .forEachOrdered(subtracted::add);

        return subtracted;
    }

    public  FileVaultNameFinder();

}