/**
   * Create an instance of {@link ECDF} based on an experiment set and a configuration
   *
   * @param data the data (experiment set)
   * @param config the configuration
   * @return the instance of the aggregate
   */
  public static final ECDF create(final IExperimentSet data, final Configuration config) {
    DimensionTransformationParser dimParser;
    final DimensionTransformation xIn, yIn;
    final Transformation yOut;
    final StatisticalParameter aggregate;
    final IDimension goalDim;
    EComparison compare;
    Number goal;

    dimParser = new DimensionTransformationParser(data);
    xIn =
        config.get( //
            FunctionAttribute.X_AXIS_PARAM, dimParser, null);
    if (xIn == null) { //
      throw new IllegalArgumentException(
          "Must specify an x-dimension via parameter '" //$NON-NLS-1$
              + FunctionAttribute.X_AXIS_PARAM
              + '\'');
    }

    yIn = config.get(FunctionAttribute.Y_INPUT_AXIS_PARAM, dimParser, null);
    if (yIn == null) { //
      throw new IllegalArgumentException(
          "Must specify an input dimension for the y-axis via parameter '" //$NON-NLS-1$
              + FunctionAttribute.Y_INPUT_AXIS_PARAM
              + '\'');
    }

    dimParser = null;

    yOut =
        config.get(
            FunctionAttribute.Y_AXIS_OUTPUT_PARAM,
            new NamedParameterTransformationParser(data),
            new Transformation());

    aggregate =
        config.get(
            ECDF.AGGREGATE_PARAM,
            StatisticalParameterParser.getInstance(),
            ArithmeticMean.INSTANCE);

    goalDim = yIn.getDimension();

    if (goalDim.getDirection().isIncreasing()) {
      compare = EComparison.GREATER_OR_EQUAL;
      if (goalDim.getDataType().isInteger()) {
        goal = Long.valueOf(goalDim.getParser().getUpperBoundLong());
      } else {
        goal = Double.valueOf(goalDim.getParser().getUpperBoundDouble());
      }
    } else {
      compare = EComparison.LESS_OR_EQUAL;
      if (goalDim.getDataType().isInteger()) {
        goal = Long.valueOf(goalDim.getParser().getLowerBoundLong());
      } else {
        goal = Double.valueOf(goalDim.getParser().getLowerBoundDouble());
      }
    }

    goal = config.get(ECDF.GOAL_PARAM, AnyNumberParser.INSTANCE, goal);
    compare = config.get(ECDF.CRITERION_PARAM, ComparisonParser.getInstance(), compare);

    return new ECDF(xIn, yIn, yOut, goal, compare, aggregate);
  }