Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/AlgorithmProblemItem.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/AlgorithmProblemItem.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/AlgorithmProblemItem.cs	(revision 7840)
@@ -0,0 +1,55 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  [StorableClass]
+  public class AlgorithmProblemItem : ParameterizedNamedItem {
+    #region Parameter Properties
+    public IValueParameter<IAlgorithm> AlgorithmParameter {
+      get { return (ValueParameter<IAlgorithm>)Parameters["Algorithm"]; }
+    }
+    public IValueParameter<IProblem> ProblemParameter {
+      get { return (ValueParameter<IProblem>)Parameters["Problem"]; }
+    }
+    #endregion
+
+    #region Constructors and Cloning
+    [StorableConstructor]
+    protected AlgorithmProblemItem(bool deserializing) : base(deserializing) { }
+    public AlgorithmProblemItem() {
+      this.Parameters.Add(new ValueParameter<IAlgorithm>("Algorithm"));
+      this.Parameters.Add(new ValueParameter<IProblem>("Problem"));
+    }
+    protected AlgorithmProblemItem(AlgorithmProblemItem original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new AlgorithmProblemItem(this, cloner);
+    }
+    #endregion
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding.csproj
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding.csproj	(revision 7839)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding.csproj	(revision 7840)
@@ -38,6 +38,20 @@
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Data-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Optimization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Parameters-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Persistence-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Problems.DataAnalysis.Symbolic-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.SequentialEngine-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="System" />
     <Reference Include="System.Core" />
+    <Reference Include="System.Drawing" />
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
@@ -47,9 +61,34 @@
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="Class1.cs" />
+    <Compile Include="AlgorithmProblemItem.cs" />
+    <Compile Include="Interfaces\ICheckedValueConfigurationCollection.cs" />
+    <Compile Include="Interfaces\IOptimizable.cs" />
+    <Compile Include="Interfaces\IParameterConfiguration.cs" />
+    <Compile Include="Interfaces\IRange.cs" />
+    <Compile Include="Interfaces\IValueConfiguration.cs" />
+    <Compile Include="MetaOptimizationUtil.cs" />
+    <Compile Include="NullValue.cs" />
+    <Compile Include="ParameterCombinationsEnumerator.cs" />
+    <Compile Include="ParameterConfigurations\ParameterConfiguration.cs" />
+    <Compile Include="ParameterConfigurations\SingleValuedParameterConfiguration.cs" />
+    <Compile Include="ParameterConfigurationTree.cs" />
+    <Compile Include="Plugin.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="RangeConstraints\ConstrainedValue.cs" />
+    <Compile Include="RangeConstraints\DoubleValueRange.cs" />
+    <Compile Include="RangeConstraints\IntValueRange.cs" />
+    <Compile Include="RangeConstraints\PercentValueRange.cs" />
+    <Compile Include="RangeConstraints\Range.cs" />
+    <Compile Include="SymbolicExpressionGrammer\SymbolicExpressionGrammarValueConfiguration.cs" />
+    <Compile Include="SymbolicExpressionGrammer\SymbolValueConfiguration.cs" />
+    <Compile Include="ValueConfigurations\CheckedValueConfigurationCollection.cs" />
+    <Compile Include="ValueConfigurations\NullValueConfiguration.cs" />
+    <Compile Include="ValueConfigurations\ParameterizedValueConfiguration.cs" />
+    <Compile Include="ValueConfigurations\RangeValueConfiguration.cs" />
+    <Compile Include="ValueConfigurations\ValueConfiguration.cs" />
   </ItemGroup>
   <ItemGroup>
     <None Include="HeuristicLab.snk" />
+    <None Include="Plugin.cs.frame" />
     <None Include="Properties\AssemblyInfo.cs.frame" />
   </ItemGroup>
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/Interfaces/ICheckedValueConfigurationCollection.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/Interfaces/ICheckedValueConfigurationCollection.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/Interfaces/ICheckedValueConfigurationCollection.cs	(revision 7840)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  public interface ICheckedValueConfigurationList : ICheckedItemList<IValueConfiguration> {
+    int MinItemCount { get; }
+    IItemSet<IItem> ValidValues { get; }
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/Interfaces/IOptimizable.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/Interfaces/IOptimizable.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/Interfaces/IOptimizable.cs	(revision 7840)
@@ -0,0 +1,50 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  public interface IOptimizable : IItem {
+    bool IsOptimizable { get; }
+    bool Optimize { get; set; }
+    ConstrainedValue ActualValue { get; set; }
+
+    void Randomize(IRandom random);
+    string ParameterInfoString { get; }
+    void CollectOptimizedParameterNames(List<string> parameterNames, string prefix);
+    double CalculateSimilarity(IOptimizable optimizable);
+
+    /// <summary>
+    /// Recursively gets all optimizables which have Optimize=true
+    /// </summary>
+    List<IOptimizable> GetAllOptimizables();
+
+    event EventHandler IsOptimizableChanged;
+    event EventHandler OptimizeChanged;
+
+    /// <summary>
+    /// indicates if the actualvalues are modifiable
+    /// </summary>
+    bool ValuesReadOnly { get; set; }
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/Interfaces/IParameterConfiguration.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/Interfaces/IParameterConfiguration.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/Interfaces/IParameterConfiguration.cs	(revision 7840)
@@ -0,0 +1,36 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  public interface IParameterConfiguration : IOptimizable, INamedItem {
+    string ParameterName { get; set; }
+    Type ParameterDataType { get; }
+    ICheckedValueConfigurationList ValueConfigurations { get; }
+    Type[] ValidTypes { get; }
+    int ActualValueConfigurationIndex { get; set; }
+
+    void Parameterize(IValueParameter parameter);
+    void UpdateActualValueIndexToItem(IValueConfiguration vc);
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/Interfaces/IRange.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/Interfaces/IRange.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/Interfaces/IRange.cs	(revision 7840)
@@ -0,0 +1,51 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  public interface IRange : IItem, IStringConvertibleValue {
+    object LowerBound { get; set; }
+    object UpperBound { get; set; }
+    object StepSize { get; set; }
+
+    event EventHandler LowerBoundChanged;
+    event EventHandler UpperBoundChanged;
+    event EventHandler StepSizeChanged;
+
+    IItem GetRandomValue(IRandom random);
+
+    IEnumerable<IItem> GetCombinations();
+
+    double CalculateSimilarity(IItem a, IItem b);
+  }
+
+  public interface IRange<T> : IRange, IItem where T : class {
+    new T LowerBound { get; set; }
+    new T UpperBound { get; set; }
+    new T StepSize { get; set; }
+    new T GetRandomValue(IRandom random);
+    new IEnumerable<T> GetCombinations();
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/Interfaces/IValueConfiguration.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/Interfaces/IValueConfiguration.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/Interfaces/IValueConfiguration.cs	(revision 7840)
@@ -0,0 +1,34 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  public interface IValueConfiguration : IOptimizable, IItem {
+    int Number { get; set; } // if larger than 0 it will be visible in the name. this can be used when multiple ValueConfiguration with the same name exist in a list
+    string NumberedName { get; }
+
+    event EventHandler ValueChanged;
+
+    //void Parameterize(IParameterizedItem item);
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/MetaOptimizationUtil.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/MetaOptimizationUtil.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/MetaOptimizationUtil.cs	(revision 7840)
@@ -0,0 +1,115 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  public static class MetaOptimizationUtil {
+    /// <summary>
+    /// Removes those results from the run which are not declared in resultsToKeep
+    /// </summary>
+    public static void ClearResults(IRun run, IEnumerable<string> resultsToKeep) {
+      var resultsToRemove = new List<string>();
+      foreach (var result in run.Results) {
+        if (!resultsToKeep.Contains(result.Key))
+          resultsToRemove.Add(result.Key);
+      }
+      foreach (var result in resultsToRemove)
+        run.Results.Remove(result);
+    }
+
+    /// <summary>
+    /// Removes those parameters from the run which are not declared in parametersToKeep
+    /// </summary>
+    public static void ClearParameters(IRun run, IEnumerable<string> parametersToKeep) {
+      var parametersToRemove = new List<string>();
+      foreach (var parameter in run.Parameters) {
+        if (!parametersToKeep.Contains(parameter.Key))
+          parametersToRemove.Add(parameter.Key);
+      }
+      foreach (var parameter in parametersToRemove)
+        run.Parameters.Remove(parameter);
+    }
+
+    public static double Normalize(
+          ParameterConfigurationTree parameterConfigurationTree,
+          double[] referenceQualityAverages,
+          double[] referenceQualityDeviations,
+          double[] referenceEvaluatedSolutionAverages,
+          double qualityAveragesWeight,
+          double qualityDeviationsWeight,
+          double evaluatedSolutionsWeight,
+          bool maximization) {
+
+      double[] qualityAveragesNormalized = new double[referenceQualityAverages.Length];
+      double[] qualityDeviationsNormalized = new double[referenceQualityDeviations.Length];
+      double[] evaluatedSolutionAveragesNormalized = new double[referenceEvaluatedSolutionAverages.Length];
+
+      for (int i = 0; i < referenceQualityAverages.Length; i++) {
+        qualityAveragesNormalized[i] = parameterConfigurationTree.AverageQualities[i] / referenceQualityAverages[i];
+        qualityDeviationsNormalized[i] = parameterConfigurationTree.QualityStandardDeviations[i] / referenceQualityDeviations[i];
+        evaluatedSolutionAveragesNormalized[i] = parameterConfigurationTree.AverageEvaluatedSolutions[i] / referenceEvaluatedSolutionAverages[i];
+      }
+      parameterConfigurationTree.NormalizedQualityAverages = new DoubleArray(qualityAveragesNormalized);
+      parameterConfigurationTree.NormalizedQualityDeviations = new DoubleArray(qualityDeviationsNormalized);
+      parameterConfigurationTree.NormalizedEvaluatedSolutions = new DoubleArray(evaluatedSolutionAveragesNormalized);
+
+      double qualityAveragesNormalizedValue = qualityAveragesNormalized.Average();
+      double qualityDeviationsNormalizedValue = qualityDeviationsNormalized.Average();
+      double evaluatedSolutionAveragesNormalizedValue = evaluatedSolutionAveragesNormalized.Average();
+
+      // deviation and evaluatedSolutions are always minimization problems. so if maximization=true, flip the values around 1.0 (e.g. 1.15 -> 0.85)
+      if (maximization) {
+        qualityDeviationsNormalizedValue -= (qualityDeviationsNormalizedValue - 1) * 2;
+        evaluatedSolutionAveragesNormalizedValue -= (evaluatedSolutionAveragesNormalizedValue - 1) * 2;
+      }
+
+      // apply weights
+      qualityAveragesNormalizedValue *= qualityAveragesWeight;
+      qualityDeviationsNormalizedValue *= qualityDeviationsWeight;
+      evaluatedSolutionAveragesNormalizedValue *= evaluatedSolutionsWeight;
+
+      double weightSum = qualityAveragesWeight + qualityDeviationsWeight + evaluatedSolutionsWeight;
+      parameterConfigurationTree.Quality = new DoubleValue((qualityAveragesNormalizedValue + qualityDeviationsNormalizedValue + evaluatedSolutionAveragesNormalizedValue) / weightSum);
+
+      return parameterConfigurationTree.Quality.Value;
+    }
+
+    /// <summary>
+    /// Creates a new instance of algorithmType, sets the given problem and parameterizes it with the given configuration
+    /// </summary>
+    public static IAlgorithm CreateParameterizedAlgorithmInstance(ParameterConfigurationTree parameterConfigurationTree, Type algorithmType, IProblem problem, bool randomize = false, IRandom random = null) {
+      var algorithm = (IAlgorithm)Activator.CreateInstance(algorithmType);
+      algorithm.Problem = problem;
+      if (algorithm is EngineAlgorithm) {
+        ((EngineAlgorithm)algorithm).Engine = new SequentialEngine.SequentialEngine();
+      }
+      if (randomize) parameterConfigurationTree.Randomize(random);
+      parameterConfigurationTree.Parameterize(algorithm);
+      return algorithm;
+    }
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/NullValue.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/NullValue.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/NullValue.cs	(revision 7840)
@@ -0,0 +1,40 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  [StorableClass]
+  public class NullValue : ValueTypeValue<int> {
+
+    public NullValue() { }
+    [StorableConstructor]
+    protected NullValue(bool deserializing) : base(deserializing) { }
+    protected NullValue(NullValue original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new NullValue(this, cloner);
+    }
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ParameterCombinationsEnumerator.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ParameterCombinationsEnumerator.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ParameterCombinationsEnumerator.cs	(revision 7840)
@@ -0,0 +1,182 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  public class ParameterCombinationsEnumerator : IEnumerator<IOptimizable> {
+    private IOptimizable node;
+    private List<IEnumerator> enumerators;
+    private EnumeratorCollectionEnumerator<IItem> valueEnumerator;
+    private bool initialized = false;
+
+    public ParameterCombinationsEnumerator(IOptimizable node) {
+      this.node = node;
+      this.enumerators = new List<IEnumerator>();
+    }
+
+    public IOptimizable Current {
+      get { return node; }
+    }
+    object IEnumerator.Current {
+      get {
+        if (!initialized)
+          throw new InvalidOperationException("Enumeration not started. Call MoveNext!");
+        return Current;
+      }
+    }
+
+    public void Dispose() { }
+
+    public bool MoveNext() {
+      if (!initialized) {
+        foreach (var enu in enumerators) {
+          enu.Reset();
+          if (!enu.MoveNext())
+            return false;
+        }
+        initialized = true;
+      } else {
+        int i = 0;
+        bool ok = false;
+        while (!ok && i < enumerators.Count) {
+          if (enumerators[i].MoveNext()) {
+            ok = true;
+          } else {
+            i++;
+          }
+        }
+
+        if (ok) {
+          for (int k = i - 1; k >= 0; k--) {
+            enumerators[k].Reset();
+            enumerators[k].MoveNext();
+          }
+        } else {
+          return false;
+        }
+      }
+
+      var pc = node as IParameterConfiguration;
+      if (pc != null && valueEnumerator != null) {
+        pc.ActualValue = ((IValueConfiguration)valueEnumerator.Current).ActualValue;
+        pc.UpdateActualValueIndexToItem((IValueConfiguration)valueEnumerator.Current);
+      }
+      var vc = node as IValueConfiguration;
+      if (vc != null && valueEnumerator != null) {
+        vc.ActualValue.Value = (IItem)valueEnumerator.Current;
+      }
+      return true;
+    }
+
+    public void Reset() {
+      enumerators.Clear();
+      valueEnumerator = null;
+      initialized = false;
+
+      var pc = node as IParameterConfiguration;
+      if (pc != null) {
+        valueEnumerator = new EnumeratorCollectionEnumerator<IItem>();
+
+        foreach (var valueConfiguration in pc.ValueConfigurations.CheckedItems) {
+          if (valueConfiguration.Value.Optimize) {
+            var enumerator = new ParameterCombinationsEnumerator(valueConfiguration.Value);
+            enumerator.Reset();
+            valueEnumerator.AddEnumerator(enumerator);
+          } else {
+            valueEnumerator.AddEnumerator(new List<IItem> { valueConfiguration.Value }.GetEnumerator());
+          }
+        }
+        valueEnumerator.Reset();
+        enumerators.Add(valueEnumerator);
+      }
+
+      var rangeVc = node as RangeValueConfiguration;
+      if (rangeVc != null) {
+        valueEnumerator = new EnumeratorCollectionEnumerator<IItem>();
+        valueEnumerator.AddEnumerator(rangeVc.RangeConstraint.GetCombinations().GetEnumerator());
+        valueEnumerator.Reset();
+        enumerators.Add(valueEnumerator);
+      }
+
+      var parameterizedVc = node as ParameterizedValueConfiguration;
+      if (parameterizedVc != null) {
+        foreach (var parameterConfiguration in parameterizedVc.ParameterConfigurations) {
+          if (parameterConfiguration.Optimize) {
+            var enumerator = new ParameterCombinationsEnumerator(parameterConfiguration);
+            enumerator.Reset();
+            enumerators.Add(enumerator);
+          }
+        }
+        enumerators.Reverse(); // this makes the list of combinations better readable
+      }
+    }
+  }
+
+  /// <summary>
+  /// Enumerator which can enumerate all elements of a list of enumerators
+  /// </summary>
+  /// <typeparam name="T"></typeparam>
+  public class EnumeratorCollectionEnumerator<T> : IEnumerator<T> {
+    private List<IEnumerator<T>> enumerators = new List<IEnumerator<T>>();
+    private IEnumerator<IEnumerator<T>> currentEnumerator;
+
+    public EnumeratorCollectionEnumerator() { }
+
+    public void AddEnumerator(IEnumerator<T> enumerator) {
+      enumerators.Add(enumerator);
+    }
+
+    public void Dispose() { }
+
+    public T Current {
+      get { return currentEnumerator.Current.Current; }
+    }
+
+    object IEnumerator.Current {
+      get { return this.Current; }
+    }
+
+    public bool MoveNext() {
+      bool ok = currentEnumerator.Current.MoveNext();
+      if (!ok) {
+        ok = currentEnumerator.MoveNext();
+        if (!ok)
+          return false;
+        else
+          return this.MoveNext();
+      }
+      return true;
+    }
+
+    public void Reset() {
+      foreach (var enu in enumerators) {
+        enu.Reset();
+      }
+      currentEnumerator = enumerators.GetEnumerator();
+      currentEnumerator.Reset();
+      currentEnumerator.MoveNext();
+    }
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ParameterConfigurationTree.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ParameterConfigurationTree.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ParameterConfigurationTree.cs	(revision 7840)
@@ -0,0 +1,356 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  [StorableClass]
+  public class ParameterConfigurationTree : ParameterizedValueConfiguration, IEnumerable {
+
+    [Storable]
+    private DoubleValue quality;
+    public DoubleValue Quality {
+      get { return quality; }
+      set {
+        if (quality != value) {
+          quality = value;
+          OnQualityChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private DoubleArray normalizedQualityAverages;
+    public DoubleArray NormalizedQualityAverages {
+      get { return normalizedQualityAverages; }
+      set {
+        if (normalizedQualityAverages != value) {
+          normalizedQualityAverages = value;
+        }
+      }
+    }
+
+    [Storable]
+    private DoubleArray normalizedQualityDeviations;
+    public DoubleArray NormalizedQualityDeviations {
+      get { return normalizedQualityDeviations; }
+      set {
+        if (normalizedQualityDeviations != value) {
+          normalizedQualityDeviations = value;
+        }
+      }
+    }
+
+    [Storable]
+    private DoubleArray normalizedEvaluatedSolutions;
+    public DoubleArray NormalizedEvaluatedSolutions {
+      get { return normalizedEvaluatedSolutions; }
+      set {
+        if (normalizedEvaluatedSolutions != value) {
+          normalizedEvaluatedSolutions = value;
+        }
+      }
+    }
+
+    [Storable]
+    private DoubleArray bestQualities;
+    public DoubleArray BestQualities {
+      get { return bestQualities; }
+      set {
+        if (bestQualities != value) {
+          bestQualities = value;
+        }
+      }
+    }
+
+    [Storable]
+    private DoubleArray averageQualities;
+    public DoubleArray AverageQualities {
+      get { return averageQualities; }
+      set { averageQualities = value; }
+    }
+
+    [Storable]
+    private DoubleArray worstQualities;
+    public DoubleArray WorstQualities {
+      get { return worstQualities; }
+      set { worstQualities = value; }
+    }
+
+    [Storable]
+    private DoubleArray qualityVariances;
+    public DoubleArray QualityVariances {
+      get { return qualityVariances; }
+      set { qualityVariances = value; }
+    }
+
+    [Storable]
+    private DoubleArray qualityStandardDeviations;
+    public DoubleArray QualityStandardDeviations {
+      get { return qualityStandardDeviations; }
+      set { qualityStandardDeviations = value; }
+    }
+
+    [Storable]
+    private ItemList<TimeSpanValue> averageExecutionTimes;
+    public ItemList<TimeSpanValue> AverageExecutionTimes {
+      get { return averageExecutionTimes; }
+      set { averageExecutionTimes = value; }
+    }
+
+    [Storable]
+    private DoubleArray averageEvaluatedSolutions;
+    public DoubleArray AverageEvaluatedSolutions {
+      get { return averageEvaluatedSolutions; }
+      set { averageEvaluatedSolutions = value; }
+    }
+
+    [Storable]
+    private IntValue repetitions;
+    public IntValue Repetitions {
+      get { return repetitions; }
+      set { repetitions = value; }
+    }
+
+    [Storable]
+    protected RunCollection runs;
+    public RunCollection Runs {
+      get { return runs; }
+      set { runs = value; }
+    }
+
+    [Storable]
+    protected IDictionary<string, IItem> parameters;
+    public IDictionary<string, IItem> Parameters {
+      get { return parameters; }
+      set { parameters = value; }
+    }
+
+    public ParameterizedValueConfiguration AlgorithmConfiguration {
+      get {
+        return this.ParameterConfigurations.ElementAt(0).ValueConfigurations.First() as ParameterizedValueConfiguration;
+      }
+    }
+
+    public ParameterizedValueConfiguration ProblemConfiguration {
+      get {
+        return this.ParameterConfigurations.ElementAt(1).ValueConfigurations.First() as ParameterizedValueConfiguration;
+      }
+    }
+
+    #region constructors and cloning
+    public ParameterConfigurationTree(IAlgorithm algorithm, IProblem problem)
+      : base(null, algorithm.GetType(), false) {
+      this.Optimize = false;
+      this.IsOptimizable = false;
+      this.parameters = new Dictionary<string, IItem>();
+      this.Name = algorithm.ItemName;
+
+      var algproblemitem = new AlgorithmProblemItem();
+      algproblemitem.AlgorithmParameter.Value = algorithm;
+      algproblemitem.ProblemParameter.Value = problem;
+      this.discoverValidValues = false;
+
+      this.parameterConfigurations.Add(new SingleValuedParameterConfiguration("Algorithm", algproblemitem.AlgorithmParameter));
+      this.parameterConfigurations.Add(new SingleValuedParameterConfiguration("Problem", algproblemitem.ProblemParameter));
+
+      // problems can be modified in the list of problem instances, so the parameters which are not Optimize=true, 
+      // must not be modifiable in the parameter configuration tree. otherwise the parameter values would be ambiguous
+      ProblemConfiguration.ValuesReadOnly = true;
+    }
+    public ParameterConfigurationTree() { }
+    [StorableConstructor]
+    protected ParameterConfigurationTree(bool deserializing) : base(deserializing) { }
+    protected ParameterConfigurationTree(ParameterConfigurationTree original, Cloner cloner)
+      : base(original, cloner) {
+      this.quality = cloner.Clone(original.quality);
+      this.normalizedQualityAverages = cloner.Clone(original.normalizedQualityAverages);
+      this.normalizedQualityDeviations = cloner.Clone(original.normalizedQualityDeviations);
+      this.normalizedEvaluatedSolutions = cloner.Clone(original.normalizedEvaluatedSolutions);
+      this.bestQualities = cloner.Clone(original.BestQualities);
+      this.averageQualities = cloner.Clone(original.averageQualities);
+      this.worstQualities = cloner.Clone(original.worstQualities);
+      this.qualityStandardDeviations = cloner.Clone(original.qualityStandardDeviations);
+      this.qualityVariances = cloner.Clone(original.qualityVariances);
+      this.averageExecutionTimes = cloner.Clone(original.averageExecutionTimes);
+      this.averageEvaluatedSolutions = cloner.Clone(original.averageEvaluatedSolutions);
+      this.repetitions = cloner.Clone(original.repetitions);
+      this.runs = cloner.Clone(original.runs);
+      this.parameters = new Dictionary<string, IItem>();
+      foreach (var p in original.parameters) {
+        this.parameters.Add(p.Key, cloner.Clone(p.Value));
+      }
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ParameterConfigurationTree(this, cloner);
+    }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (ProblemConfiguration != null) ProblemConfiguration.ValuesReadOnly = true;
+    }
+    #endregion
+
+    public virtual void CollectResultValues(IDictionary<string, IItem> values) {
+      values.Add("RunsAverageExecutionTimes", AverageExecutionTimes);
+      values.Add("RunsAverageEvaluatedSolutions", AverageEvaluatedSolutions);
+      values.Add("Repetitions", Repetitions);
+      values.Add("RunsBestQualities", BestQualities);
+      values.Add("RunsAverageQualities", AverageQualities);
+      values.Add("RunsWorstQualities", WorstQualities);
+      values.Add("RunsQualityVariances", QualityVariances);
+      values.Add("RunsQualityStandardDeviations", QualityStandardDeviations);
+      values.Add("QualitiesNormalized", NormalizedQualityAverages);
+      values.Add("AverageQualityNormalized", Quality);
+      values.Add("Runs", Runs);
+    }
+
+    public virtual void CollectParameterValues(IDictionary<string, IItem> values) {
+      foreach (var p in parameters) {
+        values.Add(p);
+      }
+    }
+
+    #region Events
+    public event EventHandler QualityChanged;
+    private void OnQualityChanged() {
+      var handler = QualityChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    private void Quality_ValueChanged(object sender, EventArgs e) {
+      OnQualityChanged();
+    }
+    #endregion
+
+    public override void Parameterize(IParameterizedItem item) {
+      this.parameters.Clear();
+      var algorithm = item as IAlgorithm;
+      var problem = algorithm.Problem;
+
+      ProblemConfiguration.Parameterize(problem);
+      AlgorithmConfiguration.Parameterize(algorithm);
+
+      algorithm.CollectParameterValues(this.Parameters);
+    }
+
+    public Experiment GenerateExperiment(IAlgorithm algorithm, bool createBatchRuns, int repetitions) {
+      Experiment experiment = new Experiment();
+      foreach (ParameterizedValueConfiguration combination in this) {
+        IAlgorithm clonedAlg = (IAlgorithm)algorithm.Clone();
+        clonedAlg.Name = combination.ParameterInfoString;
+        combination.Parameterize(clonedAlg);
+        clonedAlg.StoreAlgorithmInEachRun = false;
+        if (createBatchRuns) {
+          BatchRun batchRun = new BatchRun(string.Format("BatchRun: {0}", combination.ParameterInfoString));
+          batchRun.Optimizer = clonedAlg;
+          batchRun.Repetitions = repetitions;
+          experiment.Optimizers.Add(batchRun);
+        } else {
+          experiment.Optimizers.Add(clonedAlg);
+        }
+      }
+      return experiment;
+    }
+
+    public Experiment GenerateExperiment(IAlgorithm algorithm) {
+      return GenerateExperiment(algorithm, false, 0);
+    }
+
+    public IEnumerator GetEnumerator() {
+      IEnumerator enumerator = new ParameterCombinationsEnumerator(this);
+      enumerator.Reset();
+      return enumerator;
+    }
+
+    /// <summary>
+    /// returns the number of possible parameter combinations
+    /// </summary>
+    /// <param name="max">algorithm stops counting when max is reached. zero for infinite counting</param>
+    /// <returns></returns>
+    public long GetCombinationCount(long max) {
+      long cnt = 0;
+      foreach (var c in this) {
+        cnt++;
+        if (max > 0 && cnt >= max) {
+          return cnt;
+        }
+      }
+      return cnt;
+    }
+
+    public IOptimizable GetRandomOptimizable(IRandom random) {
+      List<IOptimizable> allOptimizables = GetAllOptimizables();
+      return allOptimizables[random.Next(allOptimizables.Count)];
+    }
+
+    public override string ToString() {
+      return this.Name;
+    }
+
+    public IRun ToRun(bool clearParameters) {
+      return ToRun(this.ParameterInfoString, clearParameters);
+    }
+
+    public IRun ToRun(string name, bool clearParameters) {
+      IRun run = new Run();
+      run.Name = name;
+      this.CollectResultValues(run.Results);
+      this.CollectParameterValues(run.Parameters);
+      if (clearParameters) MetaOptimizationUtil.ClearParameters(run, this.GetOptimizedParameterNames());
+      return run;
+    }
+
+    public override string ParameterInfoString {
+      get {
+        string algorithmInfo = this.AlgorithmConfiguration.ParameterInfoString;
+        string problemInfo = this.ProblemConfiguration.ParameterInfoString;
+        var sb = new StringBuilder();
+        if (!string.IsNullOrEmpty(algorithmInfo)) {
+          sb.Append("Algorithm (");
+          sb.Append(algorithmInfo);
+          sb.Append(")");
+        }
+        if (!string.IsNullOrEmpty(problemInfo)) {
+          if (sb.Length > 0)
+            sb.Append(", ");
+          sb.Append("Problem( ");
+          sb.Append(problemInfo);
+          sb.Append(")");
+        }
+        return sb.ToString();
+      }
+    }
+
+    public override void CollectOptimizedParameterNames(List<string> parameterNames, string prefix) {
+      AlgorithmConfiguration.CollectOptimizedParameterNames(parameterNames, string.Empty);
+      ProblemConfiguration.CollectOptimizedParameterNames(parameterNames, string.Empty);
+    }
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ParameterConfigurations/ParameterConfiguration.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ParameterConfigurations/ParameterConfiguration.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ParameterConfigurations/ParameterConfiguration.cs	(revision 7840)
@@ -0,0 +1,648 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  [StorableClass]
+  public class ParameterConfiguration : Item, IParameterConfiguration, IStorableContent {
+    public bool IsOptimizable {
+      get { return true; }
+    }
+
+    public string Filename { get; set; }
+
+    [Storable]
+    protected bool optimize;
+    public virtual bool Optimize {
+      get { return optimize; }
+      set {
+        if (optimize != value) {
+          optimize = value;
+          if (optimize) {
+            PopulateValueConfigurations();
+          } else {
+            ClearValueConfigurations();
+          }
+          OnOptimizeChanged();
+          OnToStringChanged();
+        }
+      }
+    }
+
+    [Storable]
+    protected Image itemImage;
+    public override Image ItemImage {
+      get { return itemImage ?? base.ItemImage; }
+    }
+
+    [Storable]
+    protected string parameterName;
+    public string ParameterName {
+      get { return parameterName; }
+      set {
+        if (parameterName != value) {
+          parameterName = value;
+          OnToStringChanged();
+        }
+      }
+    }
+
+    [Storable]
+    protected Type parameterDataType;
+    public Type ParameterDataType {
+      get { return this.parameterDataType; }
+    }
+
+    protected Type[] validTypes;
+    public Type[] ValidTypes {
+      get { return validTypes; }
+      protected set {
+        if (this.validTypes != value) {
+          this.validTypes = value;
+        }
+      }
+    }
+
+    [Storable]
+    protected Type valueDataType;
+    public Type ValueDataType {
+      get { return valueDataType; }
+      protected set { this.valueDataType = value; }
+    }
+
+    [Storable]
+    protected ICheckedValueConfigurationList valueConfigurations;
+    public ICheckedValueConfigurationList ValueConfigurations {
+      get { return this.valueConfigurations; }
+      protected set {
+        if (this.valueConfigurations != value) {
+          if (this.valueConfigurations != null) DeregisterValueConfigurationEvents();
+          this.valueConfigurations = value;
+          KeepActualValueConfigurationIndexConsistent();
+          if (this.valueConfigurations != null) RegisterValueConfigurationEvents();
+        }
+      }
+    }
+
+    [Storable]
+    private int actualValueConfigurationIndex = 0;
+    public int ActualValueConfigurationIndex {
+      get { return actualValueConfigurationIndex; }
+      set { actualValueConfigurationIndex = value; }
+    }
+
+    [Storable]
+    protected ConstrainedValue actualValue;
+    public ConstrainedValue ActualValue {
+      get { return actualValue; }
+      set {
+        if (actualValue != value) {
+          DeregisterActualValueEvents();
+          actualValue = value;
+          RegisterActualValueEvents();
+        }
+      }
+    }
+
+    [Storable]
+    protected bool isNullable;
+    public bool IsNullable {
+      get { return isNullable; }
+      protected set {
+        if (this.isNullable != value) {
+          this.isNullable = value;
+        }
+      }
+    }
+
+    [Storable]
+    protected bool discoverValidValues;
+    public bool DiscoverValidValues {
+      get { return discoverValidValues; }
+      set { discoverValidValues = value; }
+    }
+
+    protected IItemSet<IItem> validValues;
+
+    [Storable]
+    private bool autoPopulateValueConfigurations = true;
+    public bool AutoPopulateValueConfigurations {
+      get { return autoPopulateValueConfigurations; }
+      set { autoPopulateValueConfigurations = value; }
+    }
+
+    [Storable]
+    protected bool valuesReadOnly = false;
+    public virtual bool ValuesReadOnly {
+      get { return valuesReadOnly; }
+      set {
+        if (value != this.valuesReadOnly) {
+          this.valuesReadOnly = value;
+          foreach (var vc in this.valueConfigurations) {
+            vc.ValuesReadOnly = value;
+          }
+        }
+      }
+    }
+
+    #region Constructors and Cloning
+    public ParameterConfiguration(string parameterName, IValueParameter valueParameter, bool discoverValidValues) {
+      this.AutoPopulateValueConfigurations = true;
+      this.ParameterName = parameterName;
+      this.parameterDataType = valueParameter.GetType();
+      this.valueDataType = valueParameter.DataType;
+      this.discoverValidValues = discoverValidValues;
+      this.validValues = discoverValidValues ? GetValidValues(valueParameter) : new ItemSet<IItem> { valueParameter.Value };
+      this.validTypes = GetValidTypes(valueParameter).ToArray();
+      this.IsNullable = valueParameter.ItemName.StartsWith("Optional");
+      this.itemImage = valueParameter.ItemImage;
+      if (IsNullable) {
+        validTypes = new List<Type>(validTypes) { typeof(NullValue) }.ToArray();
+      }
+      this.ValueConfigurations = new CheckedValueConfigurationList(this.validValues ?? CreateValidValues());
+      this.ActualValue = new ConstrainedValue(
+        valueParameter.Value != null ? valueParameter.Value : null, // don't clone here; otherwise settings of a non-optimized ValueParameter will not be synchronized with the ConstrainedValue
+        valueParameter.DataType,
+        this.validValues != null ? new ItemSet<IItem>(this.validValues) : CreateValidValues(),
+        this.IsNullable);
+      if (Optimize) {
+        PopulateValueConfigurations();
+      }
+    }
+    public ParameterConfiguration(string parameterName, Type type, IItem actualValue, IEnumerable<IValueConfiguration> valueConfigurations) {
+      this.AutoPopulateValueConfigurations = false;
+      this.ParameterName = parameterName;
+      this.parameterDataType = type;
+      this.valueDataType = type;
+      this.discoverValidValues = false;
+      this.validValues = null; // maybe use values from valueConfigurations
+      this.validTypes = new Type[] { type };
+      this.IsNullable = false;
+      this.itemImage = valueConfigurations.Count() > 0 ? valueConfigurations.FirstOrDefault().ItemImage : null;
+      this.ValueConfigurations = new CheckedValueConfigurationList(valueConfigurations);
+      this.ActualValue = new ConstrainedValue(actualValue, type, CreateValidValues(), this.IsNullable);
+    }
+    public ParameterConfiguration(string parameterName, Type type, IItem actualValue) {
+      this.AutoPopulateValueConfigurations = true;
+      this.ParameterName = parameterName;
+      this.parameterDataType = type;
+      this.valueDataType = type;
+      this.discoverValidValues = false;
+      this.validValues = null;
+      this.validTypes = new Type[] { type };
+      this.IsNullable = false;
+      this.itemImage = actualValue.ItemImage;
+      this.ValueConfigurations = new CheckedValueConfigurationList();
+      this.ActualValue = new ConstrainedValue(actualValue, type, CreateValidValues(), this.IsNullable);
+      if (Optimize) {
+        PopulateValueConfigurations();
+      }
+    }
+    public ParameterConfiguration() { }
+    [StorableConstructor]
+    protected ParameterConfiguration(bool deserializing) { }
+
+    protected ParameterConfiguration(ParameterConfiguration original, Cloner cloner)
+      : base(original, cloner) {
+      this.parameterName = original.ParameterName;
+      this.parameterDataType = original.parameterDataType;
+      this.valueDataType = original.ValueDataType;
+      this.validValues = cloner.Clone(original.validValues);
+      this.validTypes = original.validTypes.ToArray();
+      this.valueConfigurations = cloner.Clone(original.ValueConfigurations);
+      if (this.valueConfigurations != null) RegisterValueConfigurationEvents();
+      this.actualValue = cloner.Clone(original.actualValue);
+      if (this.actualValue != null) RegisterActualValueEvents();
+      this.optimize = original.optimize;
+      this.actualValueConfigurationIndex = original.actualValueConfigurationIndex;
+      this.isNullable = original.isNullable;
+      this.itemImage = original.itemImage;
+      this.discoverValidValues = original.discoverValidValues;
+      this.AutoPopulateValueConfigurations = original.AutoPopulateValueConfigurations;
+      this.valuesReadOnly = original.valuesReadOnly;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ParameterConfiguration(this, cloner);
+    }
+    [StorableHook(HookType.AfterDeserialization)]
+    protected virtual void AfterDeserialization() {
+      this.validTypes = GetValidTypes(parameterDataType).ToArray();
+
+      if (IsNullable) {
+        validTypes = new List<Type>(validTypes) { typeof(NullValue) }.ToArray();
+      }
+      this.validValues = CreateValidValues();
+
+      if (this.valueConfigurations != null) RegisterValueConfigurationEvents();
+      if (this.actualValue != null) RegisterActualValueEvents();
+    }
+    #endregion
+
+    private void RegisterValueConfigurationEvents() {
+      this.ValueConfigurations.CheckedItemsChanged += new CollectionItemsChangedEventHandler<IndexedItem<IValueConfiguration>>(ValueConfigurations_CheckedItemsChanged);
+      this.ValueConfigurations.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<IValueConfiguration>>(ValueConfigurations_ItemsAdded);
+      this.ValueConfigurations.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<IValueConfiguration>>(ValueConfigurations_ItemsRemoved);
+    }
+
+    private void DeregisterValueConfigurationEvents() {
+      this.ValueConfigurations.CheckedItemsChanged -= new CollectionItemsChangedEventHandler<IndexedItem<IValueConfiguration>>(ValueConfigurations_CheckedItemsChanged);
+      this.ValueConfigurations.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<IValueConfiguration>>(ValueConfigurations_ItemsAdded);
+      this.ValueConfigurations.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<IValueConfiguration>>(ValueConfigurations_ItemsRemoved);
+    }
+
+    private void RegisterActualValueEvents() {
+      if (this.ActualValue != null) this.ActualValue.ToStringChanged += new EventHandler(ActualValue_ToStringChanged);
+    }
+    private void DeregisterActualValueEvents() {
+      if (this.ActualValue != null) this.ActualValue.ToStringChanged -= new EventHandler(ActualValue_ToStringChanged);
+    }
+
+    protected virtual void PopulateValueConfigurations() {
+      if (!this.AutoPopulateValueConfigurations)
+        return;
+
+      foreach (Type t in this.validTypes) {
+        if (t == typeof(NullValue)) {
+          this.ValueConfigurations.Add(new NullValueConfiguration());
+        } else {
+          IItem val;
+          if (ActualValue.Value != null && ActualValue.Value.GetType() == t) {
+            val = (IItem)ActualValue.Value.Clone(); // use existing value for that type (if available)
+          } else {
+            val = CreateItem(t);
+          }
+          if (val != null) { // val can be null when ValidValues does not contain the type (this can happen when discoverValidValues=false)
+            IValueConfiguration valueConfiguration;
+            if (val is IParameterizedItem) {
+              valueConfiguration = new ParameterizedValueConfiguration(val, val.GetType(), true);
+            } else {
+              if (val is ISymbolicExpressionGrammar) {
+                valueConfiguration = new SymbolicExpressionGrammarValueConfiguration((ISymbolicExpressionGrammar)val);
+              } else {
+                valueConfiguration = new RangeValueConfiguration(val, val.GetType());
+              }
+            }
+            this.ValueConfigurations.Add(valueConfiguration, true);
+          }
+        }
+      }
+    }
+
+    protected virtual void ClearValueConfigurations() {
+      if (!this.AutoPopulateValueConfigurations)
+        return;
+
+      this.ValueConfigurations.Clear();
+    }
+
+    private static IEnumerable<Type> GetValidTypes(IValueParameter parameter) {
+      // in case of IOperator return empty list, otherwise hundreds of types would be returned. this mostly occurs for Successor which will never be optimized
+      if (parameter.DataType == typeof(IOperator))
+        return new List<Type>();
+
+      // return only one type for ValueTypeValues<> (Int, Double, Percent, Bool). Otherwise 2 types would be returned for DoubleValue (PercentValue which is derived)
+      if (IsSubclassOfRawGeneric(typeof(ValueTypeValue<>), parameter.DataType))
+        return new List<Type> { parameter.DataType };
+
+      if (IsSubclassOfRawGeneric(typeof(OptionalConstrainedValueParameter<>), parameter.GetType())) {
+        // use existing validvalues if known
+        var parameterValidValues = (IEnumerable)parameter.GetType().GetProperty("ValidValues").GetValue(parameter, new object[] { });
+        return parameterValidValues.Cast<object>().Select(x => x.GetType());
+      } else {
+        // otherwise use all assignable types
+        return ApplicationManager.Manager.GetTypes(parameter.DataType, true);
+      }
+    }
+
+    private static IEnumerable<Type> GetValidTypes(Type parameter) {
+      // in case of IOperator return empty list, otherwise hundreds of types would be returned. this mostly occurs for Successor which will never be optimized
+      if (parameter == typeof(IOperator))
+        return new List<Type>();
+
+      // return only one type for ValueTypeValues<> (Int, Double, Percent, Bool). Otherwise 2 types would be returned for DoubleValue (PercentValue which is derived)
+      if (IsSubclassOfRawGeneric(typeof(ValueTypeValue<>), parameter))
+        return new List<Type> { parameter };
+
+      //TODO: not sure if this if makes sense; maybe only leave else branch here
+      if (IsSubclassOfRawGeneric(typeof(OptionalConstrainedValueParameter<>), parameter.GetType())) {
+        // use existing validvalues if known
+        var parameterValidValues = (IEnumerable)parameter.GetType().GetProperty("ValidValues").GetValue(parameter, new object[] { });
+        return parameterValidValues.Cast<object>().Select(x => x.GetType());
+      } else {
+        // otherwise use all assignable types
+        return ApplicationManager.Manager.GetTypes(parameter, true);
+      }
+    }
+
+    private IItemSet<IItem> GetValidValues(IValueParameter parameter) {
+      if (IsSubclassOfRawGeneric(typeof(OptionalConstrainedValueParameter<>), parameter.GetType())) {
+        var x = (IEnumerable)parameter.GetType().GetProperty("ValidValues").GetValue(parameter, new object[] { });
+        return new ItemSet<IItem>(x.Cast<IItem>().Select(y => (IItem)y.Clone())); // cloning actually saves memory, because references to event-subscribers are removed
+      } else {
+        return null;
+      }
+    }
+
+    public IItem CreateItem(Type type) {
+      // no valid values; just instantiate
+      try {
+        if (validValues == null)
+          return (IItem)Activator.CreateInstance(type);
+      }
+      catch (MissingMemberException) {
+        return null; // can happen, when ApplicationManager.Manager.GetTypes(type, OnlyInstantiable=true) returns objects which have no default constructor
+      }
+
+      if (type == typeof(NullValue))
+        return new NullValue();
+
+      // copy value from ValidValues; this ensures that previously set ActualNames for a type are kept
+      IItem value = this.validValues.Where(v => v.GetType() == type).SingleOrDefault();
+      if (value != null)
+        return value;
+
+      return null;
+    }
+
+    private IItemSet<IItem> CreateValidValues() {
+      var validValues = new ItemSet<IItem>();
+      foreach (Type t in this.validTypes) {
+        try {
+          var val = CreateItem(t);
+          if (val != null) validValues.Add(val);
+        }
+        catch (MissingMethodException) { /* Constructor is missing, don't use those types */ }
+      }
+      return validValues;
+    }
+
+    public static bool IsSubclassOfRawGeneric(Type generic, Type toCheck) {
+      while (toCheck != typeof(object)) {
+        var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck;
+        if (generic == cur) {
+          return true;
+        }
+        toCheck = toCheck.BaseType; // baseType is null when toCheck is an Interface
+        if (toCheck == null)
+          return false;
+      }
+      return false;
+    }
+
+    private void ValueConfigurations_CheckedItemsChanged(object sender, Collections.CollectionItemsChangedEventArgs<IndexedItem<IValueConfiguration>> e) {
+      OnToStringChanged();
+      KeepActualValueConfigurationIndexConsistent();
+    }
+
+    private void ValueConfigurations_ItemsRemoved(object sender, Collections.CollectionItemsChangedEventArgs<IndexedItem<IValueConfiguration>> e) {
+      OnToStringChanged();
+      KeepActualValueConfigurationIndexConsistent();
+    }
+    private void ValueConfigurations_ItemsAdded(object sender, Collections.CollectionItemsChangedEventArgs<IndexedItem<IValueConfiguration>> e) {
+      OnToStringChanged();
+      KeepActualValueConfigurationIndexConsistent();
+    }
+
+    #region INamedItem Properties
+    public virtual string Name {
+      get { return ParameterName; }
+      set { throw new NotSupportedException(); }
+    }
+    public virtual string Description {
+      get { return base.ItemDescription; }
+      set { throw new NotSupportedException(); }
+    }
+    public virtual bool CanChangeDescription {
+      get { return false; }
+    }
+    public virtual bool CanChangeName {
+      get { return false; }
+    }
+    public override string ItemDescription {
+      get { return base.ItemDescription; }
+    }
+    public override string ItemName {
+      get { return base.ItemName; }
+    }
+    #endregion
+
+    #region Events
+    protected virtual void ActualValue_ToStringChanged(object sender, EventArgs e) {
+      OnToStringChanged();
+    }
+    #endregion
+
+    #region Event Handler
+    public virtual event EventHandler NameChanged;
+    protected virtual void OnNameChanged(object sender, EventArgs e) {
+      var handler = NameChanged;
+      if (handler != null) handler(sender, e);
+    }
+
+    public virtual event EventHandler<CancelEventArgs<string>> NameChanging;
+    protected virtual void OnNameChanging(object sender, CancelEventArgs<string> e) {
+      var handler = NameChanging;
+      if (handler != null) handler(sender, e);
+    }
+
+    public virtual event EventHandler DescriptionChanged;
+    protected virtual void OnDescriptionChanged(object sender, EventArgs e) {
+      var handler = DescriptionChanged;
+      if (handler != null) handler(sender, e);
+    }
+
+    public virtual event EventHandler IsOptimizableChanged;
+    private void OnIsOptimizableChanged() {
+      var handler = IsOptimizableChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public virtual event EventHandler OptimizeChanged;
+    protected virtual void OnOptimizeChanged() {
+      var handler = OptimizeChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    #endregion
+
+    public override string ToString() {
+      if (Optimize) {
+        return string.Format("{0}: (Optimize: {1})", ParameterName, ValueConfigurations.CheckedItems.Count());
+      } else {
+        return string.Format("{0}: {1}", ParameterName, ActualValue.Value);
+      }
+    }
+
+    public virtual string ParameterInfoString {
+      get {
+        StringBuilder sb = new StringBuilder();
+        if (this.Optimize) {
+          var vc = this.ValueConfigurations[actualValueConfigurationIndex];
+          if (vc.ActualValue == null || vc.ActualValue.Value == null) {
+            sb.Append(string.Format("{0}: null", parameterName));
+          } else if (IsSubclassOfRawGeneric(typeof(ValueTypeValue<>), vc.ActualValue.Value.GetType())) {
+            // for int, double, bool use the value directly
+            sb.Append(string.Format("{0}: {1}", parameterName, this.ActualValue.Value.ToString()));
+          } else {
+            // for other types use NumberedName (this also uses the Number-Property for otherwise ambiguous ValueConfigurations)
+            sb.Append(string.Format("{0}: {1}", parameterName, vc.NumberedName));
+          }
+
+          if (this.ValueConfigurations[actualValueConfigurationIndex] is ParameterizedValueConfiguration) {
+            string subParams = this.ValueConfigurations[actualValueConfigurationIndex].ParameterInfoString;
+            if (!string.IsNullOrEmpty(subParams)) {
+              sb.Append(" (");
+              sb.Append(subParams);
+              sb.Append(")");
+            }
+          }
+        }
+        return sb.ToString();
+      }
+    }
+
+    public static IParameterConfiguration Create(IParameterizedNamedItem parent, IParameter parameter, bool discoverValidValues) {
+      if (parameter is IValueParameter) {
+        IValueParameter valueParameter = parameter as IValueParameter;
+        return new ParameterConfiguration(parameter.Name, valueParameter, discoverValidValues);
+      }
+      return null;
+    }
+
+    public void Parameterize(IValueParameter parameter) {
+      if (!Optimize && ValuesReadOnly)
+        return;
+
+      if (Optimize) {
+        if (this.ActualValue.Value is IParameterizedItem) {
+          ((ParameterizedValueConfiguration)this.ValueConfigurations[actualValueConfigurationIndex]).Parameterize((IParameterizedItem)this.ActualValue.Value);
+        }
+        if (this.ActualValue.Value is ISymbolicExpressionGrammar) {
+          ((SymbolicExpressionGrammarValueConfiguration)this.ValueConfigurations[actualValueConfigurationIndex]).Parameterize((ISymbolicExpressionGrammar)this.ActualValue.Value);
+        }
+      }
+      var clonedValue = this.ActualValue.Value != null ? (IItem)this.ActualValue.Value.Clone() : null;
+      if (clonedValue != null) AdaptValidValues(parameter, clonedValue);
+      parameter.Value = clonedValue;
+    }
+
+    /// <summary>
+    /// Adds value to the ValidValues of the parameter if they don't contain the value
+    /// </summary>
+    private void AdaptValidValues(IValueParameter parameter, IItem value) {
+      // this requires some tricky reflection, because the type is unknown at runtime so parameter.ValidValues cannot be casted to Collection<?>
+      if (IsSubclassOfRawGeneric(typeof(OptionalConstrainedValueParameter<>), parameter.GetType())) {
+        var validValues = parameter.GetType().GetProperty("ValidValues").GetValue(parameter, new object[] { });
+        Type validValuesType = validValues.GetType();
+
+        var containsMethod = validValuesType.GetMethod("Contains");
+        if (!(bool)containsMethod.Invoke(validValues, new object[] { value })) {
+          var addMethod = validValuesType.GetMethod("Add");
+          addMethod.Invoke(validValues, new object[] { value });
+        }
+      }
+    }
+
+    public void Randomize(IRandom random) {
+      if (Optimize) {
+        foreach (var vc in this.ValueConfigurations) {
+          if (this.ValueConfigurations.ItemChecked(vc)) {
+            if (vc.Optimize) vc.Randomize(random);
+          }
+        }
+        do {
+          actualValueConfigurationIndex = random.Next(ValueConfigurations.Count());
+        } while (!this.ValueConfigurations.ItemChecked(this.ValueConfigurations[actualValueConfigurationIndex]));
+        this.ActualValue = this.ValueConfigurations[actualValueConfigurationIndex].ActualValue;
+      }
+    }
+
+    public void UpdateActualValueIndexToItem(IValueConfiguration vc) {
+      for (int i = 0; i < this.ValueConfigurations.Count(); i++) {
+        if (this.ValueConfigurations.ElementAt(i) == vc) {
+          this.actualValueConfigurationIndex = i;
+          return;
+        }
+      }
+    }
+
+    public List<IOptimizable> GetAllOptimizables() {
+      var list = new List<IOptimizable>();
+      foreach (var vc in ValueConfigurations) {
+        if (vc.Optimize) {
+          list.Add(vc);
+          list.AddRange(vc.GetAllOptimizables());
+        }
+      }
+      return list;
+    }
+
+    public void CollectOptimizedParameterNames(List<string> parameterNames, string prefix) {
+      foreach (var vc in ValueConfigurations) {
+        if (vc.Optimize) {
+          vc.CollectOptimizedParameterNames(parameterNames, prefix);
+        }
+      }
+    }
+
+    public double CalculateSimilarity(IOptimizable optimizable) {
+      var other = (IParameterConfiguration)optimizable;
+      if (this.ActualValueConfigurationIndex == other.ActualValueConfigurationIndex) {
+        return this.ValueConfigurations[this.ActualValueConfigurationIndex].CalculateSimilarity(other.ValueConfigurations[other.ActualValueConfigurationIndex]);
+      } else {
+        return 0.0;
+      }
+    }
+
+    /// <summary>
+    /// Ensures that the ActualValueConfigurationIndex has a valid value
+    /// Only indices of items which are checked are allowed
+    /// </summary>
+    private void KeepActualValueConfigurationIndexConsistent() {
+      if (this.valueConfigurations != null && this.valueConfigurations.CheckedItems.Count() > 0) {
+        if (this.valueConfigurations.Count <= this.actualValueConfigurationIndex &&
+           this.valueConfigurations.CheckedItems.Count(x => x.Index == this.actualValueConfigurationIndex) == 1) {
+          // everything is ok; do nothing
+        } else {
+          // current index is invalid, set new one
+          this.ActualValueConfigurationIndex = this.valueConfigurations.CheckedItems.First().Index;
+        }
+      } else {
+        // no checked valueConfiguration is available; cannot be used
+        this.ActualValueConfigurationIndex = -1;
+      }
+    }
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ParameterConfigurations/SingleValuedParameterConfiguration.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ParameterConfigurations/SingleValuedParameterConfiguration.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ParameterConfigurations/SingleValuedParameterConfiguration.cs	(revision 7840)
@@ -0,0 +1,103 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  [StorableClass]
+  public class SingleValuedParameterConfiguration : ParameterConfiguration {
+
+    #region Constructors and Cloning
+    [StorableConstructor]
+    protected SingleValuedParameterConfiguration(bool deserializing) : base(deserializing) { }
+    public SingleValuedParameterConfiguration(string parameterName, IValueParameter valueParameter)
+      : base(parameterName, valueParameter, false) {
+      this.Optimize = true;
+      base.PopulateValueConfigurations();
+      this.ValueConfigurations.Single().Optimize = true;
+    }
+    public SingleValuedParameterConfiguration(string parameterName, IValueConfiguration valueConfiguration) {
+      this.ParameterName = parameterName;
+      this.parameterDataType = valueConfiguration.ActualValue.ValueDataType;
+      this.valueDataType = valueConfiguration.ActualValue.ValueDataType;
+      this.discoverValidValues = false;
+      this.validValues = new ItemSet<IItem> { valueConfiguration.ActualValue.Value };
+      this.validTypes = new Type[] { valueConfiguration.ActualValue.ValueDataType };
+      this.isNullable = false;
+      this.itemImage = valueConfiguration.ItemImage;
+      this.ValueConfigurations = new CheckedValueConfigurationList { valueConfiguration };
+      this.ValueConfigurations.Single().Optimize = true;
+      valueConfiguration.ToStringChanged += new EventHandler(valueConfiguration_ToStringChanged);
+      this.ActualValue = new ConstrainedValue(
+        valueConfiguration.ActualValue.Value,
+        valueConfiguration.ActualValue.ValueDataType,
+        this.validValues,
+        this.IsNullable);
+    }
+    public SingleValuedParameterConfiguration() { }
+    protected SingleValuedParameterConfiguration(SingleValuedParameterConfiguration original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SingleValuedParameterConfiguration(this, cloner);
+    }
+    #endregion
+
+    protected override void PopulateValueConfigurations() {
+      // don't change valueconfigurations, since it only contains the one element specified in constructor
+    }
+
+    protected override void ClearValueConfigurations() {
+      // do nothing
+    }
+
+    public override string ToString() {
+      if (this.valueConfigurations.Single() is SymbolValueConfiguration) {
+        var syVc = (SymbolValueConfiguration)this.valueConfigurations.Single();
+        if (this.Optimize) {
+          return syVc.ToString() + " (Optimize)";
+        } else {
+          return ActualValue.ToString();
+        }
+      } else {
+        return base.ToString();
+      }
+    }
+
+    protected virtual void valueConfiguration_ToStringChanged(object sender, EventArgs e) {
+      OnToStringChanged();
+    }
+
+    public override string ParameterInfoString {
+      get {
+        if (this.Optimize) {
+          return string.Format("{0} ({1})", this.Name, this.ValueConfigurations.Single().ParameterInfoString);
+        } else {
+          return string.Empty;
+        }
+      }
+    }
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/Plugin.cs.frame
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/Plugin.cs.frame	(revision 7839)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/Plugin.cs.frame	(revision 7840)
@@ -34,8 +34,11 @@
   [PluginDependency("HeuristicLab.Core", "3.3")]
   [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Encodings.SymbolicExpressionTreeEncoding", "3.4")]
   [PluginDependency("HeuristicLab.Operators", "3.3")]
   [PluginDependency("HeuristicLab.Optimization", "3.3")]
   [PluginDependency("HeuristicLab.Parameters", "3.3")]
   [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic", "3.4")]
+  [PluginDependency("HeuristicLab.SequentialEngine", "3.3")]
   public class HeuristicLabEncodingsParameterConfigurationTreeEncodingPlugin : PluginBase {
   }
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/RangeConstraints/ConstrainedValue.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/RangeConstraints/ConstrainedValue.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/RangeConstraints/ConstrainedValue.cs	(revision 7840)
@@ -0,0 +1,129 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  [StorableClass]
+  public class ConstrainedValue : Item {
+    [Storable]
+    protected Type valueDataType;
+    public Type ValueDataType {
+      get { return this.valueDataType; }
+      protected set { this.valueDataType = value; }
+    }
+
+    [Storable]
+    protected IItem value;
+    public IItem Value {
+      get { return value; }
+      set {
+        if (this.value != value) {
+          if (this.value != null) DeregisterEvents();
+          this.value = value;
+          if (this.value != null) RegisterEvents();
+          OnToStringChanged();
+        }
+      }
+    }
+
+    [Storable]
+    protected IItemSet<IItem> validValues;
+    public IItemSet<IItem> ValidValues {
+      get { return validValues; }
+      protected set {
+        if (this.validValues != value) {
+          this.validValues = value;
+        }
+      }
+    }
+
+    [Storable]
+    protected bool isNullable;
+    public bool IsNullable {
+      get { return isNullable; }
+      protected set {
+        if (this.isNullable != value) {
+          this.isNullable = value;
+        }
+      }
+    }
+
+    private void RegisterEvents() {
+      this.value.ToStringChanged += new EventHandler(value_ToStringChanged);
+      if (this.value is Symbol) {
+        ((Symbol)this.value).Changed += new EventHandler(ConstrainedValue_Changed);
+      }
+    }
+
+    private void DeregisterEvents() {
+      this.value.ToStringChanged -= new EventHandler(value_ToStringChanged);
+      if (this.value is Symbol) {
+        ((Symbol)this.value).Changed -= new EventHandler(ConstrainedValue_Changed);
+      }
+    }
+
+    #region constructors and cloning
+    public ConstrainedValue() { }
+    [StorableConstructor]
+    protected ConstrainedValue(bool deserializing) : base(deserializing) { }
+    public ConstrainedValue(IItem value, Type valueDataType, IItemSet<IItem> validValues, bool isNullable) {
+      this.Value = value;
+      this.ValueDataType = valueDataType;
+      this.ValidValues = validValues;
+      this.isNullable = isNullable;
+    }
+    protected ConstrainedValue(ConstrainedValue original, Cloner cloner)
+      : base(original, cloner) {
+      this.valueDataType = original.valueDataType;
+      this.Value = cloner.Clone(original.value);
+      if (original.ValidValues != null) this.ValidValues = cloner.Clone(original.ValidValues);
+      this.isNullable = original.isNullable;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ConstrainedValue(this, cloner);
+    }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (this.value != null) RegisterEvents();
+    }
+    #endregion
+
+    private void value_ToStringChanged(object sender, EventArgs e) {
+      OnToStringChanged();
+    }
+
+    private void ConstrainedValue_Changed(object sender, EventArgs e) {
+      OnToStringChanged();
+    }
+
+    public override string ToString() {
+      if (this.value is Symbol) {
+        return string.Format("{0}: {1}", this.value, ((Symbol)this.value).InitialFrequency);
+      }
+      return value != null ? value.ToString() : base.ToString();
+    }
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/RangeConstraints/DoubleValueRange.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/RangeConstraints/DoubleValueRange.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/RangeConstraints/DoubleValueRange.cs	(revision 7840)
@@ -0,0 +1,85 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  [StorableClass]
+  public class DoubleValueRange : Range<DoubleValue> {
+
+    public override DoubleValue LowerBound {
+      get {
+        return base.LowerBound;
+      }
+      set {
+        base.LowerBound = value;
+      }
+    }
+
+    public DoubleValueRange(DoubleValue lowerBound, DoubleValue upperBound, DoubleValue stepSize) : base(lowerBound, upperBound, stepSize) { }
+    public DoubleValueRange() { }
+    [StorableConstructor]
+    protected DoubleValueRange(bool deserializing) : base(deserializing) { }
+    protected DoubleValueRange(DoubleValueRange original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DoubleValueRange(this, cloner);
+    }
+
+    protected override DoubleValue GetRandomSample(IRandom random) {
+      double val;
+      do {
+        val = Math.Round((random.NextDouble() * (UpperBound.Value - LowerBound.Value) + LowerBound.Value) / StepSize.Value, 0) * StepSize.Value;
+      } while (!IsInRange(val));
+      return new DoubleValue(val);
+    }
+
+    public double ApplyStepSize(double value) {
+      return (Math.Round(value / this.StepSize.Value, 0)) * this.StepSize.Value;
+    }
+
+    public bool IsInRange(double value) {
+      return value <= this.UpperBound.Value && value >= this.LowerBound.Value;
+    }
+
+    public override IEnumerable<DoubleValue> GetCombinations() {
+      var solutions = new List<DoubleValue>();
+      double value = LowerBound.Value;
+
+      while (value <= UpperBound.Value) {
+        solutions.Add(new DoubleValue(value));
+        value += StepSize.Value;
+        value = ApplyStepSize(value);
+      }
+      return solutions;
+    }
+
+    protected override double CalculateSimilarityValue(DoubleValue a, DoubleValue b) {
+      double range = UpperBound.Value - LowerBound.Value;
+      double diff = Math.Abs(a.Value - b.Value);
+      return Math.Max(0, (range - (diff * 2)) / range);
+    }
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/RangeConstraints/IntValueRange.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/RangeConstraints/IntValueRange.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/RangeConstraints/IntValueRange.cs	(revision 7840)
@@ -0,0 +1,75 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  [StorableClass]
+  public class IntValueRange : Range<IntValue> {
+
+    public IntValueRange(IntValue lowerBound, IntValue upperBound, IntValue stepSize) : base(lowerBound, upperBound, stepSize) { }
+    public IntValueRange() { }
+    [StorableConstructor]
+    protected IntValueRange(bool deserializing) : base(deserializing) { }
+    protected IntValueRange(IntValueRange original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new IntValueRange(this, cloner);
+    }
+
+    protected override IntValue GetRandomSample(IRandom random) {
+      int val;
+      do {
+        val = random.Next(LowerBound.Value / StepSize.Value, UpperBound.Value / StepSize.Value + 1) * StepSize.Value;
+      } while (!IsInRange(val));
+      return new IntValue(val);
+    }
+
+    public int ApplyStepSize(int value) {
+      return ((int)Math.Round(value / (double)this.StepSize.Value, 0)) * this.StepSize.Value;
+    }
+
+    public bool IsInRange(int value) {
+      return value <= this.UpperBound.Value && value >= this.LowerBound.Value;
+    }
+
+    public override IEnumerable<IntValue> GetCombinations() {
+      var solutions = new List<IntValue>();
+      int value = this.LowerBound.Value;
+
+      while (value <= this.UpperBound.Value) {
+        solutions.Add(new IntValue(value));
+        value += this.StepSize.Value;
+      }
+      return solutions;
+    }
+
+    protected override double CalculateSimilarityValue(IntValue a, IntValue b) {
+      double range = UpperBound.Value - LowerBound.Value;
+      double diff = Math.Abs(a.Value - b.Value);
+      return Math.Max(0, (range - (diff * 2)) / range);
+    }
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/RangeConstraints/PercentValueRange.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/RangeConstraints/PercentValueRange.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/RangeConstraints/PercentValueRange.cs	(revision 7840)
@@ -0,0 +1,80 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  [StorableClass]
+  public class PercentValueRange : Range<PercentValue> {
+
+    public PercentValueRange(PercentValue lowerBound, PercentValue upperBound, PercentValue stepSize) : base(lowerBound, upperBound, stepSize) { }
+    public PercentValueRange() { }
+    [StorableConstructor]
+    protected PercentValueRange(bool deserializing) : base(deserializing) { }
+    protected PercentValueRange(PercentValueRange original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PercentValueRange(this, cloner);
+    }
+
+    protected override PercentValue GetRandomSample(IRandom random) {
+      double val;
+      do {
+        val = Math.Round((random.NextDouble() * (UpperBound.Value - LowerBound.Value) + LowerBound.Value) / StepSize.Value, 0) * StepSize.Value;
+      } while (!IsInRange(val));
+      return new PercentValue(val);
+    }
+
+    public DoubleValueRange AsDoubleValueRange() {
+      return new DoubleValueRange(LowerBound, UpperBound, StepSize);
+    }
+
+    public double ApplyStepSize(double value) {
+      return ((int)Math.Round(value / this.StepSize.Value, 0)) * this.StepSize.Value;
+    }
+
+    public bool IsInRange(double value) {
+      return value <= this.UpperBound.Value && value >= this.LowerBound.Value;
+    }
+
+    public override IEnumerable<PercentValue> GetCombinations() {
+      var solutions = new List<PercentValue>();
+      double value = LowerBound.Value;
+
+      while (value <= UpperBound.Value) {
+        solutions.Add(new PercentValue(value));
+        value += StepSize.Value;
+        value = ApplyStepSize(value);
+      }
+      return solutions;
+    }
+
+    protected override double CalculateSimilarityValue(PercentValue a, PercentValue b) {
+      double range = UpperBound.Value - LowerBound.Value;
+      double diff = Math.Abs(a.Value - b.Value);
+      return Math.Max(0, (range - (diff * 2)) / range);
+    }
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/RangeConstraints/Range.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/RangeConstraints/Range.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/RangeConstraints/Range.cs	(revision 7840)
@@ -0,0 +1,248 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  [StorableClass]
+  public abstract class Range<T> : Item, IRange<T> where T : class, IItem, IStringConvertibleValue, IDeepCloneable {
+    [Storable]
+    private T lowerBound;
+    public virtual T LowerBound {
+      get { return lowerBound; }
+      set {
+        if (lowerBound != value) {
+          if (lowerBound != null) {
+            lowerBound.ValueChanged -= new EventHandler(lowerBound_ToStringChanged);
+          }
+          lowerBound = value;
+          if (lowerBound != null) {
+            lowerBound.ValueChanged += new EventHandler(lowerBound_ToStringChanged);
+          }
+          OnLowerBoundChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private T upperBound;
+    public virtual T UpperBound {
+      get { return upperBound; }
+      set {
+        if (upperBound != value) {
+          if (upperBound != null) {
+            upperBound.ValueChanged -= new EventHandler(upperBound_ToStringChanged);
+          }
+          upperBound = value;
+          if (upperBound != null) {
+            upperBound.ValueChanged += new EventHandler(upperBound_ToStringChanged);
+          }
+          OnUpperBoundChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private T stepSize;
+    public virtual T StepSize {
+      get { return stepSize; }
+      set {
+        if (stepSize != value) {
+          if (stepSize != null) {
+            stepSize.ValueChanged -= new EventHandler(stepSize_ToStringChanged);
+          }
+          stepSize = value;
+          if (stepSize != null) {
+            stepSize.ValueChanged += new EventHandler(stepSize_ToStringChanged);
+          }
+          OnStepSizeChanged();
+        }
+      }
+    }
+
+    #region IRange Members
+    object IRange.LowerBound {
+      get { return lowerBound; }
+      set { lowerBound = (T)value; }
+    }
+    object IRange.UpperBound {
+      get { return upperBound; }
+      set { upperBound = (T)value; }
+    }
+    object IRange.StepSize {
+      get { return stepSize; }
+      set { stepSize = (T)value; }
+    }
+    #endregion
+
+    #region Constructors and Cloning
+    public Range(T lowerBound, T upperBound, T stepSize) {
+      this.LowerBound = lowerBound;
+      this.UpperBound = upperBound;
+      this.StepSize = stepSize;
+    }
+
+    public Range() { }
+    [StorableConstructor]
+    protected Range(bool deserializing) : base(deserializing) { }
+    protected Range(Range<T> original, Cloner cloner)
+      : base(original, cloner) {
+      this.LowerBound = cloner.Clone(original.LowerBound);
+      this.UpperBound = cloner.Clone(original.UpperBound);
+      this.StepSize = cloner.Clone(original.StepSize);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (lowerBound != null) {
+        lowerBound.ValueChanged += new EventHandler(lowerBound_ToStringChanged);
+      }
+      if (upperBound != null) {
+        upperBound.ValueChanged += new EventHandler(upperBound_ToStringChanged);
+      }
+      if (stepSize != null) {
+        stepSize.ValueChanged += new EventHandler(stepSize_ToStringChanged);
+      }
+    }
+    #endregion
+
+    #region Events
+    private void lowerBound_ToStringChanged(object sender, EventArgs e) {
+      OnToStringChanged();
+    }
+    private void upperBound_ToStringChanged(object sender, EventArgs e) {
+      OnToStringChanged();
+    }
+    private void stepSize_ToStringChanged(object sender, EventArgs e) {
+      OnToStringChanged();
+    }
+    #endregion
+
+    #region Eventhandler
+    public event EventHandler LowerBoundChanged;
+    private void OnLowerBoundChanged() {
+      var handler = LowerBoundChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler UpperBoundChanged;
+    private void OnUpperBoundChanged() {
+      var handler = UpperBoundChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler StepSizeChanged;
+    private void OnStepSizeChanged() {
+      var handler = StepSizeChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ValueChanged;
+    private void OnValueChanged() {
+      var handler = ValueChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    #endregion
+
+    public override string ToString() {
+      return string.Format("{0},{1}:{2}", LowerBound.ToString(), UpperBound.ToString(), StepSize.ToString());
+    }
+
+    #region IStringConvertibleValue Members
+
+    public string GetValue() {
+      return this.ToString();
+    }
+    public bool ReadOnly {
+      get { return false; }
+    }
+    public bool SetValue(string value) {
+      var parts1 = value.Split(':');
+      if (parts1.Length != 2) return false;
+      var parts2 = parts1[0].Split(',');
+      if (parts2.Length != 2) return false;
+
+      return
+        lowerBound.SetValue(parts2[0]) &&
+        upperBound.SetValue(parts2[1]) &&
+        stepSize.SetValue(parts1[1]);
+    }
+    public bool Validate(string value, out string errorMessage) {
+      // TODO: check that upper is larger than lower and that stepsize < upper-lower
+      T lower = (T)lowerBound.Clone();
+      T upper = (T)upperBound.Clone();
+      T step = (T)stepSize.Clone();
+
+      var parts1 = value.Split(':');
+      if (parts1.Length != 2) {
+        errorMessage = "Could not parse range."; return false;
+      }
+      var parts2 = parts1[0].Split(',');
+      if (parts2.Length != 2) {
+        errorMessage = "Could not parse range."; return false;
+      }
+
+      if (lowerBound.SetValue(parts2[0]) &&
+          upperBound.SetValue(parts2[1]) &&
+          stepSize.SetValue(parts1[1])) {
+        errorMessage = string.Empty; return true;
+      } else {
+        errorMessage = "Could not parse range."; return false;
+      }
+    }
+
+    #endregion
+
+    public T GetRandomValue(IRandom random) {
+      // by a chance return the extreme values of this range to intensify search in those regions
+      if (random.NextDouble() < 0.1) {
+        if (random.NextDouble() < 0.5) {
+          return (T)LowerBound.Clone();
+        } else {
+          return (T)UpperBound.Clone();
+        }
+      }
+
+      // otherwise sample a random value from the range
+      return GetRandomSample(random);
+    }
+
+    protected abstract T GetRandomSample(IRandom random);
+
+    IItem IRange.GetRandomValue(IRandom random) {
+      return GetRandomValue(random);
+    }
+
+    public abstract IEnumerable<T> GetCombinations();
+    IEnumerable<IItem> IRange.GetCombinations() {
+      return GetCombinations().Cast<IItem>().ToArray();
+    }
+
+    public virtual double CalculateSimilarity(IItem a, IItem b) {
+      return CalculateSimilarityValue((T)a, (T)b);
+    }
+
+    protected abstract double CalculateSimilarityValue(T a, T b);
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/SymbolicExpressionGrammer/SymbolValueConfiguration.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/SymbolicExpressionGrammer/SymbolValueConfiguration.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/SymbolicExpressionGrammer/SymbolValueConfiguration.cs	(revision 7840)
@@ -0,0 +1,153 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  [StorableClass]
+  public class SymbolValueConfiguration : ParameterizedValueConfiguration {
+    [Storable]
+    private IOptimizable parentOptimizable;
+    public IOptimizable ParentOptimizable {
+      get { return parentOptimizable; }
+      set { this.parentOptimizable = value; }
+    }
+
+    #region Constructors and Cloning
+    [StorableConstructor]
+    protected SymbolValueConfiguration(bool deserializing) : base(deserializing) { }
+    public SymbolValueConfiguration() : base() { }
+    public SymbolValueConfiguration(Symbol symbol)
+      : base() {
+      this.IsOptimizable = true;
+      this.Optimize = false;
+      this.Name = symbol.Name;
+      this.ActualValue = new ConstrainedValue(symbol, symbol.GetType(), new ItemSet<IItem> { symbol }, false);
+    }
+    protected SymbolValueConfiguration(SymbolValueConfiguration original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterInitialFrequencyEvents();
+      this.parentOptimizable = cloner.Clone(original.parentOptimizable);
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolValueConfiguration(this, cloner);
+    }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterInitialFrequencyEvents();
+    }
+    #endregion
+
+    protected override void PopulateParameterConfigurations(IItem item, bool discoverValidValues) {
+      this.ClearParameterConfigurations();
+      var symbol = (Symbol)item;
+
+      var initialFrequencyValueConfigurations = new List<IValueConfiguration>();
+      initialFrequencyValueConfigurations.Add(new RangeValueConfiguration(new DoubleValue(0), typeof(DoubleValue)));
+      initialFrequencyValueConfigurations.Add(new RangeValueConfiguration(new DoubleValue(1), typeof(DoubleValue)));
+      var initialFrequencyParameterConfiguration = new ParameterConfiguration("InitialFrequency", typeof(Symbol), new DoubleValue(symbol.InitialFrequency), initialFrequencyValueConfigurations);
+      this.parameterConfigurations.Add(initialFrequencyParameterConfiguration);
+      RegisterInitialFrequencyEvents();
+
+      var constant = symbol as Constant;
+      if (constant != null) {
+        var minValueParameterConfiguration = new ParameterConfiguration("MinValue", typeof(DoubleValue), new DoubleValue(constant.MinValue));
+        var maxValueParameterConfiguration = new ParameterConfiguration("MaxValue", typeof(DoubleValue), new DoubleValue(constant.MaxValue));
+        var manipulatorMuParameterConfiguration = new ParameterConfiguration("ManipulatorMu", typeof(DoubleValue), new DoubleValue(constant.ManipulatorMu));
+        var manipulatorSigmaParameterConfiguration = new ParameterConfiguration("ManipulatorSigma", typeof(DoubleValue), new DoubleValue(constant.ManipulatorSigma));
+        var multiplicativeManipulatorSigmaParameterConfiguration = new ParameterConfiguration("MultiplicativeManipulatorSigma", typeof(DoubleValue), new DoubleValue(constant.MultiplicativeManipulatorSigma));
+
+        this.parameterConfigurations.Add(minValueParameterConfiguration);
+        this.parameterConfigurations.Add(maxValueParameterConfiguration);
+        this.parameterConfigurations.Add(manipulatorMuParameterConfiguration);
+        this.parameterConfigurations.Add(manipulatorSigmaParameterConfiguration);
+        this.parameterConfigurations.Add(multiplicativeManipulatorSigmaParameterConfiguration);
+      }
+
+      var variable = symbol as HeuristicLab.Problems.DataAnalysis.Symbolic.Variable;
+      if (variable != null) {
+        var weightMuParameterConfiguration = new ParameterConfiguration("WeightMu", typeof(DoubleValue), new DoubleValue(variable.WeightMu));
+        var weightSigmaParameterConfiguration = new ParameterConfiguration("WeightSigma", typeof(DoubleValue), new DoubleValue(variable.WeightSigma));
+        var weightManipulatorMuParameterConfiguration = new ParameterConfiguration("WeightManipulatorMu", typeof(DoubleValue), new DoubleValue(variable.WeightManipulatorMu));
+        var weightManipulatorSigmaParameterConfiguration = new ParameterConfiguration("WeightManipulatorSigma", typeof(DoubleValue), new DoubleValue(variable.WeightManipulatorSigma));
+        var multiplicativeWeightManipulatorSigmaParameterConfiguration = new ParameterConfiguration("MultiplicativeWeightManipulatorSigma", typeof(DoubleValue), new DoubleValue(variable.MultiplicativeWeightManipulatorSigma));
+
+        this.parameterConfigurations.Add(weightMuParameterConfiguration);
+        this.parameterConfigurations.Add(weightSigmaParameterConfiguration);
+        this.parameterConfigurations.Add(weightManipulatorMuParameterConfiguration);
+        this.parameterConfigurations.Add(weightManipulatorSigmaParameterConfiguration);
+        this.parameterConfigurations.Add(multiplicativeWeightManipulatorSigmaParameterConfiguration);
+      }
+    }
+
+    public virtual void Parameterize(Symbol symbol) {
+      var actualValueSymbol = this.ActualValue.Value as Symbol;
+      symbol.InitialFrequency = parentOptimizable.Optimize ? GetDoubleValue("InitialFrequency") : actualValueSymbol.InitialFrequency;
+
+      var constant = symbol as Constant;
+      if (constant != null) {
+        var actualValueConstant = this.ActualValue.Value as Constant;
+        constant.MinValue = parentOptimizable.Optimize ? GetDoubleValue("MinValue") : actualValueConstant.MinValue;
+        constant.MaxValue = parentOptimizable.Optimize ? GetDoubleValue("MaxValue") : actualValueConstant.MaxValue;
+        constant.ManipulatorMu = parentOptimizable.Optimize ? GetDoubleValue("ManipulatorMu") : actualValueConstant.ManipulatorMu;
+        constant.ManipulatorSigma = parentOptimizable.Optimize ? GetDoubleValue("ManipulatorSigma") : actualValueConstant.ManipulatorSigma;
+        constant.MultiplicativeManipulatorSigma = parentOptimizable.Optimize ? GetDoubleValue("MultiplicativeManipulatorSigma") : actualValueConstant.MultiplicativeManipulatorSigma;
+      }
+
+      var variable = symbol as HeuristicLab.Problems.DataAnalysis.Symbolic.Variable;
+      if (variable != null) {
+        var actualValueVariable = this.ActualValue.Value as HeuristicLab.Problems.DataAnalysis.Symbolic.Variable;
+        variable.WeightMu = parentOptimizable.Optimize ? GetDoubleValue("WeightMu") : actualValueVariable.WeightMu;
+        variable.WeightSigma = parentOptimizable.Optimize ? GetDoubleValue("WeightSigma") : actualValueVariable.WeightSigma;
+        variable.WeightManipulatorMu = parentOptimizable.Optimize ? GetDoubleValue("WeightManipulatorMu") : actualValueVariable.WeightManipulatorMu;
+        variable.WeightManipulatorSigma = parentOptimizable.Optimize ? GetDoubleValue("WeightManipulatorSigma") : actualValueVariable.WeightManipulatorSigma;
+        variable.MultiplicativeWeightManipulatorSigma = parentOptimizable.Optimize ? GetDoubleValue("MultiplicativeWeightManipulatorSigma") : actualValueVariable.MultiplicativeWeightManipulatorSigma;
+      }
+    }
+
+    private double GetDoubleValue(string name) {
+      return ((DoubleValue)ParameterConfigurations.Single(x => x.Name == name).ActualValue.Value).Value;
+    }
+
+    private void RegisterInitialFrequencyEvents() {
+      this.parameterConfigurations.Single(x => x.Name == "InitialFrequency").ToStringChanged += new EventHandler(initialFrequencyParameterConfiguration_ToStringChanged);
+    }
+    private void DeregisterInitialFrequencyEvents() {
+      this.parameterConfigurations.Single(x => x.Name == "InitialFrequency").ToStringChanged -= new EventHandler(initialFrequencyParameterConfiguration_ToStringChanged);
+    }
+
+    protected virtual void initialFrequencyParameterConfiguration_ToStringChanged(object sender, EventArgs e) {
+      OnToStringChanged();
+    }
+
+    public override string ToString() {
+      return string.Format("{0}: {1}", this.Name, parameterConfigurations.Single(pc => pc.Name == "InitialFrequency").ActualValue.Value);
+    }
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/SymbolicExpressionGrammer/SymbolicExpressionGrammarValueConfiguration.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/SymbolicExpressionGrammer/SymbolicExpressionGrammarValueConfiguration.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/SymbolicExpressionGrammer/SymbolicExpressionGrammarValueConfiguration.cs	(revision 7840)
@@ -0,0 +1,79 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  [StorableClass]
+  public class SymbolicExpressionGrammarValueConfiguration : ParameterizedValueConfiguration {
+
+    #region Constructors and Cloning
+    [StorableConstructor]
+    protected SymbolicExpressionGrammarValueConfiguration(bool deserializing) : base(deserializing) { }
+    public SymbolicExpressionGrammarValueConfiguration() : base() { }
+    public SymbolicExpressionGrammarValueConfiguration(ISymbolicExpressionGrammar grammar) {
+      this.IsOptimizable = true;
+      this.ActualValue = new ConstrainedValue(grammar, grammar.GetType(), new ItemSet<IItem> { grammar }, false);
+    }
+    protected SymbolicExpressionGrammarValueConfiguration(SymbolicExpressionGrammarValueConfiguration original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicExpressionGrammarValueConfiguration(this, cloner);
+    }
+    #endregion
+
+    protected override void PopulateParameterConfigurations(IItem item, bool discoverValidValues) {
+      var grammar = (ISymbolicExpressionGrammar)item;
+      foreach (Symbol symbol in grammar.Symbols) {
+        var svc = new SymbolValueConfiguration(symbol);
+        var pc = new SingleValuedParameterConfiguration(symbol.Name, svc);
+        svc.ParentOptimizable = pc;
+        SetOptimizeIfOnlyOneValueConfiguration(pc);
+        this.parameterConfigurations.Add(pc);
+      }
+    }
+
+    public virtual void Parameterize(ISymbolicExpressionGrammar grammar) {
+      foreach (Symbol symbol in grammar.Symbols) {
+        var symbolValueConfiguration = (SymbolValueConfiguration)this.parameterConfigurations.Single(pc => pc.Name == symbol.Name).ValueConfigurations.First();
+        symbolValueConfiguration.Parameterize(symbol);
+      }
+    }
+
+    /// <summary>
+    /// If only 1 parameter exists (usually this is InitialFrequency), then set it to Optimize=true,
+    /// because this is what the user usually wants to do. avoids additional click.
+    /// </summary>
+    private static void SetOptimizeIfOnlyOneValueConfiguration(SingleValuedParameterConfiguration pc) {
+      var vc = pc.ValueConfigurations[0] as ParameterizedValueConfiguration;
+      if (vc != null) {
+        if (vc.ParameterConfigurations.Count == 1) {
+          vc.ParameterConfigurations.Single().Optimize = true;
+        }
+      }
+    }
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ValueConfigurations/CheckedValueConfigurationCollection.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ValueConfigurations/CheckedValueConfigurationCollection.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ValueConfigurations/CheckedValueConfigurationCollection.cs	(revision 7840)
@@ -0,0 +1,111 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  // todo: check that at least 1 elements needs to be selected
+  // todo: control creatable item types
+  [StorableClass]
+  public class CheckedValueConfigurationList : CheckedItemList<IValueConfiguration>, ICheckedValueConfigurationList {
+    [Storable]
+    private int minItemCount = 1;
+    public int MinItemCount {
+      get { return minItemCount; }
+    }
+
+    [Storable]
+    protected IItemSet<IItem> validValues;
+    public IItemSet<IItem> ValidValues {
+      get { return validValues; }
+    }
+
+    public CheckedValueConfigurationList(IItemSet<IItem> validValues) {
+      this.validValues = validValues;
+      RegisterEvents();
+    }
+    public CheckedValueConfigurationList(IEnumerable<IValueConfiguration> collection)
+      : base(collection) {
+      validValues = null;
+      // event wiring not needed
+    }
+    public CheckedValueConfigurationList() {
+      RegisterEvents();
+    }
+    [StorableConstructor]
+    protected CheckedValueConfigurationList(bool deserializing)
+      : base(deserializing) {
+      RegisterEvents();
+    }
+    protected CheckedValueConfigurationList(CheckedValueConfigurationList original, Cloner cloner)
+      : base(original, cloner) {
+      this.minItemCount = original.MinItemCount;
+      this.validValues = original.validValues;
+      RegisterEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CheckedValueConfigurationList(this, cloner);
+    }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+
+    private void RegisterEvents() {
+      this.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<IValueConfiguration>>(CheckedValueConfigurationList_ItemsAdded);
+      this.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<IValueConfiguration>>(CheckedValueConfigurationList_ItemsRemoved);
+    }
+
+    private void DeregisterEvents() {
+      this.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<IValueConfiguration>>(CheckedValueConfigurationList_ItemsRemoved);
+      this.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<IValueConfiguration>>(CheckedValueConfigurationList_ItemsAdded);
+    }
+
+    private void CheckedValueConfigurationList_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IValueConfiguration>> e) {
+      foreach (var item in e.Items) {
+        var matchingItems = this.Where(x => x != item.Value && x.ActualValue.ValueDataType == item.Value.ActualValue.ValueDataType);
+        if (matchingItems.Count() > 0) {
+          int maxNumber = matchingItems.Select(x => x.Number).Max();
+          item.Value.Number = maxNumber + 1;
+        }
+      }
+    }
+
+    private void CheckedValueConfigurationList_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IValueConfiguration>> e) {
+      // auch collectionreset gehört berücksichtigt
+      // funktioniert so nicht ganz, weil die view das hinzufügen nicht mitkriegt
+      //if (this.Count < minItemCount) {
+      //  foreach (var item in e.Items) {
+      //    if (this.Count >= minItemCount)
+      //      break;
+      //    this.Add(item);
+      //  }
+      //}
+    }
+
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ValueConfigurations/NullValueConfiguration.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ValueConfigurations/NullValueConfiguration.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ValueConfigurations/NullValueConfiguration.cs	(revision 7840)
@@ -0,0 +1,64 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  [StorableClass]
+  public class NullValueConfiguration : ValueConfiguration {
+
+    public NullValueConfiguration() {
+      this.ActualValue = new ConstrainedValue(null, null, null, true);
+      this.IsOptimizable = false;
+    }
+    [StorableConstructor]
+    protected NullValueConfiguration(bool deserializing) : base(deserializing) { }
+    protected NullValueConfiguration(NullValueConfiguration original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new NullValueConfiguration(this, cloner);
+    }
+
+    public override string ToString() {
+      return "null";
+    }
+
+    public override void Randomize(IRandom random) { }
+
+    public override double CalculateSimilarity(IOptimizable optimizable) {
+      return 1.0;
+    }
+
+    public override string ParameterInfoString {
+      get { return "null"; }
+    }
+
+    public override void CollectOptimizedParameterNames(List<string> parameterNames, string prefix) { }
+
+    public override List<IOptimizable> GetAllOptimizables() {
+      return new List<IOptimizable>();
+    }
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ValueConfigurations/ParameterizedValueConfiguration.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ValueConfigurations/ParameterizedValueConfiguration.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ValueConfigurations/ParameterizedValueConfiguration.cs	(revision 7840)
@@ -0,0 +1,196 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  [StorableClass]
+  public class ParameterizedValueConfiguration : ValueConfiguration {
+    [Storable]
+    protected IItemCollection<IParameterConfiguration> parameterConfigurations = new ItemCollection<IParameterConfiguration>();
+    public virtual IItemCollection<IParameterConfiguration> ParameterConfigurations {
+      get { return new ReadOnlyItemCollection<IParameterConfiguration>(this.parameterConfigurations); }
+      protected set { this.parameterConfigurations = value; }
+    }
+
+    public override bool Optimize {
+      get { return base.Optimize; }
+      set {
+        if (this.optimize != value) {
+          base.Optimize = value;
+          if (optimize) {
+            ClearParameterConfigurations();
+            PopulateParameterConfigurations(this.actualValue.Value, this.discoverValidValues);
+          } else {
+            ClearParameterConfigurations();
+          }
+        }
+      }
+    }
+
+    public override ConstrainedValue ActualValue {
+      get { return base.ActualValue; }
+      set {
+        ClearParameterConfigurations();
+        base.ActualValue = value;
+        if (this.Optimize && this.actualValue.Value != null) PopulateParameterConfigurations(this.actualValue.Value, this.discoverValidValues);
+      }
+    }
+
+    [Storable]
+    protected bool discoverValidValues;
+    public bool DiscoverValidValues {
+      get { return discoverValidValues; }
+      set { discoverValidValues = value; }
+    }
+
+    public override bool ValuesReadOnly {
+      set {
+        if (value != this.valuesReadOnly) {
+          this.valuesReadOnly = value;
+          foreach (var pc in this.parameterConfigurations) {
+            pc.ValuesReadOnly = value;
+          }
+        }
+      }
+    }
+
+    #region Constructors and Cloning
+    [StorableConstructor]
+    protected ParameterizedValueConfiguration(bool deserializing) : base(deserializing) { }
+    public ParameterizedValueConfiguration() {
+      this.ParameterConfigurations = new ItemList<IParameterConfiguration>();
+    }
+    public ParameterizedValueConfiguration(IItem value, Type valueDataType, bool discoverValidValues)
+      : base(value, valueDataType) {
+      this.discoverValidValues = discoverValidValues;
+    }
+    protected ParameterizedValueConfiguration(ParameterizedValueConfiguration original, Cloner cloner)
+      : base(original, cloner) {
+      this.discoverValidValues = original.discoverValidValues;
+      this.ParameterConfigurations = cloner.Clone(original.parameterConfigurations);
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ParameterizedValueConfiguration(this, cloner);
+    }
+    #endregion
+
+    protected virtual void PopulateParameterConfigurations(IItem item, bool discoverValidValues) {
+      var parameterizedItem = item as IParameterizedItem;
+      if (parameterizedItem != null) {
+        foreach (var childParameter in parameterizedItem.Parameters) {
+          IValueParameter valueParameter = childParameter as IValueParameter;
+          if (valueParameter != null) {
+            var pc = new ParameterConfiguration(valueParameter.Name, valueParameter, discoverValidValues);
+            this.parameterConfigurations.Add(pc);
+          }
+        }
+      }
+    }
+
+    protected virtual void ClearParameterConfigurations() {
+      parameterConfigurations.Clear();
+    }
+
+    public override string ParameterInfoString {
+      get {
+        StringBuilder sb = new StringBuilder();
+        if ((this.Optimize) && this.ParameterConfigurations.Count > 0) {
+          var parameterInfos = new List<string>();
+          foreach (var pc in this.ParameterConfigurations) {
+            if (pc.Optimize) parameterInfos.Add(pc.ParameterInfoString);
+          }
+          sb.Append(string.Join(", ", parameterInfos.ToArray()));
+        }
+        return sb.ToString();
+      }
+    }
+
+    public override string ToString() {
+      if (ActualValue != null && ActualValue.Value != null) {
+        if (Optimize) {
+          return string.Format("{0} (Optimize)", NumberedName);
+        } else {
+          return string.Format("{0}", NumberedName);
+        }
+      } else {
+        return base.ToString();
+      }
+    }
+
+    public override List<IOptimizable> GetAllOptimizables() {
+      var list = new List<IOptimizable>();
+      foreach (var pc in ParameterConfigurations) {
+        if (pc.Optimize) {
+          if (pc.ValueConfigurations.CheckedItems.Count() > 1) list.Add(pc); // only add if there are more than 1 choices. otherwise it makes no sense to optimize which VC is selected
+          list.AddRange(pc.GetAllOptimizables());
+        }
+      }
+      return list;
+    }
+
+    public override void CollectOptimizedParameterNames(List<string> parameterNames, string prefix) {
+      foreach (var pc in ParameterConfigurations) {
+        if (pc.Optimize) {
+          parameterNames.Add(prefix + pc.ParameterName);
+          pc.CollectOptimizedParameterNames(parameterNames, prefix + pc.ParameterName + ".");
+        }
+      }
+    }
+
+    public virtual IEnumerable<string> GetOptimizedParameterNames() {
+      var list = new List<string>();
+      this.CollectOptimizedParameterNames(list, string.Empty);
+      return list;
+    }
+
+    public virtual void Parameterize(IParameterizedItem item) {
+      foreach (IParameterConfiguration pc in this.ParameterConfigurations) {
+        pc.Parameterize((IValueParameter)item.Parameters[pc.ParameterName]);
+      }
+    }
+
+    public override void Randomize(IRandom random) {
+      foreach (IParameterConfiguration pc in this.ParameterConfigurations) {
+        pc.Randomize(random);
+      }
+    }
+
+    public override double CalculateSimilarity(IOptimizable optimizable) {
+      var other = (ParameterizedValueConfiguration)optimizable;
+      double sum = 0;
+      int count = 0;
+      for (int i = 0; i < ParameterConfigurations.Count; i++) {
+        if (this.ParameterConfigurations.ElementAt(i).Optimize) {
+          sum += this.ParameterConfigurations.ElementAt(i).CalculateSimilarity(other.ParameterConfigurations.ElementAt(i));
+          count++;
+        }
+      }
+      return count == 0 ? 1.0 : sum / (double)count;
+    }
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ValueConfigurations/RangeValueConfiguration.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ValueConfigurations/RangeValueConfiguration.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ValueConfigurations/RangeValueConfiguration.cs	(revision 7840)
@@ -0,0 +1,123 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  [StorableClass]
+  public class RangeValueConfiguration : ValueConfiguration {
+    [Storable]
+    protected IRange rangeConstraint;
+    public IRange RangeConstraint {
+      get { return rangeConstraint; }
+      private set {
+        if (rangeConstraint != value) {
+          DeregisterRangeConstraintEvents();
+          rangeConstraint = value;
+          RegisterRangeConstraintEvents();
+        }
+      }
+    }
+
+    #region Constructor and Cloning
+    [StorableConstructor]
+    protected RangeValueConfiguration(bool deserializing) : base(deserializing) { }
+    public RangeValueConfiguration() {
+
+    }
+    protected RangeValueConfiguration(RangeValueConfiguration original, Cloner cloner)
+      : base(original, cloner) {
+      this.rangeConstraint = cloner.Clone(original.RangeConstraint);
+      RegisterRangeConstraintEvents();
+    }
+    public RangeValueConfiguration(IItem value, Type valueDataType)
+      : base(value, valueDataType) {
+      if (actualValue.ValueDataType == typeof(IntValue)) {
+        RangeConstraint = new IntValueRange(new IntValue(0), (IntValue)value.Clone(), new IntValue(1));
+      } else if (actualValue.ValueDataType == typeof(DoubleValue)) {
+        RangeConstraint = new DoubleValueRange(new DoubleValue(0), (DoubleValue)value.Clone(), new DoubleValue(0.01));
+      } else if (actualValue.ValueDataType == typeof(PercentValue)) {
+        RangeConstraint = new PercentValueRange(new PercentValue(0), new PercentValue(1), new PercentValue(0.01));
+      } else if (actualValue.ValueDataType == typeof(BoolValue)) {
+        this.IsOptimizable = false; // there is nothing to configure for bools
+      } else {
+        RangeConstraint = null;
+      }
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RangeValueConfiguration(this, cloner);
+    }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterRangeConstraintEvents();
+    }
+    #endregion
+
+    private void RegisterRangeConstraintEvents() {
+      if (this.RangeConstraint != null) this.RangeConstraint.ToStringChanged += new EventHandler(RangeConstraint_ToStringChanged);
+    }
+    private void DeregisterRangeConstraintEvents() {
+      if (this.RangeConstraint != null) this.RangeConstraint.ToStringChanged -= new EventHandler(RangeConstraint_ToStringChanged);
+    }
+
+    public override string ToString() {
+      if (ActualValue != null && ActualValue.Value != null) {
+        if (Optimize) {
+          return string.Format("{0} (Optimize: {1})", NumberedName, RangeConstraint);
+        } else {
+          return string.Format("{0}: {1}", NumberedName, ActualValue.Value);
+        }
+      } else {
+        return base.ToString();
+      }
+    }
+
+    public override void Randomize(IRandom random) {
+      this.actualValue.Value = rangeConstraint.GetRandomValue(random);
+    }
+
+    public override double CalculateSimilarity(IOptimizable optimizable) {
+      var other = (IValueConfiguration)optimizable;
+      return this.RangeConstraint.CalculateSimilarity(this.ActualValue.Value, other.ActualValue.Value);
+    }
+
+    public override string ParameterInfoString {
+      get { return string.Empty; }
+    }
+
+    public override void CollectOptimizedParameterNames(List<string> parameterNames, string prefix) { }
+
+    public override List<IOptimizable> GetAllOptimizables() {
+      return new List<IOptimizable>();
+    }
+
+    #region Events
+    private void RangeConstraint_ToStringChanged(object sender, EventArgs e) {
+      OnToStringChanged();
+    }
+    #endregion
+  }
+}
Index: branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ValueConfigurations/ValueConfiguration.cs
===================================================================
--- branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ValueConfigurations/ValueConfiguration.cs	(revision 7840)
+++ branches/DataAnalysisService/HeuristicLab.Encodings.ParameterConfigurationTreeEncoding/3.3/ValueConfigurations/ValueConfiguration.cs	(revision 7840)
@@ -0,0 +1,190 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.ParameterConfigurationTreeEncoding {
+  // TODO: ItemName/Descr, storability
+  [StorableClass]
+  public abstract class ValueConfiguration : NamedItem, IValueConfiguration {
+    public override bool CanChangeName {
+      get { return true; }
+    }
+
+    public override bool CanChangeDescription {
+      get { return true; }
+    }
+
+    [Storable]
+    protected bool isOptimizable;
+    public virtual bool IsOptimizable {
+      get { return isOptimizable; }
+      set {
+        if (this.isOptimizable != value) {
+          this.isOptimizable = value;
+          OnIsOptimizableChanged();
+        }
+      }
+    }
+
+    [Storable]
+    protected bool optimize;
+    public virtual bool Optimize {
+      get { return optimize; }
+      set {
+        if (optimize != value) {
+          if (value == true && !this.IsOptimizable)
+            throw new NotSupportedException("This value is not optimizable.");
+
+          optimize = value;
+          OnOptimizeChanged();
+          OnToStringChanged();
+        }
+      }
+    }
+
+    [Storable]
+    protected ConstrainedValue actualValue;
+    public virtual ConstrainedValue ActualValue {
+      get { return actualValue; }
+      set {
+        if (this.actualValue != value) {
+          DeregisterActualValueEvents();
+          this.actualValue = value;
+          OnValueChanged();
+          OnToStringChanged();
+          RegisterActualValueEvents();
+        }
+      }
+    }
+
+    [Storable]
+    protected int number = 0;
+    public int Number {
+      get { return number; }
+      set {
+        if (value != number) {
+          number = value;
+          OnToStringChanged();
+        }
+      }
+    }
+
+    [Storable]
+    protected bool valuesReadOnly = false;
+    public virtual bool ValuesReadOnly {
+      get { return valuesReadOnly; }
+      set {
+        if (value != this.valuesReadOnly) {
+          this.valuesReadOnly = value;
+        }
+      }
+    }
+
+    #region Constructors and Cloning
+    public ValueConfiguration(IItem value, Type valueDataType) {
+      this.ActualValue = new ConstrainedValue(value, valueDataType, new ItemSet<IItem> { value }, false);
+      this.IsOptimizable = true;
+    }
+
+    public ValueConfiguration() { }
+    [StorableConstructor]
+    protected ValueConfiguration(bool deserializing) { }
+    protected ValueConfiguration(ValueConfiguration original, Cloner cloner)
+      : base(original, cloner) {
+      this.actualValue = cloner.Clone(original.ActualValue);
+      this.isOptimizable = original.isOptimizable;
+      this.optimize = original.optimize;
+      this.number = original.number;
+      this.valuesReadOnly = original.valuesReadOnly;
+      RegisterActualValueEvents();
+    }
+    #endregion
+
+    private void RegisterActualValueEvents() {
+      if (this.actualValue != null) this.actualValue.ToStringChanged += new EventHandler(actualValue_ToStringChanged);
+    }
+    private void DeregisterActualValueEvents() {
+      if (this.actualValue != null) this.actualValue.ToStringChanged -= new EventHandler(actualValue_ToStringChanged);
+    }
+
+    #region Events
+    private void actualValue_ToStringChanged(object sender, EventArgs e) {
+      OnToStringChanged();
+    }
+    #endregion
+
+    #region IItem Members
+    public override string ItemDescription {
+      get { return (actualValue != null && actualValue.Value != null) ? actualValue.Value.ItemDescription : base.ItemDescription; }
+    }
+
+    public override Image ItemImage {
+      get { return (actualValue != null && actualValue.Value != null) ? actualValue.Value.ItemImage : base.ItemImage; }
+    }
+
+    public override string ItemName {
+      get { return (actualValue != null && actualValue.Value != null) ? actualValue.Value.ItemDescription : base.ItemName; }
+    }
+    #endregion
+
+    #region Event Handlers
+    public virtual event EventHandler ValueChanged;
+    protected virtual void OnValueChanged() {
+      var handler = ValueChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public virtual event EventHandler IsOptimizableChanged;
+    private void OnIsOptimizableChanged() {
+      var handler = IsOptimizableChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public virtual event EventHandler OptimizeChanged;
+    protected virtual void OnOptimizeChanged() {
+      var handler = OptimizeChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    #endregion
+
+    public string NumberedName {
+      get {
+        if (this.number == 0) {
+          return (ActualValue != null && ActualValue.Value != null) ? ActualValue.Value.ItemName : base.ToString();
+        } else {
+          return string.Format("{0} {1}", ActualValue.Value.ItemName, number);
+        }
+      }
+    }
+
+    public abstract void Randomize(IRandom random);
+    public abstract double CalculateSimilarity(IOptimizable optimizable);
+    public abstract string ParameterInfoString { get; }
+    public abstract void CollectOptimizedParameterNames(List<string> parameterNames, string prefix);
+    public abstract List<IOptimizable> GetAllOptimizables();
+  }
+}
