class BlueprintConfigurationProcessor {

  protected void setStackToolsAndFeatures(Configuration configuration, Set<String> configTypesUpdated)
    throws ConfigurationTopologyException {
    ConfigHelper configHelper = clusterTopology.getAmbariContext().getConfigHelper();
    Stack stack = clusterTopology.getBlueprint().getStack();
    String stackName = stack.getName();
    String stackVersion = stack.getVersion();

    StackId stackId = new StackId(stackName, stackVersion);

    Set<String> properties = Sets.newHashSet(
      ConfigHelper.CLUSTER_ENV_STACK_NAME_PROPERTY,
      ConfigHelper.CLUSTER_ENV_STACK_ROOT_PROPERTY,
      ConfigHelper.CLUSTER_ENV_STACK_TOOLS_PROPERTY,
      ConfigHelper.CLUSTER_ENV_STACK_FEATURES_PROPERTY,
      ConfigHelper.CLUSTER_ENV_STACK_PACKAGES_PROPERTY);

    try {
      Map<String, Map<String, String>> defaultStackProperties = configHelper.getDefaultStackProperties(stackId);
      Map<String,String> clusterEnvDefaultProperties = defaultStackProperties.get(CLUSTER_ENV_CONFIG_TYPE_NAME);

      for( String property : properties ){
        if (clusterEnvDefaultProperties.containsKey(property)) {
          String newValue = clusterEnvDefaultProperties.get(property);
          String previous = configuration.setProperty(CLUSTER_ENV_CONFIG_TYPE_NAME, property, newValue);
          if (!Objects.equals(
            trimValue(previous, stack, CLUSTER_ENV_CONFIG_TYPE_NAME, property),
            trimValue(newValue, stack, CLUSTER_ENV_CONFIG_TYPE_NAME, property))) {
            // in case a property is updated make sure to include cluster-env as being updated
            configTypesUpdated.add(CLUSTER_ENV_CONFIG_TYPE_NAME);
          }
        }
      }
    } catch( AmbariException ambariException ){
      throw new ConfigurationTopologyException("Unable to retrieve the stack tools and features",
        ambariException);
    }
  }

  public  BlueprintConfigurationProcessor(ClusterTopology clusterTopology);

}