Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/CrowdingIndicator.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/CrowdingIndicator.cs	(revision 16309)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/CrowdingIndicator.cs	(revision 16310)
@@ -20,13 +20,10 @@
 #endregion
 
-using System;
 using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Encodings.RealVectorEncoding;
 using HeuristicLab.Optimization;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Problems.TestFunctions.MultiObjective;
 
 namespace HeuristicLab.Algorithms.MOCMAEvolutionStrategy {
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/HypervolumeIndicator.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/HypervolumeIndicator.cs	(revision 16309)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/HypervolumeIndicator.cs	(revision 16310)
@@ -20,10 +20,8 @@
 #endregion
 
-using System;
 using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Encodings.RealVectorEncoding;
 using HeuristicLab.Optimization;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/MinimalDistanceIndicator.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/MinimalDistanceIndicator.cs	(revision 16309)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/MinimalDistanceIndicator.cs	(revision 16310)
@@ -25,5 +25,4 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Encodings.RealVectorEncoding;
 using HeuristicLab.Optimization;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/DataVisualization/IndexedDataRow.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/DataVisualization/IndexedDataRow.cs	(revision 16309)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/DataVisualization/IndexedDataRow.cs	(revision 16310)
@@ -20,12 +20,12 @@
 #endregion
 
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
 using HeuristicLab.Collections;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
 
 namespace HeuristicLab.Analysis {
@@ -58,8 +58,23 @@
       set { visualProperties = value; }
     }
-    [Storable(Name = "values")]
+    // BackwardsCompatibility3.3
+    #region Backwards compatible code, remove with 3.4
+    // tuples are stored inefficiently
+    [Storable(Name = "values", AllowOneWay = true)]
     private IEnumerable<Tuple<T, double>> StorableValues {
-      get { return values; }
       set { values = new ObservableList<Tuple<T, double>>(value); }
+    }
+    #endregion
+    private T[] storableX;
+    [Storable(Name = "x")]
+    private T[] StorableX {
+      get { return Values.Select(x => x.Item1).ToArray(); }
+      set { storableX = value; }
+    }
+    private double[] storableY;
+    [Storable(Name = "y")]
+    private double[] StorableY {
+      get { return Values.Select(x => x.Item2).ToArray(); }
+      set { storableY = value; }
     }
     #endregion
@@ -109,4 +124,13 @@
       VisualProperties.DisplayName = Name;
     }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (storableX != null && storableY != null) {
+        values = new ObservableList<Tuple<T, double>>(storableX.Zip(storableY, (x, y) => Tuple.Create(x, y)));
+        storableX = null;
+        storableY = null;
+      } else if (values == null) throw new InvalidOperationException("Deserialization problem with IndexedDataRow.");
+    }
   }
 }
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 16309)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 16310)
@@ -175,6 +175,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\TimelineAnalyzer.cs" />
+    <Compile Include="MultiObjective\SpacingAnalyzer.cs" />
     <Compile Include="Plugin.cs" />
     <Compile Include="PopulationSimilarityAnalysis\PopulationDiversityAnalyzer.cs" />
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/MultiObjective/CrowdingAnalyzer.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/MultiObjective/CrowdingAnalyzer.cs	(revision 16310)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/MultiObjective/CrowdingAnalyzer.cs	(revision 16310)
@@ -0,0 +1,55 @@
+﻿#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.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  [StorableClass]
+  [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 => "Crowding";
+
+    [StorableConstructor]
+    protected CrowdingAnalyzer(bool deserializing) : base(deserializing) { }
+    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);
+      ResultParameter.ActualValue.Value = crowdingDistance;
+      return base.Apply();
+    }
+
+  }
+}
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/MultiObjective/GenerationalDistanceAnalyzer.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/MultiObjective/GenerationalDistanceAnalyzer.cs	(revision 16310)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/MultiObjective/GenerationalDistanceAnalyzer.cs	(revision 16310)
@@ -0,0 +1,73 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  [StorableClass]
+  [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 => "Generational Distance";
+
+    public IFixedValueParameter<DoubleValue> DampeningParameter => (IFixedValueParameter<DoubleValue>)Parameters["Dampening"];
+
+    public double Dampening {
+      get => DampeningParameter.Value.Value;
+      set => DampeningParameter.Value.Value = value;
+    }
+
+    public ILookupParameter<DoubleMatrix> OptimalParetoFrontParameter => (ILookupParameter<DoubleMatrix>)Parameters["BestKnownFront"];
+
+
+    [StorableConstructor]
+    protected GenerationalDistanceAnalyzer(bool deserializing) : base(deserializing) { }
+    protected GenerationalDistanceAnalyzer(GenerationalDistanceAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GenerationalDistanceAnalyzer(this, cloner);
+    }
+
+    public GenerationalDistanceAnalyzer() {
+      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]).ToList()).ToList();
+      ResultParameter.ActualValue.Value = CalculateDistance(qualities,front);
+      return base.Apply();
+    }
+
+    protected virtual double CalculateDistance(ItemArray<DoubleArray> qualities, IList<List<double>> optimalFront) {
+      return GenerationalDistanceCalculator.CalculateGenerationalDistance(qualities, optimalFront, Dampening);
+    }
+  }
+}
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/MultiObjective/HypervolumeAnalyzer.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/MultiObjective/HypervolumeAnalyzer.cs	(revision 16310)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/MultiObjective/HypervolumeAnalyzer.cs	(revision 16310)
@@ -0,0 +1,78 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  [StorableClass]
+  [Item("HypervolumeAnalyzer", "Computes the enclosed Hypervolume between the current front and a given reference Point")]
+  public class HypervolumeAnalyzer : MultiObjectiveSuccessAnalyzer {
+    public override string ResultName => "Hypervolume";
+
+    public ILookupParameter<DoubleArray> ReferencePointParameter => (ILookupParameter<DoubleArray>)Parameters["ReferencePoint"];
+
+    public IResultParameter<DoubleValue> BestKnownHypervolumeResultParameter => (IResultParameter<DoubleValue>)Parameters["Best known hypervolume"];
+
+    public IResultParameter<DoubleValue> HypervolumeDistanceResultParameter => (IResultParameter<DoubleValue>)Parameters["Absolute Distance to BestKnownHypervolume"];
+
+
+    [StorableConstructor]
+    protected HypervolumeAnalyzer(bool deserializing) : base(deserializing) {}
+
+    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/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/MultiObjective/InvertedGenerationalDistanceAnalyzer.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/MultiObjective/InvertedGenerationalDistanceAnalyzer.cs	(revision 16310)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/MultiObjective/InvertedGenerationalDistanceAnalyzer.cs	(revision 16310)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  [StorableClass]
+  [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 => false;
+    public override string ResultName => "Inverted Generational Distance";
+
+    public IResultParameter<DoubleValue> InvertedGenerationalDistanceResultParameter => (IResultParameter<DoubleValue>)Parameters["Inverted Generational Distance"];
+
+    [StorableConstructor]
+    protected InvertedGenerationalDistanceAnalyzer(bool deserializing) : base(deserializing) { }
+    protected InvertedGenerationalDistanceAnalyzer(InvertedGenerationalDistanceAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new InvertedGenerationalDistanceAnalyzer(this, cloner);
+    }
+
+    public InvertedGenerationalDistanceAnalyzer() { }
+
+    protected override double CalculateDistance(ItemArray<DoubleArray> qualities, IList<List<double>> optimalFront) {
+      return GenerationalDistanceCalculator.CalculateGenerationalDistance(optimalFront, qualities, Dampening);
+    }
+
+  }
+}
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/MultiObjective/MultiObjectiveSuccessAnalyzer.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/MultiObjective/MultiObjectiveSuccessAnalyzer.cs	(revision 16310)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/MultiObjective/MultiObjectiveSuccessAnalyzer.cs	(revision 16310)
@@ -0,0 +1,53 @@
+﻿#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;
+
+
+namespace HeuristicLab.Analysis {
+
+  [StorableClass]
+  public abstract class MultiObjectiveSuccessAnalyzer : SingleSuccessorOperator, IAnalyzer, IMultiObjectiveOperator {
+    public virtual bool EnabledByDefault => true;
+    public abstract string ResultName { get; }
+
+    public IScopeTreeLookupParameter<DoubleArray> QualitiesParameter => (IScopeTreeLookupParameter<DoubleArray>)Parameters["Qualities"];
+
+    public ILookupParameter<BoolArray> MaximizationParameter => (ILookupParameter<BoolArray>)Parameters["Maximization"];
+
+    public ResultParameter<DoubleValue> ResultParameter => (ResultParameter<DoubleValue>)Parameters[ResultName];
+
+    protected MultiObjectiveSuccessAnalyzer(MultiObjectiveSuccessAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    [StorableConstructor]
+    protected MultiObjectiveSuccessAnalyzer(bool deserializing) : base(deserializing) { }
+    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/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/MultiObjective/SpacingAnalyzer.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/MultiObjective/SpacingAnalyzer.cs	(revision 16310)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/MultiObjective/SpacingAnalyzer.cs	(revision 16310)
@@ -0,0 +1,54 @@
+﻿#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;
+
+namespace HeuristicLab.Analysis {
+  [StorableClass]
+  [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 => "Spacing";
+
+    [StorableConstructor]
+    protected SpacingAnalyzer(bool deserializing) : base(deserializing) { }
+
+
+    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 = SpacingCalculator.CalculateSpacing(qualities);
+      return base.Apply();
+    }
+  }
+}
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/MultiObjective/TimelineAnalyzer.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/MultiObjective/TimelineAnalyzer.cs	(revision 16310)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Analysis/3.3/MultiObjective/TimelineAnalyzer.cs	(revision 16310)
@@ -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.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;
+
+namespace HeuristicLab.Analysis {
+  [StorableClass]
+  [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 => true;
+    public string ResultName => "Timeline";
+
+    public IFixedValueParameter<CheckedItemList<StringValue>> CollectedSuccessMeasuresParameter => 
+      (IFixedValueParameter<CheckedItemList<StringValue>>)Parameters["CollectedSuccessMeasures"];
+
+    public ILookupParameter<ResultCollection> ResultsParameter => (ILookupParameter<ResultCollection>)Parameters["Results"];
+
+    public ResultParameter<DataTable> ResultParameter => (ResultParameter<DataTable>)Parameters[ResultName];
+
+    public CheckedItemList<StringValue> CollectedSuccessMeasures => CollectedSuccessMeasuresParameter.Value;
+
+    [StorableConstructor]
+    protected TimelineAnalyzer(bool deserializing) : base(deserializing) { }
+
+
+    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;
+        if(!(resultCollection[resultName].Value is DoubleValue res)) continue;
+        if(!plot.Rows.ContainsKey(resultName)) plot.Rows.Add(new DataRow(resultName));
+        plot.Rows[resultName].Values.Add(res.Value);
+      }
+      return base.Apply();
+    }
+  }
+}
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/StringMatrix.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/StringMatrix.cs	(revision 16309)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Data/3.3/StringMatrix.cs	(revision 16310)
@@ -209,4 +209,20 @@
     }
 
+    public string[,] CloneAsMatrix() {
+      return (string[,])matrix.Clone();
+    }
+
+    public virtual IEnumerable<string> GetRow(int row) {
+      for (var col = 0; col < Columns; col++) {
+        yield return matrix[row, col];
+      }
+    }
+
+    public virtual IEnumerable<string> GetColumn(int col) {
+      for (var row = 0; row < Rows; row++) {
+        yield return matrix[row, col];
+      }
+    }
+
     public override string ToString() {
       if (matrix.Length == 0) return "[]";
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/BasicProblems/MultiObjectiveBasicProblem.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/BasicProblems/MultiObjectiveBasicProblem.cs	(revision 16309)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/BasicProblems/MultiObjectiveBasicProblem.cs	(revision 16310)
@@ -20,6 +20,4 @@
 #endregion
 
-using System;
-using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Common;
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MetaOptimizers/TimeLimitRun.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MetaOptimizers/TimeLimitRun.cs	(revision 16309)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MetaOptimizers/TimeLimitRun.cs	(revision 16310)
@@ -188,4 +188,5 @@
           TimeSpan.FromSeconds(15) });
       snapshotTimesIndex = 0;
+      snapshots = new RunCollection();
       Runs = new RunCollection { OptimizerName = Name };
       Initialize();
@@ -199,4 +200,5 @@
           TimeSpan.FromSeconds(15) });
       snapshotTimesIndex = 0;
+      snapshots = new RunCollection();
       Runs = new RunCollection { OptimizerName = Name };
       Initialize();
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/CrowdingCalculator.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/CrowdingCalculator.cs	(revision 16309)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/CrowdingCalculator.cs	(revision 16310)
@@ -35,6 +35,5 @@
   /// 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 class CrowdingCalculator {
 
     public static double CalculateCrowding<TP>(IEnumerable<TP> qualities) where TP : IReadOnlyList<double> {
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/GenerationalDistanceCalculator.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/GenerationalDistanceCalculator.cs	(revision 16309)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/GenerationalDistanceCalculator.cs	(revision 16310)
@@ -23,10 +23,8 @@
 
 #region
-
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Common;
-
 #endregion
 
@@ -40,11 +38,10 @@
   public static class GenerationalDistanceCalculator {
     public static double CalculateGenerationalDistance<TP1, TP2>(IEnumerable<TP1> qualities, IEnumerable<TP2> bestKnownFront, double p) where TP1 : IReadOnlyList<double> where TP2 : IReadOnlyList<double> {
-      if (qualities == null || bestKnownFront == null) throw new ArgumentNullException("Fronts must not be null");
+      if (qualities == null || bestKnownFront == null) throw new ArgumentNullException(nameof(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);
+      alglib.kdtreebuild(mat, mat.GetLength(0), mat.GetLength(1), 0, 2, out var tree);
       var sum = 0.0;
       var summand = new double[1];
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/HypervolumeCalculator.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/HypervolumeCalculator.cs	(revision 16309)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/HypervolumeCalculator.cs	(revision 16310)
@@ -23,5 +23,4 @@
 using System.Linq;
 using HeuristicLab.Common;
-using HeuristicLab.Optimization;
 
 namespace HeuristicLab.Optimization {
@@ -64,5 +63,5 @@
     public static double CalculateHypervolume(double[][] qualities, double[] referencePoint, bool[] maximization){
       qualities = qualities.Where(vec => DominationCalculator.Dominates(vec, referencePoint, maximization, false) == DominationResult.Dominates).ToArray();
-      if (!qualities.Any()) return 0;//TODO replace with negative computation
+      if (qualities.Length == 0 ) return 0;//TODO computation for negative hypervolume?
       if (maximization.Length == 2)
         return Calculate2D(qualities, referencePoint, maximization);
@@ -73,9 +72,17 @@
     }
 
+
+    /// <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(double[][] front, double[] referencePoint, bool[] maximization) {
-      if (front == null) throw new ArgumentNullException("Front must not be null.");
+      if (front == null) throw new ArgumentNullException(nameof(front));
+      if (referencePoint == null) throw new ArgumentNullException(nameof(referencePoint));
+      if (maximization == null) throw new ArgumentNullException(nameof(maximization));
       if (!front.Any()) throw new ArgumentException("Front must not be empty.");
-
-      if (referencePoint == null) throw new ArgumentNullException("ReferencePoint must not be null.");
       if (referencePoint.Length != 2) throw new ArgumentException("ReferencePoint must have exactly two dimensions.");
 
@@ -87,6 +94,5 @@
       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]));
-      
+        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]);
@@ -112,4 +118,7 @@
     }
 
+
+    //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;
@@ -135,5 +144,5 @@
       var piles = new int[coverIndex];
       for (var i = 0; i < coverIndex; i++) {
-        piles[i] = IsPile(front[i], regionLow, regionUp, objectives);
+        piles[i] = IsPile(front[i], regionLow, objectives);
         if (piles[i] == -1) {
           allPiles = false;
@@ -145,9 +154,8 @@
         var trellis = new double[regionUp.Length];
         for (var j = 0; j < trellis.Length; j++) trellis[j] = regionUp[j];
-        double current = 0;
-        double next = 0;
+        double next;
         var i = 0;
         do {
-          current = front[i][objectives - 1];
+          var current = front[i][objectives - 1];
           do {
             if (front[i][piles[i]] < trellis[piles[i]]) trellis[piles[i]] = front[i][piles[i]];
@@ -176,7 +184,6 @@
         } while (bound == -1.0);
 
-        List<double[]> pointsChildLow, pointsChildUp;
-        pointsChildLow = new List<double[]>();
-        pointsChildUp = new List<double[]>();
+        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];
@@ -205,9 +212,8 @@
       double result = 0;
       var noSummands = BinarayToInt(bs);
-      int oneCounter; double summand;
       for (uint i = 1; i <= noSummands; i++) {
-        summand = 1;
+        double summand = 1;
         IntToBinary(i, bs);
-        oneCounter = 0;
+        var oneCounter = 0;
         for (var j = 0; j < objectives - 1; j++) {
           if (bs[j]) {
@@ -244,5 +250,5 @@
     }
 
-    private static int IsPile(double[] cuboid, double[] regionLow, double[] regionUp, int objectives) {
+    private static int IsPile(double[] cuboid, double[] regionLow, int objectives) {
       var pile = cuboid.Length;
       for (var i = 0; i < objectives - 1; i++) {
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/SpacingCalculator.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/SpacingCalculator.cs	(revision 16309)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Optimization/3.3/MultiObjective/SpacingCalculator.cs	(revision 16310)
@@ -34,5 +34,5 @@
 
     public static double CalculateSpacing<TP>(IEnumerable<TP> qualities) where TP: IReadOnlyList<double> {
-      if (qualities == null) throw new ArgumentException("Front must not be null.");
+      if (qualities == null) throw new ArgumentNullException(nameof(qualities));
       var l = qualities.ToList();
       if (l.Count == 0) throw new ArgumentException("Front must not be empty.");
@@ -40,6 +40,5 @@
 
       var mat = l.ToMatrix();
-      alglib.kdtree tree;
-      alglib.kdtreebuild(mat, mat.GetLength(0), mat.GetLength(1), 0, 2, out tree);
+      alglib.kdtreebuild(mat, mat.GetLength(0), mat.GetLength(1), 0, 2, out var tree);
       var summand = new double[2];
       var dists = new List<double>();
@@ -51,6 +50,4 @@
       return dists.StandardDeviationPop();
     }
-
-    
   }
 }
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/CrowdingAnalyzer.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/CrowdingAnalyzer.cs	(revision 16309)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/CrowdingAnalyzer.cs	(revision 16310)
@@ -30,16 +30,12 @@
 namespace HeuristicLab.Problems.TestFunctions.MultiObjective {
   [StorableClass]
-  [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 IResultParameter<DoubleValue> CrowdingResultParameter {
-      get { return (IResultParameter<DoubleValue>)Parameters["Crowding"]; }
-    }
+    public IResultParameter<DoubleValue> CrowdingResultParameter => (IResultParameter<DoubleValue>)Parameters["Crowding"];
 
     [StorableConstructor]
     protected CrowdingAnalyzer(bool deserializing) : base(deserializing) { }
-    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);
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/GenerationalDistanceAnalyzer.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/GenerationalDistanceAnalyzer.cs	(revision 16309)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/GenerationalDistanceAnalyzer.cs	(revision 16310)
@@ -31,20 +31,18 @@
 namespace HeuristicLab.Problems.TestFunctions.MultiObjective {
   [StorableClass]
-  [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 {
 
     private IFixedValueParameter<DoubleValue> DampeningParameter {
-      get { return (IFixedValueParameter<DoubleValue>)Parameters["Dampening"]; }
-      set { Parameters["Dampening"].ActualValue = value; }
+      get => (IFixedValueParameter<DoubleValue>)Parameters["Dampening"];
+      set => Parameters["Dampening"].ActualValue = value;
     }
 
     public double Dampening {
-      get { return DampeningParameter.Value.Value; }
-      set { DampeningParameter.Value.Value = value; }
+      get => DampeningParameter.Value.Value;
+      set => DampeningParameter.Value.Value = value;
     }
 
-    public IResultParameter<DoubleValue> GenerationalDistanceResultParameter {
-      get { return (IResultParameter<DoubleValue>)Parameters["Generational Distance"]; }
-    }
+    public IResultParameter<DoubleValue> GenerationalDistanceResultParameter => (IResultParameter<DoubleValue>)Parameters["Generational Distance"];
 
     [StorableConstructor]
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/HypervolumeAnalyzer.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/HypervolumeAnalyzer.cs	(revision 16309)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/HypervolumeAnalyzer.cs	(revision 16310)
@@ -32,29 +32,21 @@
 namespace HeuristicLab.Problems.TestFunctions.MultiObjective {
   [StorableClass]
-  [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 {
 
-    public ILookupParameter<DoubleArray> ReferencePointParameter {
-      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"]; }
-    }
+    public ILookupParameter<DoubleArray> ReferencePointParameter => (ILookupParameter<DoubleArray>)Parameters["ReferencePoint"];
+
+    public IResultParameter<DoubleValue> HypervolumeResultParameter => (IResultParameter<DoubleValue>)Parameters["Hypervolume"];
+
+    public IResultParameter<DoubleValue> BestKnownHypervolumeResultParameter => (IResultParameter<DoubleValue>)Parameters["Best known hypervolume"];
+
+    public IResultParameter<DoubleValue> HypervolumeDistanceResultParameter => (IResultParameter<DoubleValue>)Parameters["Absolute Distance to BestKnownHypervolume"];
 
 
     [StorableConstructor]
-    protected HypervolumeAnalyzer(bool deserializing)
-      : base(deserializing) {
-    }
+    protected HypervolumeAnalyzer(bool deserializing) : base(deserializing) {}
 
-    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);
@@ -69,6 +61,4 @@
       BestKnownHypervolumeResultParameter.DefaultValue = new DoubleValue(0);
       HypervolumeDistanceResultParameter.DefaultValue = new DoubleValue(0);
-
-
     }
 
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/InvertedGenerationalDistanceAnalyzer.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/InvertedGenerationalDistanceAnalyzer.cs	(revision 16309)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/InvertedGenerationalDistanceAnalyzer.cs	(revision 16310)
@@ -30,20 +30,16 @@
 namespace HeuristicLab.Problems.TestFunctions.MultiObjective {
   [StorableClass]
-  [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 => false;
 
-    private IFixedValueParameter<DoubleValue> DampeningParameter {
-      get { return (IFixedValueParameter<DoubleValue>)Parameters["Dampening"]; }
+    private IFixedValueParameter<DoubleValue> DampeningParameter => (IFixedValueParameter<DoubleValue>)Parameters["Dampening"];
+
+    public double Dampening {
+      get => DampeningParameter.Value.Value;
+      set => DampeningParameter.Value.Value = value;
     }
 
-    public double Dampening {
-      get { return DampeningParameter.Value.Value; }
-      set { DampeningParameter.Value.Value = value; }
-    }
-
-    public IResultParameter<DoubleValue> InvertedGenerationalDistanceResultParameter {
-      get { return (IResultParameter<DoubleValue>)Parameters["Inverted Generational Distance"]; }
-    }
+    public IResultParameter<DoubleValue> InvertedGenerationalDistanceResultParameter => (IResultParameter<DoubleValue>)Parameters["Inverted Generational Distance"];
 
     [StorableConstructor]
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/MOTFAnalyzer.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/MOTFAnalyzer.cs	(revision 16309)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/MOTFAnalyzer.cs	(revision 16310)
@@ -33,21 +33,13 @@
   [StorableClass]
   public abstract class MOTFAnalyzer : SingleSuccessorOperator, IMultiObjectiveTestFunctionAnalyzer {
-    public virtual bool EnabledByDefault { get { return true; } }
+    public virtual bool EnabledByDefault => true;
 
-    public IScopeTreeLookupParameter<DoubleArray> QualitiesParameter {
-      get { return (IScopeTreeLookupParameter<DoubleArray>)Parameters["Qualities"]; }
-    }
+    public IScopeTreeLookupParameter<DoubleArray> QualitiesParameter => (IScopeTreeLookupParameter<DoubleArray>)Parameters["Qualities"];
 
-    public ILookupParameter<ResultCollection> ResultsParameter {
-      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
-    }
+    public ILookupParameter<ResultCollection> ResultsParameter => (ILookupParameter<ResultCollection>)Parameters["Results"];
 
-    public ILookupParameter<IMultiObjectiveTestFunction> TestFunctionParameter {
-      get { return (ILookupParameter<IMultiObjectiveTestFunction>)Parameters["TestFunction"]; }
-    }
+    public ILookupParameter<IMultiObjectiveTestFunction> TestFunctionParameter => (ILookupParameter<IMultiObjectiveTestFunction>)Parameters["TestFunction"];
 
-    public ILookupParameter<DoubleMatrix> BestKnownFrontParameter {
-      get { return (ILookupParameter<DoubleMatrix>)Parameters["BestKnownFront"]; }
-    }
+    public ILookupParameter<DoubleMatrix> BestKnownFrontParameter => (ILookupParameter<DoubleMatrix>)Parameters["BestKnownFront"];
 
     protected MOTFAnalyzer(MOTFAnalyzer original, Cloner cloner) : base(original, cloner) { }
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/ScatterPlotAnalyzer.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/ScatterPlotAnalyzer.cs	(revision 16309)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/ScatterPlotAnalyzer.cs	(revision 16310)
@@ -23,4 +23,5 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Encodings.RealVectorEncoding;
 using HeuristicLab.Optimization;
@@ -33,12 +34,7 @@
   public class ScatterPlotAnalyzer : MOTFAnalyzer {
 
-    public IScopeTreeLookupParameter<RealVector> IndividualsParameter {
-      get { return (IScopeTreeLookupParameter<RealVector>)Parameters["Individuals"]; }
-    }
+    public IScopeTreeLookupParameter<RealVector> IndividualsParameter => (IScopeTreeLookupParameter<RealVector>)Parameters["Individuals"];
 
-    public IResultParameter<ParetoFrontScatterPlot> ScatterPlotResultParameter {
-      get { return (IResultParameter<ParetoFrontScatterPlot>)Parameters["Scatterplot"]; }
-    }
-
+    public IResultParameter<ParetoFrontScatterPlot> ScatterPlotResultParameter => (IResultParameter<ParetoFrontScatterPlot>)Parameters["Scatterplot"];
 
     [StorableConstructor]
@@ -52,5 +48,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 +54,16 @@
       var individuals = IndividualsParameter.ActualValue;
       var testFunction = TestFunctionParameter.ActualValue;
-      var objectives = qualities[0].Length;
-      var problemSize = individuals[0].Length;
+      var objectives = qualities.Length != 0 ? qualities[0].Length:0;    
+      var problemSize = individuals.Length != 0 ? individuals[0].Length:0;
 
-      var 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 +71,4 @@
 
       ScatterPlotResultParameter.ActualValue = new ParetoFrontScatterPlot(qualityClones, solutionClones, optimalFront, objectives, problemSize);
-
       return base.Apply();
     }
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/SpacingAnalyzer.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/SpacingAnalyzer.cs	(revision 16309)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/Analyzers/SpacingAnalyzer.cs	(revision 16310)
@@ -29,13 +29,11 @@
 namespace HeuristicLab.Problems.TestFunctions.MultiObjective {
   [StorableClass]
-  [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 {
 
-    public IResultParameter<DoubleValue> SpacingResultParameter {
-      get { return (IResultParameter<DoubleValue>)Parameters["Spacing"]; }
-    }
+    public IResultParameter<DoubleValue> SpacingResultParameter => (IResultParameter<DoubleValue>)Parameters["Spacing"];
+
     [StorableConstructor]
     protected SpacingAnalyzer(bool deserializing) : base(deserializing) { }
-
 
     protected SpacingAnalyzer(SpacingAnalyzer original, Cloner cloner) : base(original, cloner) { }
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.csproj
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.csproj	(revision 16309)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/HeuristicLab.Problems.TestFunctions.MultiObjective-3.3.csproj	(revision 16310)
@@ -146,5 +146,4 @@
     <Compile Include="TestFunctions\IHR\IHR2.cs" />
     <Compile Include="TestFunctions\Misc\ELLI1.cs" />
-    <Compile Include="NonDominatedSelect.cs" />
     <Compile Include="Interfaces\IMultiObjectiveTestFunction.cs" />
     <Compile Include="MultiObjectiveTestFunctionProblem.cs" />
Index: /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/MultiObjectiveTestFunctionProblem.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/MultiObjectiveTestFunctionProblem.cs	(revision 16309)
+++ /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/MultiObjectiveTestFunctionProblem.cs	(revision 16310)
@@ -39,5 +39,5 @@
     #region Parameter Properties
     public new IValueParameter<BoolArray> MaximizationParameter {
-      get { return (IValueParameter<BoolArray>)Parameters["Maximization"]; }
+      get { return (IValueParameter<BoolArray>)Parameters[MaximizationParameterName]; }
     }
     public IFixedValueParameter<IntValue> ProblemSizeParameter {
@@ -86,6 +86,5 @@
     }
 
-    protected MultiObjectiveTestFunctionProblem(MultiObjectiveTestFunctionProblem original, Cloner cloner)
-      : base(original, cloner) {
+    protected MultiObjectiveTestFunctionProblem(MultiObjectiveTestFunctionProblem original, Cloner cloner) : base(original, cloner) {
       RegisterEventHandlers();
     }
@@ -94,6 +93,5 @@
     }
 
-    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)));
@@ -130,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];
     }
 
@@ -169,4 +164,5 @@
       ParameterizeAnalyzers();
     }
+
     protected override void OnEvaluatorChanged() {
       base.OnEvaluatorChanged();
@@ -199,17 +195,15 @@
     #region Helpers
     private void InitializeOperators() {
-      Operators.Add(new CrowdingAnalyzer());
-      Operators.Add(new GenerationalDistanceAnalyzer());
-      Operators.Add(new InvertedGenerationalDistanceAnalyzer());
-      Operators.Add(new HypervolumeAnalyzer());
-      Operators.Add(new SpacingAnalyzer());
+      Operators.Add(new Analysis.CrowdingAnalyzer());
+      Operators.Add(new Analysis.GenerationalDistanceAnalyzer());
+      Operators.Add(new Analysis.InvertedGenerationalDistanceAnalyzer());
+      Operators.Add(new Analysis.HypervolumeAnalyzer());
+      Operators.Add(new Analysis.SpacingAnalyzer());
+      Operators.Add(new Analysis.TimelineAnalyzer());
       Operators.Add(new ScatterPlotAnalyzer());
-
-      ParameterizeAnalyzers();
-    }
-
-    private IEnumerable<IMultiObjectiveTestFunctionAnalyzer> Analyzers {
-      get { return Operators.OfType<IMultiObjectiveTestFunctionAnalyzer>(); }
-    }
+      ParameterizeAnalyzers();
+    }
+
+    private IEnumerable<IMultiObjectiveTestFunctionAnalyzer> Analyzers => Operators.OfType<IMultiObjectiveTestFunctionAnalyzer>();
 
     private void ParameterizeAnalyzers() {
@@ -219,12 +213,8 @@
         analyzer.TestFunctionParameter.ActualName = TestFunctionParameter.Name;
         analyzer.BestKnownFrontParameter.ActualName = BestKnownFrontParameter.Name;
-
-        var scatterPlotAnalyzer = analyzer as ScatterPlotAnalyzer;
-        if (scatterPlotAnalyzer != null) {
+        if (analyzer is ScatterPlotAnalyzer scatterPlotAnalyzer) 
           scatterPlotAnalyzer.IndividualsParameter.ActualName = Encoding.Name;
-        }
       }
     }
-
     #endregion
   }
Index: anches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/NonDominatedSelect.cs
===================================================================
--- /branches/2943_MOBasicProblem_MOCMAES/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/NonDominatedSelect.cs	(revision 16309)
+++ 	(revision )
@@ -1,29 +1,0 @@
-﻿#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;
-
-namespace HeuristicLab.Problems.TestFunctions.MultiObjective {
-
-  public static class NonDominatedSelect {
-    
-  }
-}
