SubstitutionUtils { public static <R extends HasType, T extends HasInheritance> Map<R, List<Subtypes<T>>> collectSubstitutableTemplates(List<R> templates, Map<QName, T> types) { Map<R, List<Subtypes<T>>> substitutableTypes = new HashMap<>(); templates.forEach(tNodeTemplate -> { QName nodeTemplateType = tNodeTemplate.getTypeAsQName(); collectTypeHierarchy(types, nodeTemplateType) .ifPresent(tNodeTypeSubtypes -> substitutableTypes.put(tNodeTemplate, tNodeTypeSubtypes) ); }); return substitutableTypes; }  static Map<R, List<Subtypes<T>>> collectSubstitutableTemplates(List<R> templates, Map<QName, T> types); static Optional<List<Subtypes<T>>> collectTypeHierarchy(Map<QName, T> types, QName parent); static boolean containsPatterns(List<TNodeTemplate> topologyNodes, Map<QName, TNodeType> nodeTypes);  }
@Test public void getSubstitutableTemplateMap() { List<TNodeTemplate> templates = Arrays.asList( new TNodeTemplate.Builder("id0", stranger).build(), new TNodeTemplate.Builder("id1", parent).build(), new TNodeTemplate.Builder("id2", grandFather).build(), new TNodeTemplate.Builder("id3", aunt).build() ); Map<TNodeTemplate, List<Subtypes<TNodeType>>> substitutableTemplates = SubstitutionUtils.collectSubstitutableTemplates(templates, nodeTypes); assertEquals(2, substitutableTemplates.size()); assertTrue(substitutableTemplates.entrySet() .removeIf(entry -> grandFather.equals(entry.getKey().getTypeAsQName())) ); assertTrue(substitutableTemplates.entrySet() .removeIf(entry -> parent.equals(entry.getKey().getType())) ); }