Index: /branches/2521_ProblemRefactoring/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVectorProblem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVectorProblem.cs	(revision 16949)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVectorProblem.cs	(revision 16950)
@@ -63,10 +63,9 @@
     }
 
-    public override void Analyze(BinaryVector[] individuals, double[] qualities, ResultCollection results, IRandom random) {
-      base.Analyze(individuals, qualities, results, random);
-      var orderedIndividuals = individuals.Zip(qualities, (i, q) => new { Individual = i, Quality = q }).OrderBy(z => z.Quality);
-      var best = Maximization ? orderedIndividuals.Last().Individual : orderedIndividuals.First().Individual;
+    public override void Analyze(BinaryVector[] vectors, double[] qualities, ResultCollection results, IRandom random) {
+      base.Analyze(vectors, qualities, results, random);
+      var best = GetBestSolution(vectors, qualities);
 
-      results.AddOrUpdateResult("Best Solution", (IItem)best.Clone());
+      results.AddOrUpdateResult("Best Solution", (IItem)best.Item1.Clone());
     }
 
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Encodings.IntegerVectorEncoding/3.3/IntegerVectorProblem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Encodings.IntegerVectorEncoding/3.3/IntegerVectorProblem.cs	(revision 16949)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Encodings.IntegerVectorEncoding/3.3/IntegerVectorProblem.cs	(revision 16950)
@@ -63,10 +63,9 @@
     }
 
-    public override void Analyze(IntegerVector[] individuals, double[] qualities, ResultCollection results, IRandom random) {
-      base.Analyze(individuals, qualities, results, random);
-      var orderedIndividuals = individuals.Zip(qualities, (i, q) => new { Individual = i, Quality = q }).OrderBy(z => z.Quality);
-      var best = Maximization ? orderedIndividuals.Last().Individual : orderedIndividuals.First().Individual;
+    public override void Analyze(IntegerVector[] vectors, double[] qualities, ResultCollection results, IRandom random) {
+      base.Analyze(vectors, qualities, results, random);
+      var best = GetBestSolution(vectors, qualities);
 
-      results.AddOrUpdateResult("Best Solution", (IItem)best.Clone());
+      results.AddOrUpdateResult("Best Solution", (IItem)best.Item1.Clone());
     }
 
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkageProblem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkageProblem.cs	(revision 16949)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Encodings.LinearLinkageEncoding/3.4/LinearLinkageProblem.cs	(revision 16950)
@@ -63,10 +63,9 @@
     }
 
-    public override void Analyze(LinearLinkage[] individuals, double[] qualities, ResultCollection results, IRandom random) {
-      base.Analyze(individuals, qualities, results, random);
-      var orderedIndividuals = individuals.Zip(qualities, (i, q) => new { Individual = i, Quality = q }).OrderBy(z => z.Quality);
-      var best = Maximization ? orderedIndividuals.Last().Individual : orderedIndividuals.First().Individual;
+    public override void Analyze(LinearLinkage[] vectors, double[] qualities, ResultCollection results, IRandom random) {
+      base.Analyze(vectors, qualities, results, random);
+      var best = GetBestSolution(vectors, qualities);
 
-      results.AddOrUpdateResult("Best Solution", (Item)best.Clone());
+      results.AddOrUpdateResult("Best Solution", (Item)best.Item1.Clone());
     }
 
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationProblem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationProblem.cs	(revision 16949)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Encodings.PermutationEncoding/3.3/PermutationProblem.cs	(revision 16950)
@@ -68,10 +68,8 @@
     }
 
-    public override void Analyze(Permutation[] individuals, double[] qualities, ResultCollection results, IRandom random) {
-      base.Analyze(individuals, qualities, results, random);
-      var orderedIndividuals = individuals.Zip(qualities, (i, q) => new { Individual = i, Quality = q }).OrderBy(z => z.Quality);
-      var best = Maximization ? orderedIndividuals.Last().Individual : orderedIndividuals.First().Individual;
-
-      results.AddOrUpdateResult("Best Solution", (IItem)best.Clone());
+    public override void Analyze(Permutation[] permutations, double[] qualities, ResultCollection results, IRandom random) {
+      base.Analyze(permutations, qualities, results, random);
+      var best = GetBestSolution(permutations, qualities);
+      results.AddOrUpdateResult("Best Solution", (IItem)best.Item1.Clone());
     }
 
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Encodings.RealVectorEncoding/3.3/RealVectorProblem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Encodings.RealVectorEncoding/3.3/RealVectorProblem.cs	(revision 16949)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Encodings.RealVectorEncoding/3.3/RealVectorProblem.cs	(revision 16950)
@@ -63,10 +63,9 @@
     }
 
-    public override void Analyze(RealVector[] individuals, double[] qualities, ResultCollection results, IRandom random) {
-      base.Analyze(individuals, qualities, results, random);
-      var orderedIndividuals = individuals.Zip(qualities, (i, q) => new { Individual = i, Quality = q }).OrderBy(z => z.Quality);
-      var best = Maximization ? orderedIndividuals.Last().Individual : orderedIndividuals.First().Individual;
+    public override void Analyze(RealVector[] vectors, double[] qualities, ResultCollection results, IRandom random) {
+      base.Analyze(vectors, qualities, results, random);
+      var best = GetBestSolution(vectors, qualities);
 
-      results.AddOrUpdateResult("Best Solution", (IItem)best.Clone());
+      results.AddOrUpdateResult("Best Solution", (IItem)best.Item1.Clone());
     }
 
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/MultiObjectiveTestFunctionProblem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/MultiObjectiveTestFunctionProblem.cs	(revision 16949)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/MultiObjectiveTestFunctionProblem.cs	(revision 16950)
@@ -73,5 +73,5 @@
       set { ProblemSizeParameter.Value.Value = value; }
     }
-    public int Objectives {
+    public new int Objectives {
       get { return ObjectivesParameter.Value.Value; }
       set { ObjectivesParameter.Value.Value = value; }
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 16949)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/TestFunctions/MultiObjectiveTestFunction.cs	(revision 16950)
@@ -22,4 +22,5 @@
 using System;
 using System.Collections.Generic;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -27,5 +28,4 @@
 using HeuristicLab.Encodings.RealVectorEncoding;
 using HeuristicLab.Parameters;
-using HEAL.Attic;
 
 namespace HeuristicLab.Problems.TestFunctions.MultiObjective {
@@ -71,5 +71,5 @@
     /// </summary>
     public bool[] Maximization(int objectives) {
-      CheckObjectives(objectives);
+      ThrowIfObjectivesOutOfRange(objectives);
       return GetMaximization(objectives);
     }
@@ -79,5 +79,5 @@
     /// </summary>
     public double[,] Bounds(int objectives) {
-      CheckObjectives(objectives);
+      ThrowIfObjectivesOutOfRange(objectives);
       return GetBounds(objectives);
     }
@@ -88,5 +88,5 @@
     /// </summary>
     public IEnumerable<double[]> OptimalParetoFront(int objectives) {
-      CheckObjectives(objectives);
+      ThrowIfObjectivesOutOfRange(objectives);
       return GetOptimalParetoFront(objectives);
     }
@@ -97,5 +97,5 @@
     /// </summary>
     public double[] ReferencePoint(int objectives) {
-      CheckObjectives(objectives);
+      ThrowIfObjectivesOutOfRange(objectives);
       return GetReferencePoint(objectives);
     }
@@ -106,5 +106,5 @@
     /// </summary>     
     public virtual double OptimalHypervolume(int objectives) {
-      CheckObjectives(objectives);
+      ThrowIfObjectivesOutOfRange(objectives);
       return GetBestKnownHypervolume(objectives);
     }
@@ -114,5 +114,5 @@
     }
 
-    protected void CheckObjectives(int objectives) {
+    protected void ThrowIfObjectivesOutOfRange(int objectives) {
       if (objectives < MinimumObjectives) throw new ArgumentException(string.Format("There must be at least {0} objectives", MinimumObjectives));
       if (objectives > MaximumObjectives) throw new ArgumentException(string.Format("There must be at most {0} objectives", MaximumObjectives));
@@ -121,5 +121,4 @@
     [StorableConstructor]
     protected MultiObjectiveTestFunction(StorableConstructorFlag _) : base(_) { }
-
     protected MultiObjectiveTestFunction(MultiObjectiveTestFunction original, Cloner cloner)
       : base(original, cloner) {
@@ -129,5 +128,4 @@
       MaximumSolutionLength = original.MaximumSolutionLength;
     }
-
     protected MultiObjectiveTestFunction(int minimumObjectives, int maximumObjectives, int minimumSolutionLength, int maximumSolutionLength)
       : base() {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions/3.3/SingleObjectiveTestFunctionProblem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions/3.3/SingleObjectiveTestFunctionProblem.cs	(revision 16949)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions/3.3/SingleObjectiveTestFunctionProblem.cs	(revision 16950)
@@ -116,45 +116,33 @@
 
     public override void Analyze(RealVector[] realVectors, double[] qualities, ResultCollection results, IRandom random) {
-
-      bool max = Maximization;
+      var best = GetBestSolution(realVectors, qualities);
+
       DoubleValue bestKnownQuality = BestKnownQualityParameter.Value;
+      RealVector bestKnownSolution = null;
+      var bestKnownUpdate = bestKnownQuality == null || IsBetter(best.Item2, bestKnownQuality.Value);
+      if (bestKnownUpdate) {
+        if (bestKnownQuality != null) bestKnownQuality.Value = best.Item2;
+        else BestKnownQualityParameter.Value = bestKnownQuality = new DoubleValue(best.Item2);
+        BestKnownSolutionParameter.Value = bestKnownSolution = (RealVector)best.Item1.Clone();
+      }
+
       SingleObjectiveTestFunctionSolution solution = null;
       if (results.TryGetValue("Best Solution", out var res)) {
         solution = (SingleObjectiveTestFunctionSolution)res.Value;
-      }
-
-      int i = -1;
-      if (!max) i = qualities.Select((x, index) => new { index, quality = x }).OrderBy(x => x.quality).First().index;
-      else i = qualities.Select((x, index) => new { index, quality = x }).OrderByDescending(x => x.quality).First().index;
-
-      if (bestKnownQuality == null ||
-          max && qualities[i] > bestKnownQuality.Value
-          || !max && qualities[i] < bestKnownQuality.Value) {
-        BestKnownQualityParameter.Value = new DoubleValue(qualities[i]);
-        BestKnownSolutionParameter.Value = (RealVector)realVectors[i].Clone();
-        if (solution != null)
-          solution.BestKnownRealVector = BestKnownSolutionParameter.Value;
-      }
-
-      if (solution == null) {
-        solution = new SingleObjectiveTestFunctionSolution((RealVector)realVectors[i].Clone(),
-                                                           new DoubleValue(qualities[i]),
-                                                           TestFunctionParameter.Value);
-        solution.Population = realVectors[i].Length == 2
-          ? new ItemArray<RealVector>(realVectors.Select(x => x.Clone()).Cast<RealVector>())
-          : null;
-        solution.BestKnownRealVector = BestKnownSolutionParameter.Value;
-        solution.Bounds = BoundsParameter.Value;
+        if (IsBetter(best.Item2, solution.BestQuality.Value)) {
+          solution.BestRealVector = (RealVector)best.Item1.Clone();
+          solution.BestQuality = new DoubleValue(best.Item2);
+        }
+      } else {
+        solution = new SingleObjectiveTestFunctionSolution((RealVector)best.Item1.Clone(),
+                                                           new DoubleValue(best.Item2),
+                                                           TestFunctionParameter.Value) {
+          BestKnownRealVector = bestKnownSolution,
+          Bounds = BoundsParameter.Value
+        };
         results.Add(new Result("Best Solution", solution));
-      } else {
-        if (max && qualities[i] > solution.BestQuality.Value
-          || !max && qualities[i] < solution.BestQuality.Value) {
-          solution.BestRealVector = (RealVector)realVectors[i].Clone();
-          solution.BestQuality = new DoubleValue(qualities[i]);
-        }
-        solution.Population = realVectors[i].Length == 2
-          ? new ItemArray<RealVector>(realVectors.Select(x => x.Clone()).Cast<RealVector>())
-          : null;
-      }
+      }
+      if (best.Item1.Length == 2) solution.Population = new ItemArray<RealVector>(realVectors.Select(x => (RealVector)x.Clone()));
+      if (bestKnownUpdate) solution.BestKnownRealVector = bestKnownSolution;
     }
 
