public static ConfigUpgradePack merge(ArrayList<ConfigUpgradePack> cups) {
    // Map <service_name, <component_name, component_changes>>
    Map<String, Map<String, AffectedComponent>> mergedServiceMap = new HashMap<>();

    for (ConfigUpgradePack configUpgradePack : cups) {
      for (AffectedService service : configUpgradePack.services) {
        if (! mergedServiceMap.containsKey(service.name)) {
          mergedServiceMap.put(service.name, new HashMap<>());
        }
        Map<String, AffectedComponent> mergedComponentMap = mergedServiceMap.get(service.name);

        for (AffectedComponent component : service.components) {
          if (! mergedComponentMap.containsKey(component.name)) {
            AffectedComponent mergedComponent = new AffectedComponent();
            mergedComponent.name = component.name;
            mergedComponent.changes = new ArrayList<>();
            mergedComponentMap.put(component.name, mergedComponent);
          }
          AffectedComponent mergedComponent = mergedComponentMap.get(component.name);
          mergedComponent.changes.addAll(component.changes);
        }

      }
    }
    // Convert merged maps into new ConfigUpgradePack
    ArrayList<AffectedService> mergedServices = new ArrayList<>();
    for (String serviceName : mergedServiceMap.keySet()) {
      AffectedService mergedService = new AffectedService();
      Map<String, AffectedComponent> mergedComponentMap = mergedServiceMap.get(serviceName);
      mergedService.name = serviceName;
      mergedService.components = new ArrayList<>(mergedComponentMap.values());
      mergedServices.add(mergedService);
    }

    return new ConfigUpgradePack(mergedServices);
  }
Merges few config upgrade packs into one and returs result. During merge,
a deep copy of AffectedService and AffectedComponent lists is added to resulting
config upgrade pack. The only level that is not copied deeply is a list of
per-component config changes.
@param cups list of source config upgrade packs
@return merged config upgrade pack that is a deep copy of source
config upgrade packs
ambari-server/src/main/java/org/apache/ambari/server/stack/upgrade/ConfigUpgradePack.java