public static AclLineMatchExprWithProvenance<AclLineMatchExpr> explainNormalForm( AclLineMatchExpr nf) { /* * A normal form is either a factor or a disjunction of factors. */ if (nf instanceof OrMatchExpr) { /* * Each disjunct is a factor. */ SortedSet<AclLineMatchExprWithProvenance<AclLineMatchExpr>> disjunctsWithProvenance = ((OrMatchExpr) nf) .getDisjuncts().stream() .map(AclExplanation::explainFactor) .collect(ImmutableSortedSet.toImmutableSortedSet(Ordering.natural())); List<AclLineMatchExpr> disjuncts = new LinkedList<>(); IdentityHashMap<AclLineMatchExpr, Set<AclLineMatchExpr>> provenance = new IdentityHashMap<>(); for (AclLineMatchExprWithProvenance<AclLineMatchExpr> matchExprWithProvenance : disjunctsWithProvenance) { disjuncts.add(matchExprWithProvenance.getMatchExpr()); provenance.putAll(matchExprWithProvenance.getProvenance()); } return new AclLineMatchExprWithProvenance<>(new OrMatchExpr(disjuncts), provenance); } return explainFactor(nf); } }