class 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;
    }

}