Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/HeuristicLab.Algorithms.MOCMAEvolutionStrategy-3.3.csproj
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/HeuristicLab.Algorithms.MOCMAEvolutionStrategy-3.3.csproj	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/HeuristicLab.Algorithms.MOCMAEvolutionStrategy-3.3.csproj	(revision 16171)
@@ -17,5 +17,5 @@
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
-    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <OutputPath>..\..\..\..\trunk\bin\</OutputPath>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
@@ -80,5 +80,6 @@
       <HintPath>..\..\..\..\trunk\bin\HeuristicLab.ALGLIB-3.7.0.dll</HintPath>
     </Reference>
-    <Reference Include="HeuristicLab.Collections-3.3">
+    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Collections-3.3.dll</HintPath>
     </Reference>
@@ -88,7 +89,4 @@
     <Reference Include="HeuristicLab.Core-3.3">
       <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Core-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Data-3.3">
-      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Data-3.3.dll</HintPath>
     </Reference>
     <Reference Include="HeuristicLab.Encodings.RealVectorEncoding-3.3">
@@ -131,4 +129,8 @@
       <Name>HeuristicLab.Analysis-3.3</Name>
     </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
+      <Project>{bbab9df5-5ef3-4ba8-ade9-b36e82114937}</Project>
+      <Name>HeuristicLab.Data-3.3</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
       <Project>{14ab8d24-25bc-400c-a846-4627aa945192}</Project>
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/IIndicator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/IIndicator.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/IIndicator.cs	(revision 16171)
@@ -34,5 +34,5 @@
     /// <param name="problem">The problem on which the front is evaluated (!! The function itself will NOT be evluated only bounds referencePoints & other metadata will be used</param>
     /// <returns>the index of the least contributing point according to any type of quality criteria</returns>
-    int LeastContributer(IReadOnlyList<Individual> front, MultiObjectiveBasicProblem<RealVectorEncoding> problem);
+    int LeastContributer(IReadOnlyList<Individual> front, IMultiObjectiveBasicProblem problem);
   }
 }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/CrowdingIndicator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/CrowdingIndicator.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/CrowdingIndicator.cs	(revision 16171)
@@ -28,4 +28,5 @@
 using HeuristicLab.Optimization;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.TestFunctions.MultiObjective;
 
 namespace HeuristicLab.Algorithms.MOCMAEvolutionStrategy {
@@ -41,23 +42,8 @@
     #endregion
 
-    public int LeastContributer(IReadOnlyList<Individual> front, MultiObjectiveBasicProblem<RealVectorEncoding> problem) {
-      var bounds = problem.Encoding.Bounds;
+    public int LeastContributer(IReadOnlyList<Individual> front, IMultiObjectiveBasicProblem problem) {
       var extracted = front.Select(x => x.PenalizedFitness).ToArray();
       if (extracted.Length <= 2) return 0;
-      var pointsums = new double[extracted.Length];
-
-      for (var dim = 0; dim < problem.Maximization.Length; dim++) {
-        var arr = extracted.Select(x => x[dim]).ToArray();
-        Array.Sort(arr);
-        var fmax = problem.Encoding.Bounds[dim % bounds.Rows, 1];
-        var fmin = bounds[dim % bounds.Rows, 0];
-        var pointIdx = 0;
-        foreach (var point in extracted) {
-          var pos = Array.BinarySearch(arr, point[dim]);
-          var d = pos != 0 && pos != arr.Length - 1 ? (arr[pos + 1] - arr[pos - 1]) / (fmax - fmin) : double.PositiveInfinity;
-          pointsums[pointIdx] += d;
-          pointIdx++;
-        }
-      }
+      var pointsums = CrowdingCalculator.CalculateCrowdingDistances(extracted);
       return pointsums.Select((value, index) => new { value, index }).OrderBy(x => x.value).First().index;
     }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/HypervolumeIndicator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/HypervolumeIndicator.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/HypervolumeIndicator.cs	(revision 16171)
@@ -30,5 +30,5 @@
 using HeuristicLab.Problems.TestFunctions.MultiObjective;
 namespace HeuristicLab.Algorithms.MOCMAEvolutionStrategy {
-  [Item("HypervolumeIndicator", "Selection of Offspring based on contributing Hypervolume")]
+  [Item("HypervolumeIndicator", "Selection of offspring based on contributing Hypervolume")]
   [StorableClass]
   internal class HypervolumeIndicator : Item, IIndicator {
@@ -41,9 +41,10 @@
     #endregion
 
-    public int LeastContributer(IReadOnlyList<Individual> front, MultiObjectiveBasicProblem<RealVectorEncoding> problem) {
+    public int LeastContributer(IReadOnlyList<Individual> front, IMultiObjectiveBasicProblem problem) {
       var frontCopy = front.Select(x => x.PenalizedFitness).ToList();
       if (frontCopy.Count <= 1) return 0;
       var p = problem as MultiObjectiveTestFunctionProblem;
-      var refPoint = BuildReferencePoint(p != null ? frontCopy.Concat(new[] { p.ReferencePoint.CloneAsArray() }) : frontCopy, problem.Maximization);
+      var tep = p != null ? frontCopy.Concat(new[] {p.ReferencePoint.CloneAsArray()}) : frontCopy;
+      var refPoint = HypervolumeCalculator.CalculateNadirPoint(tep, problem.Maximization);
       var contributions = Enumerable.Range(0, frontCopy.Count).Select(i => Contribution(frontCopy, i, problem.Maximization, refPoint));
       return contributions.Select((value, index) => new { value, index }).OrderBy(x => x.value).First().index;
@@ -54,14 +55,7 @@
       var point = front[idx];
       front.RemoveAt(idx);
-      var contribution = -Hypervolume.Calculate(front.ToArray(), refPoint, maximization);
+      var contribution = -HypervolumeCalculator.CalculateHypervolume(front.ToArray(), refPoint, maximization);
       front.Insert(idx, point);
       return contribution;
-    }
-    private static double[] BuildReferencePoint(IEnumerable<double[]> front, IReadOnlyList<bool> maximization) {
-      var refPoint = new double[maximization.Count];
-      foreach (var point in front)
-        for (var i = 0; i < maximization.Count; i++)
-          refPoint[i] = maximization[i] ? Math.Min(refPoint[i], point[i]) : Math.Max(refPoint[i], point[i]);
-      return refPoint;
     }
     #endregion
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/MinimalDistanceIndicator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/MinimalDistanceIndicator.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/MinimalDistanceIndicator.cs	(revision 16171)
@@ -42,5 +42,5 @@
     #endregion
 
-    public int LeastContributer(IReadOnlyList<Individual> front, MultiObjectiveBasicProblem<RealVectorEncoding> problem) {
+    public int LeastContributer(IReadOnlyList<Individual> front, IMultiObjectiveBasicProblem problem) {
       var extracted = front.Select(x => x.PenalizedFitness).ToArray();
       if (extracted.Length <= 2) return 0;
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/MOCMAEvolutionStrategy.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/MOCMAEvolutionStrategy.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/MOCMAEvolutionStrategy.cs	(revision 16171)
@@ -42,12 +42,20 @@
   public class MOCMAEvolutionStrategy : BasicAlgorithm {
     public override Type ProblemType {
-      get { return typeof(MultiObjectiveBasicProblem<RealVectorEncoding>); }
-    }
-    public new MultiObjectiveBasicProblem<RealVectorEncoding> Problem {
-      get { return (MultiObjectiveBasicProblem<RealVectorEncoding>)base.Problem; }
+      get { return typeof(IMultiObjectiveBasicProblem); }
+    }
+    public new IMultiObjectiveBasicProblem Problem {
+      get { return (IMultiObjectiveBasicProblem)base.Problem; }
       set { base.Problem = value; }
     }
     public override bool SupportsPause {
       get { return true; }
+    }
+
+    private RealVectorEncoding Encoding {
+      get {
+        if(Problem == null || !(Problem.Encoding is RealVectorEncoding))
+          throw new ArgumentException("Multiobjective CMA-ES is only applicable to problems with RealVectorEncodings");
+        return (RealVectorEncoding)Problem.Encoding;
+      }
     }
 
@@ -309,7 +317,7 @@
       solutions = new Individual[PopulationSize];
       for (var i = 0; i < PopulationSize; i++) {
-        var x = new RealVector(Problem.Encoding.Length); // Uniform distibution in all dimensions assumed.
-        var bounds = Problem.Encoding.Bounds;
-        for (var j = 0; j < Problem.Encoding.Length; j++) {
+        var x = new RealVector(Encoding.Length); // Uniform distibution in all dimensions assumed.
+        var bounds = Encoding.Bounds;
+        for (var j = 0; j < Encoding.Length; j++) {
           var dim = j % bounds.Rows;
           x[j] = random.NextDouble() * (bounds[dim, 1] - bounds[dim, 0]) + bounds[dim, 0];
@@ -322,5 +330,5 @@
     private void InitStrategy() {
       const int lambda = 1;
-      double n = Problem.Encoding.Length;
+      double n = Encoding.Length;
       targetSuccessProbability = 1.0 / (5.0 + Math.Sqrt(lambda) / 2.0);
       stepSizeDampeningFactor = 1.0 + n / (2.0 * lambda);
@@ -358,5 +366,5 @@
       if (problem == null) return;
       if (problem.BestKnownFront != null) {
-        ResultsBestKnownHypervolume = Hypervolume.Calculate(problem.BestKnownFront.ToJaggedArray(), problem.TestFunction.ReferencePoint(problem.Objectives), Problem.Maximization);
+        ResultsBestKnownHypervolume = HypervolumeCalculator.CalculateHypervolume(problem.BestKnownFront.ToJaggedArray(), problem.TestFunction.ReferencePoint(problem.Objectives), Problem.Maximization);
         ResultsDifferenceBestKnownHypervolume = ResultsBestKnownHypervolume;
       }
@@ -417,5 +425,5 @@
     }
     private RealVector ClosestFeasible(RealVector x) {
-      var bounds = Problem.Encoding.Bounds;
+      var bounds = Encoding.Bounds;
       var r = new RealVector(x.Length);
       for (var i = 0; i < x.Length; i++) {
@@ -426,5 +434,5 @@
     }
     private bool IsFeasable(RealVector offspring) {
-      var bounds = Problem.Encoding.Bounds;
+      var bounds = Encoding.Bounds;
       for (var i = 0; i < offspring.Length; i++) {
         var dim = i % bounds.Rows;
@@ -438,5 +446,5 @@
       //perform a nondominated sort to assign the rank to every element
       int[] ranks;
-      var fronts = DominationCalculator<Individual>.CalculateAllParetoFronts(parents.ToArray(), parents.Select(i => i.PenalizedFitness).ToArray(), Problem.Maximization, out ranks);
+      var fronts = DominationCalculator.CalculateAllParetoFronts(parents.ToArray(), parents.Select(i => i.PenalizedFitness).ToArray(), Problem.Maximization, out ranks);
 
       //deselect the highest rank fronts until we would end up with less or equal mu elements
@@ -470,5 +478,8 @@
 
     private void Analyze() {
-      ResultsScatterPlot = new ParetoFrontScatterPlot(solutions.Select(x => x.Fitness).ToArray(), solutions.Select(x => x.Mean.ToArray()).ToArray(), ResultsScatterPlot.ParetoFront, ResultsScatterPlot.Objectives, ResultsScatterPlot.ProblemSize);
+      var qualities = solutions.Select(x => x.Fitness).ToArray();
+
+      //to do check for side effects
+      ResultsScatterPlot = new ParetoFrontScatterPlot(qualities, solutions.Select(x => x.Mean.ToArray()).ToArray(), ResultsScatterPlot.ParetoFront, ResultsScatterPlot.Objectives, ResultsScatterPlot.ProblemSize);
       ResultsSolutions = solutions.Select(x => x.Mean.ToArray()).ToMatrix();
 
@@ -476,12 +487,11 @@
       if (problem == null) return;
 
-      var front = NonDominatedSelect.GetDominatingVectors(solutions.Select(x => x.Fitness), problem.ReferencePoint.CloneAsArray(), Problem.Maximization, true).ToArray();
-      if (front.Length == 0) return;
-      var bounds = problem.Bounds.CloneAsMatrix();
-      ResultsCrowding = Crowding.Calculate(front, bounds);
-      ResultsSpacing = Spacing.Calculate(front);
-      ResultsGenerationalDistance = problem.BestKnownFront != null ? GenerationalDistance.Calculate(front, problem.BestKnownFront.ToJaggedArray(), 1) : double.NaN;
-      ResultsInvertedGenerationalDistance = problem.BestKnownFront != null ? InvertedGenerationalDistance.Calculate(front, problem.BestKnownFront.ToJaggedArray(), 1) : double.NaN;
-      ResultsHypervolume = Hypervolume.Calculate(front, problem.ReferencePoint.CloneAsArray(), Problem.Maximization);
+      
+      if (qualities.Length == 0) return;
+      ResultsCrowding = CrowdingCalculator.CalculateCrowding(qualities);
+      ResultsSpacing = SpacingCalculator.CalculateSpacing(qualities);
+      ResultsGenerationalDistance = problem.BestKnownFront != null ? GenerationalDistanceCalculator.CalculateGenerationalDistance(qualities, problem.BestKnownFront.ToJaggedArray(), 1) : double.NaN;
+      ResultsInvertedGenerationalDistance = problem.BestKnownFront != null ? GenerationalDistanceCalculator.CalculateInverseGenerationalDistance(qualities, problem.BestKnownFront.ToJaggedArray(), 1) : double.NaN;
+      ResultsHypervolume = HypervolumeCalculator.CalculateHypervolume(qualities, problem.ReferencePoint.CloneAsArray(), Problem.Maximization);
       ResultsBestHypervolume = Math.Max(ResultsHypervolume, ResultsBestHypervolume);
       ResultsDifferenceBestKnownHypervolume = ResultsBestKnownHypervolume - ResultsBestHypervolume;
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 16171)
@@ -41,5 +41,5 @@
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
-    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <OutputPath>..\..\..\..\trunk\bin\</OutputPath>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
@@ -111,5 +111,6 @@
       <HintPath>..\..\..\..\trunk\bin\HeuristicLab.ALGLIB-3.7.0.dll</HintPath>
     </Reference>
-    <Reference Include="HeuristicLab.Collections-3.3">
+    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Collections-3.3.dll</HintPath>
     </Reference>
@@ -123,12 +124,6 @@
       <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Core-3.3.dll</HintPath>
     </Reference>
-    <Reference Include="HeuristicLab.Data-3.3">
-      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Data-3.3.dll</HintPath>
-    </Reference>
     <Reference Include="HeuristicLab.Operators-3.3">
       <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Operators-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Optimization.Operators-3.3">
-      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Optimization.Operators-3.3.dll</HintPath>
     </Reference>
     <Reference Include="HeuristicLab.Parameters-3.3">
@@ -235,4 +230,12 @@
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
+      <Project>{bbab9df5-5ef3-4ba8-ade9-b36e82114937}</Project>
+      <Name>HeuristicLab.Data-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization.Operators\3.3\HeuristicLab.Optimization.Operators-3.3.csproj">
+      <Project>{25087811-f74c-4128-bc86-8324271da13e}</Project>
+      <Name>HeuristicLab.Optimization.Operators-3.3</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
       <Project>{14ab8d24-25bc-400c-a846-4627aa945192}</Project>
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/BoolArray.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/BoolArray.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/BoolArray.cs	(revision 16171)
@@ -0,0 +1,70 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("BoolArray", "Represents an array of boolean values.")]
+  [StorableClass]
+  public class BoolArray : StringConvertibleArray<bool> {
+    [StorableConstructor]
+    protected BoolArray(bool deserializing) : base(deserializing) { }
+    protected BoolArray(BoolArray original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public BoolArray() : base() { }
+    public BoolArray(int length) : base(length) { }
+    public BoolArray(bool[] elements) : base(elements) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BoolArray(this, cloner);
+    }
+
+    protected override bool Validate(string value, out string errorMessage) {
+      bool val;
+      bool valid = bool.TryParse(value, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        StringBuilder sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetBoolFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    protected override string GetValue(int index) {
+      return this[index].ToString();
+    }
+    protected override bool SetValue(string value, int index) {
+      bool val;
+      if (bool.TryParse(value, out val)) {
+        this[index] = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/BoolMatrix.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/BoolMatrix.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/BoolMatrix.cs	(revision 16171)
@@ -0,0 +1,95 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("BoolMatrix", "Represents a matrix of boolean values.")]
+  [StorableClass]
+  public class BoolMatrix : ValueTypeMatrix<bool>, IStringConvertibleMatrix {
+    [StorableConstructor]
+    protected BoolMatrix(bool deserializing) : base(deserializing) { }
+    protected BoolMatrix(BoolMatrix original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public BoolMatrix() : base() { }
+    public BoolMatrix(int rows, int columns) : base(rows, columns) { }
+    public BoolMatrix(int rows, int columns, IEnumerable<string> columnNames) : base(rows, columns, columnNames) { }
+    public BoolMatrix(int rows, int columns, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(rows, columns, columnNames, rowNames) { }
+    public BoolMatrix(bool[,] elements) : base(elements) { }
+    public BoolMatrix(bool[,] elements, IEnumerable<string> columnNames) : base(elements, columnNames) { }
+    public BoolMatrix(bool[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(elements, columnNames, rowNames) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BoolMatrix(this, cloner);
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      bool val;
+      bool valid = bool.TryParse(value, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        StringBuilder sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetBoolFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    protected virtual string GetValue(int rowIndex, int columIndex) {
+      return this[rowIndex, columIndex].ToString();
+    }
+    protected virtual bool SetValue(string value, int rowIndex, int columnIndex) {
+      bool val;
+      if (bool.TryParse(value, out val)) {
+        this[rowIndex, columnIndex] = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region IStringConvertibleMatrix Members
+    int IStringConvertibleMatrix.Rows {
+      get { return Rows; }
+      set { Rows = value; }
+    }
+    int IStringConvertibleMatrix.Columns {
+      get { return Columns; }
+      set { Columns = value; }
+    }
+    bool IStringConvertibleMatrix.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleMatrix.GetValue(int rowIndex, int columIndex) {
+      return GetValue(rowIndex, columIndex);
+    }
+    bool IStringConvertibleMatrix.SetValue(string value, int rowIndex, int columnIndex) {
+      return SetValue(value, rowIndex, columnIndex);
+    }
+    #endregion
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/BoolValue.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/BoolValue.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/BoolValue.cs	(revision 16171)
@@ -0,0 +1,99 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Drawing;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("BoolValue", "Represents a boolean value.")]
+  [StorableClass]
+  public class BoolValue : ValueTypeValue<bool>, IComparable, IStringConvertibleValue {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Field; }
+    }
+
+    protected BoolValue(BoolValue original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public BoolValue() : base() { }
+    [StorableConstructor]
+    public BoolValue(bool value)
+      : base(value) {
+      //mkommend: Be aware that the base call refers to the storable ctor => the value is set explicitly in the ctor body.
+      //          This should not affect the persistence, because first the ctor is called and afterwards the values are set by reflection.
+      this.value = value;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BoolValue(this, cloner);
+    }
+
+    public virtual int CompareTo(object obj) {
+      BoolValue other = obj as BoolValue;
+      if (other != null)
+        return Value.CompareTo(other.Value);
+      else
+        return Value.CompareTo(obj);
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      bool val;
+      bool valid = bool.TryParse(value, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        StringBuilder sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetBoolFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    protected virtual string GetValue() {
+      return Value.ToString();
+    }
+    protected virtual bool SetValue(string value) {
+      bool val;
+      if (bool.TryParse(value, out val)) {
+        Value = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region IStringConvertibleValue Members
+    bool IStringConvertibleValue.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleValue.GetValue() {
+      return GetValue();
+    }
+    bool IStringConvertibleValue.SetValue(string value) {
+      return SetValue(value);
+    }
+    #endregion
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Comparison.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Comparison.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Comparison.cs	(revision 16171)
@@ -0,0 +1,56 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("Comparison", "Represents a comparison.")]
+  [StorableClass]
+  public class Comparison : ValueTypeValue<ComparisonType>, IComparable {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Enum; }
+    }
+
+    [StorableConstructor]
+    protected Comparison(bool deserializing) : base(deserializing) { }
+    protected Comparison(Comparison original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public Comparison() : base() { }
+    public Comparison(ComparisonType value) : base(value) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Comparison(this, cloner);
+    }
+
+    public virtual int CompareTo(object obj) {
+      Comparison other = obj as Comparison;
+      if (other != null)
+        return Value.CompareTo(other.Value);
+      else
+        return Value.CompareTo(obj);
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/ComparisonType.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/ComparisonType.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/ComparisonType.cs	(revision 16171)
@@ -0,0 +1,31 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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
+
+namespace HeuristicLab.Data {
+  public enum ComparisonType {
+    Less,
+    LessOrEqual,
+    Equal,
+    GreaterOrEqual,
+    Greater,
+    NotEqual
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/DateTimeValue.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/DateTimeValue.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/DateTimeValue.cs	(revision 16171)
@@ -0,0 +1,86 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("DateTimeValue", "Represents a date and time value.")]
+  [StorableClass]
+  public class DateTimeValue : ValueTypeValue<DateTime>, IComparable, IStringConvertibleValue {
+    [StorableConstructor]
+    protected DateTimeValue(bool deserializing) : base(deserializing) { }
+    protected DateTimeValue(DateTimeValue original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public DateTimeValue() : base() { }
+    public DateTimeValue(DateTime value) : base(value) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DateTimeValue(this, cloner);
+    }
+
+    public override string ToString() {
+      return Value.ToString("o");  // round-trip format
+    }
+
+    public virtual int CompareTo(object obj) {
+      DateTimeValue other = obj as DateTimeValue;
+      if (other != null)
+        return Value.CompareTo(other.Value);
+      else
+        return Value.CompareTo(obj);
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      DateTime val;
+      bool valid = DateTime.TryParse(value, out val);
+      errorMessage = valid ? string.Empty : "Invalid Value (values must be formatted according to the current culture settings)";
+      return valid;
+    }
+    protected virtual string GetValue() {
+      return Value.ToString("o");  // round-trip format
+    }
+    protected virtual bool SetValue(string value) {
+      DateTime val;
+      if (DateTime.TryParse(value, out val)) {
+        Value = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region IStringConvertibleValue Members
+    bool IStringConvertibleValue.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleValue.GetValue() {
+      return GetValue();
+    }
+    bool IStringConvertibleValue.SetValue(string value) {
+      return SetValue(value);
+    }
+    #endregion
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/DoubleArray.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/DoubleArray.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/DoubleArray.cs	(revision 16171)
@@ -0,0 +1,70 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("DoubleArray", "Represents an array of double values.")]
+  [StorableClass]
+  public class DoubleArray : StringConvertibleArray<double> {
+    [StorableConstructor]
+    protected DoubleArray(bool deserializing) : base(deserializing) { }
+    protected DoubleArray(DoubleArray original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public DoubleArray() : base() { }
+    public DoubleArray(int length) : base(length) { }
+    public DoubleArray(double[] elements) : base(elements) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DoubleArray(this, cloner);
+    }
+
+    protected override bool Validate(string value, out string errorMessage) {
+      double val;
+      bool valid = double.TryParse(value, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        StringBuilder sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetDoubleFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    protected override string GetValue(int index) {
+      return this[index].ToString("r");
+    }
+    protected override bool SetValue(string value, int index) {
+      double val;
+      if (double.TryParse(value, out val)) {
+        this[index] = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/DoubleMatrix.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/DoubleMatrix.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/DoubleMatrix.cs	(revision 16171)
@@ -0,0 +1,95 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("DoubleMatrix", "Represents a matrix of double values.")]
+  [StorableClass]
+  public class DoubleMatrix : ValueTypeMatrix<double>, IStringConvertibleMatrix {
+    [StorableConstructor]
+    protected DoubleMatrix(bool deserializing) : base(deserializing) { }
+    protected DoubleMatrix(DoubleMatrix original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public DoubleMatrix() : base() { }
+    public DoubleMatrix(int rows, int columns) : base(rows, columns) { }
+    public DoubleMatrix(int rows, int columns, IEnumerable<string> columnNames) : base(rows, columns, columnNames) { }
+    public DoubleMatrix(int rows, int columns, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(rows, columns, columnNames, rowNames) { }
+    public DoubleMatrix(double[,] elements) : base(elements) { }
+    public DoubleMatrix(double[,] elements, IEnumerable<string> columnNames) : base(elements, columnNames) { }
+    public DoubleMatrix(double[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(elements, columnNames, rowNames) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DoubleMatrix(this, cloner);
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      double val;
+      bool valid = double.TryParse(value, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        StringBuilder sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetDoubleFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    protected virtual string GetValue(int rowIndex, int columIndex) {
+      return this[rowIndex, columIndex].ToString("r");
+    }
+    protected virtual bool SetValue(string value, int rowIndex, int columnIndex) {
+      double val;
+      if (double.TryParse(value, out val)) {
+        this[rowIndex, columnIndex] = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region IStringConvertibleMatrix Members
+    int IStringConvertibleMatrix.Rows {
+      get { return Rows; }
+      set { Rows = value; }
+    }
+    int IStringConvertibleMatrix.Columns {
+      get { return Columns; }
+      set { Columns = value; }
+    }
+    bool IStringConvertibleMatrix.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleMatrix.GetValue(int rowIndex, int columIndex) {
+      return GetValue(rowIndex, columIndex);
+    }
+    bool IStringConvertibleMatrix.SetValue(string value, int rowIndex, int columnIndex) {
+      return SetValue(value, rowIndex, columnIndex);
+    }
+    #endregion
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/DoubleRange.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/DoubleRange.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/DoubleRange.cs	(revision 16171)
@@ -0,0 +1,68 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [StorableClass]
+  [Item("DoubleRange", "Represents a range of values betweent start and end.")]
+  public class DoubleRange : StringConvertibleValueTuple<DoubleValue, DoubleValue> {
+
+    public double Start {
+      get { return Item1.Value; }
+      set { Item1.Value = value; }
+    }
+    public double End {
+      get { return Item2.Value; }
+      set { Item2.Value = value; }
+    }
+    public double Size {
+      get { return End - Start; }
+    }
+
+    [StorableConstructor]
+    protected DoubleRange(bool deserializing) : base(deserializing) { }
+    protected DoubleRange(DoubleRange original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DoubleRange(this, cloner);
+    }
+
+    public DoubleRange() : base(new DoubleValue(), new DoubleValue()) { }
+    public DoubleRange(DoubleValue start, DoubleValue end) : base(start, end) { }
+    public DoubleRange(double start, double end) : base(new DoubleValue(start), new DoubleValue(end)) { }
+
+    public override string ToString() {
+      return string.Format("Start: {0:r}, End: {1:r}", Start, End);
+    }
+
+    public override StringConvertibleValueTuple<DoubleValue, DoubleValue> AsReadOnly() {
+      var readOnly = new DoubleRange();
+      readOnly.values = Tuple.Create<DoubleValue, DoubleValue>((DoubleValue)Item1.AsReadOnly(), (DoubleValue)Item2.AsReadOnly());
+      readOnly.readOnly = true;
+      return readOnly;
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/DoubleValue.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/DoubleValue.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/DoubleValue.cs	(revision 16171)
@@ -0,0 +1,99 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Drawing;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("DoubleValue", "Represents a double value.")]
+  [StorableClass]
+  public class DoubleValue : ValueTypeValue<double>, IComparable, IStringConvertibleValue {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Field; }
+    }
+
+    [StorableConstructor]
+    protected DoubleValue(bool deserializing) : base(deserializing) { }
+    protected DoubleValue(DoubleValue original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public DoubleValue() : base() { }
+    public DoubleValue(double value) : base(value) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DoubleValue(this, cloner);
+    }
+
+    public override string ToString() {
+      return Value.ToString("r");  // round-trip format
+    }
+
+    public virtual int CompareTo(object obj) {
+      DoubleValue other = obj as DoubleValue;
+      if (other != null)
+        return Value.CompareTo(other.Value);
+      else
+        return Value.CompareTo(obj);
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      double val;
+      bool valid = double.TryParse(value, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        StringBuilder sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetDoubleFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    protected virtual string GetValue() {
+      return Value.ToString("r");  // round-trip format
+    }
+    protected virtual bool SetValue(string value) {
+      double val;
+      if (double.TryParse(value, out val)) {
+        Value = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region IStringConvertibleValue Members
+    bool IStringConvertibleValue.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleValue.GetValue() {
+      return GetValue();
+    }
+    bool IStringConvertibleValue.SetValue(string value) {
+      return SetValue(value);
+    }
+    #endregion
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/EnumValue.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/EnumValue.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/EnumValue.cs	(revision 16171)
@@ -0,0 +1,64 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("EnumValue", "An abstract base class for representing values of enum types.")]
+  [StorableClass]
+  public sealed class EnumValue<T> : ValueTypeValue<T>, IComparable<EnumValue<T>> where T : struct, IComparable {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Enum; }
+    }
+
+    static EnumValue() {
+      if (!typeof(T).IsEnum)
+        throw new InvalidOperationException("Generic type " + typeof(T).Name + " is not an enum.");
+    }
+
+    public EnumValue() {
+      this.value = default(T);
+      this.readOnly = false;
+    }
+    public EnumValue(T value) {
+      this.value = value;
+      this.readOnly = false;
+    }
+
+    [StorableConstructor]
+    private EnumValue(bool deserializing) : base(deserializing) { }
+    private EnumValue(EnumValue<T> original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new EnumValue<T>(this, cloner);
+    }
+
+    public int CompareTo(EnumValue<T> other) {
+      return Value.CompareTo(other.Value);
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/FormatPatterns.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/FormatPatterns.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/FormatPatterns.cs	(revision 16171)
@@ -0,0 +1,56 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Globalization;
+using System.Text;
+
+namespace HeuristicLab.Data {
+  public static class FormatPatterns {
+    public static string GetBoolFormatPattern() {
+      StringBuilder sb = new StringBuilder();
+      sb.Append(bool.TrueString).Append(" | ").Append(bool.FalseString);
+      return sb.ToString();
+    }
+    public static string GetDoubleFormatPattern() {
+      StringBuilder sb = new StringBuilder();
+      NumberFormatInfo nf = CultureInfo.CurrentCulture.NumberFormat;
+      sb.Append(nf.PositiveInfinitySymbol).Append(" | ");
+      sb.Append(nf.NegativeInfinitySymbol).Append(" | ");
+      sb.Append(nf.NaNSymbol).Append(" | ");
+      sb.Append("[").Append(nf.PositiveSign).Append(" | ").Append(nf.NegativeSign).Append("]");
+      sb.Append("digits[").Append(nf.NumberDecimalSeparator).Append("[digits]]");
+      sb.Append("[(e | E)");
+      sb.Append("[").Append(nf.PositiveSign).Append(" | ").Append(nf.NegativeSign).Append("]");
+      sb.Append("digits]");
+      return sb.ToString();
+    }
+    public static string GetIntFormatPattern() {
+      StringBuilder sb = new StringBuilder();
+      NumberFormatInfo nf = CultureInfo.CurrentCulture.NumberFormat;
+      sb.Append("[").Append(nf.PositiveSign).Append(" | ").Append(nf.NegativeSign).Append("]");
+      sb.Append("digits");
+      return sb.ToString();
+    }
+    public static string GetTimeSpanFormatPattern() {
+      return "[-](d | d.hh:mm[:ss[.ff]] | hh:mm[:ss[.ff]])";
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/HeuristicLab.Data-3.3.csproj
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/HeuristicLab.Data-3.3.csproj	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/HeuristicLab.Data-3.3.csproj	(revision 16171)
@@ -0,0 +1,239 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Data</RootNamespace>
+    <AssemblyName>HeuristicLab.Data-3.3</AssemblyName>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <IsWebBootstrapper>true</IsWebBootstrapper>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+    <PublishUrl>http://localhost/HeuristicLab.Data/</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Web</InstallFrom>
+    <UpdateEnabled>true</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\..\trunk\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>
+    </DocumentationFile>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>
+    </DocumentationFile>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Common-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Core-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Plugin.cs.frame" />
+    <Compile Include="BoolArray.cs" />
+    <Compile Include="BoolMatrix.cs" />
+    <Compile Include="BoolValue.cs" />
+    <Compile Include="Comparison.cs" />
+    <Compile Include="ComparisonType.cs" />
+    <Compile Include="EnumValue.cs" />
+    <Compile Include="Interfaces\IValueTypeArray.cs" />
+    <Compile Include="Path Types\DirectoryValue.cs" />
+    <Compile Include="Path Types\FileValue.cs" />
+    <Compile Include="Path Types\PathValue.cs" />
+    <Compile Include="Path Types\TextFileValue.cs" />
+    <Compile Include="PercentMatrix.cs" />
+    <Compile Include="PercentArray.cs" />
+    <Compile Include="DoubleRange.cs" />
+    <Compile Include="IntRange.cs" />
+    <Compile Include="Interfaces\IStringConvertibleValueTuple.cs" />
+    <Compile Include="PercentValue.cs" />
+    <Compile Include="DateTimeValue.cs" />
+    <Compile Include="DoubleArray.cs" />
+    <Compile Include="DoubleMatrix.cs" />
+    <Compile Include="DoubleValue.cs" />
+    <Compile Include="FormatPatterns.cs" />
+    <Compile Include="IntArray.cs" />
+    <Compile Include="IntMatrix.cs" />
+    <Compile Include="IntValue.cs" />
+    <Compile Include="Interfaces\IStringConvertibleArray.cs" />
+    <Compile Include="Interfaces\IStringConvertibleMatrix.cs" />
+    <Compile Include="Interfaces\IStringConvertibleValue.cs" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="StringArray.cs" />
+    <Compile Include="StringConvertibleArray.cs" />
+    <Compile Include="StringMatrix.cs" />
+    <Compile Include="StringValue.cs" />
+    <Compile Include="TimeSpanValue.cs" />
+    <Compile Include="TriangularMatrix.cs" />
+    <Compile Include="ValueTypeArray.cs" />
+    <Compile Include="ValueTypeMatrix.cs" />
+    <Compile Include="StringConvertibleValueTuple.cs" />
+    <Compile Include="ValueTypeValue.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <PropertyGroup>
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd
+</PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/IntArray.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/IntArray.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/IntArray.cs	(revision 16171)
@@ -0,0 +1,70 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("IntArray", "Represents an array of integer values.")]
+  [StorableClass]
+  public class IntArray : StringConvertibleArray<int> {
+    [StorableConstructor]
+    protected IntArray(bool deserializing) : base(deserializing) { }
+    protected IntArray(IntArray original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public IntArray() : base() { }
+    public IntArray(int length) : base(length) { }
+    public IntArray(int[] elements) : base(elements) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new IntArray(this, cloner);
+    }
+
+    protected override bool Validate(string value, out string errorMessage) {
+      int val;
+      bool valid = int.TryParse(value, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        StringBuilder sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetIntFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    protected override string GetValue(int index) {
+      return this[index].ToString();
+    }
+    protected override bool SetValue(string value, int index) {
+      int val;
+      if (int.TryParse(value, out val)) {
+        this[index] = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/IntMatrix.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/IntMatrix.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/IntMatrix.cs	(revision 16171)
@@ -0,0 +1,95 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("IntMatrix", "Represents a matrix of integer values.")]
+  [StorableClass]
+  public class IntMatrix : ValueTypeMatrix<int>, IStringConvertibleMatrix {
+    [StorableConstructor]
+    protected IntMatrix(bool deserializing) : base(deserializing) { }
+    protected IntMatrix(IntMatrix original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public IntMatrix() : base() { }
+    public IntMatrix(int rows, int columns) : base(rows, columns) { }
+    public IntMatrix(int rows, int columns, IEnumerable<string> columnNames) : base(rows, columns, columnNames) { }
+    public IntMatrix(int rows, int columns, IEnumerable<string> columnNames,IEnumerable<string> rowNames) : base(rows, columns, columnNames,rowNames) { }
+    public IntMatrix(int[,] elements) : base(elements) { }
+    public IntMatrix(int[,] elements, IEnumerable<string> columnNames) : base(elements,columnNames) { }
+    public IntMatrix(int[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(elements,columnNames,rowNames) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new IntMatrix(this, cloner);
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      int val;
+      bool valid = int.TryParse(value, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        StringBuilder sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetIntFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    protected virtual string GetValue(int rowIndex, int columIndex) {
+      return this[rowIndex, columIndex].ToString();
+    }
+    protected virtual bool SetValue(string value, int rowIndex, int columnIndex) {
+      int val;
+      if (int.TryParse(value, out val)) {
+        this[rowIndex, columnIndex] = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region IStringConvertibleMatrix Members
+    int IStringConvertibleMatrix.Rows {
+      get { return Rows; }
+      set { Rows = value; }
+    }
+    int IStringConvertibleMatrix.Columns {
+      get { return Columns; }
+      set { Columns = value; }
+    }
+    bool IStringConvertibleMatrix.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleMatrix.GetValue(int rowIndex, int columIndex) {
+      return GetValue(rowIndex, columIndex);
+    }
+    bool IStringConvertibleMatrix.SetValue(string value, int rowIndex, int columnIndex) {
+      return SetValue(value, rowIndex, columnIndex);
+    }
+    #endregion
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/IntRange.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/IntRange.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/IntRange.cs	(revision 16171)
@@ -0,0 +1,68 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [StorableClass]
+  [Item("IntRange", "Represents a range of values betweent start and end.")]
+  public class IntRange : StringConvertibleValueTuple<IntValue, IntValue> {
+
+    public int Start {
+      get { return Item1.Value; }
+      set { Item1.Value = value; }
+    }
+    public int End {
+      get { return Item2.Value; }
+      set { Item2.Value = value; }
+    }
+    public int Size {
+      get { return End - Start; }
+    }
+
+    [StorableConstructor]
+    protected IntRange(bool deserializing) : base(deserializing) { }
+    protected IntRange(IntRange original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new IntRange(this, cloner);
+    }
+
+    public IntRange() : base(new IntValue(), new IntValue()) { }
+    public IntRange(IntValue start, IntValue end) : base(start, end) { }
+    public IntRange(int start, int end) : base(new IntValue(start), new IntValue(end)) { }
+
+    public override string ToString() {
+      return string.Format("Start: {0}, End: {1}", Start, End);
+    }
+
+    public override StringConvertibleValueTuple<IntValue, IntValue> AsReadOnly() {
+      var readOnly = new IntRange();
+      readOnly.values = Tuple.Create<IntValue, IntValue>((IntValue)Item1.AsReadOnly(), (IntValue)Item2.AsReadOnly());
+      readOnly.readOnly = true;
+      return readOnly;
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/IntValue.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/IntValue.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/IntValue.cs	(revision 16171)
@@ -0,0 +1,95 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Drawing;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("IntValue", "Represents an integer value.")]
+  [StorableClass]
+  public class IntValue : ValueTypeValue<int>, IComparable, IStringConvertibleValue {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Field; }
+    }
+
+    [StorableConstructor]
+    protected IntValue(bool deserializing) : base(deserializing) { }
+    protected IntValue(IntValue original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public IntValue() : base() { }
+    public IntValue(int value) : base(value) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new IntValue(this, cloner);
+    }
+
+    public virtual int CompareTo(object obj) {
+      IntValue other = obj as IntValue;
+      if (other != null)
+        return Value.CompareTo(other.Value);
+      else
+        return Value.CompareTo(obj);
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      int val;
+      bool valid = int.TryParse(value, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        StringBuilder sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetIntFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    protected virtual string GetValue() {
+      return Value.ToString();
+    }
+    protected virtual bool SetValue(string value) {
+      int val;
+      if (int.TryParse(value, out val)) {
+        Value = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region IStringConvertibleValue Members
+    bool IStringConvertibleValue.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleValue.GetValue() {
+      return GetValue();
+    }
+    bool IStringConvertibleValue.SetValue(string value) {
+      return SetValue(value);
+    }
+    #endregion
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleArray.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleArray.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleArray.cs	(revision 16171)
@@ -0,0 +1,30 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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;
+
+namespace HeuristicLab.Data {
+  public interface IStringConvertibleArray : IContent, IValueTypeArray {
+    bool Validate(string value, out string errorMessage);
+    string GetValue(int index);
+    bool SetValue(string value, int index);
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleMatrix.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleMatrix.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleMatrix.cs	(revision 16171)
@@ -0,0 +1,49 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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;
+
+namespace HeuristicLab.Data {
+  public interface IStringConvertibleMatrix : IContent {
+    int Rows { get; set; }
+    int Columns { get; set; }
+    IEnumerable<string> ColumnNames { get; set; }
+    IEnumerable<string> RowNames { get; set; }
+
+    bool SortableView { get; set; }
+    bool ReadOnly { get; }
+
+    bool Validate(string value, out string errorMessage);
+    string GetValue(int rowIndex, int columnIndex);
+    bool SetValue(string value, int rowIndex, int columnIndex);
+
+    event EventHandler ColumnsChanged;
+    event EventHandler RowsChanged;
+    event EventHandler ColumnNamesChanged;
+    event EventHandler RowNamesChanged;
+    event EventHandler SortableViewChanged;
+    event EventHandler<EventArgs<int, int>> ItemChanged;
+    event EventHandler Reset;
+
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleValue.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleValue.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleValue.cs	(revision 16171)
@@ -0,0 +1,35 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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;
+
+namespace HeuristicLab.Data {
+  public interface IStringConvertibleValue : IContent {
+    bool ReadOnly { get; }
+
+    bool Validate(string value, out string errorMessage);
+    string GetValue();
+    bool SetValue(string value);
+
+    event EventHandler ValueChanged;
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleValueTuple.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleValueTuple.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Interfaces/IStringConvertibleValueTuple.cs	(revision 16171)
@@ -0,0 +1,28 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Data {
+  public interface IStringConvertibleValueTuple : IItem {
+    IStringConvertibleValue Item1 { get; }
+    IStringConvertibleValue Item2 { get; }
+    bool ReadOnly { get; }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Interfaces/IValueTypeArray.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Interfaces/IValueTypeArray.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Interfaces/IValueTypeArray.cs	(revision 16171)
@@ -0,0 +1,51 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Common;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Data {
+  public interface IValueTypeArray : IItem, IEnumerable {
+    bool ReadOnly { get; }
+    IValueTypeArray AsReadOnly();
+
+    int Length { get; set; }
+    bool Resizable { get; set; }
+    event EventHandler ResizableChanged;
+
+    IEnumerable<string> ElementNames { get; set; }
+    event EventHandler ElementNamesChanged;
+
+    event EventHandler<EventArgs<int>> ItemChanged;
+    event EventHandler Reset;
+  }
+
+  public interface IValueTypeArray<T> : IValueTypeArray, IReadOnlyList<T> where T : struct {
+    new T this[int index] { get; set; }
+  }
+}
+
+
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Path Types/DirectoryValue.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Path Types/DirectoryValue.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Path Types/DirectoryValue.cs	(revision 16171)
@@ -0,0 +1,45 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.IO;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("DirectoryValue", "Represents the path to a directory.")]
+  [StorableClass]
+  public class DirectoryValue : PathValue {
+    [StorableConstructor]
+    protected DirectoryValue(bool deserializing) : base(deserializing) { }
+    protected DirectoryValue(DirectoryValue original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DirectoryValue(this, cloner);
+    }
+
+    public DirectoryValue() : base() { }
+
+    public override bool Exists() {
+      if (!Path.IsPathRooted(Value)) return false;
+      return Directory.Exists(Value);
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Path Types/FileValue.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Path Types/FileValue.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Path Types/FileValue.cs	(revision 16171)
@@ -0,0 +1,63 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.IO;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("FileValue", "Represents the path to a file.")]
+  [StorableClass]
+  public class FileValue : PathValue {
+    [Storable]
+    private string fileDialogFilter;
+    public string FileDialogFilter {
+      get { return fileDialogFilter; }
+      set {
+        if (fileDialogFilter != value) {
+          fileDialogFilter = value;
+        }
+      }
+    }
+
+    [StorableConstructor]
+    protected FileValue(bool deserializing) : base(deserializing) { }
+    protected FileValue(FileValue original, Cloner cloner)
+      : base(original, cloner) {
+      fileDialogFilter = original.FileDialogFilter;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new FileValue(this, cloner);
+    }
+
+    public FileValue()
+      : base() {
+      fileDialogFilter = @"All files|*.*";
+    }
+
+    public override bool Exists() {
+      if (string.IsNullOrEmpty(Value)) return false;
+      if (string.IsNullOrEmpty(Path.GetDirectoryName(Value))) return false;
+      return File.Exists(Value);
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Path Types/PathValue.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Path Types/PathValue.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Path Types/PathValue.cs	(revision 16171)
@@ -0,0 +1,71 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.IO;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("PathValue", "Represents a path.")]
+  [StorableClass]
+  public abstract class PathValue : Item {
+
+    [Storable]
+    private readonly StringValue stringValue = new StringValue();
+    public StringValue StringValue {
+      get { return stringValue; }
+    }
+
+    public string Value {
+      get { return stringValue.Value; }
+      set {
+        if (value == null) value = string.Empty;
+        value = value.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
+        stringValue.Value = value;
+      }
+    }
+
+    [StorableConstructor]
+    protected PathValue(bool deserializing) : base(deserializing) { }
+    protected PathValue(PathValue original, Cloner cloner)
+      : base(original, cloner) {
+      stringValue = cloner.Clone(original.stringValue);
+    }
+
+    protected PathValue()
+      : base() {
+      stringValue.ToStringChanged += (o, e) => OnToStringChanged();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      stringValue.ToStringChanged += (o, e) => OnToStringChanged();
+    }
+
+    public abstract bool Exists();
+
+    public override string ToString() {
+      return stringValue.ToString();
+    }
+
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Path Types/TextFileValue.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Path Types/TextFileValue.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Path Types/TextFileValue.cs	(revision 16171)
@@ -0,0 +1,43 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("TextFile", "Represents the content and path to a text file.")]
+  [StorableClass]
+  public class TextFileValue : FileValue {
+    [StorableConstructor]
+    protected TextFileValue(bool deserializing) : base(deserializing) { }
+    protected TextFileValue(TextFileValue original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TextFileValue(this, cloner);
+    }
+
+    public TextFileValue()
+      : base() {
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/PercentArray.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/PercentArray.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/PercentArray.cs	(revision 16171)
@@ -0,0 +1,80 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("PercentArray", "Represents an array of double values in percent.")]
+  [StorableClass]
+  public class PercentArray : DoubleArray {
+    [StorableConstructor]
+    protected PercentArray(bool deserializing) : base(deserializing) { }
+    protected PercentArray(PercentArray original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public PercentArray() : base() { }
+    public PercentArray(int length) : base(length) { }
+    public PercentArray(double[] elements) : base(elements) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PercentArray(this, cloner);
+    }
+
+    public override string ToString() {
+      StringBuilder sb = new StringBuilder();
+      sb.Append("[");
+      if (array.Length > 0) {
+        sb.Append(array[0].ToString("#0.#################### %"));  // percent format
+        for (int i = 1; i < array.Length; i++)
+          sb.Append(";").Append(array[i].ToString("#0.#################### %"));  // percent format
+      }
+      sb.Append("]");
+      return sb.ToString();
+    }
+
+    protected override bool Validate(string value, out string errorMessage) {
+      value = value.Replace("%", " ");
+      return base.Validate(value, out errorMessage);
+    }
+    protected override string GetValue(int index) {
+      return this[index].ToString("#0.#################### %");  // percent format
+    }
+    protected override bool SetValue(string value, int index) {
+      bool percent = value.Contains("%");
+      value = value.Replace("%", " ");
+      double val;
+      if (double.TryParse(value, out val)) {
+        if (percent) {
+          if (!(val).IsAlmost(this[index] * 100.0))
+            this[index] = val == 0 ? 0 : val / 100.0;
+        } else {
+          this[index] = val;
+        }
+        return true;
+      } else {
+        return false;
+      }
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/PercentMatrix.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/PercentMatrix.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/PercentMatrix.cs	(revision 16171)
@@ -0,0 +1,88 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("PercentMatrix", "Represents a matrix of double values in percent.")]
+  [StorableClass]
+  public class PercentMatrix : DoubleMatrix {
+    [StorableConstructor]
+    protected PercentMatrix(bool deserializing) : base(deserializing) { }
+    protected PercentMatrix(PercentMatrix original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public PercentMatrix() : base() { }
+    public PercentMatrix(int rows, int columns) : base(rows, columns) { }
+    public PercentMatrix(int rows, int columns, IEnumerable<string> columnNames) : base(rows, columns, columnNames) { }
+    public PercentMatrix(int rows, int columns, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(rows, columns, columnNames, rowNames) { }
+    public PercentMatrix(double[,] elements) : base(elements) { }
+    public PercentMatrix(double[,] elements, IEnumerable<string> columnNames) : base(elements, columnNames) { }
+    public PercentMatrix(double[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames) : base(elements, columnNames, rowNames) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PercentMatrix(this, cloner);
+    }
+
+    public override string ToString() {
+      StringBuilder sb = new StringBuilder();
+      sb.Append("[");
+      if (matrix.Length > 0) {
+        for (int i = 0; i < Rows; i++) {
+          sb.Append("[").Append(matrix[i, 0].ToString("#0.#################### %"));  // percent format
+          for (int j = 1; j < Columns; j++)
+            sb.Append(";").Append(matrix[i, j].ToString("#0.#################### %"));  // percent format
+          sb.Append("]");
+        }
+      }
+      sb.Append("]");
+      return sb.ToString();
+    }
+
+    protected override bool Validate(string value, out string errorMessage) {
+      value = value.Replace("%", " ");
+      return base.Validate(value, out errorMessage);
+    }
+    protected override string GetValue(int rowIndex, int columIndex) {
+      return this[rowIndex, columIndex].ToString("#0.#################### %");  // percent format
+    }
+    protected override bool SetValue(string value, int rowIndex, int columnIndex) {
+      bool percent = value.Contains("%");
+      value = value.Replace("%", " ");
+      double val;
+      if (double.TryParse(value, out val)) {
+        if (percent) {
+          if (!(val).IsAlmost(this[rowIndex, columnIndex] * 100.0))
+            this[rowIndex, columnIndex] = val == 0 ? 0 : val / 100.0;
+        } else {
+          this[rowIndex, columnIndex] = val;
+        }
+        return true;
+      } else {
+        return false;
+      }
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/PercentValue.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/PercentValue.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/PercentValue.cs	(revision 16171)
@@ -0,0 +1,104 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("PercentValue", "Represents a double value in percent.")]
+  [StorableClass]
+  public class PercentValue : DoubleValue {
+    [Storable(DefaultValue = false)]
+    private bool restrictToUnitInterval = false;
+    public bool RestrictToUnitInterval {
+      get { return restrictToUnitInterval; }
+    }
+
+    public override double Value {
+      get { return base.Value; }
+      set {
+        if (restrictToUnitInterval && (value < 0 || value > 1))
+          throw new ArgumentException("Value must lie in the interval [0,1].");
+        base.Value = value;
+      }
+    }
+
+    [StorableConstructor]
+    protected PercentValue(bool deserializing) : base(deserializing) { }
+    protected PercentValue(PercentValue original, Cloner cloner)
+      : base(original, cloner) {
+      restrictToUnitInterval = original.restrictToUnitInterval;
+    }
+    public PercentValue() : base() { }
+    public PercentValue(double value) : base(value) { }
+
+    public PercentValue(double value, bool restrictToUnitInterval)
+      : base() {
+      this.restrictToUnitInterval = restrictToUnitInterval;
+      if (restrictToUnitInterval && (value < 0 || value > 1))
+        throw new ArgumentException("Value must lie in the interval [0,1].");
+      this.value = value;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PercentValue(this, cloner);
+    }
+
+    public override string ToString() {
+      return Value.ToString("#0.#################### %");  // percent format
+    }
+
+    protected override bool Validate(string value, out string errorMessage) {
+      value = value.Replace("%", " ");
+      bool valid = base.Validate(value, out errorMessage);
+      if (!restrictToUnitInterval || !valid) return valid;
+
+      double val = double.Parse(value);
+      if (val < 0 || val > 1) {
+        errorMessage = "Value must lie in the interval [0,1].";
+        return false;
+      }
+      return true;
+    }
+
+    protected override string GetValue() {
+      return Value.ToString("#0.#################### %");  // percent format
+    }
+    protected override bool SetValue(string value) {
+      bool percent = value.Contains("%");
+      value = value.Replace("%", " ");
+      double val;
+      if (double.TryParse(value, out val)) {
+        if (percent) {
+          if (!(val).IsAlmost(Value * 100.0))
+            Value = val == 0 ? 0 : val / 100.0;
+        } else {
+          Value = val;
+        }
+        return true;
+      } else {
+        return false;
+      }
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Plugin.cs.frame
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Plugin.cs.frame	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Plugin.cs.frame	(revision 16171)
@@ -0,0 +1,36 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.PluginInfrastructure;
+
+namespace HeuristicLab.Data {
+  /// <summary>
+  /// Plugin class for HeuristicLab.Data plugin.
+  /// </summary>
+  [Plugin("HeuristicLab.Data", "3.3.15.$WCREV$")]
+  [PluginFile("HeuristicLab.Data-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  public class HeuristicLabDataPlugin : PluginBase {
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Properties/AssemblyInfo.cs.frame	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/Properties/AssemblyInfo.cs.frame	(revision 16171)
@@ -0,0 +1,56 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.Data")]
+[assembly: AssemblyDescription("HeuristicLab data classes")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2018 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("f1be1f44-c421-4749-9d25-160611dc18b3")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.15.$WCREV$")]
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/StringArray.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/StringArray.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/StringArray.cs	(revision 16171)
@@ -0,0 +1,239 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("StringArray", "Represents an array of strings.")]
+  [StorableClass]
+  public class StringArray : Item, IEnumerable<string>, IStringConvertibleArray {
+    private const int maximumToStringLength = 100;
+
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Class; }
+    }
+
+    [Storable]
+    protected string[] array;
+
+    [Storable]
+    protected List<string> elementNames;
+    public virtual IEnumerable<string> ElementNames {
+      get { return this.elementNames; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("ElementNames cannot be set. ValueTypeArray is read-only.");
+        if (value == null || !value.Any())
+          elementNames = new List<string>();
+        else if (value.Count() > Length)
+          throw new ArgumentException("The number of element names must not exceed the array length.");
+        else
+          elementNames = new List<string>(value);
+        OnElementNamesChanged();
+      }
+    }
+
+    public virtual int Length {
+      get { return array.Length; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("Length cannot be set. StringArray is read-only.");
+        if (value != Length) {
+          Array.Resize<string>(ref array, value);
+          while (elementNames.Count > value)
+            elementNames.RemoveAt(elementNames.Count - 1);
+          OnElementNamesChanged();
+          OnReset();
+        }
+      }
+    }
+    [Storable]
+    protected bool resizable = true;
+    public bool Resizable {
+      get { return resizable; }
+      set {
+        if (resizable != value) {
+          resizable = value;
+          OnResizableChanged();
+        }
+      }
+    }
+
+    public virtual string this[int index] {
+      get { return array[index]; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("Item cannot be set. StringArray is read-only.");
+        if (value != array[index]) {
+          if ((value != null) || (array[index] != string.Empty)) {
+            array[index] = value != null ? value : string.Empty;
+            OnItemChanged(index);
+          }
+        }
+      }
+    }
+
+    [Storable]
+    protected bool readOnly;
+    public virtual bool ReadOnly {
+      get { return readOnly; }
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (elementNames == null) { elementNames = new List<string>(); }
+    }
+
+    [StorableConstructor]
+    protected StringArray(bool deserializing) : base(deserializing) { }
+    protected StringArray(StringArray original, Cloner cloner)
+      : base(original, cloner) {
+      this.array = (string[])original.array.Clone();
+      this.readOnly = original.readOnly;
+      this.resizable = original.resizable;
+      this.elementNames = new List<string>(original.elementNames);
+    }
+    public StringArray() {
+      array = new string[0];
+      readOnly = false;
+      resizable = true;
+      elementNames = new List<string>();
+    }
+    public StringArray(int length) {
+      array = new string[length];
+      for (int i = 0; i < array.Length; i++)
+        array[i] = string.Empty;
+      readOnly = false;
+      resizable = true;
+      elementNames = new List<string>();
+    }
+    public StringArray(string[] elements) {
+      if (elements == null) throw new ArgumentNullException();
+      array = new string[elements.Length];
+      for (int i = 0; i < array.Length; i++)
+        array[i] = elements[i] == null ? string.Empty : elements[i];
+      readOnly = false;
+      resizable = true;
+      elementNames = new List<string>();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new StringArray(this, cloner);
+    }
+
+    public virtual StringArray AsReadOnly() {
+      StringArray readOnlyStringArray = (StringArray)this.Clone();
+      readOnlyStringArray.readOnly = true;
+      return readOnlyStringArray;
+    }
+    IValueTypeArray IValueTypeArray.AsReadOnly() {
+      return AsReadOnly();
+    }
+
+    public override string ToString() {
+      if (array.Length == 0) return "[]";
+
+      StringBuilder sb = new StringBuilder();
+      sb.Append("[");
+      sb.Append(array[0]);
+      for (int i = 1; i < array.Length; i++) {
+        sb.Append(";").Append(array[i]);
+        if (sb.Length > maximumToStringLength) {
+          sb.Append("...");
+          break;
+        }
+      }
+      sb.Append("]");
+      return sb.ToString();
+    }
+
+    public virtual IEnumerator<string> GetEnumerator() {
+      return array.Cast<string>().GetEnumerator();
+    }
+    IEnumerator IEnumerable.GetEnumerator() {
+      return GetEnumerator();
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      if (value == null) {
+        errorMessage = "Invalid Value (string must not be null)";
+        return false;
+      } else {
+        errorMessage = string.Empty;
+        return true;
+      }
+    }
+    protected virtual string GetValue(int index) {
+      return this[index];
+    }
+    protected virtual bool SetValue(string value, int index) {
+      if (value != null) {
+        this[index] = value;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    public event EventHandler ResizableChanged;
+    protected virtual void OnResizableChanged() {
+      EventHandler handler = ResizableChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ElementNamesChanged;
+    protected virtual void OnElementNamesChanged() {
+      EventHandler handler = ElementNamesChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler<EventArgs<int>> ItemChanged;
+    protected virtual void OnItemChanged(int index) {
+      if (ItemChanged != null)
+        ItemChanged(this, new EventArgs<int>(index));
+      if (index < maximumToStringLength)
+        OnToStringChanged();
+    }
+    public event EventHandler Reset;
+    protected virtual void OnReset() {
+      if (Reset != null)
+        Reset(this, EventArgs.Empty);
+      OnToStringChanged();
+    }
+
+    #region IStringConvertibleArray Members
+    bool IStringConvertibleArray.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleArray.GetValue(int index) {
+      return GetValue(index);
+    }
+    bool IStringConvertibleArray.SetValue(string value, int index) {
+      return SetValue(value, index);
+    }
+    #endregion
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/StringConvertibleArray.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/StringConvertibleArray.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/StringConvertibleArray.cs	(revision 16171)
@@ -0,0 +1,57 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("StringConvertibleArray", "Represents an array of string convertible values.")]
+  [StorableClass]
+  public abstract class StringConvertibleArray<T> : ValueTypeArray<T>, IStringConvertibleArray where T : struct {
+    [StorableConstructor]
+    protected StringConvertibleArray(bool deserializing) : base(deserializing) { }
+    protected StringConvertibleArray(StringConvertibleArray<T> original, Cloner cloner)
+      : base(original, cloner) { }
+
+    protected StringConvertibleArray() : base() { }
+    protected StringConvertibleArray(int length) : base(length) { }
+    protected StringConvertibleArray(T[] elements) : base(elements) { }
+
+    protected abstract bool Validate(string value, out string errorMessage);
+    protected abstract string GetValue(int index);
+    protected abstract bool SetValue(string value, int index);
+
+    #region IStringConvertibleArray Members
+    bool IStringConvertibleArray.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleArray.GetValue(int index) {
+      return GetValue(index);
+    }
+    bool IStringConvertibleArray.SetValue(string value, int index) {
+      return SetValue(value, index);
+    }
+    #endregion
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/StringConvertibleValueTuple.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/StringConvertibleValueTuple.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/StringConvertibleValueTuple.cs	(revision 16171)
@@ -0,0 +1,99 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [StorableClass]
+  [Item("StringConvertibleValueTuple<,>", "A generic abstract base class for representing multiple values of a string convertible value.")]
+  public abstract class StringConvertibleValueTuple<T, U> : Item, IStringConvertibleValueTuple
+    where T : class, IDeepCloneable, IStringConvertibleValue
+    where U : class, IDeepCloneable, IStringConvertibleValue {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.ValueType; }
+    }
+
+    [Storable]
+    protected bool readOnly;
+    public virtual bool ReadOnly {
+      get { return readOnly; }
+    }
+
+    [Storable(Name = "Values")]
+    protected Tuple<T, U> values;
+
+    protected T Item1 { get { return values.Item1; } }
+    IStringConvertibleValue IStringConvertibleValueTuple.Item1 { get { return Item1; } }
+    protected U Item2 { get { return values.Item2; } }
+    IStringConvertibleValue IStringConvertibleValueTuple.Item2 { get { return Item2; } }
+
+    [StorableConstructor]
+    protected StringConvertibleValueTuple(bool deserializing)
+      : base(deserializing) {
+    }
+    protected StringConvertibleValueTuple(StringConvertibleValueTuple<T, U> original, Cloner cloner)
+      : base(original, cloner) {
+      T item1 = (T)cloner.Clone(original.values.Item1);
+      U item2 = (U)cloner.Clone(original.values.Item2);
+      values = Tuple.Create<T, U>(item1, item2);
+      RegisterEventHandler();
+    }
+
+    public StringConvertibleValueTuple(T item1, U item2)
+      : base() {
+      values = Tuple.Create<T, U>(item1, item2);
+      readOnly = false;
+      RegisterEventHandler();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEventHandler();
+    }
+
+
+    public abstract StringConvertibleValueTuple<T, U> AsReadOnly();
+
+    public override string ToString() {
+      return string.Format("Item1: {0}, Item2: {1}", Item1, Item2);
+    }
+
+    private void RegisterEventHandler() {
+      Item1.ValueChanged += Item_ValueChanged;
+      Item2.ValueChanged += Item_ValueChanged;
+    }
+
+    private void Item_ValueChanged(object sender, EventArgs e) {
+      OnValueChanged();
+    }
+
+    public event EventHandler ValueChanged;
+    protected virtual void OnValueChanged() {
+      if (ValueChanged != null)
+        ValueChanged(this, EventArgs.Empty);
+      OnToStringChanged();
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/StringMatrix.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/StringMatrix.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/StringMatrix.cs	(revision 16171)
@@ -0,0 +1,330 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("StringMatrix", "Represents a matrix of strings.")]
+  [StorableClass]
+  public class StringMatrix : Item, IEnumerable<string>, IStringConvertibleMatrix {
+    private const int maximumToStringLength = 100;
+
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Class; }
+    }
+
+    [Storable]
+    protected string[,] matrix;
+
+    [Storable]
+    protected List<string> columnNames;
+    public virtual IEnumerable<string> ColumnNames {
+      get { return this.columnNames; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("ColumnNames cannot be set. StringMatrix is read-only.");
+        if (value == null || value.Count() == 0)
+          columnNames = new List<string>();
+        else if (value.Count() != Columns)
+          throw new ArgumentException("A column name must be specified for each column .");
+        else
+          columnNames = new List<string>(value);
+        OnColumnNamesChanged();
+      }
+    }
+    [Storable]
+    protected List<string> rowNames;
+    public virtual IEnumerable<string> RowNames {
+      get { return this.rowNames; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("RowNames cannot be set. StringMatrix is read-only.");
+        if (value == null || value.Count() == 0)
+          rowNames = new List<string>();
+        else if (value.Count() != Rows)
+          throw new ArgumentException("A row name must be specified for each row.");
+        else
+          rowNames = new List<string>(value);
+        OnRowNamesChanged();
+      }
+    }
+    [Storable]
+    protected bool sortableView;
+    public virtual bool SortableView {
+      get { return sortableView; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("SortableView cannot be set. StringMatrix is read-only.");
+        if (value != sortableView) {
+          sortableView = value;
+          OnSortableViewChanged();
+        }
+      }
+    }
+
+    public virtual int Rows {
+      get { return matrix.GetLength(0); }
+      protected set {
+        if (ReadOnly) throw new NotSupportedException("Rows cannot be set. StringMatrix is read-only.");
+        if (value != Rows) {
+          string[,] newMatrix = new string[value, Columns];
+          Array.Copy(matrix, newMatrix, Math.Min(value * Columns, matrix.Length));
+          matrix = newMatrix;
+          while (rowNames.Count > value)
+            rowNames.RemoveAt(rowNames.Count - 1);
+          while (rowNames.Count < value)
+            rowNames.Add("Row " + rowNames.Count);
+          OnRowsChanged();
+          OnRowNamesChanged();
+          OnReset();
+        }
+      }
+    }
+    public virtual int Columns {
+      get { return matrix.GetLength(1); }
+      protected set {
+        if (ReadOnly) throw new NotSupportedException("Columns cannot be set. StringMatrix is read-only.");
+        if (value != Columns) {
+          string[,] newMatrix = new string[Rows, value];
+          for (int i = 0; i < Rows; i++)
+            Array.Copy(matrix, i * Columns, newMatrix, i * value, Math.Min(value, Columns));
+          matrix = newMatrix;
+          while (columnNames.Count > value)
+            columnNames.RemoveAt(columnNames.Count - 1);
+          while (columnNames.Count < value)
+            columnNames.Add("Column " + columnNames.Count);
+          OnColumnsChanged();
+          OnColumnNamesChanged();
+          OnReset();
+        }
+      }
+    }
+    public virtual string this[int rowIndex, int columnIndex] {
+      get { return matrix[rowIndex, columnIndex]; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("Item cannot be set. StringMatrix is read-only.");
+        if (value != matrix[rowIndex, columnIndex]) {
+          if ((value != null) || (matrix[rowIndex, columnIndex] != string.Empty)) {
+            matrix[rowIndex, columnIndex] = value != null ? value : string.Empty;
+            OnItemChanged(rowIndex, columnIndex);
+          }
+        }
+      }
+    }
+
+    [Storable]
+    protected bool readOnly;
+    public virtual bool ReadOnly {
+      get { return readOnly; }
+    }
+
+    [StorableConstructor]
+    protected StringMatrix(bool deserializing) : base(deserializing) { }
+    protected StringMatrix(StringMatrix original, Cloner cloner)
+      : base(original, cloner) {
+      this.matrix = (string[,])original.matrix.Clone();
+      this.columnNames = new List<string>(original.columnNames);
+      this.rowNames = new List<string>(original.rowNames);
+      this.sortableView = original.sortableView;
+      this.readOnly = original.readOnly;
+    }
+    public StringMatrix() {
+      matrix = new string[0, 0];
+      columnNames = new List<string>();
+      rowNames = new List<string>();
+      sortableView = false;
+      readOnly = false;
+    }
+    public StringMatrix(int rows, int columns) {
+      matrix = new string[rows, columns];
+      for (int i = 0; i < matrix.GetLength(0); i++) {
+        for (int j = 0; j < matrix.GetLength(1); j++)
+          matrix[i, j] = string.Empty;
+      }
+      columnNames = new List<string>();
+      rowNames = new List<string>();
+      sortableView = false;
+      readOnly = false;
+    }
+    protected StringMatrix(int rows, int columns, IEnumerable<string> columnNames)
+      : this(rows, columns) {
+      ColumnNames = columnNames;
+    }
+    protected StringMatrix(int rows, int columns, IEnumerable<string> columnNames, IEnumerable<string> rowNames)
+      : this(rows, columns, columnNames) {
+      RowNames = rowNames;
+    }
+    public StringMatrix(string[,] elements) {
+      if (elements == null) throw new ArgumentNullException();
+      matrix = new string[elements.GetLength(0), elements.GetLength(1)];
+      for (int i = 0; i < matrix.GetLength(0); i++) {
+        for (int j = 0; j < matrix.GetLength(1); j++)
+          matrix[i, j] = elements[i, j] == null ? string.Empty : elements[i, j];
+      }
+      columnNames = new List<string>();
+      rowNames = new List<string>();
+      sortableView = false;
+      readOnly = false;
+    }
+    protected StringMatrix(string[,] elements, IEnumerable<string> columnNames)
+      : this(elements) {
+      ColumnNames = columnNames;
+    }
+    protected StringMatrix(string[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames)
+      : this(elements, columnNames) {
+      RowNames = rowNames;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new StringMatrix(this, cloner);
+    }
+
+    public virtual StringMatrix AsReadOnly() {
+      StringMatrix readOnlyStringMatrix = (StringMatrix)this.Clone();
+      readOnlyStringMatrix.readOnly = true;
+      return readOnlyStringMatrix;
+    }
+
+    public override string ToString() {
+      if (matrix.Length == 0) return "[]";
+
+      StringBuilder sb = new StringBuilder();
+      sb.Append("[");
+      for (int i = 0; i < Rows; i++) {
+        sb.Append("[").Append(matrix[i, 0]);
+        for (int j = 1; j < Columns; j++)
+          sb.Append(";").Append(matrix[i, j]);
+        sb.Append("]");
+
+        if (sb.Length > maximumToStringLength) {
+          sb.Append("[...]");
+          break;
+        }
+      }
+      sb.Append("]");
+
+      return sb.ToString();
+    }
+
+    public virtual IEnumerator<string> GetEnumerator() {
+      return matrix.Cast<string>().GetEnumerator();
+    }
+
+    IEnumerator IEnumerable.GetEnumerator() {
+      return GetEnumerator();
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      if (value == null) {
+        errorMessage = "Invalid Value (string must not be null)";
+        return false;
+      } else {
+        errorMessage = string.Empty;
+        return true;
+      }
+    }
+    protected virtual string GetValue(int rowIndex, int columIndex) {
+      return this[rowIndex, columIndex];
+    }
+    protected virtual bool SetValue(string value, int rowIndex, int columnIndex) {
+      if (value != null) {
+        this[rowIndex, columnIndex] = value;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region events
+    public event EventHandler ColumnsChanged;
+    protected virtual void OnColumnsChanged() {
+      EventHandler handler = ColumnsChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler RowsChanged;
+    protected virtual void OnRowsChanged() {
+      EventHandler handler = RowsChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ColumnNamesChanged;
+    protected virtual void OnColumnNamesChanged() {
+      EventHandler handler = ColumnNamesChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler RowNamesChanged;
+    protected virtual void OnRowNamesChanged() {
+      EventHandler handler = RowNamesChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler SortableViewChanged;
+    protected virtual void OnSortableViewChanged() {
+      EventHandler handler = SortableViewChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler<EventArgs<int, int>> ItemChanged;
+    protected virtual void OnItemChanged(int rowIndex, int columnIndex) {
+      if (ItemChanged != null)
+        ItemChanged(this, new EventArgs<int, int>(rowIndex, columnIndex));
+
+      //approximation to avoid firing of unnecessary ToStringChangedEvents
+      //columnIndex is not used, because always full rows are returned in the ToString method
+      if (rowIndex * Columns < maximumToStringLength)
+        OnToStringChanged();
+    }
+    public event EventHandler Reset;
+    protected virtual void OnReset() {
+      if (Reset != null)
+        Reset(this, EventArgs.Empty);
+      OnToStringChanged();
+    }
+    #endregion
+
+    #region IStringConvertibleMatrix Members
+    int IStringConvertibleMatrix.Rows {
+      get { return Rows; }
+      set { Rows = value; }
+    }
+    int IStringConvertibleMatrix.Columns {
+      get { return Columns; }
+      set { Columns = value; }
+    }
+    bool IStringConvertibleMatrix.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleMatrix.GetValue(int rowIndex, int columIndex) {
+      return GetValue(rowIndex, columIndex);
+    }
+    bool IStringConvertibleMatrix.SetValue(string value, int rowIndex, int columnIndex) {
+      return SetValue(value, rowIndex, columnIndex);
+    }
+    #endregion
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/StringValue.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/StringValue.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/StringValue.cs	(revision 16171)
@@ -0,0 +1,135 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("StringValue", "Represents a string.")]
+  [StorableClass]
+  public class StringValue : Item, IComparable, IStringConvertibleValue {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Field; }
+    }
+
+    [Storable]
+    protected string value;
+    public virtual string Value {
+      get { return value; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("Value cannot be set. StringValue is read-only.");
+        if (value != this.value) {
+          if ((value != null) || (this.value != string.Empty)) {
+            this.value = value != null ? value : string.Empty;
+            OnValueChanged();
+          }
+        }
+      }
+    }
+
+    [Storable]
+    protected bool readOnly;
+    public virtual bool ReadOnly {
+      get { return readOnly; }
+    }
+
+    [StorableConstructor]
+    protected StringValue(bool deserializing) : base(deserializing) { }
+    protected StringValue(StringValue original, Cloner cloner)
+      : base(original, cloner) {
+      this.value = original.value != null ? original.value : string.Empty;
+      this.readOnly = original.readOnly;
+    }
+    public StringValue() {
+      this.value = string.Empty;
+      this.readOnly = false;
+    }
+    public StringValue(string value) {
+      this.value = value != null ? value : string.Empty;
+      this.readOnly = false;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new StringValue(this, cloner);
+    }
+
+    public virtual StringValue AsReadOnly() {
+      StringValue readOnlyStringValue = (StringValue)this.Clone();
+      readOnlyStringValue.readOnly = true;
+      return readOnlyStringValue;
+    }
+
+    public override string ToString() {
+      return value;
+    }
+
+    public virtual int CompareTo(object obj) {
+      StringValue other = obj as StringValue;
+      if (other != null)
+        return Value.CompareTo(other.Value);
+      else
+        return Value.CompareTo(obj);
+    }
+
+    public event EventHandler ValueChanged;
+    protected virtual void OnValueChanged() {
+      if (ValueChanged != null)
+        ValueChanged(this, EventArgs.Empty);
+      OnToStringChanged();
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      if (value == null) {
+        errorMessage = "Invalid Value (string must not be null)";
+        return false;
+      } else {
+        errorMessage = string.Empty;
+        return true;
+      }
+    }
+    protected virtual string GetValue() {
+      return Value;
+    }
+    protected virtual bool SetValue(string value) {
+      if (value != null) {
+        Value = value;
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    #region IStringConvertibleValue Members
+    bool IStringConvertibleValue.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleValue.GetValue() {
+      return GetValue();
+    }
+    bool IStringConvertibleValue.SetValue(string value) {
+      return SetValue(value);
+    }
+    #endregion
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/TimeSpanValue.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/TimeSpanValue.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/TimeSpanValue.cs	(revision 16171)
@@ -0,0 +1,94 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Globalization;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("TimeSpanValue", "Represents a duration of time.")]
+  [StorableClass]
+  public class TimeSpanValue : ValueTypeValue<TimeSpan>, IComparable, IStringConvertibleValue {
+    [StorableConstructor]
+    protected TimeSpanValue(bool deserializing) : base(deserializing) { }
+    protected TimeSpanValue(TimeSpanValue original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public TimeSpanValue() : base() { }
+    public TimeSpanValue(TimeSpan value) : base(value) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TimeSpanValue(this, cloner);
+    }
+
+    public virtual int CompareTo(object obj) {
+      TimeSpanValue other = obj as TimeSpanValue;
+      if (other != null)
+        return Value.CompareTo(other.Value);
+      else
+        return Value.CompareTo(obj);
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      TimeSpan val;
+      bool valid = TimeSpan.TryParseExact(value, "c", CultureInfo.CurrentCulture, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        StringBuilder sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetTimeSpanFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    protected virtual string GetValue() {
+      return Value.ToString("c");
+    }
+    protected virtual bool SetValue(string value) {
+      TimeSpan val;
+      if (TimeSpan.TryParseExact(value, "c", CultureInfo.CurrentCulture, out val)) {
+        Value = val;
+        return true;
+      } else {
+        return false;
+      }
+    }
+    public override string ToString() {
+      return Value.ToString("c");
+    }
+
+    #region IStringConvertibleValue Members
+    bool IStringConvertibleValue.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    string IStringConvertibleValue.GetValue() {
+      return GetValue();
+    }
+    bool IStringConvertibleValue.SetValue(string value) {
+      return SetValue(value);
+    }
+    #endregion
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/TriangularMatrix.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/TriangularMatrix.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/TriangularMatrix.cs	(revision 16171)
@@ -0,0 +1,212 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("TriangularMatrix", "Represents a lower triangular matrix.")]
+  [StorableClass]
+  public class TriangularMatrix<T> : ValueTypeMatrix<T>, IStringConvertibleMatrix where T : struct {
+    [Storable]
+    private readonly T[] storage;
+
+    private readonly int dimension;
+    private readonly long capacity;
+
+    private TriangularMatrix() { }
+
+    public TriangularMatrix(int dimension) {
+      this.dimension = dimension;
+      capacity = (long)dimension * (dimension + 1) / 2;
+      storage = new T[capacity];
+
+      readOnly = true;
+    }
+
+    [StorableConstructor]
+    protected TriangularMatrix(bool deserializing) : base(deserializing) { }
+
+    protected TriangularMatrix(TriangularMatrix<T> original, Cloner cloner) : base(original, cloner) {
+      capacity = original.capacity;
+      dimension = original.dimension;
+      storage = (T[])original.storage.Clone();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TriangularMatrix<T>(this, cloner);
+    }
+
+    public override int Rows {
+      get { return dimension; }
+      protected set { throw new NotSupportedException(); }
+    }
+
+    public override int Columns {
+      get { return dimension; }
+      protected set { throw new NotSupportedException(); }
+    }
+
+    public int Length { get { return storage.Length; } }
+
+    // the indexing rule for the (lower-)triangular matrix is that always i <= j, otherwise an IndexOutOfBounds exception will occur 
+    public override T this[int rowIndex, int columnIndex] {
+      get {
+        // provide symmetry of returned values 
+        if (columnIndex > rowIndex) return this[columnIndex, rowIndex];
+        return storage[rowIndex * (rowIndex + 1) / 2 + columnIndex];
+      }
+      set {
+        if (columnIndex > rowIndex) this[columnIndex, rowIndex] = value;
+        else storage[rowIndex * (rowIndex + 1) / 2 + columnIndex] = value;
+      }
+    }
+
+    public T this[int index] {
+      get { return storage[index]; }
+      set { storage[index] = value; }
+    }
+
+    protected virtual string GetValue(int rowIndex, int columnIndex) {
+      return this[rowIndex, columnIndex].ToString(); // see above indexing rule
+    }
+
+    protected virtual bool SetValue(string value, int rowIndex, int columnIndex) {
+      T val;
+      if (!TryParse(value, out val))
+        return false;
+      this[rowIndex, columnIndex] = val;
+      return true;
+    }
+
+    protected virtual bool Validate(string value, out string errorMessage) {
+      T val;
+      errorMessage = "";
+      if (!TryParse(value, out val)) {
+        errorMessage = string.Format("Could not parse string \"{0}\" as {1}.", value, typeof(T));
+        return false;
+      }
+      return true;
+    }
+
+    public override IEnumerator<T> GetEnumerator() {
+      return storage.Cast<T>().GetEnumerator();
+    }
+
+    private static bool TryParse(string value, out T val) {
+      if (typeof(T) == typeof(sbyte)) {
+        sbyte v;
+        if (sbyte.TryParse(value, out v)) {
+          val = (T)(object)v;
+          return true;
+        }
+      } else if (typeof(T) == typeof(byte)) {
+        byte v;
+        if (byte.TryParse(value, out v)) {
+          val = (T)(object)v;
+          return true;
+        }
+      } else if (typeof(T) == typeof(char)) {
+        char v;
+        if (char.TryParse(value, out v)) {
+          val = (T)(object)v;
+          return true;
+        }
+      } else if (typeof(T) == typeof(short)) {
+        short v;
+        if (short.TryParse(value, out v)) {
+          val = (T)(object)v;
+          return true;
+        }
+      } else if (typeof(T) == typeof(ushort)) {
+        ushort v;
+        if (ushort.TryParse(value, out v)) {
+          val = (T)(object)v;
+          return true;
+        }
+      } else if (typeof(T) == typeof(int)) {
+        int v;
+        if (int.TryParse(value, out v)) {
+          val = (T)(object)v;
+          return true;
+        }
+      } else if (typeof(T) == typeof(uint)) {
+        uint v;
+        if (uint.TryParse(value, out v)) {
+          val = (T)(object)v;
+          return true;
+        }
+      } else if (typeof(T) == typeof(long)) {
+        long v;
+        if (long.TryParse(value, out v)) {
+          val = (T)(object)v;
+          return true;
+        }
+      } else if (typeof(T) == typeof(ulong)) {
+        ulong v;
+        if (ulong.TryParse(value, out v)) {
+          val = (T)(object)v;
+          return true;
+        }
+      }
+      val = default(T);
+      return false;
+    }
+
+    public void GetMatrixCoordinates(int index, out int row, out int col) {
+      var root = TriangularRoot(index);
+      row = (int)Math.Floor(root);
+      col = index - row * (row + 1) / 2;
+    }
+
+    private static double TriangularRoot(double x) {
+      return (Math.Sqrt(8 * x + 1) - 1) / 2;
+    }
+
+    #region IStringConvertibleMatrix Members
+    int IStringConvertibleMatrix.Rows {
+      get { return dimension; }
+      set { throw new NotSupportedException("The triangular matrix does not support changing the number of rows."); }
+    }
+
+    int IStringConvertibleMatrix.Columns {
+      get { return dimension; }
+      set { throw new NotSupportedException("The triangular matrix does not support changing the number of columns."); }
+    }
+
+    string IStringConvertibleMatrix.GetValue(int rowIndex, int columnIndex) {
+      return GetValue(rowIndex, columnIndex);
+    }
+
+    bool IStringConvertibleMatrix.SetValue(string value, int rowIndex, int columnIndex) {
+      return SetValue(value, rowIndex, columnIndex);
+    }
+
+    bool IStringConvertibleMatrix.Validate(string value, out string errorMessage) {
+      return Validate(value, out errorMessage);
+    }
+    #endregion
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/ValueTypeArray.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/ValueTypeArray.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/ValueTypeArray.cs	(revision 16171)
@@ -0,0 +1,210 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("ValueTypeArray", "An abstract base class for representing arrays of value types.")]
+  [StorableClass]
+  public abstract class ValueTypeArray<T> : Item, IValueTypeArray<T> where T : struct {
+    private const int maximumToStringLength = 100;
+
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Class; }
+    }
+
+    [Storable]
+    protected T[] array;
+
+    [Storable]
+    protected List<string> elementNames;
+    public virtual IEnumerable<string> ElementNames {
+      get { return this.elementNames; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("ElementNames cannot be set. ValueTypeArray is read-only.");
+        if (value == null || !value.Any())
+          elementNames = new List<string>();
+        else if (value.Count() > Length)
+          throw new ArgumentException("The number of element names must not exceed the array length.");
+        else
+          elementNames = new List<string>(value);
+        OnElementNamesChanged();
+      }
+    }
+
+    public virtual int Length {
+      get { return array.Length; }
+      #region Mono Compatibility
+      // this setter should be protected, but the Mono compiler couldn't handle it
+      set {
+        if (ReadOnly) throw new NotSupportedException("Length cannot be set. ValueTypeArray is read-only.");
+        if (value != Length) {
+          Array.Resize<T>(ref array, value);
+          while (elementNames.Count > value)
+            elementNames.RemoveAt(elementNames.Count - 1);
+          OnElementNamesChanged();
+          OnReset();
+        }
+      }
+      #endregion
+    }
+
+    public int Count
+    {
+      get { return Length; }
+    }
+
+    [Storable]
+    protected bool resizable = true;
+    public bool Resizable {
+      get { return resizable; }
+      set {
+        if (resizable != value) {
+          resizable = value;
+          OnResizableChanged();
+        }
+      }
+    }
+
+
+    public virtual T this[int index] {
+      get { return array[index]; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("Item cannot be set. ValueTypeArray is read-only.");
+        if (!value.Equals(array[index])) {
+          array[index] = value;
+          OnItemChanged(index);
+        }
+      }
+    }
+
+    [Storable]
+    protected bool readOnly;
+    public virtual bool ReadOnly {
+      get { return readOnly; }
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (elementNames == null) { elementNames = new List<string>(); }
+    }
+
+    [StorableConstructor]
+    protected ValueTypeArray(bool deserializing) : base(deserializing) { }
+    protected ValueTypeArray(ValueTypeArray<T> original, Cloner cloner)
+      : base(original, cloner) {
+      this.array = (T[])original.array.Clone();
+      this.readOnly = original.readOnly;
+      this.resizable = original.resizable;
+      this.elementNames = new List<string>(original.elementNames);
+    }
+    protected ValueTypeArray() {
+      array = new T[0];
+      readOnly = false;
+      resizable = true;
+      elementNames = new List<string>();
+    }
+    protected ValueTypeArray(int length) {
+      array = new T[length];
+      readOnly = false;
+      resizable = true;
+      elementNames = new List<string>();
+    }
+    protected ValueTypeArray(T[] elements) {
+      if (elements == null) throw new ArgumentNullException();
+      array = (T[])elements.Clone();
+      readOnly = false;
+      resizable = true;
+      elementNames = new List<string>();
+    }
+
+    public virtual IValueTypeArray AsReadOnly() {
+      ValueTypeArray<T> readOnlyValueTypeArray = (ValueTypeArray<T>)this.Clone();
+      readOnlyValueTypeArray.readOnly = true;
+      return readOnlyValueTypeArray;
+    }
+
+    public T[] CloneAsArray() {
+      //mkommend: this works because T must be a value type (struct constraint);
+      return (T[])array.Clone();
+    }
+
+    public override string ToString() {
+      if (array.Length == 0) return "[]";
+
+      StringBuilder sb = new StringBuilder();
+      sb.Append("[");
+      sb.Append(array[0].ToString());
+      for (int i = 1; i < array.Length; i++) {
+        sb.Append(";").Append(array[i].ToString());
+        if (sb.Length > maximumToStringLength) {
+          sb.Append("...");
+          break;
+        }
+      }
+      sb.Append("]");
+      return sb.ToString();
+    }
+
+    public virtual IEnumerator<T> GetEnumerator() {
+      return array.Cast<T>().GetEnumerator();
+    }
+
+    IEnumerator IEnumerable.GetEnumerator() {
+      return GetEnumerator();
+    }
+
+    public event EventHandler ResizableChanged;
+    protected virtual void OnResizableChanged() {
+      EventHandler handler = ResizableChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ElementNamesChanged;
+    protected virtual void OnElementNamesChanged() {
+      EventHandler handler = ElementNamesChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler<EventArgs<int>> ItemChanged;
+    protected virtual void OnItemChanged(int index) {
+      if (ItemChanged != null)
+        ItemChanged(this, new EventArgs<int>(index));
+      if (index < maximumToStringLength)
+        OnToStringChanged();
+    }
+    public event EventHandler Reset;
+    protected virtual void OnReset() {
+      if (Reset != null)
+        Reset(this, EventArgs.Empty);
+      OnToStringChanged();
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/ValueTypeMatrix.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/ValueTypeMatrix.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/ValueTypeMatrix.cs	(revision 16171)
@@ -0,0 +1,293 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("ValueTypeMatrix", "An abstract base class for representing matrices of value types.")]
+  [StorableClass]
+  public abstract class ValueTypeMatrix<T> : Item, IEnumerable<T> where T : struct {
+    private const int maximumToStringLength = 100;
+
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Class; }
+    }
+
+    [Storable]
+    protected T[,] matrix;
+
+    [Storable]
+    protected List<string> columnNames;
+    public virtual IEnumerable<string> ColumnNames {
+      get { return this.columnNames; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("ColumnNames cannot be set. ValueTypeMatrix is read-only.");
+        if (value == null || value.Count() == 0)
+          columnNames = new List<string>();
+        else if (value.Count() != Columns)
+          throw new ArgumentException("A column name must be specified for each column.");
+        else
+          columnNames = new List<string>(value);
+        OnColumnNamesChanged();
+      }
+    }
+    [Storable]
+    protected List<string> rowNames;
+    public virtual IEnumerable<string> RowNames {
+      get { return this.rowNames; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("RowNames cannot be set. ValueTypeMatrix is read-only.");
+        if (value == null || value.Count() == 0)
+          rowNames = new List<string>();
+        else if (value.Count() != Rows)
+          throw new ArgumentException("A row name must be specified for each row.");
+        else
+          rowNames = new List<string>(value);
+        OnRowNamesChanged();
+      }
+    }
+    [Storable]
+    protected bool sortableView;
+    public virtual bool SortableView {
+      get { return sortableView; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("SortableView cannot be set. ValueTypeMatrix is read-only.");
+        if (value != sortableView) {
+          sortableView = value;
+          OnSortableViewChanged();
+        }
+      }
+    }
+
+    public virtual int Rows {
+      get { return matrix.GetLength(0); }
+      protected set {
+        if (ReadOnly) throw new NotSupportedException("Rows cannot be set. ValueTypeMatrix is read-only.");
+        if (value != Rows) {
+          T[,] newArray = new T[value, Columns];
+          Array.Copy(matrix, newArray, Math.Min(value * Columns, matrix.Length));
+          matrix = newArray;
+          while (rowNames.Count > value)
+            rowNames.RemoveAt(rowNames.Count - 1);
+          while (rowNames.Count < value)
+            rowNames.Add("Row " + rowNames.Count);
+          OnRowsChanged();
+          OnRowNamesChanged();
+          OnReset();
+        }
+      }
+    }
+    public virtual int Columns {
+      get { return matrix.GetLength(1); }
+      protected set {
+        if (ReadOnly) throw new NotSupportedException("Columns cannot be set. ValueTypeMatrix is read-only.");
+        if (value != Columns) {
+          T[,] newArray = new T[Rows, value];
+          for (int i = 0; i < Rows; i++)
+            Array.Copy(matrix, i * Columns, newArray, i * value, Math.Min(value, Columns));
+          matrix = newArray;
+          while (columnNames.Count > value)
+            columnNames.RemoveAt(columnNames.Count - 1);
+          while (columnNames.Count < value)
+            columnNames.Add("Column " + columnNames.Count);
+          OnColumnsChanged();
+          OnColumnNamesChanged();
+          OnReset();
+        }
+      }
+    }
+    public virtual T this[int rowIndex, int columnIndex] {
+      get { return matrix[rowIndex, columnIndex]; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("Item cannot be set. ValueTypeMatrix is read-only.");
+        if (!value.Equals(matrix[rowIndex, columnIndex])) {
+          matrix[rowIndex, columnIndex] = value;
+          OnItemChanged(rowIndex, columnIndex);
+        }
+      }
+    }
+
+    [Storable]
+    protected bool readOnly;
+    public virtual bool ReadOnly {
+      get { return readOnly; }
+    }
+
+    [StorableConstructor]
+    protected ValueTypeMatrix(bool deserializing) : base(deserializing) { }
+    protected ValueTypeMatrix(ValueTypeMatrix<T> original, Cloner cloner)
+      : base(original, cloner) {
+      this.matrix = (T[,])original.matrix.Clone();
+      this.columnNames = new List<string>(original.columnNames);
+      this.rowNames = new List<string>(original.rowNames);
+      this.sortableView = original.sortableView;
+      this.readOnly = original.readOnly;
+    }
+    protected ValueTypeMatrix() {
+      matrix = new T[0, 0];
+      columnNames = new List<string>();
+      rowNames = new List<string>();
+      sortableView = false;
+      readOnly = false;
+    }
+    protected ValueTypeMatrix(int rows, int columns) {
+      matrix = new T[rows, columns];
+      columnNames = new List<string>();
+      rowNames = new List<string>();
+      sortableView = false;
+      readOnly = false;
+    }
+    protected ValueTypeMatrix(int rows, int columns, IEnumerable<string> columnNames)
+      : this(rows, columns) {
+      ColumnNames = columnNames;
+    }
+    protected ValueTypeMatrix(int rows, int columns, IEnumerable<string> columnNames, IEnumerable<string> rowNames)
+      : this(rows, columns, columnNames) {
+      RowNames = rowNames;
+    }
+    protected ValueTypeMatrix(T[,] elements) {
+      if (elements == null) throw new ArgumentNullException();
+      matrix = (T[,])elements.Clone();
+      columnNames = new List<string>();
+      rowNames = new List<string>();
+      sortableView = false;
+      readOnly = false;
+    }
+    protected ValueTypeMatrix(T[,] elements, IEnumerable<string> columnNames)
+      : this(elements) {
+      ColumnNames = columnNames;
+    }
+    protected ValueTypeMatrix(T[,] elements, IEnumerable<string> columnNames, IEnumerable<string> rowNames)
+      : this(elements, columnNames) {
+      RowNames = rowNames;
+    }
+
+    public virtual ValueTypeMatrix<T> AsReadOnly() {
+      ValueTypeMatrix<T> readOnlyValueTypeMatrix = (ValueTypeMatrix<T>)this.Clone();
+      readOnlyValueTypeMatrix.readOnly = true;
+      return readOnlyValueTypeMatrix;
+    }
+
+   
+    public T[,] CloneAsMatrix() {
+      //mkommend: this works because T must be a value type (struct constraint);
+      return (T[,])matrix.Clone();
+    }
+
+    public virtual IEnumerable<T> GetRow(int row) {
+      for (var col = 0; col < Columns; col++) {
+        yield return matrix[row, col];
+      }
+    }
+
+    public virtual IEnumerable<T> GetColumn(int col) {
+      for (var row = 0; row < Rows; row++) {
+        yield return matrix[row, col];
+      }
+    }
+
+    public override string ToString() {
+      if (matrix.Length == 0) return "[]";
+
+      StringBuilder sb = new StringBuilder();
+      sb.Append("[");
+      for (int i = 0; i < Rows; i++) {
+        sb.Append("[").Append(matrix[i, 0].ToString());
+        for (int j = 1; j < Columns; j++)
+          sb.Append(";").Append(matrix[i, j].ToString());
+        sb.Append("]");
+
+        if (sb.Length > maximumToStringLength) {
+          sb.Append("[...]");
+          break;
+        }
+      }
+      sb.Append("]");
+
+      return sb.ToString();
+    }
+
+    public virtual IEnumerator<T> GetEnumerator() {
+      return matrix.Cast<T>().GetEnumerator();
+    }
+
+    IEnumerator IEnumerable.GetEnumerator() {
+      return GetEnumerator();
+    }
+
+    #region events
+    public event EventHandler ColumnsChanged;
+    protected virtual void OnColumnsChanged() {
+      EventHandler handler = ColumnsChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler RowsChanged;
+    protected virtual void OnRowsChanged() {
+      EventHandler handler = RowsChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ColumnNamesChanged;
+    protected virtual void OnColumnNamesChanged() {
+      EventHandler handler = ColumnNamesChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler RowNamesChanged;
+    protected virtual void OnRowNamesChanged() {
+      EventHandler handler = RowNamesChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler SortableViewChanged;
+    protected virtual void OnSortableViewChanged() {
+      EventHandler handler = SortableViewChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    public event EventHandler<EventArgs<int, int>> ItemChanged;
+    protected virtual void OnItemChanged(int rowIndex, int columnIndex) {
+      if (ItemChanged != null)
+        ItemChanged(this, new EventArgs<int, int>(rowIndex, columnIndex));
+
+      //approximation to avoid firing of unnecessary ToStringChangedEvents
+      //columnIndex is not used, because always full rows are returned in the ToString method
+      if (rowIndex * Columns < maximumToStringLength)
+        OnToStringChanged();
+    }
+    public event EventHandler Reset;
+    protected virtual void OnReset() {
+      if (Reset != null)
+        Reset(this, EventArgs.Empty);
+      OnToStringChanged();
+    }
+    #endregion
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/ValueTypeValue.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/ValueTypeValue.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/ValueTypeValue.cs	(revision 16171)
@@ -0,0 +1,88 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Data {
+  [Item("ValueTypeValue", "An abstract base class for representing values of value types.")]
+  [StorableClass]
+  public abstract class ValueTypeValue<T> : Item where T : struct {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.ValueType; }
+    }
+
+    [Storable]
+    protected T value;
+    public virtual T Value {
+      get { return value; }
+      set {
+        if (ReadOnly) throw new NotSupportedException("Value cannot be set. ValueTypeValue is read-only.");
+        if (!value.Equals(this.value)) {
+          this.value = value;
+          OnValueChanged();
+        }
+      }
+    }
+
+    [Storable]
+    protected bool readOnly;
+    public virtual bool ReadOnly {
+      get { return readOnly; }
+    }
+
+    [StorableConstructor]
+    protected ValueTypeValue(bool deserializing) : base(deserializing) { }
+    protected ValueTypeValue(ValueTypeValue<T> original, Cloner cloner)
+      : base(original, cloner) {
+      this.value = original.value;
+      this.readOnly = original.readOnly;
+    }
+    protected ValueTypeValue() {
+      this.value = default(T);
+      this.readOnly = false;
+    }
+    protected ValueTypeValue(T value) {
+      this.value = value;
+      this.readOnly = false;
+    }
+
+    public virtual ValueTypeValue<T> AsReadOnly() {
+      ValueTypeValue<T> readOnlyValueTypeValue = (ValueTypeValue<T>)this.Clone();
+      readOnlyValueTypeValue.readOnly = true;
+      return readOnlyValueTypeValue;
+    }
+
+    public override string ToString() {
+      return value.ToString();
+    }
+
+    public event EventHandler ValueChanged;
+    protected virtual void OnValueChanged() {
+      if (ValueChanged != null)
+        ValueChanged(this, EventArgs.Empty);
+      OnToStringChanged();
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ChildrenCopyCreator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ChildrenCopyCreator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ChildrenCopyCreator.cs	(revision 16171)
@@ -0,0 +1,75 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// Creates a copy of every sub-scope in the current scope and adds it as a child to the sub-scope.
+  /// </summary>
+  /// <remarks>
+  /// Creates a copy of every sub-scope in the current scope and adds it as a child to the sub-scope.
+  /// </remarks>
+  [Item("ChildrenCopyCreator", "Creates a copy of every sub-scope in the current scope and adds it as a child to the sub-scope.")]
+  [StorableClass]
+  public sealed class ChildrenCopyCreator : SingleSuccessorOperator {
+    private ScopeParameter CurrentScopeParameter {
+      get { return (ScopeParameter)Parameters["CurrentScope"]; }
+    }
+    public IScope CurrentScope {
+      get { return CurrentScopeParameter.ActualValue; }
+    }
+
+    [StorableConstructor]
+    private ChildrenCopyCreator(bool deserializing) : base(deserializing) { }
+    private ChildrenCopyCreator(ChildrenCopyCreator original, Cloner cloner) : base(original, cloner) { }
+    public ChildrenCopyCreator()
+      : base() {
+      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope whose sub-scopes should be copied."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ChildrenCopyCreator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      int nChildren = CurrentScope.SubScopes.Count;
+
+      for (int i = 0; i < nChildren; i++) {
+        IScope child = CurrentScope.SubScopes[i];
+        if (child.SubScopes.Count > 0) throw new ArgumentException("The sub-scope that should be cloned has further sub-scopes.");
+
+        IScope childCopy = new Scope(i.ToString());
+        var cloner = new Cloner();
+        foreach (IVariable var in child.Variables)
+          childCopy.Variables.Add(cloner.Clone(var));
+
+        child.SubScopes.Add(childCopy);
+      }
+      return base.Apply();
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ChildrenCreator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ChildrenCreator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ChildrenCreator.cs	(revision 16171)
@@ -0,0 +1,87 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// An operator which is used to prepare crossover.
+  /// </summary>
+  /// <remarks>
+  /// The sub-scopes of the current scope the operator is applied on represent the parents. The operator creates
+  /// new and empty scopes for each child, adds the scopes that represent the child's parents as sub-scopes to
+  /// the child and adds the child as sub-scope to the current scope.
+  /// </remarks>
+  [Item("ChildrenCreator", "An operator which is used to prepare crossover. The sub-scopes of the current scope the operator is applied on represent the parents. The operator creates new and empty scopes for each child, adds the scopes that represent the child's parents as sub-scopes to the child and adds the child as sub-scope to the current scope.")]
+  [StorableClass]
+  public sealed class ChildrenCreator : SingleSuccessorOperator {
+    private ScopeParameter CurrentScopeParameter {
+      get { return (ScopeParameter)Parameters["CurrentScope"]; }
+    }
+    public ValueLookupParameter<IntValue> ParentsPerChildParameter {
+      get { return (ValueLookupParameter<IntValue>)Parameters["ParentsPerChild"]; }
+    }
+    public IScope CurrentScope {
+      get { return CurrentScopeParameter.ActualValue; }
+    }
+    public IntValue ParentsPerChild {
+      get { return ParentsPerChildParameter.Value; }
+      set { ParentsPerChildParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    private ChildrenCreator(bool deserializing) : base(deserializing) { }
+    private ChildrenCreator(ChildrenCreator original, Cloner cloner) : base(original, cloner) { }
+    public ChildrenCreator()
+      : base() {
+      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope whose sub-scopes represent the parents."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("ParentsPerChild", "The number of parents that should be crossed per child. Note that some of the typical crossover operators require exactly two parents.", new IntValue(2)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ChildrenCreator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      int parentsPerChild = ParentsPerChildParameter.ActualValue.Value;
+      int parents = CurrentScope.SubScopes.Count;
+      if (parents % parentsPerChild > 0) throw new InvalidOperationException("Number of parents is not an integral multiple of ParentsPerChild.");
+      int children = parents / parentsPerChild;
+
+      for (int i = 0; i < children; i++) {
+        IScope child = new Scope(i.ToString());
+        for (int j = 0; j < parentsPerChild; j++) {
+          IScope parent = CurrentScope.SubScopes[0];
+          CurrentScope.SubScopes.RemoveAt(0);
+          child.SubScopes.Add(parent);
+        }
+        CurrentScope.SubScopes.Add(child);
+      }
+      return base.Apply();
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/DiscreteDoubleValueModifier.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/DiscreteDoubleValueModifier.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/DiscreteDoubleValueModifier.cs	(revision 16171)
@@ -0,0 +1,134 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// Base class for modifying a double value according to a certain function in discrete intervalls.
+  /// </summary>
+  [Item("DiscreteDoubleValueModifier", "Base class for modifying a double value according to a certain function in discrete intervalls.")]
+  [StorableClass]
+  public abstract class DiscreteDoubleValueModifier : SingleSuccessorOperator, IDiscreteDoubleValueModifier {
+    #region parameter properties
+    /// <summary>
+    /// The parameter that should be modified.
+    /// </summary>
+    public ILookupParameter<DoubleValue> ValueParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Value"]; }
+    }
+    /// <summary>
+    /// The start value of the parameter, will be assigned to <see cref="ValueParameter"/> as soon as <see cref="IndexParamter"/> equals <see cref="StartIndexParameter"/>.
+    /// </summary>
+    public IValueLookupParameter<DoubleValue> StartValueParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["StartValue"]; }
+    }
+    /// <summary>
+    /// The end value of the parameter, will be assigned to <see cref="ValueParameter"/> as soon as <see cref="IndexParamter"/> equals <see cref="EndIndexParameter"/>.
+    /// </summary>
+    public IValueLookupParameter<DoubleValue> EndValueParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["EndValue"]; }
+    }
+    /// <summary>
+    /// The index that denotes from which point in the function (relative to <see cref="StartIndexParameter"/> and <see cref="EndIndexParameter"/> the value should be assigned.
+    /// </summary>
+    public ILookupParameter<IntValue> IndexParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["Index"]; }
+    }
+    /// <summary>
+    /// As soon as <see cref="IndexParameter"/> is &gt;= this parameter the value will start to be modified.
+    /// </summary>
+    public IValueLookupParameter<IntValue> StartIndexParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["StartIndex"]; }
+    }
+    /// <summary>
+    /// As long as <see cref="IndexParameter"/> is &lt;= this parameter the value will start to be modified.
+    /// </summary>
+    public IValueLookupParameter<IntValue> EndIndexParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["EndIndex"]; }
+    }
+    #endregion
+    [StorableConstructor]
+    protected DiscreteDoubleValueModifier(bool deserializing) : base(deserializing) { }
+    protected DiscreteDoubleValueModifier(DiscreteDoubleValueModifier original, Cloner cloner) : base(original, cloner) { }
+    /// <summary>
+    /// Initializes a new instance of <see cref="DiscreteDoubleValueModifier"/> with 6 parameters
+    /// (<c>Value</c>, <c>StartValue</c>, <c>EndValue</c>, <c>Index</c>, <c>StartIndex</c>, <c>EndIndex</c>).
+    /// </summary>
+    protected DiscreteDoubleValueModifier()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleValue>("Value", "The double value to modify."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("StartValue", "The start value of 'Value'."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("EndValue", "The end value of 'Value'."));
+      Parameters.Add(new LookupParameter<IntValue>("Index", "The current index."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("StartIndex", "The start index at which to start modifying 'Value'."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("EndIndex", "The end index by which 'Value' should have reached 'EndValue'."));
+    }
+
+    /// <summary>
+    /// Checks whether index is between start and end and forwards the call to <see cref="Modify"/> if startIndex &lt; index &lt; endIndex.
+    /// </summary>
+    /// <remarks>
+    /// If index = startIndex the call will not be forwarded and startValue will be used. The same with endIndex and endValue.
+    /// </remarks>
+    /// <returns>What the base class returns.</returns>
+    public override IOperation Apply() {
+      int index = IndexParameter.ActualValue.Value, startIndex = StartIndexParameter.ActualValue.Value;
+      if (index >= startIndex) {
+        int endIndex = EndIndexParameter.ActualValue.Value;
+        DoubleValue value = ValueParameter.ActualValue;
+        if (value == null) {
+          value = new DoubleValue();
+          ValueParameter.ActualValue = value;
+        }
+        double newValue = value.Value;
+        if (index == startIndex) {
+          newValue = StartValueParameter.ActualValue.Value;
+        } else if (index == endIndex) {
+          newValue = EndValueParameter.ActualValue.Value;
+        } else if (index < endIndex) {
+          double start = StartValueParameter.ActualValue.Value, end = EndValueParameter.ActualValue.Value;
+          newValue = Modify(value.Value, start, end, index, startIndex, endIndex);
+        }
+        value.Value = newValue;
+      }
+      return base.Apply();
+    }
+
+    /// <summary>
+    /// Modifies a given value according to two support points denoted by (startIndex; startValue) and (endIndex; endValue).
+    /// The current 'index' and the last value of 'value' is also given.
+    /// </summary>
+    /// <param name="value">The last value.</param>
+    /// <param name="startValue">The start value.</param>
+    /// <param name="endValue">The end value.</param>
+    /// <param name="index">The current index.</param>
+    /// <param name="startIndex">The start index.</param>
+    /// <param name="endIndex">The end index.</param>
+    /// <returns>The new value.</returns>
+    protected abstract double Modify(double value, double startValue, double endValue, int index, int startIndex, int endIndex);
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ExponentialDiscreteDoubleValueModifier.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ExponentialDiscreteDoubleValueModifier.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ExponentialDiscreteDoubleValueModifier.cs	(revision 16171)
@@ -0,0 +1,62 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// Modifies the value by exponential fall (steep fall initially, slow fall to the end) or rise (slow rise initially, fast rise to the end).
+  /// </summary>
+  [Item("ExponentialDiscreteDoubleValueModifier",
+@"Modifies the value by exponential fall (steep fall initially, slow fall to the end) or rise (slow rise initially, fast rise to the end).
+This uses a standard exponential distribution and yields a base which is implicitly derived by start and end indices and values.")]
+  [StorableClass]
+  public class ExponentialDiscreteDoubleValueModifier : DiscreteDoubleValueModifier {
+    [StorableConstructor]
+    protected ExponentialDiscreteDoubleValueModifier(bool deserializing) : base(deserializing) { }
+    protected ExponentialDiscreteDoubleValueModifier(ExponentialDiscreteDoubleValueModifier original, Cloner cloner) : base(original, cloner) { }
+    public ExponentialDiscreteDoubleValueModifier() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ExponentialDiscreteDoubleValueModifier(this, cloner);
+    }
+
+    /// <summary>
+    /// Calculates a new value based on exponential decay or growth.
+    /// </summary>
+    /// <exception cref="ArgumentException">Thrown when endValue or startValue or both are 0.</exception>
+    /// <param name="value">The last value.</param>
+    /// <param name="startValue">The start value.</param>
+    /// <param name="endValue">The end value.</param>
+    /// <param name="index">The current index.</param>
+    /// <param name="startIndex">The start index.</param>
+    /// <param name="endIndex">The end index.</param>
+    /// <returns>The new value.</returns>
+    protected override double Modify(double value, double startValue, double endValue, int index, int startIndex, int endIndex) {
+      if (endValue <= 0 || startValue <= 0) throw new ArgumentException("startValue and endValue must be greater than 0.");
+      double b = Math.Pow(endValue / startValue, 1.0 / (endIndex - startIndex));
+      return startValue * Math.Pow(b, index - startIndex);
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ExpressionCalculator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ExpressionCalculator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ExpressionCalculator.cs	(revision 16171)
@@ -0,0 +1,111 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// An operator that evaluates an expression.
+  /// </summary>
+  [Item("ExpressionCalculator", "An operator that evaluates an expression.")]
+  [StorableClass]
+  public class ExpressionCalculator : ValuesCollector {
+    [Storable]
+    public Calculator Calculator { get; set; }
+
+    #region Parameter Properties
+    public IValueLookupParameter<StringValue> ExpressionParameter {
+      get { return (IValueLookupParameter<StringValue>)Parameters["Expression"]; }
+    }
+    public IValueLookupParameter<IItem> ExpressionResultParameter {
+      get { return (IValueLookupParameter<IItem>)Parameters["ExpressionResult"]; }
+    }
+    #endregion
+
+    #region Properties
+    private string Formula {
+      get { return ExpressionParameter.Value.Value; }
+    }
+    private IItem ExpressionResult {
+      set { ExpressionResultParameter.ActualValue = value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected ExpressionCalculator(bool deserializing) : base(deserializing) { }
+    protected ExpressionCalculator(ExpressionCalculator original, Cloner cloner)
+      : base(original, cloner) {
+      this.Calculator = cloner.Clone(original.Calculator);
+    }
+    public ExpressionCalculator()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<IItem>("ExpressionResult", "The result of the evaluated expression."));
+      Parameters.Add(new ValueLookupParameter<StringValue>("Expression",
+@"RPN formula for new value in postfix notation.
+
+This can contain the following elements:
+
+literals:
+  numbers, true, false, null and strings in single quotes
+variables (run parameters or results):
+  unquoted or in double quotes if they contain special characters or whitespace
+mathematical functions (resulting in double values):
+  +, -, *, /, ^ (power), log
+predicates:
+  ==, <, >, isnull, not
+conversions:
+  toint, todouble
+array indexing:
+  []
+stack manipulation:
+  drop swap dup
+string matching:
+  <string> <pattern> ismatch
+string replacing:
+  <string> <pattern> <replacement> rename
+conditionals:
+  <then> <else> <condition> if
+
+If the final value is null, the result variable is removed if it exists."));
+
+      Calculator = new Calculator();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ExpressionCalculator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      Calculator.Formula = Formula;
+      var variables = new Dictionary<string, IItem>();
+      foreach (var collectedValue in CollectedValues)
+        variables[collectedValue.Name] = collectedValue.ActualValue;
+      ExpressionResult = Calculator.GetValue(variables);
+      return base.Apply();
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/GeneralizedExponentialDiscreteDoubleValueModifier.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/GeneralizedExponentialDiscreteDoubleValueModifier.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/GeneralizedExponentialDiscreteDoubleValueModifier.cs	(revision 16171)
@@ -0,0 +1,79 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+
+  /// <summary>
+  /// Modifies a value by exponentially.
+  /// </summary>
+  [Item("GeneralizedExponentialDiscreteDoubleValueModifier", @"Modifies the value exponentially.
+The base is a standardized exponential function with exponent `Base`
+that is then transformed to pass through the startValue at the startIndex
+and through the endValue at the endIndex.
+For a slow change initially use a value > 1 for `Base`.
+For a steep change initially use a value < 1 for `Base`.
+Negative slopes are automatically generated if the start value is greater than the end value.
+If you use `base`=1 you will get a linear interpolation.")]
+  [StorableClass]
+  public class GeneralizedExponentialDiscreteDoubleValueModifier : DiscreteDoubleValueModifier {
+
+    protected ValueLookupParameter<DoubleValue> BaseParameter {
+      get { return (ValueLookupParameter<DoubleValue>) Parameters["Base"]; }
+    }
+    private double Base { get { return BaseParameter.Value.Value; } }
+
+    [StorableConstructor]
+    protected GeneralizedExponentialDiscreteDoubleValueModifier(bool deserializing) : base(deserializing) { }
+    protected GeneralizedExponentialDiscreteDoubleValueModifier(GeneralizedExponentialDiscreteDoubleValueModifier original, Cloner cloner) : base(original, cloner) { }
+    public GeneralizedExponentialDiscreteDoubleValueModifier() {
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("Base", "Base of the exponential function. Must be > 0. If > 1 steep in the end, if < 1 steep at the start, if == 1 linear interpolation.", new DoubleValue(0.00001)));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GeneralizedExponentialDiscreteDoubleValueModifier(this, cloner);
+    }
+
+    /// <summary>
+    /// Calculates a new value based on exponential decay or growth.
+    /// </summary>
+    /// <exception cref="ArgumentException">Thrown if Base &lt;= 0.</exception>
+    /// <param name="value">The previous value.</param>
+    /// <param name="startValue">The initial value.</param>
+    /// <param name="endValue">The final value.</param>
+    /// <param name="index">The current index.</param>
+    /// <param name="startIndex">The initial index.</param>
+    /// <param name="endIndex">The final index.</param>
+    /// <returns>The new value.</returns>
+    protected override double Modify(double value, double startValue, double endValue, int index, int startIndex, int endIndex) {
+      if (Base <= 0)
+        throw new ArgumentException("Base must be > 0.");
+      if (Base == 1.0)
+        return startValue + (endValue - startValue)*(index - startIndex)/(endIndex - startIndex);
+      return startValue + (endValue - startValue)*(Math.Pow(Base, 1.0*(index-startIndex)/(endIndex-startIndex)) - 1)/(Base - 1);
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/HeuristicLab.Optimization.Operators-3.3.csproj
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/HeuristicLab.Optimization.Operators-3.3.csproj	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/HeuristicLab.Optimization.Operators-3.3.csproj	(revision 16171)
@@ -0,0 +1,245 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{25087811-F74C-4128-BC86-8324271DA13E}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Optimization.Operators</RootNamespace>
+    <AssemblyName>HeuristicLab.Optimization.Operators-3.3</AssemblyName>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\..\trunk\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+    <DocumentationFile>
+    </DocumentationFile>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Common-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Core-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Operators.Programmable-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Operators.Programmable-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Parameters-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Selection-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Selection-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ChildrenCopyCreator.cs" />
+    <Compile Include="ExpressionCalculator.cs" />
+    <Compile Include="NoSimilarityCalculator.cs" />
+    <Compile Include="QualitySimilarityCalculator.cs" />
+    <Compile Include="SingleObjectiveSolutionSimilarityCalculator.cs" />
+    <Compile Include="GeneralizedExponentialDiscreteDoubleValueModifier.cs" />
+    <Compile Include="MultiObjective\CrowdedComparisonSorter.cs" />
+    <Compile Include="MultiObjective\CrowdingDistanceAssignment.cs" />
+    <Compile Include="ParentCopyCrossover.cs" />
+    <Compile Include="MultiObjective\FastNonDominatedSort.cs" />
+    <Compile Include="MultiObjective\RankAndCrowdingSorter.cs" />
+    <Compile Include="SingleObjectivePathRelinker.cs" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="ProgrammableAnalyzer.cs" />
+    <Compile Include="ShakingOperator.cs" />
+    <Compile Include="SolutionSimilarityCalculator.cs" />
+    <Compile Include="UserDefinedCrossover.cs" />
+    <Compile Include="UserDefinedEvaluator.cs" />
+    <Compile Include="UserDefinedManipulator.cs" />
+    <Compile Include="UserDefinedOperator.cs" />
+    <Compile Include="UserDefinedSolutionCreator.cs" />
+    <Compile Include="ProbabilisticQualityComparator.cs" />
+    <Compile Include="ResultsCollector.cs" />
+    <Compile Include="SASEGASAReunificator.cs" />
+    <Compile Include="SquareRootDiscreteDoubleValueModifier.cs" />
+    <Compile Include="DiscreteDoubleValueModifier.cs" />
+    <Compile Include="ExponentialDiscreteDoubleValueModifier.cs" />
+    <Compile Include="LinearDiscreteDoubleValueModifier.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ChildrenCreator.cs" />
+    <Compile Include="QuadraticDiscreteDoubleValueModifier.cs" />
+    <Compile Include="QualityComparator.cs" />
+    <Compile Include="SolutionsCreator.cs" />
+    <Compile Include="TabuMaker.cs" />
+    <Compile Include="UnidirectionalRingMigrator.cs" />
+    <Compile Include="WeightedParentsQualityComparator.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Plugin.cs.frame" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
+      <Project>{bbab9df5-5ef3-4ba8-ade9-b36e82114937}</Project>
+      <Name>HeuristicLab.Data-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
+      <Project>{14ab8d24-25bc-400c-a846-4627aa945192}</Project>
+      <Name>HeuristicLab.Optimization-3.3</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <PropertyGroup>
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd
+</PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/LinearDiscreteDoubleValueModifier.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/LinearDiscreteDoubleValueModifier.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/LinearDiscreteDoubleValueModifier.cs	(revision 16171)
@@ -0,0 +1,48 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// Modifies the value by linear (constant) fall or rise.
+  /// </summary>
+  [Item("LinearDiscreteDoubleValueModifier", "Modifies the value by linear (constant) fall or rise.")]
+  [StorableClass]
+  public class LinearDiscreteDoubleValueModifier : DiscreteDoubleValueModifier {
+    [StorableConstructor]
+    protected LinearDiscreteDoubleValueModifier(bool deserializing) : base(deserializing) { }
+    protected LinearDiscreteDoubleValueModifier(LinearDiscreteDoubleValueModifier original, Cloner cloner) : base(original, cloner) { }
+    public LinearDiscreteDoubleValueModifier() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LinearDiscreteDoubleValueModifier(this, cloner);
+    }
+
+    protected override double Modify(double value, double startValue, double endValue, int index, int startIndex, int endIndex) {
+      double k = (endValue - startValue) / (endIndex - startIndex);
+      double x = index - startIndex;
+      return k * x + startValue;
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/MultiObjective/CrowdedComparisonSorter.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/MultiObjective/CrowdedComparisonSorter.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/MultiObjective/CrowdedComparisonSorter.cs	(revision 16171)
@@ -0,0 +1,99 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// CrowdedComparisonSorter as described in: Deb, Pratap, Agrawal and Meyarivan, "A Fast and Elitist Multiobjective
+  /// Genetic Algorithm: NSGA-II", IEEE Transactions On Evolutionary Computation, Vol. 6, No. 2, April 2002
+  /// </summary>
+  [Item("CrowdedComparisonSorter", @"CrowdedComparisonSorter as described in: Deb, Pratap, Agrawal and Meyarivan, ""A Fast and Elitist Multiobjective
+Genetic Algorithm: NSGA-II"", IEEE Transactions On Evolutionary Computation, Vol. 6, No. 2, April 2002.")]
+  [StorableClass]
+  public class CrowdedComparisonSorter : SingleSuccessorOperator {
+
+    public IScopeTreeLookupParameter<IntValue> RankParameter {
+      get { return (IScopeTreeLookupParameter<IntValue>)Parameters["Rank"]; }
+    }
+
+    public IScopeTreeLookupParameter<DoubleValue> CrowdingDistanceParameter {
+      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["CrowdingDistance"]; }
+    }
+
+    [StorableConstructor]
+    protected CrowdedComparisonSorter(bool deserializing) : base(deserializing) { }
+    protected CrowdedComparisonSorter(CrowdedComparisonSorter original, Cloner cloner) : base(original, cloner) { }
+    public CrowdedComparisonSorter() {
+      Parameters.Add(new ScopeTreeLookupParameter<IntValue>("Rank", "The rank of the solution."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("CrowdingDistance", "The crowding distance of the solution."));
+    }
+
+    public override IOperation Apply() {
+      ItemArray<IntValue> ranks = RankParameter.ActualValue;
+      ItemArray<DoubleValue> distances = CrowdingDistanceParameter.ActualValue;
+      int size = ranks.Length;
+      int[] indices = Enumerable.Range(0, size).ToArray();
+
+      IScope[] scopes = ExecutionContext.Scope.SubScopes.ToArray();
+      Array.Sort(indices, scopes, new CustomComparer(ranks, distances));
+      ExecutionContext.Scope.SubScopes.Clear();
+      ExecutionContext.Scope.SubScopes.AddRange(scopes);
+      return base.Apply();
+    }
+
+    private class CustomComparer : IComparer<int> {
+      ItemArray<IntValue> ranks;
+      ItemArray<DoubleValue> distances;
+
+      public CustomComparer(ItemArray<IntValue> ranks, ItemArray<DoubleValue> distances) {
+        this.ranks = ranks;
+        this.distances = distances;
+      }
+
+      #region IComparer<int> Members
+
+      public int Compare(int x, int y) {
+        if (ranks[x].Value < ranks[y].Value) return -1;
+        else if (ranks[x].Value > ranks[y].Value) return 1;
+        else { // ranks are the same -> compare by distance
+          if (distances[x].Value > distances[y].Value) return -1;
+          else if (distances[x].Value < distances[y].Value) return 1;
+          else return 0; // same distance
+        }
+      }
+
+      #endregion
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CrowdedComparisonSorter(this, cloner);
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/MultiObjective/CrowdingDistanceAssignment.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/MultiObjective/CrowdingDistanceAssignment.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/MultiObjective/CrowdingDistanceAssignment.cs	(revision 16171)
@@ -0,0 +1,82 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  [Item("CrowdingDistanceAssignment", "Calculates the crowding distances for each sub-scope as described in Deb et al. 2002. A Fast and Elitist Multiobjective Genetic Algorithm: NSGA-II. IEEE Transactions on Evolutionary Computation, 6(2), pp. 182-197.")]
+  [StorableClass]
+  public class CrowdingDistanceAssignment : SingleSuccessorOperator, IMultiObjectiveOperator {
+
+    public ScopeTreeLookupParameter<DoubleArray> QualitiesParameter {
+      get { return (ScopeTreeLookupParameter<DoubleArray>)Parameters["Qualities"]; }
+    }
+
+    public ScopeTreeLookupParameter<DoubleValue> CrowdingDistanceParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["CrowdingDistance"]; }
+    }
+
+    private void QualitiesParameter_DepthChanged(object sender, EventArgs e) {
+      CrowdingDistanceParameter.Depth = QualitiesParameter.Depth;
+    }
+
+    [StorableConstructor]
+    protected CrowdingDistanceAssignment(bool deserializing) : base(deserializing) { }
+    protected CrowdingDistanceAssignment(CrowdingDistanceAssignment original, Cloner cloner) : base(original, cloner) { }
+    public CrowdingDistanceAssignment() {
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleArray>("Qualities", "The vector of quality values."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("CrowdingDistance", "Sets the crowding distance in each sub-scope."));
+      RegisterEventHandlers();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEventHandlers();
+    }
+
+    private void RegisterEventHandlers() {
+      QualitiesParameter.DepthChanged += new EventHandler(QualitiesParameter_DepthChanged);
+    }
+
+    public static void Apply(DoubleArray[] qualities, DoubleValue[] distances) {
+      var dist = CrowdingCalculator.CalculateCrowdingDistances(qualities);
+      for (var i = 0; i < distances.Length; i++) distances[i].Value = dist[i];
+    }
+
+    public override IOperation Apply() {
+      var dist = CrowdingCalculator.CalculateCrowdingDistances(QualitiesParameter.ActualValue.ToArray());
+      CrowdingDistanceParameter.ActualValue = new ItemArray<DoubleValue>(dist.Select(d => new DoubleValue(d)));
+      return base.Apply();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CrowdingDistanceAssignment(this, cloner);
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/MultiObjective/FastNonDominatedSort.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/MultiObjective/FastNonDominatedSort.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/MultiObjective/FastNonDominatedSort.cs	(revision 16171)
@@ -0,0 +1,106 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// FastNonDominatedSort as described in: Deb, Pratap, Agrawal and Meyarivan, "A Fast and Elitist Multiobjective
+  /// Genetic Algorithm: NSGA-II", IEEE Transactions On Evolutionary Computation, Vol. 6, No. 2, April 2002
+  /// </summary>
+  [Item("FastNonDominatedSort", @"FastNonDominatedSort as described in: Deb, Pratap, Agrawal and Meyarivan, ""A Fast and Elitist Multiobjective
+Genetic Algorithm: NSGA-II"", IEEE Transactions On Evolutionary Computation, Vol. 6, No. 2, April 2002")]
+  [StorableClass]
+  public class FastNonDominatedSort : SingleSuccessorOperator, IMultiObjectiveOperator {
+
+    #region Parameter properties
+    public IValueLookupParameter<BoolArray> MaximizationParameter {
+      get { return (IValueLookupParameter<BoolArray>)Parameters["Maximization"]; }
+    }
+    public IValueLookupParameter<BoolValue> DominateOnEqualQualitiesParameter {
+      get { return (ValueLookupParameter<BoolValue>)Parameters["DominateOnEqualQualities"]; }
+    }
+    public IScopeTreeLookupParameter<DoubleArray> QualitiesParameter {
+      get { return (IScopeTreeLookupParameter<DoubleArray>)Parameters["Qualities"]; }
+    }
+    public IScopeTreeLookupParameter<IntValue> RankParameter {
+      get { return (IScopeTreeLookupParameter<IntValue>)Parameters["Rank"]; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected FastNonDominatedSort(bool deserializing) : base(deserializing) { }
+    protected FastNonDominatedSort(FastNonDominatedSort original, Cloner cloner) : base(original, cloner) { }
+    public FastNonDominatedSort() {
+      Parameters.Add(new ValueLookupParameter<BoolArray>("Maximization", "Whether each objective is maximization or minimization."));
+      Parameters.Add(new ValueLookupParameter<BoolValue>("DominateOnEqualQualities", "Flag which determines wether solutions with equal quality values should be treated as dominated."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleArray>("Qualities", "The qualities of a solution.", 1));
+      Parameters.Add(new ScopeTreeLookupParameter<IntValue>("Rank", "The rank of a solution.", 1));
+    }
+
+    public override IOperation Apply() {
+      bool dominateOnEqualQualities = DominateOnEqualQualitiesParameter.ActualValue.Value;
+      bool[] maximization = MaximizationParameter.ActualValue.ToArray();
+      double[][] qualities = QualitiesParameter.ActualValue.Select(x => x.ToArray()).ToArray();
+      if (qualities == null) throw new InvalidOperationException(Name + ": No qualities found.");
+
+      IScope scope = ExecutionContext.Scope;
+      int populationSize = scope.SubScopes.Count;
+
+      int[] rank;
+      var fronts = DominationCalculator.CalculateAllParetoFronts(scope.SubScopes.ToArray(), qualities, maximization, out rank, dominateOnEqualQualities);
+
+      RankParameter.ActualValue = new ItemArray<IntValue>(rank.Select(x => new IntValue(x)));
+
+      scope.SubScopes.Clear();
+
+      for (var i = 0; i < fronts.Count; i++) {
+        Scope frontScope = new Scope("Front " + i);
+        foreach (var p in fronts[i])
+          frontScope.SubScopes.Add(p.Item1);
+        if (frontScope.SubScopes.Count > 0)
+          scope.SubScopes.Add(frontScope);
+      }
+      return base.Apply();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new FastNonDominatedSort(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code, remove with 3.4
+      if (!Parameters.ContainsKey("DominateOnEqualQualities"))
+        Parameters.Add(new ValueLookupParameter<BoolValue>("DominateOnEqualQualities", "Flag which determines wether solutions with equal quality values should be treated as dominated."));
+      #endregion
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/MultiObjective/RankAndCrowdingSorter.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/MultiObjective/RankAndCrowdingSorter.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/MultiObjective/RankAndCrowdingSorter.cs	(revision 16171)
@@ -0,0 +1,101 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Selection;
+
+namespace HeuristicLab.Optimization.Operators {
+  [StorableClass]
+  public class RankAndCrowdingSorter : AlgorithmOperator, IMultiObjectiveOperator {
+    #region Parameter properties
+    public ValueLookupParameter<BoolArray> MaximizationParameter {
+      get { return (ValueLookupParameter<BoolArray>)Parameters["Maximization"]; }
+    }
+    public ScopeTreeLookupParameter<DoubleArray> QualitiesParameter {
+      get { return (ScopeTreeLookupParameter<DoubleArray>)Parameters["Qualities"]; }
+    }
+    public ScopeTreeLookupParameter<IntValue> RankParameter {
+      get { return (ScopeTreeLookupParameter<IntValue>)Parameters["Rank"]; }
+    }
+    public ScopeTreeLookupParameter<DoubleValue> CrowdingDistanceParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["CrowdingDistance"]; }
+    }
+    public IValueLookupParameter<BoolValue> DominateOnEqualQualitiesParameter {
+      get { return (ValueLookupParameter<BoolValue>)Parameters["DominateOnEqualQualities"]; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected RankAndCrowdingSorter(bool deserializing) : base(deserializing) { }
+    protected RankAndCrowdingSorter(RankAndCrowdingSorter original, Cloner cloner) : base(original, cloner) { }
+    public RankAndCrowdingSorter()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<BoolArray>("Maximization", "For each objective a value that is true if that objective should be maximized, or false if it should be minimized."));
+      Parameters.Add(new ValueLookupParameter<BoolValue>("DominateOnEqualQualities", "Flag which determines wether solutions with equal quality values should be treated as dominated."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleArray>("Qualities", "The vector of quality values."));
+      Parameters.Add(new ScopeTreeLookupParameter<IntValue>("Rank", "The rank of a solution (to which front it belongs)."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("CrowdingDistance", "The crowding distance of a solution in a population."));
+
+      FastNonDominatedSort fastNonDominatedSort = new FastNonDominatedSort();
+      UniformSubScopesProcessor subScopesProcessor = new UniformSubScopesProcessor();
+      CrowdingDistanceAssignment crowdingDistanceAssignment = new CrowdingDistanceAssignment();
+      CrowdedComparisonSorter crowdedComparisonSorter = new CrowdedComparisonSorter();
+      MergingReducer mergingReducer = new MergingReducer();
+
+      fastNonDominatedSort.MaximizationParameter.ActualName = MaximizationParameter.Name;
+      fastNonDominatedSort.DominateOnEqualQualitiesParameter.ActualName = DominateOnEqualQualitiesParameter.Name;
+      fastNonDominatedSort.QualitiesParameter.ActualName = QualitiesParameter.Name;
+      fastNonDominatedSort.RankParameter.ActualName = RankParameter.Name;
+
+      crowdingDistanceAssignment.CrowdingDistanceParameter.ActualName = CrowdingDistanceParameter.Name;
+      crowdingDistanceAssignment.QualitiesParameter.ActualName = QualitiesParameter.Name;
+
+      crowdedComparisonSorter.CrowdingDistanceParameter.ActualName = CrowdingDistanceParameter.Name;
+      crowdedComparisonSorter.RankParameter.ActualName = RankParameter.Name;
+
+      OperatorGraph.InitialOperator = fastNonDominatedSort;
+      fastNonDominatedSort.Successor = subScopesProcessor;
+      subScopesProcessor.Operator = crowdingDistanceAssignment;
+      crowdingDistanceAssignment.Successor = crowdedComparisonSorter;
+      crowdedComparisonSorter.Successor = null;
+      subScopesProcessor.Successor = mergingReducer;
+      mergingReducer.Successor = null;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RankAndCrowdingSorter(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code, remove with 3.4
+      if (!Parameters.ContainsKey("DominateOnEqualQualities"))
+        Parameters.Add(new ValueLookupParameter<BoolValue>("DominateOnEqualQualities", "Flag which determines wether solutions with equal quality values should be treated as dominated."));
+      #endregion
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/NoSimilarityCalculator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/NoSimilarityCalculator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/NoSimilarityCalculator.cs	(revision 16171)
@@ -0,0 +1,52 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// An item that performs similarity calculation between two solutions.
+  /// </summary>
+  /// <remarks>
+  /// The item always considers two solutions to be distinct.
+  /// </remarks>
+  [Item("NoSimilarityCalculator", "An item that performs similarity calculation between two solutions. The item always considers two solutions to be distinct.")]
+  public sealed class NoSimilarityCalculator : SingleObjectiveSolutionSimilarityCalculator {
+    protected override bool IsCommutative { get { return true; } }
+
+    private NoSimilarityCalculator(bool deserializing) : base(deserializing) { }
+    private NoSimilarityCalculator(NoSimilarityCalculator original, Cloner cloner) : base(original, cloner) { }
+    public NoSimilarityCalculator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new NoSimilarityCalculator(this, cloner);
+    }
+
+    public static double CalculateSimilarity(IScope left, IScope right) {
+      return 0.0;
+    }
+
+    public override double CalculateSolutionSimilarity(IScope leftSolution, IScope rightSolution) {
+      return CalculateSimilarity(leftSolution, rightSolution);
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ParentCopyCrossover.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ParentCopyCrossover.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ParentCopyCrossover.cs	(revision 16171)
@@ -0,0 +1,60 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  [Item("ParentCopyCrossover", "This operator creates an offspring by creating a clone of a randomly chosen parent. It can be used in situations where no crossover should occur after selection.")]
+  [StorableClass]
+  public class ParentCopyCrossover : InstrumentedOperator, ICrossover, IStochasticOperator {
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+
+    [StorableConstructor]
+    protected ParentCopyCrossover(bool deserializing) : base(deserializing) { }
+    protected ParentCopyCrossover(ParentCopyCrossover original, Cloner cloner) : base(original, cloner) { }
+    public ParentCopyCrossover()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator."));
+    }
+
+    public override IOperation InstrumentedApply() {
+      IScope scope = ExecutionContext.Scope;
+      int index = RandomParameter.ActualValue.Next(scope.SubScopes.Count);
+      IScope child = scope.SubScopes[index];
+
+      foreach (IVariable var in child.Variables)
+        scope.Variables.Add((IVariable)var.Clone());
+
+      return base.InstrumentedApply();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ParentCopyCrossover(this, cloner);
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/Plugin.cs.frame
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/Plugin.cs.frame	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/Plugin.cs.frame	(revision 16171)
@@ -0,0 +1,42 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.PluginInfrastructure;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// Plugin class for HeuristicLab.Optimization.Operators plugin.
+  /// </summary>
+  [Plugin("HeuristicLab.Optimization.Operators", "3.3.15.$WCREV$")]
+  [PluginFile("HeuristicLab.Optimization.Operators-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Operators.Programmable", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization","3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  [PluginDependency("HeuristicLab.Selection", "3.3")]
+  public class HeuristicLabOptimizationOperatorsPlugin : PluginBase {
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ProbabilisticQualityComparator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ProbabilisticQualityComparator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ProbabilisticQualityComparator.cs	(revision 16171)
@@ -0,0 +1,68 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// Compares two qualities and creates a boolean flag that indicates if the left side is better than the right side or if the difference in quality is acceptable given a certain probability.
+  /// </summary>
+  /// <remarks>
+  /// The probabilty is that of simulated annealing: A randomly drawn (uniformly) real value in
+  /// the interval [0;1) has to be smaller than e^(-diff/T) where diff is the absolute quality difference
+  /// and T is the temperature (here called dampening).
+  /// </remarks>
+  [Item("ProbabilisticQualityComparator", "Compares two qualities and creates a boolean flag that indicates if the left side is better than the right side or if the difference in quality is acceptable given a certain probability.")]
+  [StorableClass]
+  public class ProbabilisticQualityComparator : QualityComparator, IStochasticOperator {
+    public ILookupParameter<DoubleValue> DampeningParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Dampening"]; }
+    }
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    [StorableConstructor]
+    protected ProbabilisticQualityComparator(bool deserializing) : base(deserializing) { }
+    protected ProbabilisticQualityComparator(ProbabilisticQualityComparator original, Cloner cloner) : base(original, cloner) { }
+    public ProbabilisticQualityComparator()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleValue>("Dampening", "The dampening factor that influences the probability."));
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ProbabilisticQualityComparator(this, cloner);
+    }
+
+    protected override bool Compare(bool maximization, double left, double right) {
+      if (base.Compare(maximization, left, right)) return true;
+      double t = DampeningParameter.ActualValue.Value;
+      double probability = Math.Exp(-Math.Abs(left - right) / t);
+      return RandomParameter.ActualValue.NextDouble() < probability;
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ProgrammableAnalyzer.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ProgrammableAnalyzer.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ProgrammableAnalyzer.cs	(revision 16171)
@@ -0,0 +1,60 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Data;
+using HeuristicLab.Operators.Programmable;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+
+  [Item("ProgrammableAnalyzer", "An analyzer that can be programmed for arbitrary needs.")]
+  [StorableClass]
+  public class ProgrammableAnalyzer : ProgrammableSingleSuccessorOperator, IAnalyzer {
+    public virtual bool EnabledByDefault {
+      get { return false; }
+    }
+
+    [StorableConstructor]
+    protected ProgrammableAnalyzer(bool deserializing) : base(deserializing) { }
+    protected ProgrammableAnalyzer(ProgrammableAnalyzer original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public ProgrammableAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The qualities of the solutions."));
+      Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The result collection where the solution should be stored."));
+      Parameters.ForEach(x => x.Hidden = false);
+
+      SelectNamespace("HeuristicLab.Optimization");
+      SelectNamespace("HeuristicLab.Optimization.Operators");
+      Assemblies[typeof(HeuristicLab.Optimization.ResultCollection).Assembly] = true;
+      Assemblies[typeof(HeuristicLab.Optimization.Operators.ProgrammableAnalyzer).Assembly] = true;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ProgrammableAnalyzer(this, cloner);
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/Properties/AssemblyInfo.cs.frame	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/Properties/AssemblyInfo.cs.frame	(revision 16171)
@@ -0,0 +1,56 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.Optimization.Operators")]
+[assembly: AssemblyDescription("HeuristicLab operators for solving optimization problems")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2018 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("75ed50d2-6d31-4308-a373-c3820769afb8")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.15.$WCREV$")]
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/QuadraticDiscreteDoubleValueModifier.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/QuadraticDiscreteDoubleValueModifier.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/QuadraticDiscreteDoubleValueModifier.cs	(revision 16171)
@@ -0,0 +1,47 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// Modifies the value by quadratic fall (slow fall initially, fast fall to the end) or rise (slow rise initally, fast rise to the end).
+  /// </summary>
+  [Item("QuadraticDiscreteDoubleValueModifier", "Modifies the value by quadratic fall (slow fall initially, fast fall to the end) or rise (slow rise initally, fast rise to the end).")]
+  [StorableClass]
+  public class QuadraticDiscreteDoubleValueModifier : DiscreteDoubleValueModifier {
+    [StorableConstructor]
+    protected QuadraticDiscreteDoubleValueModifier(bool deserializing) : base(deserializing) { }
+    protected QuadraticDiscreteDoubleValueModifier(QuadraticDiscreteDoubleValueModifier original, Cloner cloner) : base(original, cloner) { }
+    public QuadraticDiscreteDoubleValueModifier() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new QuadraticDiscreteDoubleValueModifier(this, cloner);
+    }
+
+    protected override double Modify(double value, double startValue, double endValue, int index, int startIndex, int endIndex) {
+      double a = (endValue - startValue) / ((endIndex - startIndex) * (endIndex - startIndex));
+      return a * (index - startIndex) * (index - startIndex) + startValue;
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/QualityComparator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/QualityComparator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/QualityComparator.cs	(revision 16171)
@@ -0,0 +1,76 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  [Item("QualityComparator", "Compares two qualities and creates a boolean flag that indicates if the left side is better than the right side.")]
+  [StorableClass]
+  public class QualityComparator : SingleSuccessorOperator, IQualityComparator {
+    public ILookupParameter<DoubleValue> LeftSideParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["LeftSide"]; }
+    }
+    public IValueLookupParameter<DoubleValue> RightSideParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["RightSide"]; }
+    }
+    public ILookupParameter<BoolValue> ResultParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Result"]; }
+    }
+    public IValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+
+    [StorableConstructor]
+    protected QualityComparator(bool deserializing) : base(deserializing) { }
+    protected QualityComparator(QualityComparator original, Cloner cloner) : base(original, cloner) { }
+    public QualityComparator()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleValue>("LeftSide", "The left side of the comparison."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("RightSide", "The right side of the comparison."));
+      Parameters.Add(new LookupParameter<BoolValue>("Result", "The result of the comparison, true if the quality on the LeftSide is better than the quality on the RightSide."));
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, otherwise false."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new QualityComparator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      DoubleValue left = LeftSideParameter.ActualValue;
+      DoubleValue right = RightSideParameter.ActualValue;
+      BoolValue maximization = MaximizationParameter.ActualValue;
+      bool better = Compare(maximization.Value, left.Value, right.Value);
+      if (ResultParameter.ActualValue == null)
+        ResultParameter.ActualValue = new BoolValue(better);
+      else ResultParameter.ActualValue.Value = better;
+      return base.Apply();
+    }
+
+    protected virtual bool Compare(bool maximization, double left, double right) {
+      return maximization && left > right || !maximization && left < right;
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/QualitySimilarityCalculator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/QualitySimilarityCalculator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/QualitySimilarityCalculator.cs	(revision 16171)
@@ -0,0 +1,57 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Data;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// An item that performs similarity calculation between two solutions.
+  /// </summary>
+  /// <remarks>
+  /// The item always considers two solutions to be equal if they have the same quality.
+  /// </remarks>
+  [Item("QualitySimilarityCalculator", "An item that performs similarity calculation between two solutions. The item only considers the qualities of the two solutions.")]
+  public sealed class QualitySimilarityCalculator : SingleObjectiveSolutionSimilarityCalculator {
+    protected override bool IsCommutative { get { return true; } }
+
+    private QualitySimilarityCalculator(bool deserializing) : base(deserializing) { }
+    private QualitySimilarityCalculator(QualitySimilarityCalculator original, Cloner cloner) : base(original, cloner) { }
+    public QualitySimilarityCalculator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new QualitySimilarityCalculator(this, cloner);
+    }
+
+    public static double CalculateSimilarity(IScope left, IScope right, string qualityVariableName) {
+      double leftQuality = ((DoubleValue)left.Variables[qualityVariableName].Value).Value;
+      double rightQuality = ((DoubleValue)right.Variables[qualityVariableName].Value).Value;
+      double delta = leftQuality.IsAlmost(rightQuality) ? 0.0 : Math.Abs(leftQuality - rightQuality);
+      return 1.0 - delta / Math.Max(leftQuality, rightQuality);
+    }
+
+    public override double CalculateSolutionSimilarity(IScope leftSolution, IScope rightSolution) {
+      return CalculateSimilarity(leftSolution, rightSolution, QualityVariableName);
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ResultsCollector.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ResultsCollector.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ResultsCollector.cs	(revision 16171)
@@ -0,0 +1,89 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// An operator which collects the actual values of parameters and adds them to a collection of results.
+  /// </summary>
+  [Item("ResultsCollector", "An operator which collects the actual values of parameters and adds them to a collection of results.")]
+  [StorableClass]
+  public class ResultsCollector : ValuesCollector {
+    public ValueLookupParameter<ResultCollection> ResultsParameter {
+      get { return (ValueLookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    public ValueParameter<BoolValue> CopyValueParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["CopyValue"]; }
+    }
+
+    public BoolValue CopyValue {
+      get { return CopyValueParameter.Value; }
+      set { CopyValueParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected ResultsCollector(bool deserializing) : base(deserializing) { }
+    protected ResultsCollector(ResultsCollector original, Cloner cloner) : base(original, cloner) { }
+    public ResultsCollector()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The result collection where the collected values should be stored."));
+      Parameters.Add(new ValueParameter<BoolValue>("CopyValue", "True if the collected result value should be copied, otherwise false.", new BoolValue(false)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ResultsCollector(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      bool copy = CopyValueParameter.Value.Value;
+      ResultCollection results = ResultsParameter.ActualValue;
+      IResult result;
+      foreach (IParameter param in CollectedValues) {
+        IItem value = param.ActualValue;
+        if (value != null) {
+          ILookupParameter lookupParam = param as ILookupParameter;
+          string name = lookupParam != null ? lookupParam.TranslatedName : param.Name;
+
+          IScopeTreeLookupParameter scopeTreeLookupParam = param as IScopeTreeLookupParameter;
+          if ((scopeTreeLookupParam != null) && (scopeTreeLookupParam.Depth == 0)) {
+            IEnumerator enumerator = ((IEnumerable)value).GetEnumerator();
+            if (enumerator.MoveNext())
+              value = (IItem)enumerator.Current;
+          }
+
+          results.TryGetValue(name, out result);
+          if (result != null)
+            result.Value = copy ? (IItem)value.Clone() : value;
+          else
+            results.Add(new Result(name, param.Description, copy ? (IItem)value.Clone() : value));
+        }
+      }
+      return base.Apply();
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/SASEGASAReunificator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/SASEGASAReunificator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/SASEGASAReunificator.cs	(revision 16171)
@@ -0,0 +1,97 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// Joins all sub sub scopes of a specified scope, reduces the number of sub 
+  /// scopes by 1 and uniformly partitions the sub sub scopes again, maintaining the order.
+  /// </summary>
+  [Item("SASEGASAReunificator", "This operator merges the villages (sub-scopes) and redistributes the individuals. It is implemented as described in Affenzeller, M. et al. 2009. Genetic Algorithms and Genetic Programming - Modern Concepts and Practical Applications, CRC Press.")]
+  [StorableClass]
+  public class SASEGASAReunificator : SingleSuccessorOperator {
+
+    public LookupParameter<IntValue> VillageCountParameter {
+      get { return (LookupParameter<IntValue>)Parameters["VillageCount"]; }
+    }
+
+    [StorableConstructor]
+    protected SASEGASAReunificator(bool deserializing) : base(deserializing) { }
+    protected SASEGASAReunificator(SASEGASAReunificator original, Cloner cloner) : base(original, cloner) { }
+    public SASEGASAReunificator()
+      : base() {
+      Parameters.Add(new LookupParameter<IntValue>("VillageCount", "The number of villages left after the reunification."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SASEGASAReunificator(this, cloner);
+    }
+
+    /// <summary>
+    /// Joins all sub sub scopes of the given <paramref name="scope"/>, reduces the number of sub 
+    /// scopes by 1 and uniformly partitions the sub sub scopes again, maintaining the order.
+    /// </summary>
+    /// <exception cref="InvalidOperationException">Thrown when there are less than 2 sub-scopes available or when VillageCount does not equal the number of sub-scopes.</exception>
+    /// <param name="scope">The current scope whose sub scopes to reduce.</param>
+    /// <returns><c>null</c>.</returns>
+    public override IOperation Apply() {
+      IScope scope = ExecutionContext.Scope;
+      if (VillageCountParameter.ActualValue == null) VillageCountParameter.ActualValue = new IntValue(scope.SubScopes.Count);
+      int villageCount = VillageCountParameter.ActualValue.Value;
+      if (villageCount <= 1)
+        throw new InvalidOperationException(Name + ": Reunification requires 2 or more sub-scopes");
+      if (villageCount != scope.SubScopes.Count)
+        throw new InvalidOperationException(Name + ": VillageCount does not equal the number of sub-scopes");
+
+      // get all villages
+      List<IScope> population = new List<IScope>();
+      for (int i = 0; i < villageCount; i++) {
+        population.AddRange(scope.SubScopes[i].SubScopes);
+        scope.SubScopes[i].SubScopes.Clear();
+      }
+
+      // reduce number of villages by 1 and partition the population again
+      scope.SubScopes.RemoveAt(scope.SubScopes.Count - 1);
+      villageCount--;
+      int populationPerVillage = population.Count / villageCount;
+      for (int i = 0; i < villageCount; i++) {
+        scope.SubScopes[i].SubScopes.AddRange(population.GetRange(0, populationPerVillage));
+        population.RemoveRange(0, populationPerVillage);
+      }
+
+      // add remaining individuals to last village
+      scope.SubScopes[scope.SubScopes.Count - 1].SubScopes.AddRange(population);
+      population.Clear();
+
+      VillageCountParameter.ActualValue.Value = villageCount;
+
+      return base.Apply();
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ShakingOperator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ShakingOperator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/ShakingOperator.cs	(revision 16171)
@@ -0,0 +1,73 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// A shaking operator for VNS.
+  /// </summary>
+  [Item("ShakingOperator", "A shaking operator for VNS that can be filled with arbitrary manipulation operators.")]
+  [StorableClass]
+  public class ShakingOperator<T> : CheckedMultiOperator<T>, IMultiNeighborhoodShakingOperator where T : class, IManipulator {
+
+    public IValueLookupParameter<IntValue> CurrentNeighborhoodIndexParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["CurrentNeighborhoodIndex"]; }
+    }
+
+    public ILookupParameter<IntValue> NeighborhoodCountParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["NeighborhoodCount"]; }
+    }
+
+    [StorableConstructor]
+    protected ShakingOperator(bool deserializing) : base(deserializing) { }
+    protected ShakingOperator(ShakingOperator<T> original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ShakingOperator<T>(this, cloner);
+    }
+    public ShakingOperator()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<IntValue>("CurrentNeighborhoodIndex", "The index of the operator that should be applied (k)."));
+      Parameters.Add(new LookupParameter<IntValue>("NeighborhoodCount", "The number of operators that are available."));
+    }
+
+    public override IOperation InstrumentedApply() {
+      if (NeighborhoodCountParameter.ActualValue == null)
+        NeighborhoodCountParameter.ActualValue = new IntValue(Operators.CheckedItems.Count());
+      else NeighborhoodCountParameter.ActualValue.Value = Operators.CheckedItems.Count();
+
+      int index = CurrentNeighborhoodIndexParameter.ActualValue.Value;
+      var shaker = base.Operators.CheckedItems.SingleOrDefault(x => x.Index == index);
+
+      OperationCollection next = new OperationCollection(base.InstrumentedApply());
+      if (shaker.Value != null)
+        next.Insert(0, ExecutionContext.CreateChildOperation(shaker.Value));
+
+      return next;
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/SingleObjectivePathRelinker.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/SingleObjectivePathRelinker.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/SingleObjectivePathRelinker.cs	(revision 16171)
@@ -0,0 +1,86 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// A base class for operators that perform path relinking between single objective solutions.
+  /// </summary>
+  [Item("SingleObjectivePathRelinker", "A base class for operators that perform path relinking between single objective solutions.")]
+  [StorableClass]
+  public abstract class SingleObjectivePathRelinker : SingleSuccessorOperator, ISingleObjectivePathRelinker {
+    #region Parameter properties
+    public ScopeParameter CurrentScopeParameter {
+      get { return (ScopeParameter)Parameters["CurrentScope"]; }
+    }
+    public ILookupParameter<ItemArray<IItem>> ParentsParameter {
+      get { return (IScopeTreeLookupParameter<IItem>)Parameters["Parents"]; }
+    }
+    public IValueParameter<PercentValue> RelinkingAccuracyParameter {
+      get { return (IValueParameter<PercentValue>)Parameters["RelinkingAccuracy"]; }
+    }
+    #endregion
+
+    #region Properties
+    private IScope CurrentScope {
+      get { return CurrentScopeParameter.ActualValue; }
+    }
+    private ItemArray<IItem> Parents {
+      get { return ParentsParameter.ActualValue; }
+    }
+    private PercentValue RelinkingAccuracy {
+      get { return RelinkingAccuracyParameter.Value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected SingleObjectivePathRelinker(bool deserializing) : base(deserializing) { }
+    protected SingleObjectivePathRelinker(SingleObjectivePathRelinker original, Cloner cloner) : base(original, cloner) { }
+    protected SingleObjectivePathRelinker()
+      : base() {
+      #region Create parameters
+      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope that contains the parents."));
+      Parameters.Add(new ScopeTreeLookupParameter<IItem>("Parents", "The parents used for path relinking."));
+      Parameters.Add(new ValueParameter<PercentValue>("RelinkingAccuracy", "The percentage of relinked offspring that should be yielded.", new PercentValue(0.25)));
+      #endregion
+    }
+
+    public sealed override IOperation Apply() {
+      ItemArray<IItem> relinkedSolutions = Relink(Parents, RelinkingAccuracy);
+      var offspringScope = new Scope("Offspring");
+      foreach (var solution in relinkedSolutions) {
+        var scope = new Scope();
+        scope.Variables.Add(new Variable(ParentsParameter.ActualName, solution));
+        offspringScope.SubScopes.Add(scope);
+      }
+      CurrentScope.SubScopes.Add(offspringScope);
+      return base.Apply();
+    }
+
+    protected abstract ItemArray<IItem> Relink(ItemArray<IItem> parents, PercentValue n);
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/SingleObjectiveSolutionSimilarityCalculator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/SingleObjectiveSolutionSimilarityCalculator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/SingleObjectiveSolutionSimilarityCalculator.cs	(revision 16171)
@@ -0,0 +1,56 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// A base class for items that perform similarity calculation between two single objective solutions.
+  /// </summary>
+  [Item("SimilarityCalculator", "A base class for items that perform similarity calculation between two solutions.")]
+  [StorableClass]
+#pragma warning disable 0618
+  public abstract class SingleObjectiveSolutionSimilarityCalculator : SolutionSimilarityCalculator, ISingleObjectiveSolutionSimilarityCalculator {
+#pragma warning restore 0618
+    [StorableConstructor]
+    protected SingleObjectiveSolutionSimilarityCalculator(bool deserializing) : base(deserializing) { }
+    protected SingleObjectiveSolutionSimilarityCalculator(SingleObjectiveSolutionSimilarityCalculator original, Cloner cloner)
+      : base(original, cloner) {
+
+    }
+    protected SingleObjectiveSolutionSimilarityCalculator() : base() { }
+
+    public override bool Equals(IScope x, IScope y) {
+      if (object.ReferenceEquals(x, y)) return true;
+      if (x == null || y == null) return false;
+      double q1 = ((DoubleValue)x.Variables[QualityVariableName].Value).Value;
+      double q2 = ((DoubleValue)y.Variables[QualityVariableName].Value).Value;
+      return q1.IsAlmost(q2) && CalculateSolutionSimilarity(x, y).IsAlmost(1.0);
+    }
+
+    public override int GetHashCode(IScope scope) {
+      return ((DoubleValue)scope.Variables[QualityVariableName].Value).Value.GetHashCode();
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/SolutionSimilarityCalculator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/SolutionSimilarityCalculator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/SolutionSimilarityCalculator.cs	(revision 16171)
@@ -0,0 +1,206 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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 System.Threading.Tasks;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// A base class for items that perform similarity calculation between two solutions.
+  /// </summary>
+  [Item("SimilarityCalculator", "A base class for items that perform similarity calculation between two solutions.")]
+  [StorableClass]
+  public abstract class SolutionSimilarityCalculator : Item, ISolutionSimilarityCalculator {
+    protected abstract bool IsCommutative { get; }
+
+    #region Properties
+    [Storable]
+    public string SolutionVariableName { get; set; }
+    [Storable]
+    public string QualityVariableName { get; set; }
+    [Storable]
+    public bool ExecuteInParallel { get; set; }
+    [Storable]
+    public int MaxDegreeOfParallelism { get; set; }
+    #endregion
+
+    [StorableConstructor]
+    protected SolutionSimilarityCalculator(bool deserializing) : base(deserializing) { }
+
+    protected SolutionSimilarityCalculator(SolutionSimilarityCalculator original, Cloner cloner)
+      : base(original, cloner) {
+      SolutionVariableName = original.SolutionVariableName;
+      QualityVariableName = original.QualityVariableName;
+      ExecuteInParallel = original.ExecuteInParallel;
+      MaxDegreeOfParallelism = original.MaxDegreeOfParallelism;
+    }
+
+    protected SolutionSimilarityCalculator() : base() {
+      ExecuteInParallel = false;
+      MaxDegreeOfParallelism = -1;
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (MaxDegreeOfParallelism == 0) {
+        ExecuteInParallel = false;
+        MaxDegreeOfParallelism = -1;
+      }
+    }
+
+    public double[][] CalculateSolutionCrowdSimilarity(IScope leftSolutionCrowd, IScope rightSolutionCrowd) {
+      if (leftSolutionCrowd == null || rightSolutionCrowd == null)
+        throw new ArgumentException("Cannot calculate similarity because one of the provided crowds or both are null.");
+
+      var leftIndividuals = leftSolutionCrowd.SubScopes;
+      var rightIndividuals = rightSolutionCrowd.SubScopes;
+
+      if (!leftIndividuals.Any() || !rightIndividuals.Any())
+        throw new ArgumentException("Cannot calculate similarity because one of the provided crowds or both are empty.");
+
+      var similarityMatrix = new double[leftIndividuals.Count][];
+      for (int i = 0; i < leftIndividuals.Count; i++) {
+        similarityMatrix[i] = new double[rightIndividuals.Count];
+        for (int j = 0; j < rightIndividuals.Count; j++) {
+          similarityMatrix[i][j] = CalculateSolutionSimilarity(leftIndividuals[i], rightIndividuals[j]);
+        }
+      }
+
+      return similarityMatrix;
+    }
+
+    public double[][] CalculateSolutionCrowdSimilarity(IScope solutionCrowd) {
+      if (solutionCrowd == null) {
+        throw new ArgumentException("Cannot calculate similarity because the provided crowd is null.");
+      }
+      var individuals = solutionCrowd.SubScopes;
+
+      if (!individuals.Any()) {
+        throw new ArgumentException("Cannot calculate similarity because the provided crowd is empty.");
+      }
+
+      var similarityMatrix = new double[individuals.Count][];
+      for (int i = 0; i < individuals.Count; i++) {
+        similarityMatrix[i] = new double[individuals.Count];
+      }
+
+      if (ExecuteInParallel) {
+        var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = MaxDegreeOfParallelism };
+        if (IsCommutative) {
+          Parallel.For(0, individuals.Count, parallelOptions, i => {
+            for (int j = i; j < individuals.Count; j++) {
+              similarityMatrix[i][j] =
+                similarityMatrix[j][i] = CalculateSolutionSimilarity(individuals[i], individuals[j]);
+            }
+          });
+        } else {
+          Parallel.For(0, individuals.Count, parallelOptions, i => {
+            for (int j = i; j < individuals.Count; j++) {
+              similarityMatrix[i][j] = CalculateSolutionSimilarity(individuals[i], individuals[j]);
+              if (i == j) continue;
+              similarityMatrix[j][i] = CalculateSolutionSimilarity(individuals[j], individuals[i]);
+            }
+          });
+        }
+      } else {
+        if (IsCommutative) {
+          for (int i = 0; i < individuals.Count; i++) {
+            for (int j = i; j < individuals.Count; j++) {
+              similarityMatrix[i][j] =
+                similarityMatrix[j][i] = CalculateSolutionSimilarity(individuals[i], individuals[j]);
+            }
+          }
+        } else {
+          for (int i = 0; i < individuals.Count; i++) {
+            for (int j = i; j < individuals.Count; j++) {
+              similarityMatrix[i][j] = CalculateSolutionSimilarity(individuals[i], individuals[j]);
+              if (i == j) continue;
+              similarityMatrix[j][i] = CalculateSolutionSimilarity(individuals[j], individuals[i]);
+            }
+          }
+        }
+      }
+
+      return similarityMatrix;
+    }
+
+    public abstract double CalculateSolutionSimilarity(IScope leftSolution, IScope rightSolution);
+
+    public virtual bool Equals(IScope x, IScope y) {
+      if (ReferenceEquals(x, y)) return true;
+      if (x == null || y == null) return false;
+
+      var q1 = x.Variables[QualityVariableName].Value;
+      var q2 = y.Variables[QualityVariableName].Value;
+
+      return CheckQualityEquality(q1, q2) && CalculateSolutionSimilarity(x, y).IsAlmost(1.0);
+    }
+
+    public virtual int GetHashCode(IScope scope) {
+      var quality = scope.Variables[QualityVariableName].Value;
+      var dv = quality as DoubleValue;
+      if (dv != null)
+        return dv.Value.GetHashCode();
+
+      var da = quality as DoubleArray;
+      if (da != null) {
+        int hash = 17;
+        unchecked {
+          for (int i = 0; i < da.Length; ++i) {
+            hash += hash * 23 + da[i].GetHashCode();
+          }
+          return hash;
+        }
+      }
+      return 0;
+    }
+
+    private static bool CheckQualityEquality(IItem q1, IItem q2) {
+      var d1 = q1 as DoubleValue;
+      var d2 = q2 as DoubleValue;
+
+      if (d1 != null && d2 != null)
+        return d1.Value.IsAlmost(d2.Value);
+
+      var da1 = q1 as DoubleArray;
+      var da2 = q2 as DoubleArray;
+
+      if (da1 != null && da2 != null) {
+        if (da1.Length != da2.Length)
+          throw new ArgumentException("The quality arrays must have the same length.");
+
+        for (int i = 0; i < da1.Length; ++i) {
+          if (!da1[i].IsAlmost(da2[i]))
+            return false;
+        }
+
+        return true;
+      }
+
+      throw new ArgumentException("Could not determine quality equality.");
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/SolutionsCreator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/SolutionsCreator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/SolutionsCreator.cs	(revision 16171)
@@ -0,0 +1,102 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// An operator which creates new solutions. Evaluation of the new solutions is executed in parallel, if an engine is used which supports parallelization.
+  /// </summary>
+  [Item("SolutionsCreator", "An operator which creates new solutions. Evaluation of the new solutions is executed in parallel, if an engine is used which supports parallelization.")]
+  [StorableClass]
+  public sealed class SolutionsCreator : SingleSuccessorOperator {
+    public ValueLookupParameter<IntValue> NumberOfSolutionsParameter {
+      get { return (ValueLookupParameter<IntValue>)Parameters["NumberOfSolutions"]; }
+    }
+    public ValueLookupParameter<IOperator> SolutionCreatorParameter {
+      get { return (ValueLookupParameter<IOperator>)Parameters["SolutionCreator"]; }
+    }
+    public ValueLookupParameter<IOperator> EvaluatorParameter {
+      get { return (ValueLookupParameter<IOperator>)Parameters["Evaluator"]; }
+    }
+    public ValueLookupParameter<BoolValue> ParallelParameter {
+      get { return (ValueLookupParameter<BoolValue>)Parameters["Parallel"]; }
+    }
+    private ScopeParameter CurrentScopeParameter {
+      get { return (ScopeParameter)Parameters["CurrentScope"]; }
+    }
+    public IScope CurrentScope {
+      get { return CurrentScopeParameter.ActualValue; }
+    }
+    public IntValue NumberOfSolutions {
+      get { return NumberOfSolutionsParameter.Value; }
+      set { NumberOfSolutionsParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    private SolutionsCreator(bool deserializing) : base(deserializing) { }
+    private SolutionsCreator(SolutionsCreator original, Cloner cloner) : base(original, cloner) { }
+    public SolutionsCreator()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<IntValue>("NumberOfSolutions", "The number of solutions that should be created."));
+      Parameters.Add(new ValueLookupParameter<IOperator>("SolutionCreator", "The operator which is used to create new solutions."));
+      Parameters.Add(new ValueLookupParameter<IOperator>("Evaluator", "The operator which is used to evaluate new solutions. This operator is executed in parallel, if an engine is used which supports parallelization."));
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Parallel", "True if the operator should be applied in parallel on all sub-scopes, otherwise false.", new BoolValue(true)));
+      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope to which the new solutions are added as sub-scopes."));      
+    }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (!Parameters.ContainsKey("Parallel")) Parameters.Add(new ValueLookupParameter<BoolValue>("Parallel", "True if the operator should be applied in parallel on all sub-scopes, otherwise false.", new BoolValue(true))); // backwards compatibility
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SolutionsCreator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      int count = NumberOfSolutionsParameter.ActualValue.Value;
+      IOperator creator = SolutionCreatorParameter.ActualValue;
+      IOperator evaluator = EvaluatorParameter.ActualValue;
+      bool parallel = ParallelParameter.ActualValue.Value;
+
+      int current = CurrentScope.SubScopes.Count;
+      for (int i = 0; i < count; i++)
+        CurrentScope.SubScopes.Add(new Scope((current + i).ToString()));
+
+      OperationCollection creation = new OperationCollection();
+      OperationCollection evaluation = new OperationCollection() { Parallel = parallel };
+      for (int i = 0; i < count; i++) {
+        if (creator != null) creation.Add(ExecutionContext.CreateOperation(creator, CurrentScope.SubScopes[current + i]));
+        if (evaluator != null) evaluation.Add(ExecutionContext.CreateOperation(evaluator, CurrentScope.SubScopes[current + i]));
+      }
+      OperationCollection next = new OperationCollection();
+      next.Add(creation);
+      next.Add(evaluation);
+      next.Add(base.Apply());
+      return next;
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/SquareRootDiscreteDoubleValueModifier.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/SquareRootDiscreteDoubleValueModifier.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/SquareRootDiscreteDoubleValueModifier.cs	(revision 16171)
@@ -0,0 +1,48 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// Modifies the value by square rooted fall (fast fall initially, slow fall to the end) or rise (fast rise initially, slow rise to the end).
+  /// </summary>
+  [Item("SquareRootDiscreteDoubleValueModifier", "Modifies the value by square rooted fall (fast fall initially, slow fall to the end) or rise (fast rise initially, slow rise to the end).")]
+  [StorableClass]
+  public class SquareRootDiscreteDoubleValueModifier : DiscreteDoubleValueModifier {
+    [StorableConstructor]
+    protected SquareRootDiscreteDoubleValueModifier(bool deserializing) : base(deserializing) { }
+    protected SquareRootDiscreteDoubleValueModifier(SquareRootDiscreteDoubleValueModifier original, Cloner cloner) : base(original, cloner) { }
+    public SquareRootDiscreteDoubleValueModifier() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SquareRootDiscreteDoubleValueModifier(this, cloner);
+    }
+
+    protected override double Modify(double value, double startValue, double endValue, int index, int startIndex, int endIndex) {
+      double a = (endValue - startValue) / Math.Sqrt(endIndex - startIndex);
+      return a * Math.Sqrt(index - startIndex) + startValue;
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/TabuMaker.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/TabuMaker.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/TabuMaker.cs	(revision 16171)
@@ -0,0 +1,85 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  [Item("TabuMaker", "Base class for all operators that set a move tabu.")]
+  [StorableClass]
+  public abstract class TabuMaker : SingleSuccessorOperator, ITabuMaker, ISingleObjectiveOperator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public LookupParameter<ItemList<IItem>> TabuListParameter {
+      get { return (LookupParameter<ItemList<IItem>>)Parameters["TabuList"]; }
+    }
+    public ValueLookupParameter<IntValue> TabuTenureParameter {
+      get { return (ValueLookupParameter<IntValue>)Parameters["TabuTenure"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
+    }
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public IValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+
+    [StorableConstructor]
+    protected TabuMaker(bool deserializing) : base(deserializing) { }
+    protected TabuMaker(TabuMaker original, Cloner cloner) : base(original, cloner) { }
+    protected TabuMaker()
+      : base() {
+      Parameters.Add(new LookupParameter<ItemList<IItem>>("TabuList", "The tabu list where move attributes are stored."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("TabuTenure", "The tenure of the tabu list."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The quality of the move."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of the solution."));
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, else if it is a minimization problem."));
+    }
+
+    public override IOperation Apply() {
+      ItemList<IItem> tabuList = TabuListParameter.ActualValue;
+      int tabuTenure = TabuTenureParameter.ActualValue.Value;
+      if (tabuTenure == 0) return base.Apply();
+      if (tabuTenure < 0) throw new InvalidOperationException("A TabuTenure of less than 0 is not allowed.");
+
+      int overlength = tabuList.Count - tabuTenure;
+      if (overlength >= 0) {
+        for (int i = 0; i < tabuTenure - 1; i++)
+          tabuList[i] = tabuList[i + overlength + 1];
+        while (tabuList.Count >= tabuTenure)
+          tabuList.RemoveAt(tabuList.Count - 1);
+      }
+
+      tabuList.Add(GetTabuAttribute(MaximizationParameter.ActualValue.Value, QualityParameter.ActualValue.Value, MoveQualityParameter.ActualValue.Value));
+      return base.Apply();
+    }
+
+    protected abstract IItem GetTabuAttribute(bool maximization, double quality, double moveQuality);
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/UnidirectionalRingMigrator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/UnidirectionalRingMigrator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/UnidirectionalRingMigrator.cs	(revision 16171)
@@ -0,0 +1,104 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// Operator that migrates the selected sub scopes in each subscope in an unidirectional ring.
+  /// </summary>
+  [Item("UnidirectionalRingMigrator", "Migrates the selected sub scopes in each subscope in an unidirectional ring.")]
+  [StorableClass]
+  public class UnidirectionalRingMigrator : SingleSuccessorOperator, IMigrator {
+    public IValueLookupParameter<BoolValue> ClockwiseMigrationParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["ClockwiseMigration"]; }
+    }
+
+    [StorableConstructor]
+    protected UnidirectionalRingMigrator(bool deserializing) : base(deserializing) { }
+    protected UnidirectionalRingMigrator(UnidirectionalRingMigrator original, Cloner cloner) : base(original, cloner) { }
+
+    public UnidirectionalRingMigrator()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<BoolValue>("ClockwiseMigration", "True to migrate individuals clockwise, false to migrate individuals counterclockwise.", new BoolValue(true)));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code (remove with 3.4)
+      if (!Parameters.ContainsKey("ClockwiseMigration")) {
+        Parameters.Add(new ValueLookupParameter<BoolValue>("ClockwiseMigration", "True to migrate individuals clockwise, false to migrate individuals counterclockwise.", new BoolValue(false)));
+      }
+      #endregion
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new UnidirectionalRingMigrator(this, cloner);
+    }
+
+    /// <summary>
+    /// Migrates every first sub scope of each child to its right or left neighbour (like a ring).
+    /// If clockwise migration (default) is used the selected scopes A D G becomes G A D, contrary to counterclockwise where A D G becomes D G A.
+    /// <pre>
+    ///          __ scope __              __ scope __
+    ///         /     |     \            /     |     \
+    ///       Pop1   Pop2   Pop3  =>   Pop1   Pop2   Pop3
+    ///       / \    / \    / \        / \    / \    / \
+    ///      R   S  R   S  R   S      R   S  R   S  R   S
+    ///     /|\  | /|\  | /|\  |     /|\  | /|\  | /|\  |
+    ///     ABC  A DEF  D GHI  G     ABC  G DEF  A GHI  D
+    /// </pre>
+    /// </summary>
+    /// <returns>The next operation.</returns>
+    public override IOperation Apply() {
+      bool clockwise = ClockwiseMigrationParameter.ActualValue.Value;
+      IScope scope = ExecutionContext.Scope;
+      List<IScope> emigrantsList = new List<IScope>();
+
+      for (int i = 0; i < scope.SubScopes.Count; i++) {
+        IScope emigrants = scope.SubScopes[i].SubScopes[1];
+        scope.SubScopes[i].SubScopes.Remove(emigrants);
+        emigrantsList.Add(emigrants);
+      }
+
+      if (clockwise) {
+        // shift last emigrants to start of list
+        emigrantsList.Insert(0, emigrantsList[emigrantsList.Count - 1]);
+        emigrantsList.RemoveAt(emigrantsList.Count - 1);
+      } else {
+        // shift first emigrants to end of list
+        emigrantsList.Add(emigrantsList[0]);
+        emigrantsList.RemoveAt(0);
+      }
+
+      for (int i = 0; i < scope.SubScopes.Count; i++)
+        scope.SubScopes[i].SubScopes.Add(emigrantsList[i]);
+
+      return base.Apply();
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/UserDefinedCrossover.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/UserDefinedCrossover.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/UserDefinedCrossover.cs	(revision 16171)
@@ -0,0 +1,39 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  [Item("UserDefinedCrossover", "A crossover that can be customized with operators which it will execute one after another.")]
+  [StorableClass]
+  public class UserDefinedCrossover : UserDefinedOperator, ICrossover {
+    [StorableConstructor]
+    protected UserDefinedCrossover(bool deserializing) : base(deserializing) { }
+    protected UserDefinedCrossover(UserDefinedCrossover original, Cloner cloner) : base(original, cloner) { }
+    public UserDefinedCrossover() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new UserDefinedCrossover(this, cloner);
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/UserDefinedEvaluator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/UserDefinedEvaluator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/UserDefinedEvaluator.cs	(revision 16171)
@@ -0,0 +1,48 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  [Item("UserDefinedEvaluator", "An evaluator that can be customized with operators which it will execute one after another.")]
+  [StorableClass]
+  public class UserDefinedEvaluator : UserDefinedOperator, ISingleObjectiveEvaluator {
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+
+    [StorableConstructor]
+    protected UserDefinedEvaluator(bool deserializing) : base(deserializing) { }
+    protected UserDefinedEvaluator(UserDefinedEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public UserDefinedEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value of the solution."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new UserDefinedEvaluator(this, cloner);
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/UserDefinedManipulator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/UserDefinedManipulator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/UserDefinedManipulator.cs	(revision 16171)
@@ -0,0 +1,39 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  [Item("UserDefinedManipulator", "A manipulator that can be customized with operators which it will execute one after another.")]
+  [StorableClass]
+  public class UserDefinedManipulator : UserDefinedOperator, IManipulator {
+    [StorableConstructor]
+    protected UserDefinedManipulator(bool deserializing) : base(deserializing) { }
+    protected UserDefinedManipulator(UserDefinedManipulator original, Cloner cloner) : base(original, cloner) { }
+    public UserDefinedManipulator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new UserDefinedManipulator(this, cloner);
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/UserDefinedOperator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/UserDefinedOperator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/UserDefinedOperator.cs	(revision 16171)
@@ -0,0 +1,46 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Operators;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  [Item("UserDefinedOperator", "An operator that can be parameterized with multiple operators which will be executed one after another.")]
+  [StorableClass]
+  public abstract class UserDefinedOperator : CheckedMultiOperator<IOperator> {
+    [StorableConstructor]
+    protected UserDefinedOperator(bool deserializing) : base(deserializing) { }
+    protected UserDefinedOperator(UserDefinedOperator original, Cloner cloner) : base(original, cloner) { }
+    public UserDefinedOperator() : base() { }
+
+    public override IOperation InstrumentedApply() {
+      OperationCollection result = new OperationCollection();
+      foreach (IOperator op in Operators.CheckedItems.OrderBy(x => x.Index).Select(x => x.Value)) {
+        result.Add(ExecutionContext.CreateOperation(op));
+      }
+      result.Add(base.InstrumentedApply());
+      return result;
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/UserDefinedSolutionCreator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/UserDefinedSolutionCreator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/UserDefinedSolutionCreator.cs	(revision 16171)
@@ -0,0 +1,39 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  [Item("UserDefinedSolutionCreator", "A solution creator that can be customized with operators which it will execute one after another.")]
+  [StorableClass]
+  public class UserDefinedSolutionCreator : UserDefinedOperator, ISolutionCreator {
+    [StorableConstructor]
+    protected UserDefinedSolutionCreator(bool deserializing) : base(deserializing) { }
+    protected UserDefinedSolutionCreator(UserDefinedSolutionCreator original, Cloner cloner) : base(original, cloner) { }
+    public UserDefinedSolutionCreator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new UserDefinedSolutionCreator(this, cloner);
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/WeightedParentsQualityComparator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/WeightedParentsQualityComparator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization.Operators/3.3/WeightedParentsQualityComparator.cs	(revision 16171)
@@ -0,0 +1,127 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  [Item("WeightedParentsQualityComparator", "Compares the quality against that of its parents (assumes the parents are subscopes to the child scope). This operator works with any number of subscopes > 0.")]
+  [StorableClass]
+  public class WeightedParentsQualityComparator : SingleSuccessorOperator, ISubScopesQualityComparator {
+    public IValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ILookupParameter<DoubleValue> LeftSideParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["LeftSide"]; }
+    }
+    public ILookupParameter<ItemArray<DoubleValue>> RightSideParameter {
+      get { return (ILookupParameter<ItemArray<DoubleValue>>)Parameters["RightSide"]; }
+    }
+    public ILookupParameter<BoolValue> ResultParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Result"]; }
+    }
+    public ValueLookupParameter<DoubleValue> ComparisonFactorParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["ComparisonFactor"]; }
+    }
+
+    [StorableConstructor]
+    protected WeightedParentsQualityComparator(bool deserializing) : base(deserializing) { }
+    protected WeightedParentsQualityComparator(WeightedParentsQualityComparator original, Cloner cloner) : base(original, cloner) { }
+    public WeightedParentsQualityComparator()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, false otherwise"));
+      Parameters.Add(new LookupParameter<DoubleValue>("LeftSide", "The quality of the child."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("RightSide", "The qualities of the parents."));
+      Parameters.Add(new LookupParameter<BoolValue>("Result", "The result of the comparison: True means Quality is better, False means it is worse than parents."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("ComparisonFactor", "Determines if the quality should be compared to the better parent (1.0), to the worse (0.0) or to any linearly interpolated value between them."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new WeightedParentsQualityComparator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      ItemArray<DoubleValue> rightQualities = RightSideParameter.ActualValue;
+      if (rightQualities.Length < 1) throw new InvalidOperationException(Name + ": No subscopes found.");
+      double compFact = ComparisonFactorParameter.ActualValue.Value;
+      bool maximization = MaximizationParameter.ActualValue.Value;
+      double leftQuality = LeftSideParameter.ActualValue.Value;
+
+      double threshold = 0;
+
+      #region Calculate threshold
+      if (rightQualities.Length == 2) { // this case will probably be used most often
+        double minQuality = Math.Min(rightQualities[0].Value, rightQualities[1].Value);
+        double maxQuality = Math.Max(rightQualities[0].Value, rightQualities[1].Value);
+        if (maximization)
+          threshold = minQuality + (maxQuality - minQuality) * compFact;
+        else
+          threshold = maxQuality - (maxQuality - minQuality) * compFact;
+      } else if (rightQualities.Length == 1) { // case for just one parent
+        threshold = rightQualities[0].Value;
+      } else { // general case extended to 3 or more parents
+        List<double> sortedQualities = rightQualities.Select(x => x.Value).ToList();
+        sortedQualities.Sort();
+        double minimumQuality = sortedQualities.First();
+
+        double integral = 0;
+        for (int i = 0; i < sortedQualities.Count - 1; i++) {
+          integral += (sortedQualities[i] + sortedQualities[i + 1]) / 2.0; // sum of the trapezoid
+        }
+        integral -= minimumQuality * sortedQualities.Count;
+        if (integral == 0) threshold = sortedQualities[0]; // all qualities are equal
+        else {
+          double selectedArea = integral * (maximization ? compFact : (1 - compFact));
+          integral = 0;
+          for (int i = 0; i < sortedQualities.Count - 1; i++) {
+            double currentSliceArea = (sortedQualities[i] + sortedQualities[i + 1]) / 2.0;
+            double windowedSliceArea = currentSliceArea - minimumQuality;
+            if (windowedSliceArea == 0) continue;
+            integral += windowedSliceArea;
+            if (integral >= selectedArea) {
+              double factor = 1 - ((integral - selectedArea) / (windowedSliceArea));
+              threshold = sortedQualities[i] + (sortedQualities[i + 1] - sortedQualities[i]) * factor;
+              break;
+            }
+          }
+        }
+      }
+      #endregion
+
+      bool result = maximization && leftQuality > threshold || !maximization && leftQuality < threshold;
+      BoolValue resultValue = ResultParameter.ActualValue;
+      if (resultValue == null) {
+        ResultParameter.ActualValue = new BoolValue(result);
+      } else {
+        resultValue.Value = result;
+      }
+
+      return base.Apply();
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/BasicProblems/BasicProblem.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/BasicProblems/BasicProblem.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/BasicProblems/BasicProblem.cs	(revision 16171)
@@ -30,5 +30,5 @@
 namespace HeuristicLab.Optimization {
   [StorableClass]
-  public abstract class BasicProblem<TEncoding, TEvaluator> : HeuristicOptimizationProblem<TEvaluator, ISolutionCreator>, IProblemDefinition, IStorableContent
+  public abstract class BasicProblem<TEncoding, TEvaluator> : HeuristicOptimizationProblem<TEvaluator, ISolutionCreator>, IBasicProblem
     where TEncoding : class, IEncoding
     where TEvaluator : class, IEvaluator {
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IBasicProblem.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IBasicProblem.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IBasicProblem.cs	(revision 16171)
@@ -0,0 +1,25 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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
+
+namespace HeuristicLab.Optimization {
+  public interface IBasicProblem : IHeuristicOptimizationProblem, IProblemDefinition {
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IMultiObjectiveBasicProblem.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IMultiObjectiveBasicProblem.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IMultiObjectiveBasicProblem.cs	(revision 16171)
@@ -0,0 +1,35 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  public interface IMultiObjectiveBasicProblem : IBasicProblem, IMultiObjectiveProblemDefinition, IMultiObjectiveHeuristicOptimizationProblem
+  {
+    IValueParameter<DoubleMatrix> BestKnownFrontParameter { get; } 
+    DoubleMatrix BestKnownFront { get; }
+
+    IValueParameter<DoubleArray> ReferencePointParameter { get; }
+    DoubleArray ReferencePoint { get; }
+
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/ISingleObjectiveBasicProblem.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/ISingleObjectiveBasicProblem.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/ISingleObjectiveBasicProblem.cs	(revision 16171)
@@ -0,0 +1,30 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+
+  public interface ISingleObjectiveBasicProblem : IBasicProblem, ISingleObjectiveProblemDefinition, ISingleObjectiveHeuristicOptimizationProblem {
+    double BestKnownQuality { get; }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/BasicProblems/MultiObjectiveBasicProblem.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/BasicProblems/MultiObjectiveBasicProblem.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/BasicProblems/MultiObjectiveBasicProblem.cs	(revision 16171)
@@ -31,6 +31,39 @@
 namespace HeuristicLab.Optimization {
   [StorableClass]
-  public abstract class MultiObjectiveBasicProblem<TEncoding> : BasicProblem<TEncoding, MultiObjectiveEvaluator>, IMultiObjectiveHeuristicOptimizationProblem, IMultiObjectiveProblemDefinition
+  public abstract class MultiObjectiveBasicProblem<TEncoding> : BasicProblem<TEncoding, MultiObjectiveEvaluator>, IMultiObjectiveBasicProblem
   where TEncoding : class, IEncoding {
+
+    #region Parameternames
+    public const string MaximizationParameterName = "Maximization";
+    public const string BestKnownFrontParameterName = "BestKnownFront";
+    public const string ReferencePointParameterName = "ReferencePoint";
+    #endregion
+
+    #region Parameterproperties
+    public IValueParameter<BoolArray> MaximizationParameter {
+      get { return (IValueParameter<BoolArray>) Parameters[MaximizationParameterName]; }
+    }
+    public IValueParameter<DoubleMatrix> BestKnownFrontParameter {
+      get { return (IValueParameter<DoubleMatrix>)Parameters[BestKnownFrontParameterName]; }
+    }
+    public IValueParameter<DoubleArray> ReferencePointParameter {
+      get { return (IValueParameter<DoubleArray>)Parameters[ReferencePointParameterName]; }
+    }
+    #endregion
+
+    #region Properties
+
+    public abstract bool[] Maximization { get; }
+
+    public DoubleMatrix BestKnownFront {
+      get { return Parameters.ContainsKey(BestKnownFrontParameterName) ? BestKnownFrontParameter.Value : null; }
+      set { BestKnownFrontParameter.Value = value; }
+    }
+    public DoubleArray ReferencePoint {
+      get { return Parameters.ContainsKey(ReferencePointParameterName) ? ReferencePointParameter.Value : null; }
+      set { ReferencePointParameter.Value = value; }
+    }
+    #endregion
+
     [StorableConstructor]
     protected MultiObjectiveBasicProblem(bool deserializing) : base(deserializing) { }
@@ -43,6 +76,7 @@
     protected MultiObjectiveBasicProblem()
       : base() {
-      Parameters.Add(new ValueParameter<BoolArray>("Maximization", "Set to false if the problem should be minimized.", (BoolArray)new BoolArray(Maximization).AsReadOnly()));
-
+      Parameters.Add(new ValueParameter<BoolArray>(MaximizationParameterName, "Set to false if the problem should be minimized.", (BoolArray)new BoolArray(Maximization).AsReadOnly()));
+      Parameters.Add(new OptionalValueParameter<DoubleMatrix>(BestKnownFrontParameterName, "A double matrix representing the best known qualites for this problem (aka points on the Pareto front). Points are to be given in a row-wise fashion."));
+      Parameters.Add(new OptionalValueParameter<DoubleArray>(ReferencePointParameterName, "The refrence point for hypervolume calculations on this problem"));
       Operators.Add(Evaluator);
       Operators.Add(new MultiObjectiveAnalyzer());
@@ -56,5 +90,5 @@
     }
 
-    public abstract bool[] Maximization { get; }
+    
     public abstract double[] Evaluate(Individual individual, IRandom random);
     public virtual void Analyze(Individual[] individuals, double[][] qualities, ResultCollection results, IRandom random) { }
@@ -96,8 +130,7 @@
     }
 
-
     #region IMultiObjectiveHeuristicOptimizationProblem Members
     IParameter IMultiObjectiveHeuristicOptimizationProblem.MaximizationParameter {
-      get { return Parameters["Maximization"]; }
+      get { return Parameters[MaximizationParameterName]; }
     }
     IMultiObjectiveEvaluator IMultiObjectiveHeuristicOptimizationProblem.Evaluator {
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/BasicProblems/SingleObjectiveBasicProblem.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/BasicProblems/SingleObjectiveBasicProblem.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/BasicProblems/SingleObjectiveBasicProblem.cs	(revision 16171)
@@ -31,6 +31,5 @@
 namespace HeuristicLab.Optimization {
   [StorableClass]
-  public abstract class SingleObjectiveBasicProblem<TEncoding> : BasicProblem<TEncoding, SingleObjectiveEvaluator>,
-    ISingleObjectiveProblemDefinition, ISingleObjectiveHeuristicOptimizationProblem
+  public abstract class SingleObjectiveBasicProblem<TEncoding> : BasicProblem<TEncoding, SingleObjectiveEvaluator>, ISingleObjectiveBasicProblem
   where TEncoding : class, IEncoding {
 
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 16171)
@@ -41,5 +41,5 @@
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
-    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <OutputPath>..\..\..\..\trunk\bin\</OutputPath>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
@@ -105,4 +105,12 @@
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="ALGLIB-3.7.0, Version=3.7.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\ALGLIB-3.7.0.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.ALGLIB-3.7.0, Version=3.7.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.ALGLIB-3.7.0.dll</HintPath>
+    </Reference>
     <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -120,8 +128,4 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Core-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Data-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Data-3.3.dll</HintPath>
     </Reference>
     <Reference Include="HeuristicLab.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
@@ -162,7 +166,9 @@
     <Compile Include="BasicProblems\Individuals\MultiEncodingIndividual.cs" />
     <Compile Include="BasicProblems\Individuals\SingleEncodingIndividual.cs" />
+    <Compile Include="BasicProblems\Interfaces\IBasicProblem.cs" />
     <Compile Include="BasicProblems\Interfaces\IEncoding.cs" />
     <Compile Include="BasicProblems\Interfaces\IEncodingOperator.cs" />
     <Compile Include="BasicProblems\Interfaces\IMultiEncodingOperator.cs" />
+    <Compile Include="BasicProblems\Interfaces\IMultiObjectiveBasicProblem.cs" />
     <Compile Include="BasicProblems\Interfaces\IMultiObjectiveProblemDefinition.cs" />
     <Compile Include="BasicProblems\Interfaces\internal\IMultiObjectiveAnalysisOperator.cs" />
@@ -172,4 +178,5 @@
     <Compile Include="BasicProblems\Interfaces\internal\ISingleObjectiveEvaluationOperator.cs" />
     <Compile Include="BasicProblems\Interfaces\IProblemDefinition.cs" />
+    <Compile Include="BasicProblems\Interfaces\ISingleObjectiveBasicProblem.cs" />
     <Compile Include="BasicProblems\Interfaces\ISingleObjectiveMoveOperator.cs" />
     <Compile Include="BasicProblems\Interfaces\ISingleObjectiveProblemDefinition.cs" />
@@ -192,5 +199,9 @@
     <Compile Include="Interfaces\ILocalImprovementAlgorithmOperator.cs" />
     <Compile Include="Interfaces\IMultiObjectiveOperator.cs" />
+    <Compile Include="MultiObjective\CrowdingCalculator.cs" />
     <Compile Include="MultiObjective\DominationCalculator.cs" />
+    <Compile Include="MultiObjective\GenerationalDistanceCalculator.cs" />
+    <Compile Include="MultiObjective\HypervolumeCalculator.cs" />
+    <Compile Include="MultiObjective\SpacingCalculator.cs" />
     <Compile Include="Results\IResultParameter.cs" />
     <Compile Include="Interfaces\ISingleObjectiveOperator.cs" />
@@ -319,5 +330,10 @@
     </BootstrapperPackage>
   </ItemGroup>
-  <ItemGroup />
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
+      <Project>{bbab9df5-5ef3-4ba8-ade9-b36e82114937}</Project>
+      <Name>HeuristicLab.Data-3.3</Name>
+    </ProjectReference>
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/CrowdingCalculator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/CrowdingCalculator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/CrowdingCalculator.cs	(revision 16171)
@@ -0,0 +1,67 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Data;
+
+namespace HeuristicLab.Optimization {
+
+  /// <summary>
+  /// CrowdingCalculator distance d(x,A) is usually defined between a point x and a set of points A
+  /// d(x,A) is the sum over all dimensions where for each dimension the next larger and the next smaller Point to x are subtracted
+  /// see in more detail: "A fast elitist non-dominated sorting genetic algorithm for multi-objective optimization: NSGA-II" by K Deb, S Agrawal, A Pratap, T Meyarivan
+  /// CrowdingCalculator as a quality of the complete qualities is defined here as the mean of the crowding distances of every point x in A 
+  /// C(A) = mean(d(x,A)) where x in A  and d(x,A) is not infinite
+  /// Beware that CrowdingCalculator is not normalized for the number of dimensions. A higher number of dimensions normally causes higher CrowdingCalculator values
+  /// </summary>
+  public static class CrowdingCalculator
+  {
+
+    public static double CalculateCrowding<TP>(IEnumerable<TP> qualities) where TP : IReadOnlyList<double> {
+      return CalculateCrowdingDistances(qualities.ToArray()).Where(d => !double.IsPositiveInfinity(d)).DefaultIfEmpty(double.PositiveInfinity).Average();
+    }
+
+    public static IList<double> CalculateCrowdingDistances<TP>(TP[] qualities) where TP : IReadOnlyList<double> {
+      if (qualities == null) throw new ArgumentException("qualities must not be null");
+      if (!qualities.Any()) throw new ArgumentException("qualities must not be empty");
+
+      var lastIndex = qualities.Length-1;
+      int objectiveCount = qualities[0].Count;
+
+      var pointsums = qualities.ToDictionary(x => x, x => 0.0);
+      for (var dim = 0; dim < objectiveCount; dim++) {
+        var arr = qualities.OrderBy(x => x[dim]).ToArray();
+
+        pointsums[arr[0]] = double.PositiveInfinity;
+        pointsums[arr[lastIndex]] = double.PositiveInfinity;
+
+        var d = arr[lastIndex][dim]-arr[0][dim];
+
+        for (var i = 1; i < lastIndex; i++)
+          pointsums[arr[i]] += (arr[i + 1][dim] - arr[i - 1][dim])/d;
+      }
+      return qualities.Select(x=> pointsums[x]).ToList();
+    }
+
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/DominationCalculator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/DominationCalculator.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/DominationCalculator.cs	(revision 16171)
@@ -24,7 +24,8 @@
 
 namespace HeuristicLab.Optimization {
+
   public enum DominationResult { Dominates, IsDominated, IsNonDominated };
 
-  public static class DominationCalculator<T> {
+  public static class DominationCalculator {
     /// <summary>
     /// Calculates the best pareto front only. The fast non-dominated sorting algorithm is used
@@ -43,6 +44,6 @@
     /// <param name="dominateOnEqualQualities">Whether solutions of exactly equal quality should dominate one another.</param>
     /// <returns>The pareto front containing the best solutions and their associated quality resp. fitness.</returns>
-    public static List<Tuple<T, double[]>> CalculateBestParetoFront(T[] solutions, double[][] qualities, bool[] maximization, bool dominateOnEqualQualities = true) {
-      int populationSize = solutions.Length;
+    public static List<Tuple<T, double[]>> CalculateBestParetoFront<T>(T[] solutions, double[][] qualities, bool[] maximization, bool dominateOnEqualQualities = true) {
+      var populationSize = solutions.Length;
 
       Dictionary<T, List<int>> dominatedIndividuals;
@@ -69,6 +70,6 @@
     /// <param name="dominateOnEqualQualities">Whether solutions of exactly equal quality should dominate one another.</param>
     /// <returns>A sorted list of the pareto fronts from best to worst.</returns>
-    public static List<List<Tuple<T, double[]>>> CalculateAllParetoFronts(T[] solutions, double[][] qualities, bool[] maximization, out int[] rank, bool dominateOnEqualQualities = true) {
-      int populationSize = solutions.Length;
+    public static List<List<Tuple<T, double[]>>> CalculateAllParetoFronts<T>(T[] solutions, double[][] qualities, bool[] maximization, out int[] rank, bool dominateOnEqualQualities = true) {
+      var populationSize = solutions.Length;
 
       Dictionary<T, List<int>> dominatedIndividuals;
@@ -76,5 +77,5 @@
       var fronts = new List<List<Tuple<T, double[]>>>();
       fronts.Add(CalculateBestFront(solutions, qualities, maximization, dominateOnEqualQualities, populationSize, out dominatedIndividuals, out dominationCounter, out rank));
-      int i = 0;
+      var i = 0;
       while (i < fronts.Count && fronts[i].Count > 0) {
         var nextFront = new List<Tuple<T, double[]>>();
@@ -82,6 +83,6 @@
           List<int> dominatedIndividualsByp;
           if (dominatedIndividuals.TryGetValue(p.Item1, out dominatedIndividualsByp)) {
-            for (int k = 0; k < dominatedIndividualsByp.Count; k++) {
-              int dominatedIndividual = dominatedIndividualsByp[k];
+            for (var k = 0; k < dominatedIndividualsByp.Count; k++) {
+              var dominatedIndividual = dominatedIndividualsByp[k];
               dominationCounter[dominatedIndividual] -= 1;
               if (dominationCounter[dominatedIndividual] == 0) {
@@ -98,15 +99,15 @@
     }
 
-    private static List<Tuple<T, double[]>> CalculateBestFront(T[] solutions, double[][] qualities, bool[] maximization, bool dominateOnEqualQualities, int populationSize, out Dictionary<T, List<int>> dominatedIndividuals, out int[] dominationCounter, out int[] rank) {
+    private static List<Tuple<T, double[]>> CalculateBestFront<T>(T[] solutions, double[][] qualities, bool[] maximization, bool dominateOnEqualQualities, int populationSize, out Dictionary<T, List<int>> dominatedIndividuals, out int[] dominationCounter, out int[] rank) {
       var front = new List<Tuple<T, double[]>>();
       dominatedIndividuals = new Dictionary<T, List<int>>();
       dominationCounter = new int[populationSize];
       rank = new int[populationSize];
-      for (int pI = 0; pI < populationSize - 1; pI++) {
+      for (var pI = 0; pI < populationSize - 1; pI++) {
         var p = solutions[pI];
         List<int> dominatedIndividualsByp;
         if (!dominatedIndividuals.TryGetValue(p, out dominatedIndividualsByp))
           dominatedIndividuals[p] = dominatedIndividualsByp = new List<int>();
-        for (int qI = pI + 1; qI < populationSize; qI++) {
+        for (var qI = pI + 1; qI < populationSize; qI++) {
           var test = Dominates(qualities[pI], qualities[qI], maximization, dominateOnEqualQualities);
           if (test == DominationResult.Dominates) {
@@ -147,5 +148,5 @@
       if (dominateOnEqualQualities) {
         var equal = true;
-        for (int i = 0; i < left.Length; i++) {
+        for (var i = 0; i < left.Length; i++) {
           if (left[i] != right[i]) {
             equal = false;
@@ -157,5 +158,5 @@
 
       bool leftIsBetter = false, rightIsBetter = false;
-      for (int i = 0; i < left.Length; i++) {
+      for (var i = 0; i < left.Length; i++) {
         if (IsDominated(left[i], right[i], maximizations[i])) rightIsBetter = true;
         else if (IsDominated(right[i], left[i], maximizations[i])) leftIsBetter = true;
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/GenerationalDistanceCalculator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/GenerationalDistanceCalculator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/GenerationalDistanceCalculator.cs	(revision 16171)
@@ -0,0 +1,79 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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
+
+#region
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+
+#endregion
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// The generational Distance is defined as the pth-root of the sum of all d[i]^(p) divided by the size of the qualities
+  ///  where d[i] is the minimal distance the ith point of the evaluated qualities has to any point in the optimal pareto qualities.   
+  ///  p is a dampening factor and is normally set to 1. 
+  ///  http://shodhganga.inflibnet.ac.in/bitstream/10603/15070/28/28_appendix_h.pdf
+  /// </summary>
+  public static class GenerationalDistanceCalculator {
+    public static double CalculateGenerationalDistance<TP1, TP2>(IEnumerable<TP1> qualities, IEnumerable<TP2> bestKnownFront, double p) where TP1 : IReadOnlyList<double> where TP2 : IReadOnlyList<double> {
+      if (qualities == null || bestKnownFront == null) throw new ArgumentNullException("Fronts must not be null");
+      if (p.IsAlmost(0.0)) throw new ArgumentException("p must not be zero.");
+      var mat = bestKnownFront.ToMatrix();
+      if (mat.GetLength(0) == 0) throw new ArgumentException("Fronts must not be empty.");
+
+      alglib.kdtree tree;
+      alglib.kdtreebuild(mat, mat.GetLength(0), mat.GetLength(1), 0, 2, out tree);
+      var sum = 0.0;
+      var summand = new double[1];
+      var count = 0;
+      foreach(var point in qualities) {
+        alglib.kdtreequeryknn(tree, point.ToArray(), 1, true);
+        alglib.kdtreequeryresultsdistances(tree, ref summand);
+        sum += Math.Pow(summand[0], p);
+        count++;
+      }
+
+      if (count == 0) throw new ArgumentException("Fronts must not be empty.");
+      return Math.Pow(sum, 1 / p) / count;
+    }
+
+    public static double CalculateInverseGenerationalDistance<TP1, TP2>(IEnumerable<TP1> qualities, IEnumerable<TP2> bestKnownFront, double p) where TP1 : IReadOnlyList<double> where TP2 : IReadOnlyList<double> {
+      return CalculateGenerationalDistance(bestKnownFront, qualities, p);
+    }
+
+    internal static double[,] ToMatrix<TP>(this IEnumerable<TP> source) where TP : IReadOnlyList<double> {
+      var l = source.ToArray();
+      var firstDimension = l.Length;
+      var secondDimension = l[0].Count;
+      var result = new double[firstDimension, secondDimension];
+      for (var i = 0; i < firstDimension; ++i)
+        for (var j = 0; j < secondDimension; ++j)
+          result[i, j] = l[i][j];
+
+      return result;
+    }
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/HypervolumeCalculator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/HypervolumeCalculator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/HypervolumeCalculator.cs	(revision 16171)
@@ -0,0 +1,305 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Optimization;
+
+namespace HeuristicLab.Optimization {
+
+  public static class HypervolumeCalculator {
+
+    public static double[] CalculateNadirPoint(IEnumerable<double[]> qualities, bool[] maximization){
+      var res = maximization.Select(m => m ? double.MaxValue : double.MinValue).ToArray();
+      foreach (var quality in qualities)
+        for (var i = 0; i < quality.Length; i++)
+          if (maximization[i] == res[i] > quality[i])
+            res[i] = quality[i];
+      return res;
+    }
+
+    /// <summary>
+    /// The Hyprevolume-metric is defined as the HypervolumeCalculator enclosed between a given reference point,
+    /// that is fixed for every evaluation function and the evaluated qualities.
+    /// 
+    /// Example:
+    /// r is the reference point at (1|1) and every point p is part of the evaluated qualities
+    /// The filled area labled HV is the 2 dimensional HypervolumeCalculator enclosed by this qualities. 
+    /// 
+    /// (0|1)                (1|1)
+    ///   +      +-------------r
+    ///   |      |###### HV ###|
+    ///   |      p------+######|
+    ///   |             p+#####|
+    ///   |              |#####|
+    ///   |              p-+###|
+    ///   |                p---+
+    ///   |                 
+    ///   +--------------------1
+    /// (0|0)                (1|0)
+    /// 
+    ///  Please note that in this example both dimensions are minimized. The reference point needs to be dominated by EVERY point in the evaluated qualities 
+    /// 
+    /// </summary>
+    /// 
+    public static double CalculateHypervolume(double[][] qualities, double[] referencePoint, bool[] maximization){
+      qualities = qualities.Where(vec => DominationCalculator.Dominates(vec, referencePoint, maximization, false) == DominationResult.Dominates).ToArray();
+      if (!qualities.Any()) return 0;//TODO replace with negative computation
+      if (maximization.Length == 2)
+        return Calculate2D(qualities, referencePoint, maximization);
+
+      if (Array.TrueForAll(maximization, x => !x))
+        return CalculateMultiDimensional(qualities, referencePoint);
+      throw new NotImplementedException("HypervolumeCalculator calculation for more than two dimensions is supported only with minimization problems.");
+    }
+
+    public static double Calculate2D(double[][] front, double[] referencePoint, bool[] maximization) {
+      if (front == null) throw new ArgumentNullException("Front must not be null.");
+      if (!front.Any()) throw new ArgumentException("Front must not be empty.");
+
+      if (referencePoint == null) throw new ArgumentNullException("ReferencePoint must not be null.");
+      if (referencePoint.Length != 2) throw new ArgumentException("ReferencePoint must have exactly two dimensions.");
+
+      var set = front.ToArray();
+      if (set.Any(s => s.Length != 2)) throw new ArgumentException("Points in qualities must have exactly two dimensions.");
+
+      Array.Sort(set, new DimensionComparer(0, maximization[0]));
+
+      double sum = 0;
+      for (var i = 0; i < set.Length - 1; i++) 
+        sum += Math.Abs((set[i][0] - set[i + 1][0])) * Math.Abs((set[i][1] - referencePoint[1]));
+      
+      var lastPoint = set[set.Length - 1];
+      sum += Math.Abs(lastPoint[0] - referencePoint[0]) * Math.Abs(lastPoint[1] - referencePoint[1]);
+
+      return sum;
+    }
+
+    public static double CalculateMultiDimensional(double[][] front, double[] referencePoint) {
+      if (referencePoint == null || referencePoint.Length < 3) throw new ArgumentException("ReferencePoint unfit for complex HypervolumeCalculator calculation");
+
+      var objectives = referencePoint.Length;
+      var fronList = front.ToList();
+      fronList.StableSort(new DimensionComparer(objectives - 1, false));
+
+      var regLow = Enumerable.Repeat(1E15, objectives).ToArray();
+      foreach (var p in fronList) {
+        for (var i = 0; i < regLow.Length; i++) {
+          if (p[i] < regLow[i]) regLow[i] = p[i];
+        }
+      }
+
+      return Stream(regLow, referencePoint, fronList, 0, referencePoint[objectives - 1], (int)Math.Sqrt(fronList.Count), objectives);
+    }
+
+    private static double Stream(double[] regionLow, double[] regionUp, List<double[]> front, int split, double cover, int sqrtNoPoints, int objectives) {
+      var coverOld = cover;
+      var coverIndex = 0;
+      var coverIndexOld = -1;
+      int c;
+      double result = 0;
+
+      var dMeasure = GetMeasure(regionLow, regionUp, objectives);
+      while (cover == coverOld && coverIndex < front.Count()) {
+        if (coverIndexOld == coverIndex) break;
+        coverIndexOld = coverIndex;
+        if (Covers(front[coverIndex], regionLow, objectives)) {
+          cover = front[coverIndex][objectives - 1];
+          result += dMeasure * (coverOld - cover);
+        } else coverIndex++;
+      }
+
+      for (c = coverIndex; c > 0; c--) if (front[c - 1][objectives - 1] == cover) coverIndex--;
+      if (coverIndex == 0) return result;
+
+      var allPiles = true;
+      var piles = new int[coverIndex];
+      for (var i = 0; i < coverIndex; i++) {
+        piles[i] = IsPile(front[i], regionLow, regionUp, objectives);
+        if (piles[i] == -1) {
+          allPiles = false;
+          break;
+        }
+      }
+
+      if (allPiles) {
+        var trellis = new double[regionUp.Length];
+        for (var j = 0; j < trellis.Length; j++) trellis[j] = regionUp[j];
+        double current = 0;
+        double next = 0;
+        var i = 0;
+        do {
+          current = front[i][objectives - 1];
+          do {
+            if (front[i][piles[i]] < trellis[piles[i]]) trellis[piles[i]] = front[i][piles[i]];
+            i++;
+            if (i < coverIndex) next = front[i][objectives - 1];
+            else { next = cover; break; }
+          } while (next == current);
+          result += ComputeTrellis(regionLow, regionUp, trellis, objectives) * (next - current);
+        } while (next != cover);
+      } else {
+        double bound = -1;
+        var boundaries = new double[coverIndex];
+        var noBoundaries = new double[coverIndex];
+        var boundIdx = 0;
+        var noBoundIdx = 0;
+
+        do {
+          for (var i = 0; i < coverIndex; i++) {
+            var contained = ContainesBoundary(front[i], regionLow, split);
+            if (contained == 0) boundaries[boundIdx++] = front[i][split];
+            else if (contained == 1) noBoundaries[noBoundIdx++] = front[i][split];
+          }
+          if (boundIdx > 0) bound = GetMedian(boundaries, boundIdx);
+          else if (noBoundIdx > sqrtNoPoints) bound = GetMedian(noBoundaries, noBoundIdx);
+          else split++;
+        } while (bound == -1.0);
+
+        List<double[]> pointsChildLow, pointsChildUp;
+        pointsChildLow = new List<double[]>();
+        pointsChildUp = new List<double[]>();
+        var regionUpC = new double[regionUp.Length];
+        for (var j = 0; j < regionUpC.Length; j++) regionUpC[j] = regionUp[j];
+        var regionLowC = new double[regionLow.Length];
+        for (var j = 0; j < regionLowC.Length; j++) regionLowC[j] = regionLow[j];
+
+        for (var i = 0; i < coverIndex; i++) {
+          if (PartCovers(front[i], regionUpC, objectives)) pointsChildUp.Add(front[i]);
+          if (PartCovers(front[i], regionUp, objectives)) pointsChildLow.Add(front[i]);
+        }
+
+        if (pointsChildUp.Count > 0) result += Stream(regionLow, regionUpC, pointsChildUp, split, cover, sqrtNoPoints, objectives);
+        if (pointsChildLow.Count > 0) result += Stream(regionLowC, regionUp, pointsChildLow, split, cover, sqrtNoPoints, objectives);
+      }
+      return result;
+    }
+
+    private static double GetMedian(double[] vector, int length) {
+      return vector.Take(length).Median();
+    }
+
+    private static double ComputeTrellis(double[] regionLow, double[] regionUp, double[] trellis, int objectives) {
+      var bs = new bool[objectives - 1];
+      for (var i = 0; i < bs.Length; i++) bs[i] = true;
+
+      double result = 0;
+      var noSummands = BinarayToInt(bs);
+      int oneCounter; double summand;
+      for (uint i = 1; i <= noSummands; i++) {
+        summand = 1;
+        IntToBinary(i, bs);
+        oneCounter = 0;
+        for (var j = 0; j < objectives - 1; j++) {
+          if (bs[j]) {
+            summand *= regionUp[j] - trellis[j];
+            oneCounter++;
+          } else {
+            summand *= regionUp[j] - regionLow[j];
+          }
+        }
+        if (oneCounter % 2 == 0) result -= summand;
+        else result += summand;
+
+      }
+      return result;
+    }
+
+    private static void IntToBinary(uint i, bool[] bs) {
+      for (var j = 0; j < bs.Length; j++) bs[j] = false;
+      var rest = i;
+      var idx = 0;
+      while (rest != 0) {
+        bs[idx] = rest % 2 == 1;
+        rest = rest / 2;
+        idx++;
+      }
+    }
+
+    private static uint BinarayToInt(bool[] bs) {
+      uint result = 0;
+      for (var i = 0; i < bs.Length; i++) {
+        result += bs[i] ? ((uint)1 << i) : 0;
+      }
+      return result;
+    }
+
+    private static int IsPile(double[] cuboid, double[] regionLow, double[] regionUp, int objectives) {
+      var pile = cuboid.Length;
+      for (var i = 0; i < objectives - 1; i++) {
+        if (cuboid[i] > regionLow[i]) {
+          if (pile != objectives) return 1;
+          pile = i;
+        }
+      }
+      return pile;
+    }
+
+    private static double GetMeasure(double[] regionLow, double[] regionUp, int objectives) {
+      double volume = 1;
+      for (var i = 0; i < objectives - 1; i++) {
+        volume *= (regionUp[i] - regionLow[i]);
+      }
+      return volume;
+    }
+
+    private static int ContainesBoundary(double[] cub, double[] regionLow, int split) {
+      if (regionLow[split] >= cub[split]) return -1;
+      else {
+        for (var j = 0; j < split; j++) {
+          if (regionLow[j] < cub[j]) return 1;
+        }
+      }
+      return 0;
+    }
+
+    private static bool PartCovers(double[] v, double[] regionUp, int objectives) {
+      for (var i = 0; i < objectives - 1; i++) {
+        if (v[i] >= regionUp[i]) return false;
+      }
+      return true;
+    }
+
+    private static bool Covers(double[] v, double[] regionLow, int objectives) {
+      for (var i = 0; i < objectives - 1; i++) {
+        if (v[i] > regionLow[i]) return false;
+      }
+      return true;
+    }
+
+    private class DimensionComparer : IComparer<double[]> {
+      private readonly int dimension;
+      private readonly int descending;
+
+      public DimensionComparer(int dimension, bool descending) {
+        this.dimension = dimension;
+        this.descending = descending ? -1 : 1;
+      }
+
+      public int Compare(double[] x, double[] y){
+        return x[dimension].CompareTo(y[dimension]) * descending;
+      }
+    }
+
+  }
+}
+
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/SpacingCalculator.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/SpacingCalculator.cs	(revision 16171)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/SpacingCalculator.cs	(revision 16171)
@@ -0,0 +1,56 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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;
+
+namespace HeuristicLab.Optimization {
+
+  /// <summary>
+  /// SpacingCalculator is defined as the standarddeviation of all d[i] 
+  /// where d[i] is the minimum eukildean distance any point i has 
+  /// to all OTHER points in the same front 
+  /// </summary>
+  public static class SpacingCalculator {
+
+    public static double CalculateSpacing<TP>(IEnumerable<TP> qualities) where TP: IReadOnlyList<double> {
+      if (qualities == null) throw new ArgumentException("Front must not be null.");
+      var l = qualities.ToList();
+      if (l.Count == 0) throw new ArgumentException("Front must not be empty.");
+      if (l.Count == 1) return 0;
+
+      var mat = l.ToMatrix();
+      alglib.kdtree tree;
+      alglib.kdtreebuild(mat, mat.GetLength(0), mat.GetLength(1), 0, 2, out tree);
+      var summand = new double[2];
+      var dists = new List<double>();
+      foreach (var point in l) {
+        alglib.kdtreequeryknn(tree, point.ToArray(), 2, true);
+        alglib.kdtreequeryresultsdistances(tree, ref summand);
+        dists.Add(summand[1]);
+      }
+      return dists.StandardDeviationPop();
+    }
+
+    
+  }
+}
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/CrowdingAnalyzer.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/CrowdingAnalyzer.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/CrowdingAnalyzer.cs	(revision 16171)
@@ -33,8 +33,4 @@
   public class CrowdingAnalyzer : MOTFAnalyzer {
 
-    public ILookupParameter<DoubleMatrix> BoundsParameter {
-      get { return (ILookupParameter<DoubleMatrix>)Parameters["Bounds"]; }
-    }
-
     public IResultParameter<DoubleValue> CrowdingResultParameter {
       get { return (IResultParameter<DoubleValue>)Parameters["Crowding"]; }
@@ -51,18 +47,12 @@
 
     public CrowdingAnalyzer() {
-      Parameters.Add(new LookupParameter<DoubleMatrix>("Bounds",
-        "The bounds of the solution given as either one line for all variables or a line for each variable. The first column specifies lower bound, the second upper bound."));
-      Parameters.Add(new ResultParameter<DoubleValue>("Crowding", "The average corwding value of all points (excluding infinities)"));
+      Parameters.Add(new ResultParameter<DoubleValue>("Crowding", "The average corwding distance of all points (excluding infinities)"));
       CrowdingResultParameter.DefaultValue = new DoubleValue(double.NaN);
-
     }
 
     public override IOperation Apply() {
       var qualities = QualitiesParameter.ActualValue;
-      var bounds = BoundsParameter.ActualValue;
-
-      var crowdingDistance = Crowding.Calculate(qualities.Select(x => x.ToArray()), bounds.CloneAsMatrix());
+      var crowdingDistance = CrowdingCalculator.CalculateCrowding(qualities);
       CrowdingResultParameter.ActualValue.Value = crowdingDistance;
-
       return base.Apply();
     }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/GenerationalDistanceAnalyzer.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/GenerationalDistanceAnalyzer.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/GenerationalDistanceAnalyzer.cs	(revision 16171)
@@ -64,12 +64,7 @@
     public override IOperation Apply() {
       var qualities = QualitiesParameter.ActualValue;
-      int objectives = qualities[0].Length;
-
-      var optimalfront = TestFunctionParameter.ActualValue.OptimalParetoFront(objectives);
+      var optimalfront = TestFunctionParameter.ActualValue.OptimalParetoFront(qualities[0].Length);
       if (optimalfront == null) return base.Apply();
-
-      var distance = GenerationalDistance.Calculate(qualities.Select(x => x.CloneAsArray()), optimalfront, Dampening);
-      GenerationalDistanceResultParameter.ActualValue.Value = distance;
-
+      GenerationalDistanceResultParameter.ActualValue.Value = GenerationalDistanceCalculator.CalculateGenerationalDistance(qualities, optimalfront, Dampening);
       return base.Apply();
     }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/HypervolumeAnalyzer.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/HypervolumeAnalyzer.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/HypervolumeAnalyzer.cs	(revision 16171)
@@ -76,15 +76,13 @@
       var qualities = QualitiesParameter.ActualValue;
       var testFunction = TestFunctionParameter.ActualValue;
-      int objectives = qualities[0].Length;
+      var objectives = qualities[0].Length;
       var referencePoint = ReferencePointParameter.ActualValue;
 
-      double best = BestKnownHypervolumeResultParameter.ActualValue.Value;
+      var best = BestKnownHypervolumeResultParameter.ActualValue.Value;
       if (referencePoint.SequenceEqual(testFunction.ReferencePoint(objectives))) {
         best = Math.Max(best, testFunction.OptimalHypervolume(objectives));
       }
 
-      IEnumerable<double[]> front = NonDominatedSelect.SelectNonDominatedVectors(qualities.Select(q => q.ToArray()), testFunction.Maximization(objectives), true);
-
-      double hv = Hypervolume.Calculate(front, referencePoint.ToArray(), testFunction.Maximization(objectives));
+      var hv = HypervolumeCalculator.CalculateHypervolume(qualities.Select(x=>x.CloneAsArray()).ToArray(), referencePoint.ToArray(), testFunction.Maximization(objectives));
 
       if (hv > best) {
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/InvertedGenerationalDistanceAnalyzer.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/InvertedGenerationalDistanceAnalyzer.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/InvertedGenerationalDistanceAnalyzer.cs	(revision 16171)
@@ -47,12 +47,4 @@
     }
 
-    public InvertedGenerationalDistanceAnalyzer() {
-      Parameters.Add(new FixedValueParameter<DoubleValue>("Dampening", "", new DoubleValue(1)));
-      Parameters.Add(new ResultParameter<DoubleValue>("Inverted Generational Distance", "The genrational distance between the current front and the optimal front"));
-      InvertedGenerationalDistanceResultParameter.DefaultValue = new DoubleValue(double.NaN);
-
-    }
-
-
     [StorableConstructor]
     protected InvertedGenerationalDistanceAnalyzer(bool deserializing) : base(deserializing) { }
@@ -62,19 +54,17 @@
     }
 
+    public InvertedGenerationalDistanceAnalyzer() {
+      Parameters.Add(new FixedValueParameter<DoubleValue>("Dampening", "", new DoubleValue(1)));
+      Parameters.Add(new ResultParameter<DoubleValue>("Inverted Generational Distance", "The genrational distance between the current front and the optimal front"));
+      InvertedGenerationalDistanceResultParameter.DefaultValue = new DoubleValue(double.NaN);
+    }
+
     public override IOperation Apply() {
       var qualities = QualitiesParameter.ActualValue;
-      var testFunction = TestFunctionParameter.ActualValue;
-      int objectives = qualities[0].Length;
-
-      var optimalfront = testFunction.OptimalParetoFront(objectives);
+      var optimalfront = TestFunctionParameter.ActualValue.OptimalParetoFront(qualities[0].Length);
       if (optimalfront == null) return base.Apply();
-
-      var invertedGenerationalDistance = InvertedGenerationalDistance.Calculate(qualities.Select(q => q.ToArray()), optimalfront, DampeningParameter.Value.Value);
-      InvertedGenerationalDistanceResultParameter.ActualValue.Value = invertedGenerationalDistance;
-
+      InvertedGenerationalDistanceResultParameter.ActualValue.Value = GenerationalDistanceCalculator.CalculateInverseGenerationalDistance(qualities, optimalfront, Dampening);
       return base.Apply();
     }
-
-
   }
 }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/ScatterPlotAnalyzer.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/ScatterPlotAnalyzer.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/ScatterPlotAnalyzer.cs	(revision 16171)
@@ -59,8 +59,8 @@
       var individuals = IndividualsParameter.ActualValue;
       var testFunction = TestFunctionParameter.ActualValue;
-      int objectives = qualities[0].Length;
-      int problemSize = individuals[0].Length;
+      var objectives = qualities[0].Length;
+      var problemSize = individuals[0].Length;
 
-      double[][] optimalFront = new double[0][];
+      var optimalFront = new double[0][];
       var front = testFunction.OptimalParetoFront(objectives);
       if (front != null) optimalFront = front.ToArray();
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/SpacingAnalyzer.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/SpacingAnalyzer.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/SpacingAnalyzer.cs	(revision 16171)
@@ -51,7 +51,5 @@
     public override IOperation Apply() {
       var qualities = QualitiesParameter.ActualValue;
-      var spacing = Spacing.Calculate(qualities.Select(q => q.ToArray()));
-      SpacingResultParameter.ActualValue.Value = spacing;
-
+      SpacingResultParameter.ActualValue.Value = SpacingCalculator.CalculateSpacing(qualities);
       return base.Apply();
     }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.csproj
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.csproj	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.csproj	(revision 16171)
@@ -17,5 +17,5 @@
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
-    <OutputPath>..\..\bin\</OutputPath>
+    <OutputPath>..\..\..\..\trunk\bin\</OutputPath>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
@@ -90,7 +90,4 @@
     <Reference Include="HeuristicLab.Core-3.3">
       <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Core-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Data-3.3">
-      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Data-3.3.dll</HintPath>
     </Reference>
     <Reference Include="HeuristicLab.Encodings.RealVectorEncoding-3.3">
@@ -134,9 +131,4 @@
     <Compile Include="Interfaces\IConstrainedTestFunction.cs" />
     <Compile Include="Interfaces\IMultiObjectiveTestFunctionAnalyzer.cs" />
-    <Compile Include="Calculators\Crowding.cs" />
-    <Compile Include="Calculators\Spacing.cs" />
-    <Compile Include="Calculators\HyperVolume.cs" />
-    <Compile Include="Calculators\InvertedGenerationalDistance.cs" />
-    <Compile Include="Calculators\GenerationalDistance.cs" />
     <Compile Include="ParetoFrontScatterPlot.cs" />
     <Compile Include="Utilities.cs" />
@@ -206,4 +198,8 @@
       <Name>HeuristicLab.Analysis-3.3</Name>
     </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
+      <Project>{bbab9df5-5ef3-4ba8-ade9-b36e82114937}</Project>
+      <Name>HeuristicLab.Data-3.3</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
       <Project>{14ab8d24-25bc-400c-a846-4627aa945192}</Project>
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/MultiObjectiveTestFunctionProblem.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/MultiObjectiveTestFunctionProblem.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/MultiObjectiveTestFunctionProblem.cs	(revision 16171)
@@ -38,5 +38,5 @@
 
     #region Parameter Properties
-    public IValueParameter<BoolArray> MaximizationParameter {
+    public new IValueParameter<BoolArray> MaximizationParameter {
       get { return (IValueParameter<BoolArray>)Parameters["Maximization"]; }
     }
@@ -53,10 +53,4 @@
       get { return (IValueParameter<IMultiObjectiveTestFunction>)Parameters["TestFunction"]; }
     }
-    public IValueParameter<DoubleArray> ReferencePointParameter {
-      get { return (IValueParameter<DoubleArray>)Parameters["ReferencePoint"]; }
-    }
-    public OptionalValueParameter<DoubleMatrix> BestKnownFrontParameter {
-      get { return (OptionalValueParameter<DoubleMatrix>)Parameters["BestKnownFront"]; }
-    }
 
     #endregion
@@ -64,8 +58,5 @@
     #region Properties
     public override bool[] Maximization {
-      get {
-        if (!Parameters.ContainsKey("Maximization")) return new bool[2];
-        return MaximizationParameter.Value.ToArray();
-      }
+      get{ return Parameters.ContainsKey(MaximizationParameterName) ? MaximizationParameter.Value.CloneAsArray() : new Fonseca().Maximization(2); }
     }
 
@@ -85,12 +76,4 @@
       get { return TestFunctionParameter.Value; }
       set { TestFunctionParameter.Value = value; }
-    }
-    public DoubleArray ReferencePoint {
-      get { return ReferencePointParameter.Value; }
-      set { ReferencePointParameter.Value = value; }
-    }
-    public DoubleMatrix BestKnownFront {
-      get { return BestKnownFrontParameter.Value; }
-      set { BestKnownFrontParameter.Value = value; }
     }
     #endregion
@@ -116,7 +99,5 @@
       Parameters.Add(new FixedValueParameter<IntValue>("Objectives", "The dimensionality of the solution vector (number of objectives).", new IntValue(2)));
       Parameters.Add(new ValueParameter<DoubleMatrix>("Bounds", "The bounds of the solution given as either one line for all variables or a line for each variable. The first column specifies lower bound, the second upper bound.", new DoubleMatrix(new double[,] { { -4, 4 } })));
-      Parameters.Add(new ValueParameter<DoubleArray>("ReferencePoint", "The reference point used for hypervolume calculation."));
       Parameters.Add(new ValueParameter<IMultiObjectiveTestFunction>("TestFunction", "The function that is to be optimized.", new Fonseca()));
-      Parameters.Add(new OptionalValueParameter<DoubleMatrix>("BestKnownFront", "The currently best known Pareto front"));
 
       Encoding.LengthParameter = ProblemSizeParameter;
@@ -138,7 +119,6 @@
     public override void Analyze(Individual[] individuals, double[][] qualities, ResultCollection results, IRandom random) {
       base.Analyze(individuals, qualities, results, random);
-      if (results.ContainsKey("Pareto Front")) {
+      if (results.ContainsKey("Pareto Front")) 
         ((DoubleMatrix)results["Pareto Front"].Value).SortableView = true;
-      }
     }
 
@@ -170,14 +150,16 @@
     #region Events
     private void UpdateParameterValues() {
-      MaximizationParameter.Value = (BoolArray)new BoolArray(TestFunction.Maximization(Objectives)).AsReadOnly();
-
+      Parameters.Remove(MaximizationParameterName);
+      Parameters.Add(new FixedValueParameter<BoolArray>(MaximizationParameterName, "Set to false if the problem should be minimized.", (BoolArray)new BoolArray(TestFunction.Maximization(Objectives)).AsReadOnly()));
+
+      Parameters.Remove(BestKnownFrontParameterName);
       var front = TestFunction.OptimalParetoFront(Objectives);
-      if (front != null) {
-        BestKnownFrontParameter.Value = (DoubleMatrix)Utilities.ToMatrix(front).AsReadOnly();
-      } else BestKnownFrontParameter.Value = null;
-
+      var bkf = front != null ? (DoubleMatrix)Utilities.ToMatrix(front).AsReadOnly() : null;
+      Parameters.Add(new FixedValueParameter<DoubleMatrix>(BestKnownFrontParameterName, "A double matrix representing the best known qualites for this problem (aka points on the Pareto front). Points are to be given in a row-wise fashion.", bkf));
+
+      Parameters.Remove(ReferencePointParameterName);
+      Parameters.Add(new FixedValueParameter<DoubleArray>(ReferencePointParameterName, "The refrence point for hypervolume calculations on this problem", new DoubleArray(TestFunction.ReferencePoint(Objectives))));
 
       BoundsParameter.Value = new DoubleMatrix(TestFunction.Bounds(Objectives));
-      ReferencePointParameter.Value = new DoubleArray(TestFunction.ReferencePoint(Objectives));
     }
 
@@ -196,5 +178,6 @@
       ProblemSize = Math.Max(TestFunction.MinimumSolutionLength, Math.Min(ProblemSize, TestFunction.MaximumSolutionLength));
       Objectives = Math.Max(TestFunction.MinimumObjectives, Math.Min(Objectives, TestFunction.MaximumObjectives));
-      ReferencePointParameter.ActualValue = new DoubleArray(TestFunction.ReferencePoint(Objectives));
+      Parameters.Remove(ReferencePointParameterName);
+      Parameters.Add(new FixedValueParameter<DoubleArray>(ReferencePointParameterName, "The refrence point for hypervolume calculations on this problem", new DoubleArray(TestFunction.ReferencePoint(Objectives))));
       ParameterizeAnalyzers();
       UpdateParameterValues();
@@ -237,9 +220,4 @@
         analyzer.BestKnownFrontParameter.ActualName = BestKnownFrontParameter.Name;
 
-        var crowdingAnalyzer = analyzer as CrowdingAnalyzer;
-        if (crowdingAnalyzer != null) {
-          crowdingAnalyzer.BoundsParameter.ActualName = BoundsParameter.Name;
-        }
-
         var scatterPlotAnalyzer = analyzer as ScatterPlotAnalyzer;
         if (scatterPlotAnalyzer != null) {
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/NonDominatedSelect.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/NonDominatedSelect.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/NonDominatedSelect.cs	(revision 16171)
@@ -25,66 +25,5 @@
 
   public static class NonDominatedSelect {
-    public enum DominationResult { Dominates, IsDominated, IsNonDominated };
-
-    public static IEnumerable<double[]> SelectNonDominatedVectors(IEnumerable<double[]> qualities, bool[] maximization, bool dominateOnEqualQualities) {
-
-      List<double[]> front = new List<double[]>();
-      foreach (double[] row in qualities) {
-        bool insert = true;
-        for (int i = 0; i < front.Count; i++) {
-          DominationResult res = Dominates(front[i], row, maximization, dominateOnEqualQualities);
-          if (res == DominationResult.Dominates) { insert = false; break; }           //Vector domiates Row
-          else if (res == DominationResult.IsDominated) {   //Row dominates Vector
-            front.RemoveAt(i);
-          }
-        }
-        if (insert) {
-          front.Add(row);
-        }
-      }
-
-      return front;
-    }
-
-    public static IEnumerable<double[]> GetDominatingVectors(IEnumerable<double[]> qualities, double[] reference, bool[] maximization, bool dominateOnEqualQualities) {
-      List<double[]> front = new List<double[]>();
-      foreach (double[] vec in qualities) {
-        if (Dominates(vec, reference, maximization, dominateOnEqualQualities) == DominationResult.Dominates) {
-          front.Add(vec);
-        }
-      }
-      return front;
-    }
-
-    public static DominationResult Dominates(double[] left, double[] right, bool[] maximizations, bool dominateOnEqualQualities) {
-      //mkommend Caution: do not use LINQ.SequenceEqual for comparing the two quality arrays (left and right) due to performance reasons
-      if (dominateOnEqualQualities) {
-        var equal = true;
-        for (int i = 0; i < left.Length; i++) {
-          if (left[i] != right[i]) {
-            equal = false;
-            break;
-          }
-        }
-        if (equal) return DominationResult.Dominates;
-      }
-
-      bool leftIsBetter = false, rightIsBetter = false;
-      for (int i = 0; i < left.Length; i++) {
-        if (IsDominated(left[i], right[i], maximizations[i])) rightIsBetter = true;
-        else if (IsDominated(right[i], left[i], maximizations[i])) leftIsBetter = true;
-        if (leftIsBetter && rightIsBetter) break;
-      }
-
-      if (leftIsBetter && !rightIsBetter) return DominationResult.Dominates;
-      if (!leftIsBetter && rightIsBetter) return DominationResult.IsDominated;
-      return DominationResult.IsNonDominated;
-    }
-
-    private static bool IsDominated(double left, double right, bool maximization) {
-      return maximization && left < right
-        || !maximization && left > right;
-    }
-
+    
   }
 }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ.cs	(revision 16171)
@@ -42,6 +42,6 @@
 
     protected override double[] GetReferencePoint(int objectives) {
-      double[] rp = new double[objectives];
-      for (int i = 0; i < objectives; i++) {
+      var rp = new double[objectives];
+      for (var i = 0; i < objectives; i++) {
         rp[i] = 11;
       }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ1.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ1.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ1.cs	(revision 16171)
@@ -48,9 +48,9 @@
         throw new ArgumentException("The dimensionality of the problem(ProblemSize) must be larger than or equal to the number of objectives");
       }
-      double[] res = new double[objectives];
-      int k = r.Length - objectives + 1;
+      var res = new double[objectives];
+      var k = r.Length - objectives + 1;
       double g = 0;
 
-      for (int i = r.Length - k; i < r.Length; i++) {
+      for (var i = r.Length - k; i < r.Length; i++) {
         g += (r[i] - 0.5) * (r[i] - 0.5) - Math.Cos(20.0 * Math.PI * (r[i] - 0.5));
       };
@@ -58,7 +58,7 @@
       g *= 100;
 
-      for (int i = 0; i < objectives; i++) {
+      for (var i = 0; i < objectives; i++) {
         res[i] = 0.5 * (1.0 + g);
-        for (int j = 0; j < objectives - i - 1; ++j)
+        for (var j = 0; j < objectives - i - 1; ++j)
           res[i] *= (r[j]);
         if (i > 0)
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ2.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ2.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ2.cs	(revision 16171)
@@ -48,17 +48,17 @@
       }
 
-      double[] res = new double[objectives];
+      var res = new double[objectives];
 
       //calculate g(Xm)
       double g = 0;
-      for (int i = objectives; i < r.Length; i++) {
-        double d = r[i] - 0.5;
+      for (var i = objectives; i < r.Length; i++) {
+        var d = r[i] - 0.5;
         g += d * d;
       }
 
       //calculating f0...fM-1
-      for (int i = 0; i < objectives; i++) {
-        double f = i == 0 ? 1 : (Math.Sin(r[objectives - i - 1] * Math.PI / 2)) * (1 + g);
-        for (int j = 0; j < objectives - i - 1; j++) {
+      for (var i = 0; i < objectives; i++) {
+        var f = i == 0 ? 1 : (Math.Sin(r[objectives - i - 1] * Math.PI / 2)) * (1 + g);
+        for (var j = 0; j < objectives - i - 1; j++) {
           f *= Math.Cos(r[j] * Math.PI / 2);
         }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ3.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ3.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ3.cs	(revision 16171)
@@ -47,19 +47,19 @@
         throw new ArgumentException("The dimensionality of the problem(ProblemSize) must be larger than or equal to the number of objectives");
       }
-      double[] res = new double[objectives];
+      var res = new double[objectives];
 
       //calculate g(Xm)
       double sum = 0;
-      int length = r.Length - objectives + 1;
-      for (int i = r.Length - length; i < r.Length; i++) {
-        double d = r[i] - 0.5;
+      var length = r.Length - objectives + 1;
+      for (var i = r.Length - length; i < r.Length; i++) {
+        var d = r[i] - 0.5;
         sum += d * d - Math.Cos(20 * Math.PI * d);
       }
-      double g = 100 * (length + sum);
+      var g = 100 * (length + sum);
 
       //calculating f0...fM-1
-      for (int i = 0; i < objectives; i++) {
-        double f = i == 0 ? 1 : (Math.Sin(r[objectives - i - 1] * Math.PI / 2)) * (1 + g);
-        for (int j = 0; j < objectives - i - 1; j++) {
+      for (var i = 0; i < objectives; i++) {
+        var f = i == 0 ? 1 : (Math.Sin(r[objectives - i - 1] * Math.PI / 2)) * (1 + g);
+        for (var j = 0; j < objectives - i - 1; j++) {
           f *= Math.Cos(r[j] * Math.PI / 2);
         }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ4.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ4.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ4.cs	(revision 16171)
@@ -47,17 +47,17 @@
         throw new ArgumentException("The dimensionality of the problem(ProblemSize) must be larger than or equal to the number of objectives");
       }
-      double[] res = new double[objectives];
+      var res = new double[objectives];
 
       //calculate g(Xm)
       double g = 0;
-      for (int i = objectives; i < r.Length; i++) {
-        double d = r[i] - 0.5;
+      for (var i = objectives; i < r.Length; i++) {
+        var d = r[i] - 0.5;
         g += d * d;
       }
 
       //calculating f0...fM-1
-      for (int i = 0; i < objectives; i++) {
-        double f = i == 0 ? 1 : (Math.Sin(Math.Pow(r[objectives - i - 1], 100) * Math.PI / 2)) * (1 + g);
-        for (int j = 0; j < objectives - i - 1; j++) {
+      for (var i = 0; i < objectives; i++) {
+        var f = i == 0 ? 1 : (Math.Sin(Math.Pow(r[objectives - i - 1], 100) * Math.PI / 2)) * (1 + g);
+        for (var j = 0; j < objectives - i - 1; j++) {
           f *= Math.Cos(Math.Pow(r[j], 100) * Math.PI / 2);
         }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ5.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ5.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ5.cs	(revision 16171)
@@ -42,10 +42,10 @@
         throw new ArgumentException("The dimensionality of the problem(ProblemSize) must be larger than or equal to the number of objectives");
       }
-      double[] res = new double[objectives];
+      var res = new double[objectives];
 
       //calculate g(Xm)
       double g = 0;
-      for (int i = objectives; i < r.Length; i++) {
-        double d = r[i] - 0.5;
+      for (var i = objectives; i < r.Length; i++) {
+        var d = r[i] - 0.5;
         g += d * d;
       }
@@ -56,7 +56,7 @@
 
       //calculating f0...fM-1
-      for (int i = 0; i < objectives; i++) {
-        double f = i == 0 ? 1 : (Math.Sin(phi(r[objectives - i - 1]) * Math.PI / 2)) * (1 + g);
-        for (int j = 0; j < objectives - i - 1; j++) {
+      for (var i = 0; i < objectives; i++) {
+        var f = i == 0 ? 1 : (Math.Sin(phi(r[objectives - i - 1]) * Math.PI / 2)) * (1 + g);
+        for (var j = 0; j < objectives - i - 1; j++) {
           f *= Math.Cos(phi(r[j]) * Math.PI / 2);
         }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ6.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ6.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ6.cs	(revision 16171)
@@ -42,9 +42,9 @@
         throw new ArgumentException("The dimensionality of the problem(ProblemSize) must be larger than or equal to the number of objectives");
       }
-      double[] res = new double[objectives];
+      var res = new double[objectives];
 
       //calculate g(Xm)
       double g = 0;
-      for (int i = objectives; i < r.Length; i++) {
+      for (var i = objectives; i < r.Length; i++) {
         g += Math.Pow(r[i], 0.1);
       }
@@ -55,7 +55,7 @@
 
       //calculating f0...fM-1
-      for (int i = 0; i < objectives; i++) {
-        double f = i == 0 ? 1 : (Math.Sin(phi(r[objectives - i - 1]) * Math.PI / 2)) * (1 + g);
-        for (int j = 0; j < objectives - i - 1; j++) {
+      for (var i = 0; i < objectives; i++) {
+        var f = i == 0 ? 1 : (Math.Sin(phi(r[objectives - i - 1]) * Math.PI / 2)) * (1 + g);
+        for (var j = 0; j < objectives - i - 1; j++) {
           f *= Math.Cos(phi(r[j]) * Math.PI / 2);
         }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ7.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ7.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ7.cs	(revision 16171)
@@ -47,9 +47,9 @@
         throw new ArgumentException("The dimensionality of the problem(ProblemSize) must be larger than or equal to the number of objectives");
       }
-      double[] res = new double[objectives];
+      var res = new double[objectives];
 
       //calculate g(Xm)
       double g = 0, length = length = r.Length - objectives + 1;
-      for (int i = objectives; i < r.Length; i++) {
+      for (var i = objectives; i < r.Length; i++) {
         g += r[i];
       }
@@ -58,10 +58,10 @@
 
       //calculating f0...fM-2
-      for (int i = 0; i < objectives - 1; i++) {
+      for (var i = 0; i < objectives - 1; i++) {
         res[i] = r[i];
       }
       //calculate fM-1
       double h = objectives;
-      for (int i = 0; i < objectives - 1; i++) {
+      for (var i = 0; i < objectives - 1; i++) {
         h -= res[i] / (1 + g) * (1 + Math.Sin(3 * Math.PI * res[i]));
       }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ8.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ8.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ8.cs	(revision 16171)
@@ -30,6 +30,6 @@
   public class DTLZ8 : DTLZ, IConstrainedTestFunction {
     public static double[] IllegalValue(int size, bool[] maximization) {
-      double[] res = new double[size];
-      for (int i = 0; i < size; i++) {
+      var res = new double[size];
+      for (var i = 0; i < size; i++) {
         res[i] = maximization[i] ? Double.MinValue : Double.MaxValue;
       }
@@ -49,9 +49,9 @@
       double n = r.Length;
       double M = objectives;
-      double ratio = n / M;
-      double[] res = new double[objectives];
-      for (int j = 0; j < objectives; j++) {
+      var ratio = n / M;
+      var res = new double[objectives];
+      for (var j = 0; j < objectives; j++) {
         double sum = 0;
-        for (int i = (int)(j * ratio); i < (j + 1) + ratio; i++) {
+        for (var i = (int)(j * ratio); i < (j + 1) + ratio; i++) {
           sum += r[i];
         }
@@ -59,11 +59,11 @@
         res[j] = sum;
       }
-      for (int j = 0; j < M - 1; j++) {
+      for (var j = 0; j < M - 1; j++) {
         if (res[objectives - 1] + 4 * res[j] - 1 < 0) return IllegalValue(objectives, GetMaximization(objectives));
       }
-      double min = Double.PositiveInfinity;
-      for (int i = 0; i < res.Length - 1; i++) {
-        for (int j = 0; j < i; j++) {
-          double d = res[i] + res[j];
+      var min = Double.PositiveInfinity;
+      for (var i = 0; i < res.Length - 1; i++) {
+        for (var j = 0; j < i; j++) {
+          var d = res[i] + res[j];
           if (min < d) min = d;
         }
@@ -78,10 +78,10 @@
       double n = r.Length;
       double M = objectives;
-      double ratio = n / M;
-      double[] res = new double[objectives];
-      double[] constraints = new double[objectives];
-      for (int j = 0; j < objectives; j++) {
+      var ratio = n / M;
+      var res = new double[objectives];
+      var constraints = new double[objectives];
+      for (var j = 0; j < objectives; j++) {
         double sum = 0;
-        for (int i = (int)(j * ratio); i < (j + 1) + ratio; i++) {
+        for (var i = (int)(j * ratio); i < (j + 1) + ratio; i++) {
           sum += r[i];
         }
@@ -89,16 +89,16 @@
         res[j] = sum;
       }
-      for (int j = 0; j < M - 1; j++) {
-        double d1 = res[objectives - 1] + 4 * res[j] - 1;
+      for (var j = 0; j < M - 1; j++) {
+        var d1 = res[objectives - 1] + 4 * res[j] - 1;
         constraints[j] = d1 < 0 ? -d1 : 0;
       }
-      double min = Double.PositiveInfinity;
-      for (int i = 0; i < res.Length - 1; i++) {
-        for (int j = 0; j < i; j++) {
-          double d2 = res[i] + res[j];
+      var min = Double.PositiveInfinity;
+      for (var i = 0; i < res.Length - 1; i++) {
+        for (var j = 0; j < i; j++) {
+          var d2 = res[i] + res[j];
           if (min < d2) min = d2;
         }
       }
-      double d = 2 * res[objectives - 1] + min - 1;
+      var d = 2 * res[objectives - 1] + min - 1;
       constraints[constraints.Length - 1] = d < 0 ? -d : 0;
       return constraints;
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR.cs	(revision 16171)
@@ -20,6 +20,8 @@
 #endregion
 using System;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -36,6 +38,6 @@
 
     protected override double[] GetReferencePoint(int objectives) {
-      double[] rp = new double[objectives];
-      for (int i = 0; i < objectives; i++) {
+      var rp = new double[objectives];
+      for (var i = 0; i < objectives; i++) {
         rp[i] = 11;
       }
@@ -58,4 +60,7 @@
     protected abstract double G(RealVector y);
 
+    protected override double GetBestKnownHypervolume(int objectives) {
+      return HypervolumeCalculator.CalculateHypervolume(GetOptimalParetoFront(objectives).ToArray(), GetReferencePoint(objectives), GetMaximization(objectives));
+    }
 
     protected double H(double x, RealVector r) {
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR1.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR1.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR1.cs	(revision 16171)
@@ -31,15 +31,11 @@
   public class IHR1 : IHR {
     protected override IEnumerable<double[]> GetOptimalParetoFront(int objectives) {
-      List<double[]> res = new List<double[]>();
-      for (int i = 0; i <= 500; i++) {
-        RealVector r = new RealVector(objectives);
+      var res = new List<double[]>();
+      for (var i = 0; i <= 500; i++) {
+        var r = new RealVector(objectives);
         r[0] = 1 / 500.0 * i;
         res.Add(this.Evaluate(r, objectives));
       }
       return res;
-    }
-
-    protected override double GetBestKnownHypervolume(int objectives) {
-      return Hypervolume.Calculate(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
     }
 
@@ -64,6 +60,6 @@
 
     protected override double G(RealVector y) {
-      double sum = 0.0;
-      for (int i = 1; i < y.Length; i++) {
+      var sum = 0.0;
+      for (var i = 1; i < y.Length; i++) {
         sum += HG(y[i]);
       }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR2.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR2.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR2.cs	(revision 16171)
@@ -31,7 +31,7 @@
   public class IHR2 : IHR {
     protected override IEnumerable<double[]> GetOptimalParetoFront(int objectives) {
-      List<double[]> res = new List<double[]>();
-      for (int i = 0; i <= 500; i++) {
-        RealVector r = new RealVector(objectives);
+      var res = new List<double[]>();
+      for (var i = 0; i <= 500; i++) {
+        var r = new RealVector(objectives);
         r[0] = 1 / 500.0 * i;
 
@@ -39,8 +39,4 @@
       }
       return res;
-    }
-
-    protected override double GetBestKnownHypervolume(int objectives) {
-      return Hypervolume.Calculate(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
     }
 
@@ -66,6 +62,6 @@
 
     protected override double G(RealVector y) {
-      double sum = 0.0;
-      for (int i = 1; i < y.Length; i++) {
+      var sum = 0.0;
+      for (var i = 1; i < y.Length; i++) {
         sum += HG(y[i]);
       }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR3.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR3.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR3.cs	(revision 16171)
@@ -21,4 +21,5 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -31,7 +32,7 @@
   public class IHR3 : IHR {
     protected override IEnumerable<double[]> GetOptimalParetoFront(int objectives) {
-      List<double[]> res = new List<double[]>();
-      for (int i = 0; i <= 500; i++) {
-        RealVector r = new RealVector(objectives);
+      var res = new List<double[]>();
+      for (var i = 0; i <= 500; i++) {
+        var r = new RealVector(objectives);
         r[0] = 1 / 500.0 * i;
 
@@ -39,8 +40,4 @@
       }
       return res;
-    }
-
-    protected override double GetBestKnownHypervolume(int objectives) {
-      return Hypervolume.Calculate(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
     }
 
@@ -66,6 +63,6 @@
 
     protected override double G(RealVector y) {
-      double sum = 0.0;
-      for (int i = 1; i < y.Length; i++) {
+      var sum = 0.0;
+      for (var i = 1; i < y.Length; i++) {
         sum += HG(y[i]);
       }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR4.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR4.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR4.cs	(revision 16171)
@@ -21,4 +21,5 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -31,15 +32,11 @@
   public class IHR4 : IHR {
     protected override IEnumerable<double[]> GetOptimalParetoFront(int objectives) {
-      List<double[]> res = new List<double[]>();
-      for (int i = 0; i <= 500; i++) {
-        RealVector r = new RealVector(objectives);
+      var res = new List<double[]>();
+      for (var i = 0; i <= 500; i++) {
+        var r = new RealVector(objectives);
         r[0] = 1 / 500.0 * i;
         res.Add(this.Evaluate(r, objectives));
       }
       return res;
-    }
-
-    protected override double GetBestKnownHypervolume(int objectives) {
-      return Hypervolume.Calculate(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
     }
 
@@ -69,6 +66,6 @@
 
     protected override double G(RealVector y) {
-      double sum = 0.0;
-      for (int i = 1; i < y.Length; i++) {
+      var sum = 0.0;
+      for (var i = 1; i < y.Length; i++) {
         sum += y[i] * y[i] - 10 * Math.Cos(4 * Math.PI * y[i]);
       }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR6.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR6.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR6.cs	(revision 16171)
@@ -21,4 +21,5 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -31,15 +32,11 @@
   public class IHR6 : IHR {
     protected override IEnumerable<double[]> GetOptimalParetoFront(int objectives) {
-      List<double[]> res = new List<double[]>();
-      for (int i = 0; i <= 500; i++) {
-        RealVector r = new RealVector(objectives);
+      var res = new List<double[]>();
+      for (var i = 0; i <= 500; i++) {
+        var r = new RealVector(objectives);
         r[0] = 1 / 500.0 * i;
         res.Add(this.Evaluate(r, objectives));
       }
       return res;
-    }
-
-    protected override double GetBestKnownHypervolume(int objectives) {
-      return Hypervolume.Calculate(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
     }
 
@@ -65,6 +62,6 @@
 
     protected override double G(RealVector y) {
-      double sum = 0.0;
-      for (int i = 1; i < y.Length; i++) {
+      var sum = 0.0;
+      for (var i = 1; i < y.Length; i++) {
         sum += HG(y[i]);
       }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/CIGTAB.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/CIGTAB.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/CIGTAB.cs	(revision 16171)
@@ -21,7 +21,9 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -43,7 +45,7 @@
 
     protected override IEnumerable<double[]> GetOptimalParetoFront(int objecitves) {
-      List<double[]> res = new List<double[]>();
-      for (int i = 0; i <= 500; i++) {
-        RealVector r = new RealVector(2);
+      var res = new List<double[]>();
+      for (var i = 0; i <= 500; i++) {
+        var r = new RealVector(2);
         r[0] = 2 / 500.0 * i;
         r[1] = 2 / 500.0 * i;
@@ -54,5 +56,5 @@
 
     protected override double GetBestKnownHypervolume(int objectives) {
-      return Hypervolume.Calculate(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
+      return HypervolumeCalculator.CalculateHypervolume(GetOptimalParetoFront(objectives).ToArray(), GetReferencePoint(objectives), GetMaximization(objectives));
     }
 
@@ -68,8 +70,8 @@
     public override double[] Evaluate(RealVector r, int objectives) {
       if (objectives != 2) throw new ArgumentException("The CIGTAB problem must always have 2 objectives");
-      double x = r[0];
+      var x = r[0];
       double a = 1000;
-      double sum = x * x;
-      for (int i = 1; i < r.Length - 1; i++) {
+      var sum = x * x;
+      for (var i = 1; i < r.Length - 1; i++) {
         sum += a * r[i] * r[i];
       }
@@ -77,9 +79,9 @@
 
       //objective1
-      double f0 = 1 / (a * a * r.Length) * sum;
+      var f0 = 1 / (a * a * r.Length) * sum;
 
       x = x - 2;
       sum = x * x;
-      for (int i = 1; i < r.Length - 1; i++) {
+      for (var i = 1; i < r.Length - 1; i++) {
         sum += a * (r[i] - 2) * (r[i] - 2);
       }
@@ -87,5 +89,5 @@
       sum += a * a * (r[r.Length - 1] - 2) * (r[r.Length - 1] - 2);
       //objective0
-      double f1 = 1 / (a * a * r.Length) * sum;
+      var f1 = 1 / (a * a * r.Length) * sum;
 
       return new double[] { f0, f1 };
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/ELLI1.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/ELLI1.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/ELLI1.cs	(revision 16171)
@@ -21,7 +21,9 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -43,7 +45,7 @@
 
     protected override IEnumerable<double[]> GetOptimalParetoFront(int objecitves) {
-      List<double[]> res = new List<double[]>();
-      for (int i = 0; i <= 500; i++) {
-        RealVector r = new RealVector(2);
+      var res = new List<double[]>();
+      for (var i = 0; i <= 500; i++) {
+        var r = new RealVector(2);
         r[0] = 2 / 500.0 * i;
         r[1] = 2 / 500.0 * i;
@@ -54,5 +56,5 @@
 
     protected override double GetBestKnownHypervolume(int objectives) {
-      return Hypervolume.Calculate(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
+      return HypervolumeCalculator.CalculateHypervolume(GetOptimalParetoFront(objectives).ToArray(), GetReferencePoint(objectives), GetMaximization(objectives));
     }
 
@@ -69,18 +71,18 @@
       if (objectives != 2) throw new ArgumentException("The ELLI problem must always have 2 objectives");
       double a = 1000;
-      double sum = 0.0;
-      for (int i = 0; i < r.Length; i++) {
+      var sum = 0.0;
+      for (var i = 0; i < r.Length; i++) {
         sum += Math.Pow(a, 2 * i / (r.Length - 1)) * r[i] * r[i];
       }
 
       //objective1
-      double f0 = 1 / (a * a * r.Length) * sum;
+      var f0 = 1 / (a * a * r.Length) * sum;
 
       sum = 0.0;
-      for (int i = 0; i < r.Length; i++) {
+      for (var i = 0; i < r.Length; i++) {
         sum += Math.Pow(a, 2 * i / (r.Length - 1)) * (r[i] - 2) * (r[i] - 2);
       }
       //objective0
-      double f1 = 1 / (a * a * r.Length) * sum;
+      var f1 = 1 / (a * a * r.Length) * sum;
 
       return new double[] { f0, f1 };
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/Fonseca.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/Fonseca.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/Fonseca.cs	(revision 16171)
@@ -22,7 +22,9 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -44,5 +46,5 @@
 
     protected override double GetBestKnownHypervolume(int objectives) {
-      return Hypervolume.Calculate(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
+      return HypervolumeCalculator.CalculateHypervolume(GetOptimalParetoFront(objectives).ToArray(), GetReferencePoint(objectives), GetMaximization(objectives));
     }
 
@@ -65,6 +67,6 @@
 
       //objective1
-      for (int i = 0; i < r.Length; i++) {
-        double d = r[i] - aux;
+      for (var i = 0; i < r.Length; i++) {
+        var d = r[i] - aux;
         f0 += d * d;
       }
@@ -72,7 +74,7 @@
 
       //objective2
-      double f1 = 0.0;
-      for (int i = 0; i < r.Length; i++) {
-        double d = r[i] + aux;
+      var f1 = 0.0;
+      for (var i = 0; i < r.Length; i++) {
+        var d = r[i] + aux;
         f1 += d * d;
       }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/Kursawe.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/Kursawe.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/Kursawe.cs	(revision 16171)
@@ -21,7 +21,9 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -43,5 +45,5 @@
 
     protected override double GetBestKnownHypervolume(int objectives) {
-      return Hypervolume.Calculate(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
+      return HypervolumeCalculator.CalculateHypervolume(GetOptimalParetoFront(objectives).ToArray(), GetReferencePoint(objectives), GetMaximization(objectives));
     }
 
@@ -65,11 +67,11 @@
       if (objectives != 2) throw new ArgumentException("The Kursawe problem must always have 2 objectives");
       //objective 1
-      double f0 = 0.0;
-      for (int i = 0; i < r.Length - 1; i++) {
+      var f0 = 0.0;
+      for (var i = 0; i < r.Length - 1; i++) {
         f0 += -10 * Math.Exp(-0.2 * Math.Sqrt(r[i] * r[i] + r[i + 1] * r[i + 1]));
       }
       //objective2
-      double f1 = 0.0;
-      for (int i = 0; i < r.Length; i++) {
+      var f1 = 0.0;
+      for (var i = 0; i < r.Length; i++) {
         f1 += Math.Pow(Math.Abs(r[i]), 0.8) + 5 * Math.Sin(Math.Pow(r[i], 3));
       }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/SchafferN1.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/SchafferN1.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/SchafferN1.cs	(revision 16171)
@@ -21,7 +21,9 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -48,5 +50,5 @@
 
     protected override double GetBestKnownHypervolume(int objectives) {
-      return Hypervolume.Calculate(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
+      return HypervolumeCalculator.CalculateHypervolume(GetOptimalParetoFront(objectives).ToArray(), GetReferencePoint(objectives), GetMaximization(objectives));
     }
 
@@ -63,11 +65,11 @@
       if (objectives != 2) throw new ArgumentException("The Schaffer N1 problem must always have 2 objectives");
       if (r.Length != 1) return null;
-      double x = r[0];
+      var x = r[0];
 
       //objective1
-      double f0 = x * x;
+      var f0 = x * x;
 
       //objective0
-      double f1 = x - 2;
+      var f1 = x - 2;
       f1 *= f1;
 
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/SchafferN2.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/SchafferN2.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/SchafferN2.cs	(revision 16171)
@@ -59,5 +59,5 @@
     public override double[] Evaluate(RealVector r, int objectives) {
       if (objectives != 2) throw new ArgumentException("The Schaffer N1 problem must always have 2 objectives");
-      double x = r[0];
+      var x = r[0];
 
       //objective1
@@ -69,5 +69,5 @@
 
       //objective0
-      double f1 = x - 5;
+      var f1 = x - 5;
       f1 *= f1;
 
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ParetoFrontStore.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ParetoFrontStore.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ParetoFrontStore.cs	(revision 16171)
@@ -29,7 +29,7 @@
   internal class ParetoFrontStore {
     internal static IEnumerable<double[]> GetParetoFront(String filename) {
-      List<double[]> data = new List<double[]>();
+      var data = new List<double[]>();
       var assembly = Assembly.GetExecutingAssembly();
-      String ressourcename = typeof(ParetoFrontStore).Namespace + ".TestFunctions." + filename + ".pf";
+      var ressourcename = typeof(ParetoFrontStore).Namespace + ".TestFunctions." + filename + ".pf";
 
       //check if file is listed
@@ -42,6 +42,6 @@
       while ((s = ressourceReader.ReadLine()) != null) {
         var tokens = s.Split(new char[0], StringSplitOptions.RemoveEmptyEntries);
-        double[] point = new double[tokens.Length];
-        for (int i = 0; i < point.Length; i++) {
+        var point = new double[tokens.Length];
+        for (var i = 0; i < point.Length; i++) {
           point[i] = Double.Parse(tokens[i], CultureInfo.InvariantCulture);
         }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ZDT/ZDT1.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ZDT/ZDT1.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ZDT/ZDT1.cs	(revision 16171)
@@ -44,8 +44,8 @@
     public override double[] Evaluate(RealVector r) {
       double g = 0;
-      for (int i = 1; i < r.Length; i++) g += r[i];
+      for (var i = 1; i < r.Length; i++) g += r[i];
       g = 1.0 + 9.0 * g / (r.Length - 1);
-      double f0 = r[0];
-      double f1 = g * (1.0 - Math.Sqrt(r[0] / g));
+      var f0 = r[0];
+      var f1 = g * (1.0 - Math.Sqrt(r[0] / g));
       return new double[] { f0, f1 };
     }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ZDT/ZDT2.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ZDT/ZDT2.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ZDT/ZDT2.cs	(revision 16171)
@@ -42,9 +42,9 @@
     public override double[] Evaluate(RealVector r) {
       double g = 0;
-      for (int i = 1; i < r.Length; i++) g += r[i];
+      for (var i = 1; i < r.Length; i++) g += r[i];
       g = 1.0 + 9.0 * g / (r.Length - 1);
-      double d = r[0] / g;
-      double f0 = r[0];
-      double f1 = g * (1.0 - d * d);
+      var d = r[0] / g;
+      var f0 = r[0];
+      var f1 = g * (1.0 - d * d);
       return new double[] { f0, f1 };
     }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ZDT/ZDT3.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ZDT/ZDT3.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ZDT/ZDT3.cs	(revision 16171)
@@ -44,9 +44,9 @@
     public override double[] Evaluate(RealVector r) {
       double g = 0;
-      for (int i = 1; i < r.Length; i++) g += r[i];
+      for (var i = 1; i < r.Length; i++) g += r[i];
       g = 1.0 + 9.0 * g / (r.Length - 1);
-      double d = r[0] / g;
-      double f0 = r[0];
-      double f1 = g * (1.0 - Math.Sqrt(d) - d * Math.Sin(10 * Math.PI * r[0]));
+      var d = r[0] / g;
+      var f0 = r[0];
+      var f1 = g * (1.0 - Math.Sqrt(d) - d * Math.Sin(10 * Math.PI * r[0]));
       return new double[] { f0, f1 };
     }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ZDT/ZDT4.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ZDT/ZDT4.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ZDT/ZDT4.cs	(revision 16171)
@@ -30,7 +30,7 @@
   public class ZDT4 : ZDT {
     protected override double[,] GetBounds(int objectives) {
-      double[,] bounds = new double[objectives, 2];
+      var bounds = new double[objectives, 2];
       bounds[0, 0] = 0; bounds[0, 1] = 1;
-      for (int i = 1; i < objectives; i++) {
+      for (var i = 1; i < objectives; i++) {
         bounds[i, 0] = -5;
         bounds[i, 1] = 5;
@@ -53,12 +53,12 @@
     public override double[] Evaluate(RealVector r) {
       double g = 0;
-      for (int i = 1; i < r.Length; i++) {
-        double v = r[i];
+      for (var i = 1; i < r.Length; i++) {
+        var v = r[i];
         g += v * v - 10 * Math.Cos(4 * Math.PI * v);
       }
       g = 1.0 + 10.0 * (r.Length - 1) + g;
-      double d = r[0] / g;
-      double f0 = r[0];
-      double f1 = 1 - Math.Sqrt(d);
+      var d = r[0] / g;
+      var f0 = r[0];
+      var f1 = 1 - Math.Sqrt(d);
       return new double[] { f0, f1 };
     }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ZDT/ZDT6.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ZDT/ZDT6.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ZDT/ZDT6.cs	(revision 16171)
@@ -43,9 +43,9 @@
     public override double[] Evaluate(RealVector r) {
       double g = 0;
-      for (int i = 1; i < r.Length; i++) g += r[i];
+      for (var i = 1; i < r.Length; i++) g += r[i];
       g = 1.0 + 9.0 * Math.Pow(g / (r.Length - 1), 0.25);
-      double f1 = 1 - Math.Exp(-4 * r[0]) * Math.Pow(Math.Sin(6 * Math.PI * r[0]), 6);
-      double d = f1 / g;
-      double f2 = g * (1.0 - d * d);
+      var f1 = 1 - Math.Exp(-4 * r[0]) * Math.Pow(Math.Sin(6 * Math.PI * r[0]), 6);
+      var d = f1 / g;
+      var f2 = g * (1.0 - d * d);
       return new double[] { f1, f2 };
     }
Index: branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Utilities.cs
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Utilities.cs	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Utilities.cs	(revision 16171)
@@ -26,32 +26,13 @@
 namespace HeuristicLab.Problems.TestFunctions.MultiObjective {
   internal static class Utilities {
-    internal static double MinimumDistance(double[] point, IEnumerable<double[]> points) {
-      if (point == null) throw new ArgumentNullException("Point must not be null.");
-      if (points == null) throw new ArgumentNullException("Points must not be null.");
-      if (!points.Any()) throw new ArgumentException("Points must not be empty.");
-
-      double minDistance = double.MaxValue;
-      foreach (double[] r in points) {
-        if (r.Length != point.Length) throw new ArgumentException("Dimensions of Points and Point do not match.");
-
-        double squaredDistance = 0;
-        for (int i = 0; i < r.Length; i++) {
-          squaredDistance += (point[i] - r[i]) * (point[i] - r[i]);
-        }
-        minDistance = Math.Min(squaredDistance, minDistance);
-      }
-
-      return Math.Sqrt(minDistance);
-    }
-
     internal static DoubleMatrix ToMatrix(IEnumerable<double[]> source) {
       try {
-        int firstDimension = source.Count();
-        int secondDimension = source.GroupBy(row => row.Length).Single().Key; // throws InvalidOperationException if source is not rectangular
+        var firstDimension = source.Count();
+        var secondDimension = source.GroupBy(row => row.Length).Single().Key; // throws InvalidOperationException if source is not rectangular
 
         var result = new DoubleMatrix(firstDimension, secondDimension);
         var enumarator = source.GetEnumerator();
-        for (int i = 0; i < firstDimension && enumarator.MoveNext(); ++i)
-          for (int j = 0; j < secondDimension; ++j)
+        for (var i = 0; i < firstDimension && enumarator.MoveNext(); ++i)
+          for (var j = 0; j < secondDimension; ++j)
             result[i, j] = enumarator.Current[j];
         return result;
@@ -62,19 +43,5 @@
     }
 
-    internal class DimensionComparer : IComparer<double[]> {
-      private readonly int dim;
-      private readonly int descending;
-
-      public DimensionComparer(int dimension, bool descending) {
-        this.dim = dimension;
-        this.descending = descending ? -1 : 1;
-      }
-
-      public int Compare(double[] x, double[] y) {
-        if (x[dim] < y[dim]) return -descending;
-        else if (x[dim] > y[dim]) return descending;
-        else return 0;
-      }
-    }
+    
   }
 }
Index: branches/2943_MOBasicProblem_MOCMAES/MOCMAES-TestProblem-Rework.sln
===================================================================
--- branches/2943_MOBasicProblem_MOCMAES/MOCMAES-TestProblem-Rework.sln	(revision 16159)
+++ branches/2943_MOBasicProblem_MOCMAES/MOCMAES-TestProblem-Rework.sln	(revision 16171)
@@ -11,4 +11,8 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.TestFunctions.MultiObjective-3.3", "HeuristicLab.Problems.TestFunctions.MultiObjective\3.3\HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.csproj", "{D53E8E48-CFAA-4F57-AC35-63BEF4476159}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Optimization.Operators-3.3", "HeuristicLab.Optimization.Operators\3.3\HeuristicLab.Optimization.Operators-3.3.csproj", "{25087811-F74C-4128-BC86-8324271DA13E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Data-3.3", "HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj", "{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}"
 EndProject
 Global
@@ -70,4 +74,28 @@
 		{D53E8E48-CFAA-4F57-AC35-63BEF4476159}.Release|x86.ActiveCfg = Release|x86
 		{D53E8E48-CFAA-4F57-AC35-63BEF4476159}.Release|x86.Build.0 = Release|x86
+		{25087811-F74C-4128-BC86-8324271DA13E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{25087811-F74C-4128-BC86-8324271DA13E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{25087811-F74C-4128-BC86-8324271DA13E}.Debug|x64.ActiveCfg = Debug|x64
+		{25087811-F74C-4128-BC86-8324271DA13E}.Debug|x64.Build.0 = Debug|x64
+		{25087811-F74C-4128-BC86-8324271DA13E}.Debug|x86.ActiveCfg = Debug|x86
+		{25087811-F74C-4128-BC86-8324271DA13E}.Debug|x86.Build.0 = Debug|x86
+		{25087811-F74C-4128-BC86-8324271DA13E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{25087811-F74C-4128-BC86-8324271DA13E}.Release|Any CPU.Build.0 = Release|Any CPU
+		{25087811-F74C-4128-BC86-8324271DA13E}.Release|x64.ActiveCfg = Release|x64
+		{25087811-F74C-4128-BC86-8324271DA13E}.Release|x64.Build.0 = Release|x64
+		{25087811-F74C-4128-BC86-8324271DA13E}.Release|x86.ActiveCfg = Release|x86
+		{25087811-F74C-4128-BC86-8324271DA13E}.Release|x86.Build.0 = Release|x86
+		{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}.Debug|x64.ActiveCfg = Debug|x64
+		{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}.Debug|x64.Build.0 = Debug|x64
+		{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}.Debug|x86.ActiveCfg = Debug|x86
+		{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}.Debug|x86.Build.0 = Debug|x86
+		{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}.Release|Any CPU.Build.0 = Release|Any CPU
+		{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}.Release|x64.ActiveCfg = Release|x64
+		{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}.Release|x64.Build.0 = Release|x64
+		{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}.Release|x86.ActiveCfg = Release|x86
+		{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}.Release|x86.Build.0 = Release|x86
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
