class AbstractUpgradeCatalog implements UpgradeCatalog {

  public void addNewConfigurationsFromXml() throws AmbariException {
    Clusters clusters = injector.getInstance(Clusters.class);
    if (clusters == null) {
      return;
    }

    ConfigHelper configHelper = injector.getInstance(ConfigHelper.class);
    Map<String, Cluster> clusterMap = clusters.getClusters();

    if (clusterMap != null && !clusterMap.isEmpty()) {
      for (Cluster cluster : clusterMap.values()) {
        Map<String, Set<String>> toAddProperties = new HashMap<>();
        Map<String, Set<String>> toUpdateProperties = new HashMap<>();
        Map<String, Set<String>> toRemoveProperties = new HashMap<>();


        Set<PropertyInfo> stackProperties = configHelper.getStackProperties(cluster);
        for(String serviceName: cluster.getServices().keySet()) {
          Set<PropertyInfo> properties = configHelper.getServiceProperties(cluster, serviceName);

          if (properties == null) {
            continue;
          }
          properties.addAll(stackProperties);

          for (PropertyInfo property : properties) {
            String configType = ConfigHelper.fileNameToConfigType(property.getFilename());
            PropertyUpgradeBehavior upgradeBehavior = property.getPropertyAmbariUpgradeBehavior();

            if (property.isDeleted()) {
              // Do nothing
            } else if (upgradeBehavior.isDelete()) {
              if (!toRemoveProperties.containsKey(configType)) {
                toRemoveProperties.put(configType, new HashSet<>());
              }
              toRemoveProperties.get(configType).add(property.getName());
            } else if (upgradeBehavior.isUpdate()) {
              if (!toUpdateProperties.containsKey(configType)) {
                toUpdateProperties.put(configType, new HashSet<>());
              }
              toUpdateProperties.get(configType).add(property.getName());
            } else if (upgradeBehavior.isAdd()) {
              if (!toAddProperties.containsKey(configType)) {
                toAddProperties.put(configType, new HashSet<>());
              }
              toAddProperties.get(configType).add(property.getName());
            }
          }
        }

        for (Entry<String, Set<String>> newProperty : toAddProperties.entrySet()) {
          String newPropertyKey = newProperty.getKey();
          updateConfigurationPropertiesWithValuesFromXml(newPropertyKey, newProperty.getValue(), false, true);
        }

        for (Entry<String, Set<String>> newProperty : toUpdateProperties.entrySet()) {
          String newPropertyKey = newProperty.getKey();
          updateConfigurationPropertiesWithValuesFromXml(newPropertyKey, newProperty.getValue(), true, false);
        }

        for (Entry<String, Set<String>> toRemove : toRemoveProperties.entrySet()) {
          String newPropertyKey = toRemove.getKey();
          updateConfigurationPropertiesWithValuesFromXml(newPropertyKey, Collections.emptySet(), toRemove.getValue(), false, true);
        }
      }
    }
  }

  @Inject public  AbstractUpgradeCatalog(Injector injector);

}