private void processFeaturePackConfigFile(
     ServerProvisioningFeaturePack.ConfigFile serverProvisioningFeaturePackConfigFile,
     ZipFile zipFile,
     ServerProvisioningFeaturePack provisioningFeaturePack,
     Map<String, ServerProvisioning.ConfigFile> provisioningConfigFiles)
     throws IOException, XMLStreamException {
   ConfigFile configFile = serverProvisioningFeaturePackConfigFile.getFeaturePackConfigFile();
   // get provisioning config file for the output file being processed
   ServerProvisioning.ConfigFile provisioningConfigFile =
       provisioningConfigFiles.get(configFile.getOutputFile());
   if (provisioningConfigFile == null) {
     // the provisioning config file does not exists yet, create one
     provisioningConfigFile = new ServerProvisioning.ConfigFile(configFile.getOutputFile());
     provisioningConfigFiles.put(configFile.getOutputFile(), provisioningConfigFile);
   }
   ConfigFileOverride configFileOverride =
       serverProvisioningFeaturePackConfigFile.getConfigFileOverride();
   // process template
   if (configFileOverride == null || configFileOverride.isUseTemplate()) {
     // template file from this config file to be used
     // get the template's file zip entry
     ZipEntry templateFileZipEntry = zipFile.getEntry(configFile.getTemplate());
     if (templateFileZipEntry == null) {
       throw new RuntimeException(
           "Feature pack "
               + provisioningFeaturePack.getFeaturePack().getFeaturePackFile()
               + " template file "
               + configFile.getTemplate()
               + " not found");
     }
     // set the input stream source
     provisioningConfigFile.setTemplateInputStreamSource(
         new ZipEntryInputStreamSource(
             provisioningFeaturePack.getFeaturePack().getFeaturePackFile(), templateFileZipEntry));
   }
   // get this config file subsystems
   Map<String, Map<String, SubsystemConfig>> subsystems =
       serverProvisioningFeaturePackConfigFile.getSubsystems();
   // merge the subsystems in the provisioning config file
   for (Map.Entry<String, Map<String, SubsystemConfig>> subsystemsEntry : subsystems.entrySet()) {
     // get the subsystems in the provisioning config file
     String profileName = subsystemsEntry.getKey();
     Map<String, SubsystemConfig> subsystemConfigMap = subsystemsEntry.getValue();
     Map<String, SubsystemConfig> provisioningSubsystems =
         provisioningConfigFile.getSubsystems().get(profileName);
     if (provisioningSubsystems == null) {
       // do not exist yet, create it
       provisioningSubsystems = new LinkedHashMap<>();
       provisioningConfigFile.getSubsystems().put(profileName, provisioningSubsystems);
     }
     // add the 'new' subsystem configs and related input stream sources
     for (Map.Entry<String, SubsystemConfig> subsystemConfigMapEntry :
         subsystemConfigMap.entrySet()) {
       String subsystemFile = subsystemConfigMapEntry.getKey();
       SubsystemConfig subsystemConfig = subsystemConfigMapEntry.getValue();
       getLog()
           .debugf(
               "Adding subsystem config %s to provisioning config file %s",
               subsystemFile, provisioningConfigFile.getOutputFile());
       // put subsystem config
       provisioningSubsystems.put(subsystemFile, subsystemConfig);
     }
   }
 }
 private void processConfig(
     ServerProvisioning serverProvisioning, File outputDirectory, Set<String> filesProcessed)
     throws IOException, XMLStreamException {
   ServerProvisioning.Config provisioningConfig = serverProvisioning.getConfig();
   // 1. collect and merge each feature pack configs
   for (ServerProvisioningFeaturePack provisioningFeaturePack :
       serverProvisioning.getFeaturePacks()) {
     processFeaturePackConfig(provisioningFeaturePack, provisioningConfig);
   }
   // 2. assemble the merged configs
   for (ServerProvisioning.ConfigFile provisioningConfigFile :
       provisioningConfig.getDomainConfigFiles().values()) {
     if (provisioningConfigFile.getTemplateInputStreamSource() == null) {
       getLog()
           .debugf(
               "Skipping assembly of config file %s, template not set.",
               provisioningConfigFile.getOutputFile());
       continue;
     }
     getLog().debugf("Assembling config file %s", provisioningConfigFile.getOutputFile());
     filesProcessed.add(provisioningConfigFile.getOutputFile());
     new ConfigurationAssembler(
             provisioningConfig.getInputStreamSources(),
             provisioningConfigFile.getTemplateInputStreamSource(),
             "domain",
             provisioningConfigFile.getSubsystems(),
             new File(outputDirectory, provisioningConfigFile.getOutputFile()))
         .assemble();
   }
   for (ServerProvisioning.ConfigFile provisioningConfigFile :
       provisioningConfig.getStandaloneConfigFiles().values()) {
     if (provisioningConfigFile.getTemplateInputStreamSource() == null) {
       getLog()
           .debugf(
               "Skipping assembly of config file %s, template not set.",
               provisioningConfigFile.getOutputFile());
       continue;
     }
     getLog().debugf("Assembling config file %s", provisioningConfigFile.getOutputFile());
     filesProcessed.add(provisioningConfigFile.getOutputFile());
     new ConfigurationAssembler(
             provisioningConfig.getInputStreamSources(),
             provisioningConfigFile.getTemplateInputStreamSource(),
             "server",
             provisioningConfigFile.getSubsystems(),
             new File(outputDirectory, provisioningConfigFile.getOutputFile()))
         .assemble();
   }
   for (ServerProvisioning.ConfigFile provisioningConfigFile :
       provisioningConfig.getHostConfigFiles().values()) {
     if (provisioningConfigFile.getTemplateInputStreamSource() == null) {
       getLog()
           .debugf(
               "Skipping assembly of config file %s, template not set.",
               provisioningConfigFile.getOutputFile());
       continue;
     }
     getLog().debugf("Assembling config file %s", provisioningConfigFile.getOutputFile());
     filesProcessed.add(provisioningConfigFile.getOutputFile());
     new ConfigurationAssembler(
             provisioningConfig.getInputStreamSources(),
             provisioningConfigFile.getTemplateInputStreamSource(),
             "host",
             provisioningConfigFile.getSubsystems(),
             new File(outputDirectory, provisioningConfigFile.getOutputFile()))
         .assemble();
   }
 }