/**
 * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
 * 
 * Please see distribution for license.
 */
package com.opengamma.engine.function.config;

import java.util.List;
import java.util.Set;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.opengamma.core.config.ConfigSource;
import com.opengamma.id.VersionCorrection;
import com.opengamma.util.ArgumentChecker;

/**
 * Aggregate functions defined in a {@link FunctionConfigurationDefinition}
 */
public final class FunctionConfigurationDefinitionAggregator {

  private final ConfigSource _configSource;
  
  public FunctionConfigurationDefinitionAggregator(final ConfigSource configSource) {
    ArgumentChecker.notNull(configSource, "configSource");
    _configSource = configSource;
  }
  
  public FunctionConfigurationSource aggregate(String configDefinitionName) {
    ArgumentChecker.notNull(configDefinitionName, "configDefinitionName");
    FunctionConfigurationDefinition configDefinition = _configSource.getSingle(FunctionConfigurationDefinition.class, configDefinitionName, VersionCorrection.LATEST);
   
    return new SimpleFunctionConfigurationSource(functionAggregator(configDefinition));
  }

  private FunctionConfigurationBundle functionAggregator(final FunctionConfigurationDefinition configDefinition) {
    final Set<FunctionConfiguration> functions = Sets.newHashSet();
    final List<String> visitedConfigs = Lists.newArrayList();
    functionAggregatorHelper(functions, visitedConfigs, configDefinition);
    return new FunctionConfigurationBundle(functions);
  }

  private void functionAggregatorHelper(final Set<FunctionConfiguration> functions, final List<String> visitedConfigs, final FunctionConfigurationDefinition configDefinition) {
    visitedConfigs.add(configDefinition.getName());
    functions.addAll(configDefinition.getStaticFunctions());
    functions.addAll(configDefinition.getParameterizedFunctions());
    
    for (String configDefinitionName : configDefinition.getFunctionConfigurationDefinitions()) {
      if (!visitedConfigs.contains(configDefinitionName)) {
        FunctionConfigurationDefinition linkedConfig = _configSource.getSingle(FunctionConfigurationDefinition.class, configDefinitionName, VersionCorrection.LATEST);
        functionAggregatorHelper(functions, visitedConfigs, linkedConfig);
      }
    }
  }
}

@@ -1146,94 +1146,231 @@
 %0A   
-%0A    return new SimpleFunctionConfigurationSource(functionAggregator(configDefinition)
+ FunctionConfigurationBundle bundle = new FunctionConfigurationBundle();%0A    if (configDefinition != null) %7B%0A      bundle = functionAggregator(configDefinition);%0A    %7D%0A    return new SimpleFunctionConfigurationSource(bundle
 );%0A 
@@ -2436,24 +2436,62 @@
 on.LATEST);%0A
+        if (linkedConfig != null) %7B%0A  
         func
@@ -2553,16 +2553,26 @@
 onfig);%0A
+        %7D%0A
       %7D%0A

Check for missing function configuration docs