private void readComponents(DeployState deployState,
                                TreeConfigProducer<AnyConfigProducer> ancestor,
                                Collection<ComponentType<T>> componentTypes,
                                List<Element> elementsContainingComponentElems,
                                Map<String, ComponentType<?>> outerComponentTypeByComponentName) {

        for (ComponentType<T> componentType : componentTypes) {
            for (Element elemContainingComponentElems : elementsContainingComponentElems) {
                for (Element componentElement : XML.getChildren(elemContainingComponentElems, componentType.name)) {
                    readComponent(deployState, ancestor, componentElement, componentType, outerComponentTypeByComponentName);
                }
            }
        }
    }
@param ancestor The parent config producer
@param componentTypes The allowed component types for 'elementContainingComponentElements' - MUST match &lt;T&gt;
@param elementsContainingComponentElems All elements containing elements with name matching ComponentType.name
@param outerComponentTypeByComponentName Use null if this is the outermost scope, i.e.
                                         every component is a definition, not a reference.
config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/chains/ComponentsBuilder.java