private static boolean matchNode(final ValueNode origin, final ValueNode candidate) { if (Objects.equals(origin.type, candidate.type)) { if (origin.render != null && origin.render.contains("readonly") && !Objects.equals(origin.defaultValue, candidate.value)) { return false; } else if (!origin.getPredefinedValues().isEmpty() && !origin.getPredefinedValues().contains(candidate.value)) { return false; } for (ValueNode originChild : origin.children) { final List<ValueNode> candidateChildren = candidate.getChildrenByName(originChild.name); if (!originChild.multiple && candidateChildren.size() > 1) { return false; } for (ValueNode candidateChild : candidateChildren) { if (!matchNode(originChild, candidateChild)) { return false; } } } return true; } return false; }