public ContentCluster build(Collection<ContainerModel> containers, ConfigModelContext context, Element w3cContentElement) {
            ModelElement contentElement = new ModelElement(w3cContentElement);
            DeployState deployState = context.getDeployState();
            ModelElement documentsElement = contentElement.child("documents");
            Map<String, NewDocumentType> documentDefinitions =
                    new SearchDefinitionBuilder().build(deployState.getDocumentModel().getDocumentManager(), documentsElement);

            String routingSelection = new DocumentSelectionBuilder().build(documentsElement);
            Set<NewDocumentType> globallyDistributedDocuments = new GlobalDistributionBuilder(documentDefinitions).build(documentsElement);

            String clusterId = getClusterId(contentElement);
            ContentCluster c = new ContentCluster(context.getParentProducer(), clusterId, documentDefinitions,
                                                  globallyDistributedDocuments, routingSelection,
                                                  deployState);
            c.search = new ContentSearchCluster.Builder(documentDefinitions,
                                                        globallyDistributedDocuments,
                                                        fractionOfMemoryReserved(clusterId, containers))
                    .build(deployState, c, contentElement.getXml());
            c.persistenceFactory = new EngineFactoryBuilder().build(contentElement, c);
            c.storageNodes = new StorageCluster.Builder().build(deployState, c, w3cContentElement);
            c.distributorNodes = new DistributorCluster.Builder(c).build(deployState, c, w3cContentElement);
            c.rootGroup = new StorageGroup.Builder(contentElement, context).buildRootGroup(deployState, c, c.search.isStreaming());
            var resourceLimits = calculateAndSetResourceLimits(c, deployState, contentElement);
            c.clusterControllerConfig = createClusterControllerConfig(contentElement, deployState, c, resourceLimits);
            validateThatGroupSiblingsAreUnique(c.clusterId, c.rootGroup);
            warnIfDistributionKeyRangeIsSuboptimal(c.clusterId, c.rootGroup, deployState);
            warnWhenMinNodeRatioLowAndManySmallGroups(c, deployState);
            c.search.handleRedundancy(c.redundancy);
            setupSearchCluster(c.search, contentElement, deployState.getDeployLogger());

            if (c.search.hasIndexed() && !(c.persistenceFactory instanceof ProtonEngine.Factory) )
                throw new IllegalArgumentException("Indexed search requires proton as engine");

            if (documentsElement != null) {
                ModelElement e = documentsElement.child("document-processing");
                if (e != null)
                    setupDocumentProcessing(c, e);
            } else if (c.persistenceFactory != null) {
                throw new IllegalArgumentException("The <documents> element is mandatory in content cluster '" + clusterId + "'");
            }

            ModelElement tuning = contentElement.child("tuning");
            if (tuning != null)
                setupTuning(c, tuning);

            if (context.getParentProducer().getRoot() == null) return c;

            addClusterControllers(context, contentElement, c, deployState);
            return c;
        }
The admin model of this system or null if none (which only happens in tests)
config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java