Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/NullValueConfiguration.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/NullValueConfiguration.cs	(revision 5522)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/NullValueConfiguration.cs	(revision 5653)
@@ -1,9 +1,6 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+﻿using System.Collections.Generic;
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Common;
 
 namespace HeuristicLab.Problems.MetaOptimization {
@@ -12,5 +9,4 @@
 
     public NullValueConfiguration() {
-      this.ParameterConfigurations = new ItemList<IParameterConfiguration>();
       this.ActualValue = new ConstrainedValue(null, null, null, true);
       this.IsOptimizable = false;
@@ -28,4 +24,24 @@
       return "null";
     }
+
+    public override void Randomize(IRandom random) { }
+
+    public override void Mutate(IRandom random, MutateDelegate mutate, IIntValueManipulator intValueManipulator, IDoubleValueManipulator doubleValueManipulator) { }
+
+    public override void Cross(IRandom random, IOptimizable other, CrossDelegate cross, IIntValueCrossover intValueCrossover, IDoubleValueCrossover doubleValueCrossover) { }
+
+    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/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/ParameterizedValueConfiguration.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/ParameterizedValueConfiguration.cs	(revision 5653)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/ParameterizedValueConfiguration.cs	(revision 5653)
@@ -0,0 +1,160 @@
+﻿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.Problems.MetaOptimization {
+  [StorableClass]
+  public class ParameterizedValueConfiguration : ValueConfiguration {
+    [Storable]
+    protected IItemCollection<IParameterConfiguration> parameterConfigurations = new ItemCollection<IParameterConfiguration>();
+    public IItemCollection<IParameterConfiguration> ParameterConfigurations {
+      get { return new ReadOnlyItemCollection<IParameterConfiguration>(this.parameterConfigurations); }
+      protected set { this.parameterConfigurations = value; }
+    }
+
+    public override bool Optimize {
+      get { return base.Optimize; }
+      set {
+        base.Optimize = value;
+        if (optimize) {
+          ClearParameterConfigurations();
+          if (this.actualValue.Value is IParameterizedNamedItem) PopulateParameterConfigurations(this.actualValue.Value as IParameterizedNamedItem);
+        } else {
+          ClearParameterConfigurations();
+        }
+      }
+    }
+
+    public override ConstrainedValue ActualValue {
+      get { return base.ActualValue; }
+      set {
+        ClearParameterConfigurations();
+        base.ActualValue = value;
+        if(this.actualValue.Value != null) PopulateParameterConfigurations(this.actualValue.Value as IParameterizedNamedItem);
+      }
+    }
+
+    #region Constructors and Cloning
+    [StorableConstructor]
+    protected ParameterizedValueConfiguration(bool deserializing) : base(deserializing) { }
+    public ParameterizedValueConfiguration() {
+      this.ParameterConfigurations = new ItemList<IParameterConfiguration>();
+    }
+    public ParameterizedValueConfiguration(IItem value, Type valueDataType)
+      : base(value, valueDataType) {
+    }
+    protected ParameterizedValueConfiguration(ParameterizedValueConfiguration original, Cloner cloner)
+      : base(original, cloner) {
+      this.ParameterConfigurations = cloner.Clone(original.parameterConfigurations);
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ParameterizedValueConfiguration(this, cloner);
+    }
+    #endregion
+
+    protected virtual void PopulateParameterConfigurations(IParameterizedNamedItem parameterizedItem) {
+      foreach (var childParameter in parameterizedItem.Parameters) {
+        var pc = ParameterConfiguration.Create(parameterizedItem, childParameter);
+        if (pc != null) 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 IEnumerable<string> GetOptimizedParameterNames() {
+      var list = new List<string>();
+      this.CollectOptimizedParameterNames(list, "");
+      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 void Mutate(IRandom random, MutateDelegate mutate, IIntValueManipulator intValueManipulator, IDoubleValueManipulator doubleValueManipulator) {
+      foreach (IParameterConfiguration pc in this.ParameterConfigurations) {
+        pc.Mutate(random, mutate, intValueManipulator, doubleValueManipulator);
+      }
+    }
+
+    public override void Cross(IRandom random, IOptimizable other, CrossDelegate cross, IIntValueCrossover intValueCrossover, IDoubleValueCrossover doubleValueCrossover) {
+      var otherVc = (ParameterizedValueConfiguration)other;
+      for (int i = 0; i < this.ParameterConfigurations.Count; i++) {
+        this.ParameterConfigurations.ElementAt(i).Cross(random, otherVc.ParameterConfigurations.ElementAt(i), cross, intValueCrossover, doubleValueCrossover);
+      }
+    }
+
+    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/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/RangeValueConfiguration.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/RangeValueConfiguration.cs	(revision 5653)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/RangeValueConfiguration.cs	(revision 5653)
@@ -0,0 +1,110 @@
+﻿using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.MetaOptimization {
+  [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, new IntValue(1));
+      } else if (actualValue.ValueDataType == typeof(DoubleValue)) {
+        RangeConstraint = new DoubleValueRange(new DoubleValue(0), (DoubleValue)value, 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 void Mutate(IRandom random, MutateDelegate mutate, IIntValueManipulator intValueManipulator, IDoubleValueManipulator doubleValueManipulator) {
+      mutate(random, this, intValueManipulator, doubleValueManipulator);
+    }
+
+    public override void Cross(IRandom random, IOptimizable other, CrossDelegate cross, IIntValueCrossover intValueCrossover, IDoubleValueCrossover doubleValueCrossover) {
+      cross(random, this, other, intValueCrossover, doubleValueCrossover);
+    }
+
+    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/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/ValueConfiguration.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/ValueConfiguration.cs	(revision 5522)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/ValueConfiguration.cs	(revision 5653)
@@ -1,19 +1,15 @@
 ﻿using System;
+using System.Collections.Generic;
+using System.Drawing;
 using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Data;
-using System.Drawing;
-using HeuristicLab.Encodings.RealVectorEncoding;
-using HeuristicLab.Encodings.IntegerVectorEncoding;
 using HeuristicLab.PluginInfrastructure;
-using System.Collections.Generic;
-using System.Text;
 
 namespace HeuristicLab.Problems.MetaOptimization {
   // TODO: ItemName/Descr, storability
   [StorableClass]
-  public class ValueConfiguration : NamedItem, IValueConfiguration {
+  public abstract class ValueConfiguration : NamedItem, IValueConfiguration {
     public override bool CanChangeName {
       get { return true; }
@@ -38,26 +34,13 @@
     [Storable]
     protected bool optimize;
-    public bool Optimize {
+    public virtual bool Optimize {
       get { return optimize; }
       set {
         if (optimize != value) {
           optimize = value;
-          if (optimize) {
-            ClearParameterConfigurations();
-            if (this.actualValue.Value is IParameterizedNamedItem) PopulateParameterConfigurations(this.actualValue.Value as IParameterizedNamedItem);
-          } else {
-            ClearParameterConfigurations();
-          }
           OnOptimizeChanged();
           OnToStringChanged();
         }
       }
-    }
-
-    [Storable]
-    protected IItemCollection<IParameterConfiguration> parameterConfigurations = new ItemCollection<IParameterConfiguration>();
-    public IItemCollection<IParameterConfiguration> ParameterConfigurations {
-      get { return new ReadOnlyItemCollection<IParameterConfiguration>(this.parameterConfigurations); }
-      protected set { this.parameterConfigurations = value; }
     }
 
@@ -69,22 +52,7 @@
         if (this.actualValue != value) {
           DeregisterActualValueEvents();
-          ClearParameterConfigurations();
           this.actualValue = value;
-          if (this.actualValue.Value is IParameterizedNamedItem) PopulateParameterConfigurations(this.actualValue.Value as IParameterizedNamedItem);
           OnValueChanged();
           OnToStringChanged();
-          RegisterActualValueEvents();
-        }
-      }
-    }
-
-    [Storable]
-    protected IRange rangeConstraint;
-    public IRange RangeConstraint {
-      get { return rangeConstraint; }
-      private set {
-        if (rangeConstraint != value) {
-          DeregisterRangeConstraintEvents();
-          rangeConstraint = value;
           RegisterActualValueEvents();
         }
@@ -106,19 +74,7 @@
     #region Constructors and Cloning
     public ValueConfiguration(IItem value, Type valueDataType) {
-      this.ParameterConfigurations = new ItemList<IParameterConfiguration>();
       var validTypes = ApplicationManager.Manager.GetTypes(valueDataType).OrderBy(x => x.Name).ToArray();
       this.ActualValue = new ConstrainedValue(value, valueDataType, new ItemSet<IItem> { value }, false);
       this.IsOptimizable = true;
-      if (actualValue.ValueDataType == typeof(IntValue)) {
-        RangeConstraint = new IntValueRange(new IntValue(0), (IntValue)value, new IntValue(1));
-      } else if (actualValue.ValueDataType == typeof(DoubleValue)) {
-        RangeConstraint = new DoubleValueRange(new DoubleValue(0), (DoubleValue)value, 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;
-      }
     }
 
@@ -128,38 +84,12 @@
     protected ValueConfiguration(ValueConfiguration original, Cloner cloner)
       : base(original, cloner) {
-      this.ParameterConfigurations = cloner.Clone(original.parameterConfigurations);
       this.actualValue = cloner.Clone(original.ActualValue);
-      this.rangeConstraint = cloner.Clone(original.RangeConstraint);
       this.isOptimizable = original.isOptimizable;
       this.optimize = original.optimize;
       this.number = original.number;
       RegisterActualValueEvents();
-      RegisterRangeConstraintEvents();
-    }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new ValueConfiguration(this, cloner);
-    }
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      RegisterRangeConstraintEvents();
     }
     #endregion
 
-    protected virtual void PopulateParameterConfigurations(IParameterizedNamedItem parameterizedItem) {
-      foreach (var childParameter in parameterizedItem.Parameters) {
-        var pc = ParameterConfiguration.Create(parameterizedItem, childParameter);
-        if (pc != null) this.parameterConfigurations.Add(pc);
-      }
-    }
-    protected virtual void ClearParameterConfigurations() {
-      parameterConfigurations.Clear();
-    }
-
-    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);
-    }
     private void RegisterActualValueEvents() {
       if (this.actualValue != null) this.actualValue.ToStringChanged += new EventHandler(actualValue_ToStringChanged);
@@ -170,8 +100,5 @@
 
     #region Events
-    void actualValue_ToStringChanged(object sender, EventArgs e) {
-      OnToStringChanged();
-    }
-    void RangeConstraint_ToStringChanged(object sender, EventArgs e) {
+    private void actualValue_ToStringChanged(object sender, EventArgs e) {
       OnToStringChanged();
     }
@@ -212,26 +139,4 @@
     #endregion
 
-    public override string ToString() {
-      if (ActualValue != null && ActualValue.Value != null) {
-        string name = NumberedName;
-
-        if (ActualValue.Value is IParameterizedItem) {
-          if (Optimize) {
-            return string.Format("{0} (Optimize)", name);
-          } else {
-            return string.Format("{0}", name);
-          }
-        } else {
-          if (Optimize) {
-            return string.Format("{0} (Optimize: {1})", name, RangeConstraint);
-          } else {
-            return string.Format("{0}: {1}", name, ActualValue.Value);
-          }
-        }
-      } else {
-        return base.ToString();
-      }
-    }
-
     public string NumberedName {
       get {
@@ -244,103 +149,11 @@
     }
 
-    public 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 virtual void Parameterize(IParameterizedItem item) {
-      foreach (IParameterConfiguration pc in this.ParameterConfigurations) {
-        pc.Parameterize((IValueParameter)item.Parameters[pc.ParameterName]);
-      }
-    }
-
-    public void Randomize(IRandom random) {
-      if (Optimize) {
-        if (rangeConstraint != null) {
-          this.actualValue.Value = rangeConstraint.GetRandomValue(random);
-        } else {
-          foreach (IParameterConfiguration pc in this.ParameterConfigurations) {
-            pc.Randomize(random);
-          }
-        }
-      }
-    }
-
-    public void Mutate(IRandom random, MutateDelegate mutate, IIntValueManipulator intValueManipulator, IDoubleValueManipulator doubleValueManipulator) {
-      if (Optimize) {
-        if (rangeConstraint != null) {
-          mutate(random, this, intValueManipulator, doubleValueManipulator);
-        } else {
-          foreach (IParameterConfiguration pc in this.ParameterConfigurations) {
-            pc.Mutate(random, mutate, intValueManipulator, doubleValueManipulator);
-          }
-        }
-      }
-    }
-
-    public void Cross(IRandom random, IOptimizable other, CrossDelegate cross, IIntValueCrossover intValueCrossover, IDoubleValueCrossover doubleValueCrossover) {
-      if (Optimize) {
-        if (rangeConstraint != null) {
-          cross(random, this, other, intValueCrossover, doubleValueCrossover);
-        } else {
-          IValueConfiguration otherVc = (IValueConfiguration)other;
-          for (int i = 0; i < this.ParameterConfigurations.Count; i++) {
-            this.ParameterConfigurations.ElementAt(i).Cross(random, otherVc.ParameterConfigurations.ElementAt(i), cross, intValueCrossover, doubleValueCrossover);
-          }
-        }
-      }
-    }
-
-    public 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 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 IEnumerable<string> GetOptimizedParameterNames() {
-      var list = new List<string>();
-      this.CollectOptimizedParameterNames(list, "");
-      return list;
-    }
-
-    public double CalculateSimilarity(IOptimizable optimizable) {
-      var other = (IValueConfiguration)optimizable;
-      if (rangeConstraint != null) {
-        return this.RangeConstraint.CalculateSimilarity(this.ActualValue.Value, other.ActualValue.Value);
-      } else {
-        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;
-      }
-    }
+    public abstract void Randomize(IRandom random);
+    public abstract void Mutate(IRandom random, MutateDelegate mutate, IIntValueManipulator intValueManipulator, IDoubleValueManipulator doubleValueManipulator);
+    public abstract void Cross(IRandom random, IOptimizable other, CrossDelegate cross, IIntValueCrossover intValueCrossover, IDoubleValueCrossover doubleValueCrossover);
+    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();
   }
 }
