Index: /branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/IIndicator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/IIndicator.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/IIndicator.cs	(revision 17225)
@@ -36,5 +36,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, MultiObjectiveProblem<RealVectorEncoding, RealVector> problem);
+    int LeastContributer(IReadOnlyList<Individual> front, IMultiObjectiveProblemDefinition problem);
   }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/CrowdingIndicator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/CrowdingIndicator.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/CrowdingIndicator.cs	(revision 17225)
@@ -20,5 +20,4 @@
 #endregion
 
-using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -37,28 +36,15 @@
     protected CrowdingIndicator(StorableConstructorFlag _) : base(_) { }
     protected CrowdingIndicator(CrowdingIndicator original, Cloner cloner) : base(original, cloner) { }
-    public override IDeepCloneable Clone(Cloner cloner) { return new CrowdingIndicator(this, cloner); }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CrowdingIndicator(this, cloner);
+    }
     public CrowdingIndicator() { }
     #endregion
 
-    public int LeastContributer(IReadOnlyList<Individual> front, MultiObjectiveProblem<RealVectorEncoding, RealVector> problem) {
-      var bounds = problem.Encoding.Bounds;
+    public int LeastContributer(IReadOnlyList<Individual> front, IMultiObjectiveProblemDefinition 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++;
-        }
-      }
-      return pointsums.Select((value, index) => new { value, index }).OrderBy(x => x.value).First().index;
+      var pointsums = CrowdingCalculator.CalculateCrowdingDistances(extracted);
+      return pointsums.Select((value, index) => new {value, index}).OrderBy(x => x.value).First().index;
     }
   }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/HypervolumeIndicator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/HypervolumeIndicator.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/HypervolumeIndicator.cs	(revision 17225)
@@ -20,5 +20,4 @@
 #endregion
 
-using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -26,9 +25,9 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Encodings.RealVectorEncoding;
 using HeuristicLab.Optimization;
 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")]
   [StorableType("ADF439D6-64E4-4C92-A4D3-E8C05B050406")]
   internal class HypervolumeIndicator : Item, IIndicator {
@@ -37,16 +36,18 @@
     protected HypervolumeIndicator(StorableConstructorFlag _) : base(_) { }
     protected HypervolumeIndicator(HypervolumeIndicator original, Cloner cloner) : base(original, cloner) { }
-    public override IDeepCloneable Clone(Cloner cloner) { return new HypervolumeIndicator(this, cloner); }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new HypervolumeIndicator(this, cloner);
+    }
     public HypervolumeIndicator() { }
     #endregion
 
-    public int LeastContributer(IReadOnlyList<Individual> front, MultiObjectiveProblem<RealVectorEncoding, RealVector> problem) {
+    public int LeastContributer(IReadOnlyList<Individual> front, IMultiObjectiveProblemDefinition problem) {
       var frontCopy = front.Select(x => x.PenalizedFitness).ToList();
       if (frontCopy.Count <= 1) return 0;
       //TODO discuss with bwerth
-      var p = problem as MultiObjectiveTestFunctionProblem;
-      var refPoint = BuildReferencePoint(p != null ? frontCopy.Concat(new[] { p.ReferencePoint.CloneAsArray() }) : frontCopy, problem.Maximization);
+      var tep = problem != null ? frontCopy.Concat(new[] {problem.ReferencePoint}) : 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;
+      return contributions.Select((value, index) => new {value, index}).OrderBy(x => x.value).First().index;
     }
 
@@ -55,14 +56,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/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/MinimalDistanceIndicator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/MinimalDistanceIndicator.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/MinimalDistanceIndicator.cs	(revision 17225)
@@ -33,14 +33,15 @@
   [StorableType("FBBD4517-164C-4DEE-B87D-49B99172EDF4")]
   internal class MinimalDistanceIndicator : Item, IIndicator {
-
     #region Constructor and Cloning
     [StorableConstructor]
     protected MinimalDistanceIndicator(StorableConstructorFlag _) : base(_) { }
     protected MinimalDistanceIndicator(MinimalDistanceIndicator original, Cloner cloner) : base(original, cloner) { }
-    public override IDeepCloneable Clone(Cloner cloner) { return new MinimalDistanceIndicator(this, cloner); }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MinimalDistanceIndicator(this, cloner);
+    }
     public MinimalDistanceIndicator() { }
     #endregion
 
-    public int LeastContributer(IReadOnlyList<Individual> front, MultiObjectiveProblem<RealVectorEncoding, RealVector> problem) {
+    public int LeastContributer(IReadOnlyList<Individual> front, IMultiObjectiveProblemDefinition problem) {
       var extracted = front.Select(x => x.PenalizedFitness).ToArray();
       if (extracted.Length <= 2) return 0;
@@ -88,6 +89,6 @@
       var res = new double[extracted.Count, extracted.Count];
       for (var i = 0; i < extracted.Count; i++)
-        for (var j = 0; j < i; j++)
-          res[i, j] = res[j, i] = Dist(extracted[i], extracted[j]);
+      for (var j = 0; j < i; j++)
+        res[i, j] = res[j, i] = Dist(extracted[i], extracted[j]);
       return res;
     }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/MOCMAEvolutionStrategy.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/MOCMAEvolutionStrategy.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/MOCMAEvolutionStrategy.cs	(revision 17225)
@@ -52,4 +52,8 @@
     }
 
+    public RealVectorEncoding Encoding {
+      get { return Problem.Encoding; }
+    }
+
     #region Storable fields
     [Storable]
@@ -64,14 +68,13 @@
     private double stepSizeDampeningFactor; //d
     [Storable]
-    private double targetSuccessProbability;// p^target_succ
-    [Storable]
-    private double evolutionPathLearningRate;//cc
-    [Storable]
-    private double covarianceMatrixLearningRate;//ccov
+    private double targetSuccessProbability; // p^target_succ
+    [Storable]
+    private double evolutionPathLearningRate; //cc
+    [Storable]
+    private double covarianceMatrixLearningRate; //ccov
     [Storable]
     private double covarianceMatrixUnlearningRate;
     [Storable]
     private double successThreshold; //ptresh
-
     #endregion
 
@@ -162,11 +165,25 @@
     }
 
-    public double StepSizeLearningRate { get { return stepSizeLearningRate; } }
-    public double StepSizeDampeningFactor { get { return stepSizeDampeningFactor; } }
-    public double TargetSuccessProbability { get { return targetSuccessProbability; } }
-    public double EvolutionPathLearningRate { get { return evolutionPathLearningRate; } }
-    public double CovarianceMatrixLearningRate { get { return covarianceMatrixLearningRate; } }
-    public double CovarianceMatrixUnlearningRate { get { return covarianceMatrixUnlearningRate; } }
-    public double SuccessThreshold { get { return successThreshold; } }
+    public double StepSizeLearningRate {
+      get { return stepSizeLearningRate; }
+    }
+    public double StepSizeDampeningFactor {
+      get { return stepSizeDampeningFactor; }
+    }
+    public double TargetSuccessProbability {
+      get { return targetSuccessProbability; }
+    }
+    public double EvolutionPathLearningRate {
+      get { return evolutionPathLearningRate; }
+    }
+    public double CovarianceMatrixLearningRate {
+      get { return covarianceMatrixLearningRate; }
+    }
+    public double CovarianceMatrixUnlearningRate {
+      get { return covarianceMatrixUnlearningRate; }
+    }
+    public double SuccessThreshold {
+      get { return successThreshold; }
+    }
     #endregion
 
@@ -238,5 +255,4 @@
       get { return ((DoubleValue)Results[DifferenceToBestKnownHypervolumeResultName].Value).Value; }
       set { ((DoubleValue)Results[DifferenceToBestKnownHypervolumeResultName].Value).Value = value; }
-
     }
     //Solutions
@@ -257,8 +273,8 @@
       Parameters.Add(new FixedValueParameter<BoolValue>(SetSeedRandomlyName, "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
       Parameters.Add(new FixedValueParameter<IntValue>(PopulationSizeName, "λ (lambda) - the size of the offspring population.", new IntValue(20)));
-      Parameters.Add(new ValueParameter<DoubleArray>(InitialSigmaName, "The initial sigma can be a single value or a value for each dimension. All values need to be > 0.", new DoubleArray(new[] { 0.5 })));
+      Parameters.Add(new ValueParameter<DoubleArray>(InitialSigmaName, "The initial sigma can be a single value or a value for each dimension. All values need to be > 0.", new DoubleArray(new[] {0.5})));
       Parameters.Add(new FixedValueParameter<IntValue>(MaximumGenerationsName, "The maximum number of generations which should be processed.", new IntValue(1000)));
       Parameters.Add(new FixedValueParameter<IntValue>(MaximumEvaluatedSolutionsName, "The maximum number of evaluated solutions that should be computed.", new IntValue(int.MaxValue)));
-      var set = new ItemSet<IIndicator> { new HypervolumeIndicator(), new CrowdingIndicator(), new MinimalDistanceIndicator() };
+      var set = new ItemSet<IIndicator> {new HypervolumeIndicator(), new CrowdingIndicator(), new MinimalDistanceIndicator()};
       Parameters.Add(new ConstrainedValueParameter<IIndicator>(IndicatorName, "The selection mechanism on non-dominated solutions", set, set.First()));
     }
@@ -280,5 +296,7 @@
     }
 
-    public override IDeepCloneable Clone(Cloner cloner) { return new MOCMAEvolutionStrategy(this, cloner); }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MOCMAEvolutionStrategy(this, cloner);
+    }
     #endregion
 
@@ -309,7 +327,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 +340,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);
@@ -355,11 +373,12 @@
       Results.Add(new Result(ScatterPlotResultName, "A scatterplot displaying the evaluated solutions and (if available) the analytically optimal front", new ParetoFrontScatterPlot()));
 
-      var problem = Problem as MultiObjectiveTestFunctionProblem;
+      var problem = Problem;
       if (problem == null) return;
-      if (problem.BestKnownFront != null) {
-        ResultsBestKnownHypervolume = Hypervolume.Calculate(problem.BestKnownFront.ToJaggedArray(), problem.TestFunction.ReferencePoint(problem.Objectives), Problem.Maximization);
+      var bkf = problem.BestKnownFront == null ? null : problem.BestKnownFront.ToArray();
+      if (bkf != null && problem.ReferencePoint != null) {
+        ResultsBestKnownHypervolume = HypervolumeCalculator.CalculateHypervolume(bkf, problem.ReferencePoint, Problem.Maximization);
         ResultsDifferenceBestKnownHypervolume = ResultsBestKnownHypervolume;
       }
-      ResultsScatterPlot = new ParetoFrontScatterPlot(new double[0][], new double[0][], problem.BestKnownFront.ToJaggedArray(), Problem.Objectives, Problem.Encoding.Length);
+      ResultsScatterPlot = new ParetoFrontScatterPlot(new double[0][], new double[0][], bkf, Problem.Objectives, Problem.Encoding.Length);
     }
     #endregion
@@ -417,5 +436,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 +445,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 +457,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,18 +489,22 @@
 
     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();
 
-      var problem = Problem as MultiObjectiveTestFunctionProblem;
+      var problem = Problem as MultiObjectiveProblem<RealVectorEncoding, RealVector>;
       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 = Spacing.Calculate(qualities);
+
+
+      ResultsGenerationalDistance = problem.BestKnownFront != null ? GenerationalDistance.Calculate(qualities, problem.BestKnownFront, 1) : double.NaN;
+      ResultsInvertedGenerationalDistance = problem.BestKnownFront != null ? InvertedGenerationalDistance.Calculate(qualities, problem.BestKnownFront, 1) : double.NaN;
+      ResultsHypervolume = problem.ReferencePoint != null ? HypervolumeCalculator.CalculateHypervolume(qualities, problem.ReferencePoint, Problem.Maximization) : double.NaN;
       ResultsBestHypervolume = Math.Max(ResultsHypervolume, ResultsBestHypervolume);
       ResultsDifferenceBestKnownHypervolume = ResultsBestKnownHypervolume - ResultsBestHypervolume;
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 17225)
@@ -150,6 +150,13 @@
     <Compile Include="DataVisualization\ScatterPlot.cs" />
     <Compile Include="MultidimensionalScaling\MultidimensionalScaling.cs" />
+    <Compile Include="MultiObjective\CrowdingAnalyzer.cs" />
+    <Compile Include="MultiObjective\GenerationalDistanceAnalyzer.cs" />
+    <Compile Include="MultiObjective\HypervolumeAnalyzer.cs" />
+    <Compile Include="MultiObjective\InvertedGenerationalDistanceAnalyzer.cs" />
+    <Compile Include="MultiObjective\MultiObjectiveSuccessAnalyzer.cs" />
     <Compile Include="MultiObjective\RankBasedParetoFrontAnalyzer.cs" />
     <Compile Include="MultiObjective\ParetoFrontAnalyzer.cs" />
+    <Compile Include="MultiObjective\SpacingAnalyzer.cs" />
+    <Compile Include="MultiObjective\TimelineAnalyzer.cs" />
     <Compile Include="Plugin.cs" />
     <Compile Include="PopulationSimilarityAnalysis\PopulationDiversityAnalyzer.cs" />
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/MultiObjective/CrowdingAnalyzer.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/MultiObjective/CrowdingAnalyzer.cs	(revision 17225)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/MultiObjective/CrowdingAnalyzer.cs	(revision 17225)
@@ -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.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
+
+namespace HeuristicLab.Analysis {
+  [StorableType("6f09f028-039d-4da8-9585-2575f9aef074")]
+  [Item("CrowdingAnalyzer", "The mean crowding distance for each point of the Front (see Multi-Objective Performance Metrics - Shodhganga for more information)")]
+  public class CrowdingAnalyzer : MultiObjectiveSuccessAnalyzer {
+    public override string ResultName {
+      get { return "Crowding"; }
+    }
+
+    [StorableConstructor]
+    protected CrowdingAnalyzer(StorableConstructorFlag _) : base(_) { }
+    public CrowdingAnalyzer(CrowdingAnalyzer original, Cloner cloner)
+      : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CrowdingAnalyzer(this, cloner);
+    }
+
+    public CrowdingAnalyzer() {
+      Parameters.Add(new ResultParameter<DoubleValue>("Crowding", "The average corwding distance of all points (excluding infinities)", "Results", new DoubleValue(double.NaN)));
+    }
+
+    public override IOperation Apply() {
+      var qualities = QualitiesParameter.ActualValue;
+      var crowdingDistance = CrowdingCalculator.CalculateCrowding(qualities.Select(x => x.ToArray()));
+      ResultParameter.ActualValue.Value = crowdingDistance;
+      return base.Apply();
+    }
+  }
+}
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/MultiObjective/GenerationalDistanceAnalyzer.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/MultiObjective/GenerationalDistanceAnalyzer.cs	(revision 17225)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/MultiObjective/GenerationalDistanceAnalyzer.cs	(revision 17225)
@@ -0,0 +1,105 @@
+﻿#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 HEAL.Attic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+
+namespace HeuristicLab.Analysis {
+  [StorableType("f8ae6c1c-5f8f-45d6-b513-bb8041546808")]
+  [Item("GenerationalDistanceAnalyzer", "The generational distance between the current and the optimal front (if known)(see Multi-Objective Performance Metrics - Shodhganga for more information). The calculation of generational distance requires a known optimal pareto front")]
+  public class GenerationalDistanceAnalyzer : MultiObjectiveSuccessAnalyzer {
+    public override string ResultName {
+      get { return "Generational Distance"; }
+    }
+
+    public IFixedValueParameter<DoubleValue> DampeningParameter {
+      get { return (IFixedValueParameter<DoubleValue>)Parameters["Dampening"]; }
+    }
+
+    public double Dampening {
+      get { return DampeningParameter.Value.Value; }
+      set { DampeningParameter.Value.Value = value; }
+    }
+
+    public ILookupParameter<DoubleMatrix> OptimalParetoFrontParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters["BestKnownFront"]; }
+    }
+
+
+    [StorableConstructor]
+    protected GenerationalDistanceAnalyzer(StorableConstructorFlag _) : base(_) { }
+    protected GenerationalDistanceAnalyzer(GenerationalDistanceAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GenerationalDistanceAnalyzer(this, cloner);
+    }
+
+    public GenerationalDistanceAnalyzer() : base() {
+      Parameters.Add(new FixedValueParameter<DoubleValue>("Dampening", "", new DoubleValue(1)));
+      Parameters.Add(new LookupParameter<ItemArray<DoubleArray>>("OptimalParetoFront", "The analytically best known Pareto front"));
+      Parameters.Add(new ResultParameter<DoubleValue>(ResultName, "The generational distance between the current front and the optimal front", "Results", new DoubleValue(double.NaN)));
+    }
+
+    public override IOperation Apply() {
+      var qualities = QualitiesParameter.ActualValue;
+      var optimalFront = OptimalParetoFrontParameter.ActualValue;
+      if (optimalFront == null) return base.Apply();
+      var front = Enumerable.Range(0, optimalFront.Rows).Select(r => Enumerable.Range(0, optimalFront.Columns).Select(c => optimalFront[r, c]).ToArray()).ToList();
+      ResultParameter.ActualValue.Value = CalculateDistance(qualities, front);
+      return base.Apply();
+    }
+
+    protected virtual double CalculateDistance(ItemArray<DoubleArray> qualities, IEnumerable<double[]> optimalFront) {
+      return CalculateGenerationalDistance(qualities.Select(x => x.ToArray()), optimalFront, Dampening);
+    }
+
+    public static double CalculateGenerationalDistance(IEnumerable<double[]> qualities, IEnumerable<double[]> bestKnownFront, double p) {
+      if (qualities == null || bestKnownFront == null) throw new ArgumentNullException("qualities");
+      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(IEnumerable<double[]> qualities, IEnumerable<double[]> bestKnownFront, double p) {
+      return CalculateGenerationalDistance(bestKnownFront, qualities, p);
+    }
+  }
+}
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/MultiObjective/HypervolumeAnalyzer.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/MultiObjective/HypervolumeAnalyzer.cs	(revision 17225)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/MultiObjective/HypervolumeAnalyzer.cs	(revision 17225)
@@ -0,0 +1,84 @@
+﻿#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 HEAL.Attic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+
+namespace HeuristicLab.Analysis {
+  [StorableType("fc42ed56-15de-41df-bf59-0e5b11cd4f9b")]
+  [Item("HypervolumeAnalyzer", "Computes the enclosed Hypervolume between the current front and a given reference Point")]
+  public class HypervolumeAnalyzer : MultiObjectiveSuccessAnalyzer {
+    public override string ResultName {
+      get { return "Hypervolume"; }
+    }
+
+    public ILookupParameter<DoubleArray> ReferencePointParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["ReferencePoint"]; }
+    }
+
+    public IResultParameter<DoubleValue> BestKnownHypervolumeResultParameter {
+      get { return (IResultParameter<DoubleValue>)Parameters["Best known hypervolume"]; }
+    }
+
+    public IResultParameter<DoubleValue> HypervolumeDistanceResultParameter {
+      get { return (IResultParameter<DoubleValue>)Parameters["Absolute Distance to BestKnownHypervolume"]; }
+    }
+
+
+    [StorableConstructor]
+    protected HypervolumeAnalyzer(StorableConstructorFlag _) : base(_) { }
+
+    protected HypervolumeAnalyzer(HypervolumeAnalyzer original, Cloner cloner) : base(original, cloner) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new HypervolumeAnalyzer(this, cloner);
+    }
+
+    public HypervolumeAnalyzer() {
+      Parameters.Add(new LookupParameter<DoubleArray>("ReferencePoint", "The reference point for hypervolume calculation"));
+      Parameters.Add(new ResultParameter<DoubleValue>("Hypervolume", "The hypervolume of the current generation", "Results", new DoubleValue(double.NaN)));
+      Parameters.Add(new ResultParameter<DoubleValue>("Best known hypervolume", "The optimal hypervolume"));
+      Parameters.Add(new ResultParameter<DoubleValue>("Absolute Distance to BestKnownHypervolume", "The difference between the best known and the current hypervolume"));
+      BestKnownHypervolumeResultParameter.DefaultValue = new DoubleValue(double.NaN);
+      HypervolumeDistanceResultParameter.DefaultValue = new DoubleValue(double.NaN);
+    }
+
+    public override IOperation Apply() {
+      var qualities = QualitiesParameter.ActualValue.Select(x => x.CloneAsArray()).ToArray();
+      var referencePoint = ReferencePointParameter.ActualValue.ToArray();
+      var best = BestKnownHypervolumeResultParameter.ActualValue.Value;
+      var maximization = MaximizationParameter.ActualValue.ToArray();
+
+      var hv = HypervolumeCalculator.CalculateHypervolume(qualities, referencePoint, maximization);
+      if (hv > best || double.IsNaN(best)) best = hv;
+      ResultParameter.ActualValue.Value = hv;
+      BestKnownHypervolumeResultParameter.ActualValue.Value = best;
+      HypervolumeDistanceResultParameter.ActualValue.Value = best - hv;
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/MultiObjective/InvertedGenerationalDistanceAnalyzer.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/MultiObjective/InvertedGenerationalDistanceAnalyzer.cs	(revision 17225)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/MultiObjective/InvertedGenerationalDistanceAnalyzer.cs	(revision 17225)
@@ -0,0 +1,58 @@
+﻿#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.Linq;
+using HEAL.Attic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Analysis {
+  [StorableType("1004980a-9b3d-4b6f-b5bf-81e75d288344")]
+  [Item("InvertedGenerationalDistanceAnalyzer", "The inverted generational distance between the current and the best known front (see Multi-Objective Performance Metrics - Shodhganga for more information)")]
+  public class InvertedGenerationalDistanceAnalyzer : GenerationalDistanceAnalyzer {
+    public override bool EnabledByDefault {
+      get { return false; }
+    }
+    public override string ResultName {
+      get { return "Inverted Generational Distance"; }
+    }
+
+    public IResultParameter<DoubleValue> InvertedGenerationalDistanceResultParameter {
+      get { return (IResultParameter<DoubleValue>)Parameters["Inverted Generational Distance"]; }
+    }
+
+    [StorableConstructor]
+    protected InvertedGenerationalDistanceAnalyzer(StorableConstructorFlag _) : base(_) { }
+    protected InvertedGenerationalDistanceAnalyzer(InvertedGenerationalDistanceAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new InvertedGenerationalDistanceAnalyzer(this, cloner);
+    }
+
+    public InvertedGenerationalDistanceAnalyzer() : base() { }
+
+    protected override double CalculateDistance(ItemArray<DoubleArray> qualities, IEnumerable<double[]> optimalFront) {
+      return CalculateGenerationalDistance(optimalFront, qualities.Select(x => x.ToArray()), Dampening);
+    }
+  }
+}
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/MultiObjective/MultiObjectiveSuccessAnalyzer.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/MultiObjective/MultiObjectiveSuccessAnalyzer.cs	(revision 17225)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/MultiObjective/MultiObjectiveSuccessAnalyzer.cs	(revision 17225)
@@ -0,0 +1,61 @@
+﻿#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.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
+
+
+namespace HeuristicLab.Analysis {
+  [StorableType("3659291a-927c-4016-88be-8a0f65476660")]
+  public abstract class MultiObjectiveSuccessAnalyzer : SingleSuccessorOperator, IAnalyzer, IMultiObjectiveOperator {
+    public virtual bool EnabledByDefault {
+      get { return true; }
+    }
+    public abstract string ResultName { get; }
+
+    public IScopeTreeLookupParameter<DoubleArray> QualitiesParameter {
+      get { return (IScopeTreeLookupParameter<DoubleArray>)Parameters["Qualities"]; }
+    }
+
+    public ILookupParameter<BoolArray> MaximizationParameter {
+      get { return (ILookupParameter<BoolArray>)Parameters["Maximization"]; }
+    }
+
+    public ResultParameter<DoubleValue> ResultParameter {
+      get { return (ResultParameter<DoubleValue>)Parameters[ResultName]; }
+    }
+
+    protected MultiObjectiveSuccessAnalyzer(MultiObjectiveSuccessAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    [StorableConstructor]
+    protected MultiObjectiveSuccessAnalyzer(StorableConstructorFlag _) : base(_) { }
+    protected MultiObjectiveSuccessAnalyzer() {
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleArray>("Qualities", "The qualities of the parameter vector."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("BestKnownFront", "The currently best known Pareto front"));
+      Parameters.Add(new LookupParameter<BoolArray>("Maximization", ""));
+    }
+  }
+}
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/MultiObjective/SpacingAnalyzer.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/MultiObjective/SpacingAnalyzer.cs	(revision 17225)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/MultiObjective/SpacingAnalyzer.cs	(revision 17225)
@@ -0,0 +1,77 @@
+﻿#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 HEAL.Attic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Analysis {
+  [StorableType("d84ac1f1-a6d4-425f-bcff-28472ef7529a")]
+  [Item("SpacingAnalyzer", "The spacing of the current front (see Multi-Objective Performance Metrics - Shodhganga for more information)")]
+  public class SpacingAnalyzer : MultiObjectiveSuccessAnalyzer {
+    public override string ResultName {
+      get { return "Spacing"; }
+    }
+
+    [StorableConstructor]
+    protected SpacingAnalyzer(StorableConstructorFlag _) : base(_) { }
+
+
+    protected SpacingAnalyzer(SpacingAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SpacingAnalyzer(this, cloner);
+    }
+
+    public SpacingAnalyzer() {
+      Parameters.Add(new ResultParameter<DoubleValue>("Spacing", "The spacing of the current front", "Results", new DoubleValue(double.NaN)));
+    }
+
+    public override IOperation Apply() {
+      var qualities = QualitiesParameter.ActualValue;
+      ResultParameter.ActualValue.Value = CalculateSpacing(qualities.Select(x => x.ToArray()));
+      return base.Apply();
+    }
+
+    public static double CalculateSpacing(IEnumerable<double[]> qualities) {
+      if (qualities == null) throw new ArgumentNullException("qualities");
+      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/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/MultiObjective/TimelineAnalyzer.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/MultiObjective/TimelineAnalyzer.cs	(revision 17225)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Analysis/3.3/MultiObjective/TimelineAnalyzer.cs	(revision 17225)
@@ -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.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
+
+namespace HeuristicLab.Analysis {
+  [StorableType("48fc7ff7-a8ab-4ef9-8c01-cc6fbbe3da0b")]
+  [Item("TimelineAnalyzer", "Collects the specified double values from the results and displays them as a timeline")]
+  public class TimelineAnalyzer : SingleSuccessorOperator, IAnalyzer, IMultiObjectiveOperator {
+    public bool EnabledByDefault {
+      get { return true; }
+    }
+    public string ResultName {
+      get { return "Timeline"; }
+    }
+
+    public IFixedValueParameter<CheckedItemList<StringValue>> CollectedSuccessMeasuresParameter {
+      get { return (IFixedValueParameter<CheckedItemList<StringValue>>)Parameters["CollectedSuccessMeasures"]; }
+    }
+
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+
+    public ResultParameter<DataTable> ResultParameter {
+      get { return (ResultParameter<DataTable>)Parameters[ResultName]; }
+    }
+
+    public CheckedItemList<StringValue> CollectedSuccessMeasures {
+      get { return CollectedSuccessMeasuresParameter.Value; }
+    }
+
+    [StorableConstructor]
+    protected TimelineAnalyzer(StorableConstructorFlag _) : base(_) { }
+
+
+    protected TimelineAnalyzer(TimelineAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TimelineAnalyzer(this, cloner);
+    }
+
+    public TimelineAnalyzer() {
+      var names = new List<string> {
+        new CrowdingAnalyzer().ResultName,
+        new GenerationalDistanceAnalyzer().ResultName,
+        new InvertedGenerationalDistanceAnalyzer().ResultName,
+        new HypervolumeAnalyzer().ResultName,
+        new SpacingAnalyzer().ResultName
+      };
+      var analyzers = new CheckedItemList<StringValue>(names.Select(n => new StringValue(n)));
+      Parameters.Add(new FixedValueParameter<CheckedItemList<StringValue>>("CollectedSuccessMeasures", analyzers));
+      Parameters.Add(new LookupParameter<ResultCollection>("Results"));
+      Parameters.Add(new ResultParameter<DataTable>("Timeline", "The development of the success measures over the generations", "Results", new DataTable("Timeline", "")));
+    }
+
+    public override IOperation Apply() {
+      if (ResultParameter.ActualValue == null) ResultParameter.ActualValue = new DataTable(ResultName, "");
+      var plot = ResultParameter.ActualValue;
+      var resultCollection = ResultsParameter.ActualValue;
+      foreach (var resultName in CollectedSuccessMeasures.CheckedItems.Select(i => i.Value.Value)) {
+        if (!resultCollection.ContainsKey(resultName)) continue;
+        var res = resultCollection[resultName].Value as DoubleValue;
+        if (res == null) continue;
+        if (!plot.Rows.ContainsKey(resultName)) plot.Rows.Add(new DataRow(resultName));
+        plot.Rows[resultName].Values.Add(res.Value);
+      }
+      return base.Apply();
+    }
+  }
+}
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Common/3.3/EnumerableExtensions.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Common/3.3/EnumerableExtensions.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Common/3.3/EnumerableExtensions.cs	(revision 17225)
@@ -26,4 +26,28 @@
 namespace HeuristicLab.Common {
   public static class EnumerableExtensions {
+    public static T[,] ToMatrix<T>(this IEnumerable<IEnumerable<T>> source) {
+      if (source == null) throw new ArgumentNullException("source");
+      if (!source.Any()) return new T[0, 0];
+
+      int firstDimension = source.Count();
+      int secondDimension = source.First().Count();
+      var result = new T[firstDimension, secondDimension];
+
+      int i = 0;
+      int j = 0;
+      foreach (var row in source) {
+        j = 0;
+        foreach (var element in row) {
+          result[i, j] = element;
+          j++;
+        }
+        if (j != secondDimension) throw new InvalidOperationException("All enumerables must be of the same length.");
+        i++;
+      }
+
+      return result;
+    }
+
+
     /// <summary>
     /// Selects all elements in the sequence that are maximal with respect to the given value.
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/Interfaces/IValueTypeArray.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/Interfaces/IValueTypeArray.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/Interfaces/IValueTypeArray.cs	(revision 17225)
@@ -1,4 +1,3 @@
 ﻿#region License Information
-
 /* HeuristicLab
  * Copyright (C) 2002-2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
@@ -19,5 +18,4 @@
  * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
  */
-
 #endregion
 
@@ -47,8 +45,6 @@
 
   [StorableType("f9db5740-1c4f-4f62-a9a8-84b32a461ea8")]
-  public interface IValueTypeArray<T> : IValueTypeArray, IEnumerable<T> where T : struct {
-    T this[int index] { get; set; }
+  public interface IValueTypeArray<out T> : IValueTypeArray, IReadOnlyList<T> where T : struct {
+    //T this[int index] { get; set; }
   }
 }
-
-
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/ValueTypeArray.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/ValueTypeArray.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/ValueTypeArray.cs	(revision 17225)
@@ -76,4 +76,9 @@
     }
 
+    public int Count
+    {
+      get { return Length; }
+    }
+
     [Storable]
     protected bool resizable = true;
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkageMultiObjectiveProblem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkageMultiObjectiveProblem.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkageMultiObjectiveProblem.cs	(revision 17225)
@@ -64,5 +64,5 @@
       base.Analyze(individuals, qualities, results, random);
 
-      var result = DominationCalculator<LinearLinkage>.CalculateBestParetoFront(individuals, qualities, Maximization);
+      var result = DominationCalculator.CalculateBestParetoFront(individuals, qualities, Maximization);
       // TODO: Add results
     }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Optimization.Operators/3.3/MultiObjective/CrowdingDistanceAssignment.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization.Operators/3.3/MultiObjective/CrowdingDistanceAssignment.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization.Operators/3.3/MultiObjective/CrowdingDistanceAssignment.cs	(revision 17225)
@@ -34,5 +34,4 @@
   [StorableType("F7DF8B74-F1E6-45D6-A1A8-5D381F20B382")]
   public class CrowdingDistanceAssignment : SingleSuccessorOperator, IMultiObjectiveOperator {
-
     public ScopeTreeLookupParameter<DoubleArray> QualitiesParameter {
       get { return (ScopeTreeLookupParameter<DoubleArray>)Parameters["Qualities"]; }
@@ -66,58 +65,12 @@
 
     public static void Apply(DoubleArray[] qualities, DoubleValue[] distances) {
-      int populationSize = qualities.Length;
-      int objectiveCount = qualities[0].Length;
-      for (int m = 0; m < objectiveCount; m++) {
-        Array.Sort<DoubleArray, DoubleValue>(qualities, distances, new QualitiesComparer(m));
-
-        distances[0].Value = double.MaxValue;
-        distances[populationSize - 1].Value = double.MaxValue;
-
-        double minQuality = qualities[0][m];
-        double maxQuality = qualities[populationSize - 1][m];
-        for (int i = 1; i < populationSize - 1; i++) {
-          distances[i].Value += (qualities[i + 1][m] - qualities[i - 1][m]) / (maxQuality - minQuality);
-        }
-      }
+      var dist = CrowdingCalculator.CalculateCrowdingDistances(qualities.Select(x => x.ToArray()).ToArray());
+      for (var i = 0; i < distances.Length; i++) distances[i].Value = dist[i];
     }
 
     public override IOperation Apply() {
-      DoubleArray[] qualities = QualitiesParameter.ActualValue.ToArray();
-      int populationSize = qualities.Length;
-      DoubleValue[] distances = new DoubleValue[populationSize];
-      for (int i = 0; i < populationSize; i++)
-        distances[i] = new DoubleValue(0);
-
-      CrowdingDistanceParameter.ActualValue = new ItemArray<DoubleValue>(distances);
-
-      Apply(qualities, distances);
-
+      var dist = CrowdingCalculator.CalculateCrowdingDistances(QualitiesParameter.ActualValue.Select(x => x.ToArray()).ToArray());
+      CrowdingDistanceParameter.ActualValue = new ItemArray<DoubleValue>(dist.Select(d => new DoubleValue(d)));
       return base.Apply();
-    }
-
-    private void Initialize(ItemArray<DoubleValue> distances) {
-      for (int i = 0; i < distances.Length; i++) {
-        if (distances[i] == null) distances[i] = new DoubleValue(0);
-        else distances[i].Value = 0;
-      }
-    }
-
-    [StorableType("30fd1927-b268-4ce7-8960-b04bfa83f1e6")]
-    private class QualitiesComparer : IComparer<DoubleArray> {
-      private int index;
-
-      public QualitiesComparer(int index) {
-        this.index = index;
-      }
-
-      #region IComparer<DoubleArray> Members
-
-      public int Compare(DoubleArray x, DoubleArray y) {
-        if (x[index] < y[index]) return -1;
-        else if (x[index] > y[index]) return +1;
-        else return 0;
-      }
-
-      #endregion
     }
 
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Optimization.Operators/3.3/MultiObjective/FastNonDominatedSort.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization.Operators/3.3/MultiObjective/FastNonDominatedSort.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization.Operators/3.3/MultiObjective/FastNonDominatedSort.cs	(revision 17225)
@@ -74,5 +74,5 @@
 
       int[] rank;
-      var fronts = DominationCalculator<IScope>.CalculateAllParetoFronts(scope.SubScopes.ToArray(), qualities, maximization, out rank, dominateOnEqualQualities);
+      var fronts = DominationCalculator.CalculateAllParetoFronts(scope.SubScopes.ToArray(), qualities, maximization, out rank, dominateOnEqualQualities);
 
       RankParameter.ActualValue = new ItemArray<IntValue>(rank.Select(x => new IntValue(x)));
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IMultiObjectiveProblem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IMultiObjectiveProblem.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IMultiObjectiveProblem.cs	(revision 17225)
@@ -1,4 +1,3 @@
 ﻿#region License Information
-
 /* HeuristicLab
  * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
@@ -19,12 +18,16 @@
  * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
  */
-
 #endregion
 
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
 namespace HeuristicLab.Optimization {
-  public interface IMultiObjectiveProblem<TEncoding, TEncodedSolution> : IProblem<TEncoding, TEncodedSolution>, IMultiObjectiveHeuristicOptimizationProblem
-    where TEncoding : class, IEncoding<TEncodedSolution>
-    where TEncodedSolution : class, IEncodedSolution {
+  public interface IMultiObjectiveProblem : IProblem, IMultiObjectiveHeuristicOptimizationProblem {
 
   }
+
+  public interface IMultiObjectiveProblem<TEncoding, TEncodedSolution> : IMultiObjectiveProblem, IProblem<TEncoding, TEncodedSolution>
+    where TEncoding : class, IEncoding<TEncodedSolution>
+    where TEncodedSolution : class, IEncodedSolution { }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IMultiObjectiveProblemDefinition.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IMultiObjectiveProblemDefinition.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IMultiObjectiveProblemDefinition.cs	(revision 17225)
@@ -20,15 +20,22 @@
 #endregion
 
+using System.Collections;
+using System.Collections.Generic;
 using HEAL.Attic;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 
 namespace HeuristicLab.Optimization {
+  public interface IMultiObjectiveProblemDefinition {
+    int Objectives { get; }
+    bool[] Maximization { get; }
+    IReadOnlyList<double[]> BestKnownFront { get; }
+    double[] ReferencePoint { get; }
+  }
+
   [StorableType("39eacdb5-80a0-425d-902a-00eb3e1d6610")]
-  public interface IMultiObjectiveProblemDefinition<TEncoding, TEncodedSolution> : IProblemDefinition<TEncoding, TEncodedSolution>
+  public interface IMultiObjectiveProblemDefinition<TEncoding, TEncodedSolution> : IMultiObjectiveProblemDefinition, IProblemDefinition<TEncoding, TEncodedSolution>
     where TEncoding : class, IEncoding<TEncodedSolution>
     where TEncodedSolution : class, IEncodedSolution {
-
-    int Objectives { get; }
-    bool[] Maximization { get; }
     double[] Evaluate(TEncodedSolution solution, IRandom random);
     void Analyze(TEncodedSolution[] solutions, double[][] qualities, ResultCollection results, IRandom random);
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/ISingleObjectiveProblem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/ISingleObjectiveProblem.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/ISingleObjectiveProblem.cs	(revision 17225)
@@ -1,4 +1,3 @@
 ﻿#region License Information
-
 /* HeuristicLab
  * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
@@ -19,13 +18,14 @@
  * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
  */
-
 #endregion
 
 
 namespace HeuristicLab.Optimization {
-  public interface ISingleObjectiveProblem<TEncoding, TEncodedSolution> : IProblem<TEncoding, TEncodedSolution>, ISingleObjectiveHeuristicOptimizationProblem
-    where TEncoding : class, IEncoding<TEncodedSolution>
-    where TEncodedSolution : class, IEncodedSolution {
+  public interface ISingleObjectiveProblem : ISingleObjectiveHeuristicOptimizationProblem {
 
   }
+
+  public interface ISingleObjectiveProblem<TEncoding, TEncodedSolution> : ISingleObjectiveProblem, IProblem<TEncoding, TEncodedSolution>
+    where TEncoding : class, IEncoding<TEncodedSolution>
+    where TEncodedSolution : class, IEncodedSolution { }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/ISingleObjectiveProblemDefinition.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/ISingleObjectiveProblemDefinition.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/ISingleObjectiveProblemDefinition.cs	(revision 17225)
@@ -25,13 +25,16 @@
 
 namespace HeuristicLab.Optimization {
+  public interface ISingleObjectiveProblemDefinition {
+    bool Maximization { get; }
+    bool IsBetter(double quality, double bestQuality);
+  }
+
   [StorableType("7ec7bf7e-aaa7-4681-828b-3401cf67e2b3")]
-  public interface ISingleObjectiveProblemDefinition<TEncoding, TEncodedSolution> : IProblemDefinition<TEncoding, TEncodedSolution>
+  public interface ISingleObjectiveProblemDefinition<TEncoding, TEncodedSolution> : ISingleObjectiveProblemDefinition, IProblemDefinition<TEncoding, TEncodedSolution>
     where TEncoding : class, IEncoding<TEncodedSolution>
     where TEncodedSolution : class, IEncodedSolution {
-    bool Maximization { get; }
     double Evaluate(TEncodedSolution solution, IRandom random);
     void Analyze(TEncodedSolution[] solutions, double[] qualities, ResultCollection results, IRandom random);
     IEnumerable<TEncodedSolution> GetNeighbors(TEncodedSolution solution, IRandom random);
-    bool IsBetter(double quality, double bestQuality);
   }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/MultiObjectiveProblem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/MultiObjectiveProblem.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/MultiObjectiveProblem.cs	(revision 17225)
@@ -20,4 +20,6 @@
 #endregion
 
+using System.Collections;
+using System.Collections.Generic;
 using System.Linq;
 using HEAL.Attic;
@@ -35,8 +37,22 @@
     where TEncoding : class, IEncoding<TEncodedSolution>
     where TEncodedSolution : class, IEncodedSolution {
+    #region Parameternames
+    public const string MaximizationParameterName = "Maximization";
+    public const string BestKnownFrontParameterName = "BestKnownFront";
+    public const string ReferencePointParameterName = "ReferencePoint";
+    #endregion
 
-    protected IValueParameter<BoolArray> MaximizationParameter {
-      get { return (IValueParameter<BoolArray>)Parameters["Maximization"]; }
+    #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
+
 
     [StorableConstructor]
@@ -49,18 +65,18 @@
 
     protected MultiObjectiveProblem() : 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<TEncodedSolution>());
-
       ParameterizeOperators();
     }
 
     protected MultiObjectiveProblem(TEncoding encoding) : base(encoding) {
-      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<TEncodedSolution>());
-
       ParameterizeOperators();
     }
@@ -71,8 +87,46 @@
     }
 
-    public int Objectives => Maximization.Length;
+    public int Objectives {
+      get { return Maximization.Length; }
+    }
     public abstract bool[] Maximization { get; }
+
+    public virtual IReadOnlyList<double[]> BestKnownFront {
+      get {
+        if (!Parameters.ContainsKey(BestKnownFrontParameterName)) return null;
+        var mat = BestKnownFrontParameter.Value;
+        if (mat == null) return null;
+        var v = new double[mat.Rows][];
+        for (var i = 0; i < mat.Rows; i++) {
+          var r = v[i] = new double[mat.Columns];
+          for (var j = 0; j < mat.Columns; j++) {
+            r[j] = mat[i, j];
+          }
+        }
+        return v;
+      }
+      set {
+        if (value == null || value.Count == 0) {
+          BestKnownFrontParameter.Value = new DoubleMatrix();
+          return;
+        }
+        var mat = new DoubleMatrix(value.Count, value[0].Length);
+        for (int i = 0; i < value.Count; i++) {
+          for (int j = 0; j < value[i].Length; j++) {
+            mat[i, j] = value[i][j];
+          }
+        }
+
+        BestKnownFrontParameter.Value = mat;
+      }
+    }
+    public virtual double[] ReferencePoint {
+      get { return ReferencePointParameter.Value != null ? ReferencePointParameter.Value.CloneAsArray() : null; }
+      set { ReferencePointParameter.Value = new DoubleArray(value); }
+    }
+
     public abstract double[] Evaluate(TEncodedSolution solution, IRandom random);
     public virtual void Analyze(TEncodedSolution[] solutions, double[][] qualities, ResultCollection results, IRandom random) { }
+
 
     protected override void OnOperatorsChanged() {
@@ -115,5 +169,5 @@
     #region IMultiObjectiveHeuristicOptimizationProblem Members
     IParameter IMultiObjectiveHeuristicOptimizationProblem.MaximizationParameter {
-      get { return Parameters["Maximization"]; }
+      get { return Parameters[MaximizationParameterName]; }
     }
     IMultiObjectiveEvaluator IMultiObjectiveHeuristicOptimizationProblem.Evaluator {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiEncodingCreator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiEncodingCreator.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiEncodingCreator.cs	(revision 17225)
@@ -35,5 +35,7 @@
     }
 
-    public override string OperatorPrefix => "Creator";
+    public override string OperatorPrefix {
+      get { return "Creator"; }
+    }
 
     [StorableConstructor]
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiEncodingCrossover.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiEncodingCrossover.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiEncodingCrossover.cs	(revision 17225)
@@ -33,5 +33,7 @@
     }
 
-    public override string OperatorPrefix => "Crossover";
+    public override string OperatorPrefix {
+      get { return "Crossover"; }
+    }
 
     [StorableConstructor]
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiEncodingManipulator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiEncodingManipulator.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiEncodingManipulator.cs	(revision 17225)
@@ -33,5 +33,7 @@
     }
 
-    public override string OperatorPrefix => "Manipulator";
+    public override string OperatorPrefix {
+      get { return "Manipulator"; }
+    }
     [StorableConstructor]
     private MultiEncodingManipulator(StorableConstructorFlag _) : base(_) { }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Problem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Problem.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Problem.cs	(revision 17225)
@@ -36,5 +36,4 @@
     where TEncodedSolution : class, IEncodedSolution
     where TEvaluator : class, IEvaluator {
-
     public string Filename { get; set; } // TODO: Really okay here? should be in Problem (non-generic)
 
@@ -60,6 +59,10 @@
     }
     event EventHandler IHeuristicOptimizationProblem.SolutionCreatorChanged {
-      add { Encoding.SolutionCreatorChanged += value; }
-      remove { Encoding.SolutionCreatorChanged -= value; }
+      add {
+        if (Encoding != null) Encoding.SolutionCreatorChanged += value;
+      }
+      remove {
+        if (Encoding != null) Encoding.SolutionCreatorChanged -= value;
+      }
     }
 
@@ -72,6 +75,10 @@
       protected set { EvaluatorParameter.Value = value; }
     }
-    IEvaluator IHeuristicOptimizationProblem.Evaluator { get { return Evaluator; } }
-    IParameter IHeuristicOptimizationProblem.EvaluatorParameter { get { return EvaluatorParameter; } }
+    IEvaluator IHeuristicOptimizationProblem.Evaluator {
+      get { return Evaluator; }
+    }
+    IParameter IHeuristicOptimizationProblem.EvaluatorParameter {
+      get { return EvaluatorParameter; }
+    }
 
     public event EventHandler EvaluatorChanged;
@@ -90,5 +97,5 @@
       get {
         if (Encoding == null) return base.ExecutionContextItems;
-        return base.ExecutionContextItems.Concat(new[] { Encoding });
+        return base.ExecutionContextItems.Concat(new[] {Encoding});
       }
     }
@@ -173,5 +180,5 @@
         if (!oldMultiEncoding.Encodings.SequenceEqual(newMultiEncoding.Encodings, new TypeEqualityComparer<IEncoding>())) return;
 
-        var nestedEncodings = oldMultiEncoding.Encodings.Zip(newMultiEncoding.Encodings, (o, n) => new { oldEnc = o, newEnc = n });
+        var nestedEncodings = oldMultiEncoding.Encodings.Zip(newMultiEncoding.Encodings, (o, n) => new {oldEnc = o, newEnc = n});
         foreach (var multi in nestedEncodings)
           AdaptEncodingOperators(multi.oldEnc, multi.newEnc);
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 17225)
@@ -158,5 +158,7 @@
     <Compile Include="Interfaces\ILocalImprovementAlgorithmOperator.cs" />
     <Compile Include="Interfaces\IMultiObjectiveOperator.cs" />
+    <Compile Include="MultiObjective\CrowdingCalculator.cs" />
     <Compile Include="MultiObjective\DominationCalculator.cs" />
+    <Compile Include="MultiObjective\HypervolumeCalculator.cs" />
     <Compile Include="Results\IResultParameter.cs" />
     <Compile Include="Interfaces\ISingleObjectiveOperator.cs" />
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/Interfaces/IAnalyzer.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/Interfaces/IAnalyzer.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/Interfaces/IAnalyzer.cs	(revision 17225)
@@ -25,7 +25,4 @@
 namespace HeuristicLab.Optimization {
   [StorableType("eefee3ee-96ea-41fe-af01-ef96961c99b4")]
-  /// <summary>
-  /// An interface which represents an analysis operator.
-  /// </summary>
   public interface IAnalyzer : IOperator {
     bool EnabledByDefault { get; }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/Interfaces/IProblem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/Interfaces/IProblem.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/Interfaces/IProblem.cs	(revision 17225)
@@ -40,5 +40,4 @@
   public interface IProblem<TEncoding, TEncodedSolution> : IHeuristicOptimizationProblem
     where TEncoding : class, IEncoding<TEncodedSolution>
-    where TEncodedSolution : class, IEncodedSolution {
-  }
+    where TEncodedSolution : class, IEncodedSolution { }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/MultiObjective/CrowdingCalculator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/MultiObjective/CrowdingCalculator.cs	(revision 17225)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/MultiObjective/CrowdingCalculator.cs	(revision 17225)
@@ -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;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+
+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];
+        if (d.IsAlmost(0.0)) d = 1.0;
+        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/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/MultiObjective/DominationCalculator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/MultiObjective/DominationCalculator.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/MultiObjective/DominationCalculator.cs	(revision 17225)
@@ -25,8 +25,9 @@
 
 namespace HeuristicLab.Optimization {
+
   [StorableType("d76eb753-5088-4490-ad18-e78d3629c60b")]
   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
@@ -45,7 +46,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;
       int[] dominationCounter, rank;
@@ -71,6 +71,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;
@@ -78,5 +78,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[]>>();
@@ -84,6 +84,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) {
@@ -100,15 +100,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) {
@@ -149,5 +149,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;
@@ -159,5 +159,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/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/MultiObjective/HypervolumeCalculator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/MultiObjective/HypervolumeCalculator.cs	(revision 17225)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/MultiObjective/HypervolumeCalculator.cs	(revision 17225)
@@ -0,0 +1,312 @@
+﻿#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 {
+  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 Hypervolume-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(IList<double[]> qualities, double[] referencePoint, bool[] maximization) {
+      qualities = qualities.Where(vec => DominationCalculator.Dominates(vec, referencePoint, maximization, false) == DominationResult.Dominates).ToArray();
+      if (qualities.Count== 0) return 0; //TODO computation for negative hypervolume?
+      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.");
+    }
+
+
+    /// <summary>
+    /// Caluclates the Hypervolume for a 2 dimensional problem
+    /// </summary>
+    /// <param name="front">All points within the front need to be Non-Dominated and need to dominate the reference point</param>
+    /// <param name="referencePoint"></param>
+    /// <param name="maximization"></param>
+    /// <returns></returns>
+    public static double Calculate2D(IList<double[]> front, double[] referencePoint, bool[] maximization) {
+      if (front == null) throw new ArgumentNullException("front");
+      if (referencePoint == null) throw new ArgumentNullException("referencePoint");
+      if (maximization == null) throw new ArgumentNullException("maximization");
+      if (!front.Any()) throw new ArgumentException("Front must not be empty.");
+      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(IList<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);
+    }
+
+
+    //within Stream a number of equality comparisons on double values are performed
+    //this is intentional and required
+    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, 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 next;
+        var i = 0;
+        do {
+          var 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);
+
+        var pointsChildLow = new List<double[]>();
+        var 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);
+      for (uint i = 1; i <= noSummands; i++) {
+        double summand = 1;
+        IntToBinary(i, bs);
+        var 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, 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/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/CompiledProblemDefinition.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/CompiledProblemDefinition.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/CompiledProblemDefinition.cs	(revision 17225)
@@ -23,4 +23,5 @@
 using System.Collections.Generic;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Optimization;
 
@@ -51,5 +52,4 @@
     where TEncoding : class, IEncoding<TEncodedSolution>
     where TEncodedSolution : class, IEncodedSolution {
-
     protected CompiledSingleObjectiveProblemDefinition() : base() { }
 
@@ -72,5 +72,4 @@
     where TEncoding : class, IEncoding<TEncodedSolution>
     where TEncodedSolution : class, IEncodedSolution {
-
     protected CompiledMultiObjectiveProblemDefinition() : base() { }
 
@@ -79,7 +78,8 @@
 
     #region ISingleObjectiveProblemDefinition<TEncoding,TEncodedSolution> Members
-
     public int Objectives => Maximization.Length;
     public abstract bool[] Maximization { get; }
+    public abstract IReadOnlyList<double[]> BestKnownFront { get; }
+    public abstract double[] ReferencePoint { get; }
     public abstract double[] Evaluate(TEncodedSolution individual, IRandom random);
     public abstract void Analyze(TEncodedSolution[] individuals, double[][] qualities, ResultCollection results, IRandom random);
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/MultiObjectiveProblemDefinitionScript.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/MultiObjectiveProblemDefinitionScript.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/MultiObjectiveProblemDefinitionScript.cs	(revision 17225)
@@ -20,7 +20,9 @@
 #endregion
 
+using System.Collections.Generic;
 using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Optimization;
 
@@ -47,9 +49,9 @@
     }
 
-    int IMultiObjectiveProblemDefinition<TEncoding, TEncodedSolution>.Objectives => CompiledProblemDefinition.Objectives;
+    public int Objectives => CompiledProblemDefinition.Objectives;
+    public IReadOnlyList<double[]> BestKnownFront => CompiledProblemDefinition.BestKnownFront;
+    public double[] ReferencePoint => CompiledProblemDefinition.ReferencePoint;
+    public bool[] Maximization => CompiledProblemDefinition.Maximization;
 
-    bool[] IMultiObjectiveProblemDefinition<TEncoding, TEncodedSolution>.Maximization {
-      get { return CompiledProblemDefinition.Maximization; }
-    }
 
     double[] IMultiObjectiveProblemDefinition<TEncoding, TEncodedSolution>.Evaluate(TEncodedSolution individual, IRandom random) {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/MultiObjectiveProgrammableProblem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/MultiObjectiveProgrammableProblem.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/MultiObjectiveProgrammableProblem.cs	(revision 17225)
@@ -20,4 +20,5 @@
 #endregion
 
+using System.Collections.Generic;
 using System.Drawing;
 using HEAL.Attic;
@@ -59,4 +60,5 @@
     }
 
+
     [StorableConstructor]
     protected MultiObjectiveProgrammableProblem(StorableConstructorFlag _) : base(_) { }
@@ -69,5 +71,5 @@
       : base(encoding) {
       Parameters.Add(new FixedValueParameter<MultiObjectiveProblemDefinitionScript<TEncoding, TEncodedSolution>>("ProblemScript", "Defines the problem.",
-        new MultiObjectiveProblemDefinitionScript<TEncoding, TEncodedSolution>() { Name = Name }));
+        new MultiObjectiveProblemDefinitionScript<TEncoding, TEncodedSolution>() {Name = Name}));
       ProblemScript.Encoding = (TEncoding)encoding.Clone();
 
@@ -93,5 +95,5 @@
     private void OnProblemDefinitionChanged() {
       Parameters.Remove("Maximization");
-      Parameters.Add(new ValueParameter<BoolArray>("Maximization", "Set to false if the problem should be minimized.", (BoolArray)new BoolArray(Maximization).AsReadOnly()) { Hidden = true });
+      Parameters.Add(new ValueParameter<BoolArray>("Maximization", "Set to false if the problem should be minimized.", (BoolArray)new BoolArray(Maximization).AsReadOnly()) {Hidden = true});
       Encoding = (TEncoding)ProblemScript.Encoding.Clone();
 
@@ -108,5 +110,13 @@
 
     public override bool[] Maximization {
-      get { return Parameters.ContainsKey("ProblemScript") ? ProblemDefinition.Maximization : new[] { false }; }
+      get { return Parameters.ContainsKey("ProblemScript") ? ProblemDefinition.Maximization : new[] {false}; }
+    }
+
+    public override IReadOnlyList<double[]> BestKnownFront {
+      get { return Parameters.ContainsKey("ProblemScript") ? ProblemDefinition.BestKnownFront : null; }
+    }
+
+    public override double[] ReferencePoint {
+      get { return Parameters.ContainsKey("ProblemScript") ? ProblemDefinition.ReferencePoint : null; }
     }
 
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/SingleObjectiveProblemDefinitionScript.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/SingleObjectiveProblemDefinitionScript.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/SingleObjectiveProblemDefinitionScript.cs	(revision 17225)
@@ -48,7 +48,5 @@
     }
 
-    bool ISingleObjectiveProblemDefinition<TEncoding, TEncodedSolution>.Maximization {
-      get { return CompiledProblemDefinition.Maximization; }
-    }
+    public bool Maximization => CompiledProblemDefinition.Maximization;
 
     double ISingleObjectiveProblemDefinition<TEncoding, TEncodedSolution>.Evaluate(TEncodedSolution individual, IRandom random) {
@@ -63,5 +61,5 @@
     }
 
-    bool ISingleObjectiveProblemDefinition<TEncoding, TEncodedSolution>.IsBetter(double quality, double bestQuality) {
+    public bool IsBetter(double quality, double bestQuality) {
       return CompiledProblemDefinition.IsBetter(quality, bestQuality);
     }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/Templates/MultiObjectiveCombinedEncodingProblem_Template.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/Templates/MultiObjectiveCombinedEncodingProblem_Template.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/Templates/MultiObjectiveCombinedEncodingProblem_Template.cs	(revision 17225)
@@ -17,4 +17,6 @@
   public class CompiledMultiObjectiveProblemDefinition : CompiledMultiObjectiveProblemDefinition<CombinedEncoding, CombinedSolution> {
     public override bool[] Maximization { get { return new[] { true, false }; } }
+    public override double[] ReferencePoint { get { return null; } }
+    public override IReadOnlyList<double[]> BestKnownFront { get { return null; } }
 
     public override void Initialize() {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/Templates/MultiObjectiveProblem_Template.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/Templates/MultiObjectiveProblem_Template.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/Templates/MultiObjectiveProblem_Template.cs	(revision 17225)
@@ -12,4 +12,6 @@
   public class CompiledMultiObjectiveProblemDefinition : CompiledMultiObjectiveProblemDefinition<ENCODING_CLASS, SOLUTION_CLASS> {
     public override bool[] Maximization { get { return new[] { false, false }; } }
+    public override double[] ReferencePoint { get { return null; } }
+    public override IReadOnlyList<double[]> BestKnownFront { get { return null; } }
 
     public override void Initialize() {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/CrowdingAnalyzer.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/CrowdingAnalyzer.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/CrowdingAnalyzer.cs	(revision 17225)
@@ -30,10 +30,6 @@
 namespace HeuristicLab.Problems.TestFunctions.MultiObjective {
   [StorableType("F06FB45C-051E-4AD8-BD82-16DA9DCBCACB")]
-  [Item("CrowdingAnalyzer", "The mean crowding distance for each point of the Front (see Multi-Objective Performance Metrics - Shodhganga for more information)")]
+  [Item("CrowdingAnalyzer", "This analyzer is functionally equivalent to the CrowdingAnalyzer in HeuristicLab.Analysis, but is kept as not to break backwards compatibility")]
   public class CrowdingAnalyzer : MOTFAnalyzer {
-
-    public ILookupParameter<DoubleMatrix> BoundsParameter {
-      get { return (ILookupParameter<DoubleMatrix>)Parameters["Bounds"]; }
-    }
 
     public IResultParameter<DoubleValue> CrowdingResultParameter {
@@ -43,7 +39,5 @@
     [StorableConstructor]
     protected CrowdingAnalyzer(StorableConstructorFlag _) : base(_) { }
-    public CrowdingAnalyzer(CrowdingAnalyzer original, Cloner cloner)
-      : base(original, cloner) {
-    }
+    public CrowdingAnalyzer(CrowdingAnalyzer original, Cloner cloner): base(original, cloner) {}
     public override IDeepCloneable Clone(Cloner cloner) {
       return new CrowdingAnalyzer(this, cloner);
@@ -51,18 +45,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/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/GenerationalDistanceAnalyzer.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/GenerationalDistanceAnalyzer.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/GenerationalDistanceAnalyzer.cs	(revision 17225)
@@ -30,5 +30,5 @@
 namespace HeuristicLab.Problems.TestFunctions.MultiObjective {
   [StorableType("EBC72F16-E329-4D18-800C-8642EFD0F05C")]
-  [Item("GenerationalDistanceAnalyzer", "The generational distance between the current and the best known front (see Multi-Objective Performance Metrics - Shodhganga for more information)")]
+  [Item("GenerationalDistanceAnalyzer", "This analyzer is functionally equivalent to the GenerationalDistanceAnalyzer in HeuristicLab.Analysis, but is kept as not to break backwards compatibility")]
   public class GenerationalDistanceAnalyzer : MOTFAnalyzer {
 
@@ -63,12 +63,9 @@
     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;
-
+      var q = qualities.Select(x => x.ToArray());
+      GenerationalDistanceResultParameter.ActualValue.Value = GenerationalDistance.Calculate(q, optimalfront, Dampening);
       return base.Apply();
     }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/HypervolumeAnalyzer.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/HypervolumeAnalyzer.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/HypervolumeAnalyzer.cs	(revision 17225)
@@ -32,5 +32,5 @@
 namespace HeuristicLab.Problems.TestFunctions.MultiObjective {
   [StorableType("13D363E4-76FF-4A5A-9B2C-767D9E880E4B")]
-  [Item("HypervolumeAnalyzer", "Computes the enclosed Hypervolume between the current front and a given reference Point")]
+  [Item("HypervolumeAnalyzer", "This analyzer is functionally equivalent to the HypervolumeAnalyzer in HeuristicLab.Analysis, but is kept as not to break backwards compatibility")]
   public class HypervolumeAnalyzer : MOTFAnalyzer {
 
@@ -38,10 +38,13 @@
       get { return (ILookupParameter<DoubleArray>)Parameters["ReferencePoint"]; }
     }
+
     public IResultParameter<DoubleValue> HypervolumeResultParameter {
       get { return (IResultParameter<DoubleValue>)Parameters["Hypervolume"]; }
     }
+
     public IResultParameter<DoubleValue> BestKnownHypervolumeResultParameter {
       get { return (IResultParameter<DoubleValue>)Parameters["Best known hypervolume"]; }
     }
+
     public IResultParameter<DoubleValue> HypervolumeDistanceResultParameter {
       get { return (IResultParameter<DoubleValue>)Parameters["Absolute Distance to BestKnownHypervolume"]; }
@@ -53,7 +56,6 @@
     }
 
-    protected HypervolumeAnalyzer(HypervolumeAnalyzer original, Cloner cloner)
-      : base(original, cloner) {
-    }
+    protected HypervolumeAnalyzer(HypervolumeAnalyzer original, Cloner cloner) : base(original, cloner) {}
+
     public override IDeepCloneable Clone(Cloner cloner) {
       return new HypervolumeAnalyzer(this, cloner);
@@ -68,6 +70,4 @@
       BestKnownHypervolumeResultParameter.DefaultValue = new DoubleValue(0);
       HypervolumeDistanceResultParameter.DefaultValue = new DoubleValue(0);
-
-
     }
 
@@ -75,15 +75,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/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/InvertedGenerationalDistanceAnalyzer.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/InvertedGenerationalDistanceAnalyzer.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/InvertedGenerationalDistanceAnalyzer.cs	(revision 17225)
@@ -30,7 +30,9 @@
 namespace HeuristicLab.Problems.TestFunctions.MultiObjective {
   [StorableType("EC99F3C1-D8D2-4738-9523-0D07438647A5")]
-  [Item("InvertedGenerationalDistanceAnalyzer", "The inverted generational distance between the current and the best known front (see Multi-Objective Performance Metrics - Shodhganga for more information)")]
+  [Item("InvertedGenerationalDistanceAnalyzer", "This analyzer is functionally equivalent to the InvertedGenerationalDistanceAnalyzer in HeuristicLab.Analysis, but is kept as not to break backwards compatibility")]
   public class InvertedGenerationalDistanceAnalyzer : MOTFAnalyzer {
-    public override bool EnabledByDefault { get { return false; } }
+    public override bool EnabledByDefault {
+      get { return false; }
+    }
 
     private IFixedValueParameter<DoubleValue> DampeningParameter {
@@ -51,5 +53,4 @@
       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);
-
     }
 
@@ -64,17 +65,11 @@
     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;
-
+      var q = qualities.Select(x => x.ToArray());
+      InvertedGenerationalDistanceResultParameter.ActualValue.Value = InvertedGenerationalDistance.Calculate(q, optimalfront, Dampening);
       return base.Apply();
     }
-
-
   }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/MOTFAnalyzer.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/MOTFAnalyzer.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/MOTFAnalyzer.cs	(revision 17225)
@@ -33,5 +33,7 @@
   [StorableType("CFBB2CAB-C1B7-4F14-9A01-6D5624B7B681")]
   public abstract class MOTFAnalyzer : SingleSuccessorOperator, IMultiObjectiveTestFunctionAnalyzer {
-    public virtual bool EnabledByDefault { get { return true; } }
+    public virtual bool EnabledByDefault {
+      get { return true; }
+    }
 
     public IScopeTreeLookupParameter<DoubleArray> QualitiesParameter {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/ScatterPlotAnalyzer.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/ScatterPlotAnalyzer.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/ScatterPlotAnalyzer.cs	(revision 17225)
@@ -23,4 +23,5 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Encodings.RealVectorEncoding;
 using HeuristicLab.Optimization;
@@ -41,5 +42,4 @@
     }
 
-
     [StorableConstructor]
     protected ScatterPlotAnalyzer(StorableConstructorFlag _) : base(_) { }
@@ -52,5 +52,4 @@
       Parameters.Add(new ScopeTreeLookupParameter<RealVector>("Individuals", "The individual solutions to the problem"));
       Parameters.Add(new ResultParameter<ParetoFrontScatterPlot>("Scatterplot", "The scatterplot for the current and optimal (if known front)"));
-
     }
 
@@ -59,10 +58,16 @@
       var individuals = IndividualsParameter.ActualValue;
       var testFunction = TestFunctionParameter.ActualValue;
-      int objectives = qualities[0].Length;
-      int problemSize = individuals[0].Length;
+      var objectives = qualities.Length != 0 ? qualities[0].Length:0;    
+      var problemSize = individuals.Length != 0 ? individuals[0].Length:0;
 
-      double[][] optimalFront = new double[0][];
-      var front = testFunction.OptimalParetoFront(objectives);
-      if (front != null) optimalFront = front.ToArray();
+      var optimalFront = new double[0][];               
+      if (testFunction != null) {
+        var front = testFunction.OptimalParetoFront(objectives);
+        if (front != null) optimalFront = front.ToArray();
+      }
+      else {
+        var mat = BestKnownFrontParameter.ActualValue;
+        optimalFront = mat == null ? null : Enumerable.Range(0, mat.Rows).Select(r => Enumerable.Range(0, mat.Columns).Select(c => mat[r, c]).ToArray()).ToArray();
+      }
 
       var qualityClones = qualities.Select(s => s.ToArray()).ToArray();
@@ -70,5 +75,4 @@
 
       ScatterPlotResultParameter.ActualValue = new ParetoFrontScatterPlot(qualityClones, solutionClones, optimalFront, objectives, problemSize);
-
       return base.Apply();
     }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/SpacingAnalyzer.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/SpacingAnalyzer.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/SpacingAnalyzer.cs	(revision 17225)
@@ -21,13 +21,13 @@
 
 using System.Linq;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
 using HeuristicLab.Optimization;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.TestFunctions.MultiObjective {
   [StorableType("F32027A7-3116-4864-A404-820F866BFD65")]
-  [Item("SpacingAnalyzer", "The spacing of the current front (see Multi-Objective Performance Metrics - Shodhganga for more information)")]
+  [Item("SpacingAnalyzer", "This analyzer is functionally equivalent to the SpacingAnalyzer in HeuristicLab.Analysis, but is kept as not to break backwards compatibility")]
   public class SpacingAnalyzer : MOTFAnalyzer {
 
@@ -35,7 +35,7 @@
       get { return (IResultParameter<DoubleValue>)Parameters["Spacing"]; }
     }
+
     [StorableConstructor]
     protected SpacingAnalyzer(StorableConstructorFlag _) : base(_) { }
-
 
     protected SpacingAnalyzer(SpacingAnalyzer original, Cloner cloner) : base(original, cloner) { }
@@ -51,7 +51,6 @@
     public override IOperation Apply() {
       var qualities = QualitiesParameter.ActualValue;
-      var spacing = Spacing.Calculate(qualities.Select(q => q.ToArray()));
-      SpacingResultParameter.ActualValue.Value = spacing;
-
+      var q = qualities.Select(x => x.ToArray());
+      SpacingResultParameter.ActualValue.Value = Spacing.Calculate(q);
       return base.Apply();
     }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.csproj
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.csproj	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.csproj	(revision 17225)
@@ -174,4 +174,9 @@
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
+      <Project>{887425b4-4348-49ed-a457-b7d2c26ddbf9}</Project>
+      <Name>HeuristicLab.Analysis-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Collections\3.3\HeuristicLab.Collections-3.3.csproj">
       <Project>{958b43bc-cc5c-4fa2-8628-2b3b01d890b6}</Project>
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Interfaces/IMultiObjectiveTestFunction.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Interfaces/IMultiObjectiveTestFunction.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Interfaces/IMultiObjectiveTestFunction.cs	(revision 17225)
@@ -34,5 +34,5 @@
     double[,] Bounds(int objectives);
 
-    IEnumerable<double[]> OptimalParetoFront(int objectives);
+    IList<double[]> OptimalParetoFront(int objectives);
     double OptimalHypervolume(int objectives);
     double[] ReferencePoint(int objectives);
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/MultiObjectiveTestFunctionProblem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/MultiObjectiveTestFunctionProblem.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/MultiObjectiveTestFunctionProblem.cs	(revision 17225)
@@ -23,4 +23,5 @@
 using System.Linq;
 using HEAL.Attic;
+using HeuristicLab.Analysis;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -35,7 +36,5 @@
   [Creatable(CreatableAttribute.Categories.Problems, Priority = 95)]
   [Item("Test Function (multi-objective)", "Test functions with real valued inputs and multiple objectives.")]
-  public class MultiObjectiveTestFunctionProblem : RealVectorMultiObjectiveProblem,
-    IProblemInstanceConsumer<MOTFData> {
-
+  public class MultiObjectiveTestFunctionProblem : RealVectorMultiObjectiveProblem, IProblemInstanceConsumer<MOTFData>, IMultiObjectiveProblemDefinition<RealVectorEncoding, RealVector> {
     #region Parameter Properties
     public IFixedValueParameter<IntValue> ProblemSizeParameter {
@@ -51,11 +50,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
 
@@ -85,12 +77,4 @@
       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
 
@@ -102,6 +86,5 @@
     }
 
-    protected MultiObjectiveTestFunctionProblem(MultiObjectiveTestFunctionProblem original, Cloner cloner)
-      : base(original, cloner) {
+    protected MultiObjectiveTestFunctionProblem(MultiObjectiveTestFunctionProblem original, Cloner cloner) : base(original, cloner) {
       RegisterEventHandlers();
     }
@@ -110,12 +93,9 @@
     }
 
-    public MultiObjectiveTestFunctionProblem()
-      : base() {
+    public MultiObjectiveTestFunctionProblem() : base() {
       Parameters.Add(new FixedValueParameter<IntValue>("ProblemSize", "The dimensionality of the problem instance (number of variables in the function).", new IntValue(2)));
       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;
@@ -137,7 +117,6 @@
     public override void Analyze(RealVector[] solutions, double[][] qualities, ResultCollection results, IRandom random) {
       base.Analyze(solutions, qualities, results, random);
-      if (results.ContainsKey("Pareto Front")) {
+      if (results.ContainsKey("Pareto Front"))
         ((DoubleMatrix)results["Pareto Front"].Value).SortableView = true;
-      }
     }
 
@@ -149,8 +128,5 @@
     public double[] CheckContraints(RealVector individual) {
       var constrainedTestFunction = (IConstrainedTestFunction)TestFunction;
-      if (constrainedTestFunction != null) {
-        return constrainedTestFunction.CheckConstraints(individual, Objectives);
-      }
-      return new double[0];
+      return constrainedTestFunction != null ? constrainedTestFunction.CheckConstraints(individual, Objectives) : new double[0];
     }
 
@@ -166,14 +142,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));
     }
 
@@ -183,4 +161,5 @@
       ParameterizeAnalyzers();
     }
+
     protected override void OnEvaluatorChanged() {
       base.OnEvaluatorChanged();
@@ -192,5 +171,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();
@@ -207,5 +187,4 @@
       UpdateParameterValues();
     }
-
     #endregion
 
@@ -217,6 +196,6 @@
       Operators.Add(new HypervolumeAnalyzer());
       Operators.Add(new SpacingAnalyzer());
+      Operators.Add(new TimelineAnalyzer());
       Operators.Add(new ScatterPlotAnalyzer());
-
       ParameterizeAnalyzers();
     }
@@ -232,19 +211,10 @@
         analyzer.TestFunctionParameter.ActualName = TestFunctionParameter.Name;
         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) {
+        if (scatterPlotAnalyzer != null)
           scatterPlotAnalyzer.IndividualsParameter.ActualName = Encoding.Name;
-        }
       }
     }
-
     #endregion
   }
 }
-
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/DTLZ/DTLZ.cs	(revision 17225)
@@ -28,5 +28,5 @@
   [StorableType("3ED6C22E-EA6E-4336-BC49-884CE151E514")]
   public abstract class DTLZ : MultiObjectiveTestFunction {
-    protected override IEnumerable<double[]> GetOptimalParetoFront(int objectives) {
+    protected override IList<double[]> GetOptimalParetoFront(int objectives) {
       if (objectives == 2) return ParetoFrontStore.GetParetoFront("DTLZ.ParetoFronts." + this.ItemName + ".2D");
       return null;
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR1.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR1.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR1.cs	(revision 17225)
@@ -24,4 +24,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
 using HEAL.Attic;
 
@@ -30,5 +31,5 @@
   [StorableType("16DF9415-9D12-4FB9-A985-7EEAE05A24CA")]
   public class IHR1 : IHR {
-    protected override IEnumerable<double[]> GetOptimalParetoFront(int objectives) {
+    protected override IList<double[]> GetOptimalParetoFront(int objectives) {
       List<double[]> res = new List<double[]>();
       for (int i = 0; i <= 500; i++) {
@@ -41,5 +42,5 @@
 
     protected override double GetBestKnownHypervolume(int objectives) {
-      return Hypervolume.Calculate(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
+      return HypervolumeCalculator.CalculateHypervolume(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
     }
 
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR2.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR2.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR2.cs	(revision 17225)
@@ -24,4 +24,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
 using HEAL.Attic;
 
@@ -30,5 +31,5 @@
   [StorableType("3E06E73F-61CD-4B99-99A8-84E6E9C0EFC9")]
   public class IHR2 : IHR {
-    protected override IEnumerable<double[]> GetOptimalParetoFront(int objectives) {
+    protected override IList<double[]> GetOptimalParetoFront(int objectives) {
       List<double[]> res = new List<double[]>();
       for (int i = 0; i <= 500; i++) {
@@ -42,5 +43,5 @@
 
     protected override double GetBestKnownHypervolume(int objectives) {
-      return Hypervolume.Calculate(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
+      return HypervolumeCalculator.CalculateHypervolume(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
     }
 
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR3.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR3.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR3.cs	(revision 17225)
@@ -24,4 +24,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
 using HEAL.Attic;
 
@@ -30,5 +31,5 @@
   [StorableType("316D5351-762D-4883-ACEF-06F4EAFA73AE")]
   public class IHR3 : IHR {
-    protected override IEnumerable<double[]> GetOptimalParetoFront(int objectives) {
+    protected override IList<double[]> GetOptimalParetoFront(int objectives) {
       List<double[]> res = new List<double[]>();
       for (int i = 0; i <= 500; i++) {
@@ -42,5 +43,5 @@
 
     protected override double GetBestKnownHypervolume(int objectives) {
-      return Hypervolume.Calculate(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
+      return HypervolumeCalculator.CalculateHypervolume(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
     }
 
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR4.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR4.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR4.cs	(revision 17225)
@@ -24,4 +24,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
 using HEAL.Attic;
 
@@ -30,5 +31,5 @@
   [StorableType("E83A9E6E-F7B3-4B27-B5CA-A323D89844F5")]
   public class IHR4 : IHR {
-    protected override IEnumerable<double[]> GetOptimalParetoFront(int objectives) {
+    protected override IList<double[]> GetOptimalParetoFront(int objectives) {
       List<double[]> res = new List<double[]>();
       for (int i = 0; i <= 500; i++) {
@@ -41,5 +42,5 @@
 
     protected override double GetBestKnownHypervolume(int objectives) {
-      return Hypervolume.Calculate(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
+      return HypervolumeCalculator.CalculateHypervolume(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
     }
 
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR6.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR6.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/IHR/IHR6.cs	(revision 17225)
@@ -24,4 +24,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
 using HEAL.Attic;
 
@@ -30,5 +31,5 @@
   [StorableType("5C0A4163-831B-4507-997F-A70B59E3A445")]
   public class IHR6 : IHR {
-    protected override IEnumerable<double[]> GetOptimalParetoFront(int objectives) {
+    protected override IList<double[]> GetOptimalParetoFront(int objectives) {
       List<double[]> res = new List<double[]>();
       for (int i = 0; i <= 500; i++) {
@@ -41,5 +42,5 @@
 
     protected override double GetBestKnownHypervolume(int objectives) {
-      return Hypervolume.Calculate(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
+      return HypervolumeCalculator.CalculateHypervolume(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
     }
 
@@ -47,6 +48,5 @@
     protected IHR6(StorableConstructorFlag _) : base(_) { }
     protected IHR6(IHR6 original, Cloner cloner) : base(original, cloner) { }
-    public IHR6() : base() {
-    }
+    public IHR6() : base() { }
 
     public override IDeepCloneable Clone(Cloner cloner) {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/CIGTAB.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/CIGTAB.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/CIGTAB.cs	(revision 17225)
@@ -24,4 +24,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
 using HEAL.Attic;
 
@@ -31,5 +32,5 @@
   public class CIGTAB : MultiObjectiveTestFunction {
     protected override double[,] GetBounds(int objectives) {
-      return new double[,] { { -10, 10 } };
+      return new double[,] {{-10, 10}};
     }
 
@@ -39,8 +40,8 @@
 
     protected override double[] GetReferencePoint(int objecitves) {
-      return new double[] { 11, 11 };
+      return new double[] {11, 11};
     }
 
-    protected override IEnumerable<double[]> GetOptimalParetoFront(int objecitves) {
+    protected override IList<double[]> GetOptimalParetoFront(int objecitves) {
       List<double[]> res = new List<double[]>();
       for (int i = 0; i <= 500; i++) {
@@ -54,5 +55,5 @@
 
     protected override double GetBestKnownHypervolume(int objectives) {
-      return Hypervolume.Calculate(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
+      return HypervolumeCalculator.CalculateHypervolume(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
     }
 
@@ -89,5 +90,5 @@
       double f1 = 1 / (a * a * r.Length) * sum;
 
-      return new double[] { f0, f1 };
+      return new double[] {f0, f1};
     }
   }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/ELLI1.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/ELLI1.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/ELLI1.cs	(revision 17225)
@@ -24,4 +24,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
 using HEAL.Attic;
 
@@ -31,5 +32,5 @@
   public class ELLI : MultiObjectiveTestFunction {
     protected override double[,] GetBounds(int objectives) {
-      return new double[,] { { -10, 10 } };
+      return new double[,] {{-10, 10}};
     }
 
@@ -39,8 +40,8 @@
 
     protected override double[] GetReferencePoint(int objecitves) {
-      return new double[] { 11, 11 };
+      return new double[] {11, 11};
     }
 
-    protected override IEnumerable<double[]> GetOptimalParetoFront(int objecitves) {
+    protected override IList<double[]> GetOptimalParetoFront(int objecitves) {
       List<double[]> res = new List<double[]>();
       for (int i = 0; i <= 500; i++) {
@@ -54,5 +55,5 @@
 
     protected override double GetBestKnownHypervolume(int objectives) {
-      return Hypervolume.Calculate(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
+      return HypervolumeCalculator.CalculateHypervolume(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
     }
 
@@ -84,5 +85,5 @@
       double f1 = 1 / (a * a * r.Length) * sum;
 
-      return new double[] { f0, f1 };
+      return new double[] {f0, f1};
     }
   }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/Fonseca.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/Fonseca.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/Fonseca.cs	(revision 17225)
@@ -22,8 +22,10 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
 
 namespace HeuristicLab.Problems.TestFunctions.MultiObjective {
@@ -32,5 +34,5 @@
   public class Fonseca : MultiObjectiveTestFunction {
     protected override double[,] GetBounds(int objectives) {
-      return new double[,] { { -4, 4 } };
+      return new double[,] {{-4, 4}};
     }
 
@@ -39,14 +41,14 @@
     }
 
-    protected override IEnumerable<double[]> GetOptimalParetoFront(int objectives) {
-      return ParetoFrontStore.GetParetoFront("Misc.ParetoFronts." + this.ItemName);
+    protected override IList<double[]> GetOptimalParetoFront(int objectives) {
+      return ParetoFrontStore.GetParetoFront("Misc.ParetoFronts." + this.ItemName).ToList();
     }
 
     protected override double GetBestKnownHypervolume(int objectives) {
-      return Hypervolume.Calculate(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
+      return HypervolumeCalculator.CalculateHypervolume(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
     }
 
     protected override double[] GetReferencePoint(int objectives) {
-      return new double[] { 11, 11 };
+      return new double[] {11, 11};
     }
 
@@ -79,8 +81,7 @@
       f1 = 1 - Math.Exp(-f1);
 
-      double[] res = { f0, f1 };
+      double[] res = {f0, f1};
       return res;
     }
-
   }
 }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/Kursawe.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/Kursawe.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/Kursawe.cs	(revision 17225)
@@ -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 HEAL.Attic;
 
@@ -31,5 +33,5 @@
   public class Kursawe : MultiObjectiveTestFunction {
     protected override double[,] GetBounds(int objectives) {
-      return new double[,] { { -5, 5 } };
+      return new double[,] {{-5, 5}};
     }
 
@@ -38,14 +40,14 @@
     }
 
-    protected override IEnumerable<double[]> GetOptimalParetoFront(int objecitves) {
+    protected override IList<double[]> GetOptimalParetoFront(int objecitves) {
       return ParetoFrontStore.GetParetoFront("Misc.ParetoFronts." + this.ItemName);
     }
 
     protected override double GetBestKnownHypervolume(int objectives) {
-      return Hypervolume.Calculate(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
+      return HypervolumeCalculator.CalculateHypervolume(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
     }
 
     protected override double[] GetReferencePoint(int objectives) {
-      return new double[] { 11, 11 };
+      return new double[] {11, 11};
     }
 
@@ -57,7 +59,4 @@
     }
     public Kursawe() : base(minimumObjectives: 2, maximumObjectives: 2, minimumSolutionLength: 3, maximumSolutionLength: int.MaxValue) { }
-
-
-
 
 
@@ -75,5 +74,5 @@
       }
 
-      return new double[] { f0, f1 };
+      return new double[] {f0, f1};
     }
   }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/SchafferN1.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/SchafferN1.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/SchafferN1.cs	(revision 17225)
@@ -24,4 +24,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
 using HEAL.Attic;
 
@@ -31,5 +32,5 @@
   public class SchafferN1 : MultiObjectiveTestFunction {
     protected override double[,] GetBounds(int objectives) {
-      return new double[,] { { -1e5, 1e5 } };
+      return new double[,] {{-1e5, 1e5}};
     }
 
@@ -39,14 +40,14 @@
 
     protected override double[] GetReferencePoint(int objectives) {
-      return new double[] { 1e5, 1e5 };
+      return new double[] {1e5, 1e5};
     }
 
 
-    protected override IEnumerable<double[]> GetOptimalParetoFront(int objectives) {
+    protected override IList<double[]> GetOptimalParetoFront(int objectives) {
       return ParetoFrontStore.GetParetoFront("Misc.ParetoFronts." + "SchafferN1");
     }
 
     protected override double GetBestKnownHypervolume(int objectives) {
-      return Hypervolume.Calculate(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
+      return HypervolumeCalculator.CalculateHypervolume(GetOptimalParetoFront(objectives), GetReferencePoint(objectives), GetMaximization(objectives));
     }
 
@@ -72,5 +73,5 @@
       f1 *= f1;
 
-      return new double[] { f0, f1 };
+      return new double[] {f0, f1};
     }
   }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/SchafferN2.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/SchafferN2.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/Misc/SchafferN2.cs	(revision 17225)
@@ -31,5 +31,5 @@
   public class SchafferN2 : MultiObjectiveTestFunction {
     protected override double[,] GetBounds(int objectives) {
-      return new double[,] { { -5, 10 } };
+      return new double[,] {{-5, 10}};
     }
 
@@ -39,9 +39,9 @@
 
     protected override double[] GetReferencePoint(int objecitves) {
-      return new double[] { 100, 100 };
+      return new double[] {100, 100};
     }
 
 
-    protected override IEnumerable<double[]> GetOptimalParetoFront(int objectives) {
+    protected override IList<double[]> GetOptimalParetoFront(int objectives) {
       return null;
     }
@@ -72,5 +72,5 @@
       f1 *= f1;
 
-      return new double[] { f0, f1 };
+      return new double[] {f0, f1};
     }
   }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/MultiObjectiveTestFunction.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/MultiObjectiveTestFunction.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/MultiObjectiveTestFunction.cs	(revision 17225)
@@ -87,9 +87,9 @@
     /// retrieves the optimal pareto front (if known from a file)
     /// </summary>
-    public IEnumerable<double[]> OptimalParetoFront(int objectives) {
+    public IList<double[]> OptimalParetoFront(int objectives) {
       ThrowIfObjectivesOutOfRange(objectives);
       return GetOptimalParetoFront(objectives);
     }
-    protected abstract IEnumerable<double[]> GetOptimalParetoFront(int objectives);
+    protected abstract IList<double[]> GetOptimalParetoFront(int objectives);
 
     /// <summary>
@@ -132,8 +132,8 @@
       Parameters.Add(new FixedValueParameter<IntValue>("Minimum Objectives",
         "The dimensionality of the problem instance (number of variables in the function).",
-        (IntValue)new IntValue(minimumObjectives).AsReadOnly()) { GetsCollected = false });
-      Parameters.Add(new FixedValueParameter<IntValue>("Maximum Objectives", "The dimensionality of the problem instance (number of variables in the function).", (IntValue)new IntValue(maximumObjectives).AsReadOnly()) { GetsCollected = false });
-      Parameters.Add(new FixedValueParameter<IntValue>("Minimum SolutionLength", "The dimensionality of the problem instance (number of variables in the function).", (IntValue)new IntValue(minimumSolutionLength).AsReadOnly()) { GetsCollected = false });
-      Parameters.Add(new FixedValueParameter<IntValue>("Maximum SolutionLength", "The dimensionality of the problem instance (number of variables in the function).", (IntValue)new IntValue(maximumSolutionLength).AsReadOnly()) { GetsCollected = false });
+        (IntValue)new IntValue(minimumObjectives).AsReadOnly()) {GetsCollected = false});
+      Parameters.Add(new FixedValueParameter<IntValue>("Maximum Objectives", "The dimensionality of the problem instance (number of variables in the function).", (IntValue)new IntValue(maximumObjectives).AsReadOnly()) {GetsCollected = false});
+      Parameters.Add(new FixedValueParameter<IntValue>("Minimum SolutionLength", "The dimensionality of the problem instance (number of variables in the function).", (IntValue)new IntValue(minimumSolutionLength).AsReadOnly()) {GetsCollected = false});
+      Parameters.Add(new FixedValueParameter<IntValue>("Maximum SolutionLength", "The dimensionality of the problem instance (number of variables in the function).", (IntValue)new IntValue(maximumSolutionLength).AsReadOnly()) {GetsCollected = false});
 
       MinimumObjectives = minimumObjectives;
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ParetoFrontStore.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ParetoFrontStore.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ParetoFrontStore.cs	(revision 17225)
@@ -28,5 +28,5 @@
 namespace HeuristicLab.Problems.TestFunctions.MultiObjective {
   internal class ParetoFrontStore {
-    internal static IEnumerable<double[]> GetParetoFront(String filename) {
+    internal static IList<double[]> GetParetoFront(String filename) {
       List<double[]> data = new List<double[]>();
       var assembly = Assembly.GetExecutingAssembly();
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ZDT/ZDT.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ZDT/ZDT.cs	(revision 17224)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/ZDT/ZDT.cs	(revision 17225)
@@ -28,10 +28,10 @@
   [StorableType("A8192C08-A1DA-479A-9381-9B634761B521")]
   public abstract class ZDT : MultiObjectiveTestFunction {
-    protected override IEnumerable<double[]> GetOptimalParetoFront(int objectives) {
+    protected override IList<double[]> GetOptimalParetoFront(int objectives) {
       return ParetoFrontStore.GetParetoFront("ZDT.ParetoFronts." + this.ItemName);
     }
 
     protected override double[,] GetBounds(int objectives) {
-      return new double[,] { { 0, 1 } };
+      return new double[,] {{0, 1}};
     }
 
@@ -41,5 +41,5 @@
 
     protected override double[] GetReferencePoint(int objecitives) {
-      return new double[] { 11.0, 11.0 };
+      return new double[] {11.0, 11.0};
     }
 
@@ -51,6 +51,5 @@
     protected ZDT(StorableConstructorFlag _) : base(_) { }
     protected ZDT(MultiObjectiveTestFunction original, Cloner cloner)
-      : base(original, cloner) {
-    }
+      : base(original, cloner) { }
     protected ZDT() : base(minimumObjectives: 2, maximumObjectives: 2, minimumSolutionLength: 1, maximumSolutionLength: int.MaxValue) { }
 
