class AdvancedFilterValidator implements GenericMetaInfDataValidator, FilterValidator, DocumentViewXmlValidator, JcrPathValidator {

    @Nullable String getDanglingAncestorNodePath(String nodePath, WorkspaceFilter filter) {
        // check cache first (in that case the issue has already been emitted)
        if (danglingNodePaths.contains(nodePath)) {
            return null;
        }
        // check that all ancestor nodes till the filter root node are contained as well
        for (PathFilterSet pathFilterSet : filter.getFilterSets()) {
            if (pathFilterSet.contains(nodePath)) {
                String parentNodePath = Text.getRelativeParent(nodePath, 1);
                // make sure that all ancestors till the root node are contained as well
                if (!nodePath.equals(pathFilterSet.getRoot()) && !parentNodePath.equals(pathFilterSet.getRoot())) {
                    // ancestor might also be contained in another filter
                    return getDanglingAncestorNodePath(parentNodePath, filter);
                } else {
                    // once the root level is reached this node path is contained
                    return null;
                }
            } 
        }
        danglingNodePaths.add(nodePath);
        return nodePath;
    }

    public  AdvancedFilterValidator(@NotNull DocumentBuilderFactory factory, @NotNull ValidationMessageSeverity defaultSeverity, @NotNull ValidationMessageSeverity severityForUncoveredAncestorNodes, @NotNull ValidationMessageSeverity severityForUncoveredFilterRootAncestors, @NotNull ValidationMessageSeverity severityForOrphanedFilterEntries, boolean isSubPackage, @NotNull Collection<PackageInfo> dependenciesMetaInfo, @NotNull WorkspaceFilter filter, @NotNull Collection<String> validRoots);

}