Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/AfterCrossoverCombinedOperator.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/AfterCrossoverCombinedOperator.cs	(revision 9184)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/AfterCrossoverCombinedOperator.cs	(revision 9185)
@@ -40,4 +40,7 @@
     protected VariableDuplicator varDuplicator;
 
+    [Storable]
+    protected WorstQualityAnalyzer wqAnalyzer;
+
     public ILookupParameter<IEvaluator> EvaluatorParameter {
       get { return ((LookupParameter<IEvaluator>)Parameters["Evaluator"]); }
@@ -79,5 +82,7 @@
       solToPopAnalyzer = new SolutionToPopulationAnalyzer();
       solToPopAnalyzer.ChartPostfixParameter.Value = new Data.StringValue("after Crossover");
+      wqAnalyzer = new WorstQualityAnalyzer();
 
+      Operators.Add(wqAnalyzer);
       Operators.Add(EvaluatorParameter.ActualValue);
       Operators.Add(cxAnalyzer);
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/QAPAfterCrossoverCombinedOperator.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/QAPAfterCrossoverCombinedOperator.cs	(revision 9184)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/QAPAfterCrossoverCombinedOperator.cs	(revision 9185)
@@ -63,4 +63,6 @@
       solToPopAnalyzer.SolutionParameter.ActualName = "Assignment";
       solToPopAnalyzer.QualityParameter.ActualName = "Quality";
+
+      wqAnalyzer.ParentsQualityParameter.ActualName = "Quality";
     }
   }
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/TFAfterCrossoverCombinedOperator.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/TFAfterCrossoverCombinedOperator.cs	(revision 9184)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/TFAfterCrossoverCombinedOperator.cs	(revision 9185)
@@ -59,4 +59,6 @@
       solToPopAnalyzer.SolutionParameter.ActualName = "Point";
       solToPopAnalyzer.QualityParameter.ActualName = "Quality";
+
+      wqAnalyzer.ParentsQualityParameter.ActualName = "Quality";
       //TODO: add unwanted mutation analyzer for TF
     }
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/VRPAfterCrossoverCombinedOperator.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/VRPAfterCrossoverCombinedOperator.cs	(revision 9184)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/VRPAfterCrossoverCombinedOperator.cs	(revision 9185)
@@ -59,4 +59,6 @@
       solToPopAnalyzer.SolutionParameter.ActualName = "VRPTours";
       solToPopAnalyzer.QualityParameter.ActualName = "Quality";
+
+      wqAnalyzer.ParentsQualityParameter.ActualName = "Quality";
     }
   }
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CrossoverPerformanceAnalyzer.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CrossoverPerformanceAnalyzer.cs	(revision 9184)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CrossoverPerformanceAnalyzer.cs	(revision 9185)
@@ -67,4 +67,10 @@
       get { return (ILookupParameter<ItemCollection<IItem>>)Parameters["Operators"]; }
     }
+    public ILookupParameter<DoubleValue> BestKnownQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
+    }
+    public ILookupParameter<DoubleValue> WorstKnownQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["WorstKnownQuality"]; }
+    }
     #endregion
 
@@ -124,5 +130,6 @@
       Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, false otherwise"));
       Parameters.Add(new ValueLookupParameter<ItemCollection<DoubleValue>>("ComparisonFactor", "Determines if the quality should be compared to the better parent (1.0), to the worse (0.0) or to any linearly interpolated value between them."));
-
+      Parameters.Add(new LookupParameter<DoubleValue>("BestKnownQuality", "The quality of the best known solution of this problem."));
+      Parameters.Add(new LookupParameter<DoubleValue>("WorstKnownQuality", "The quality of the worst known solution of this problem."));
 
       worseParentCrossoverPerformancePlot = new ScatterPlotHelper(false, true, true);
@@ -172,4 +179,5 @@
       }
       successHelper.InitializeChart(Results, "Successfull Crossovers", successfullCXRowNames.ToArray());
+
       Reset();
     }
@@ -234,4 +242,29 @@
       }
 
+      if (GenerationsParameter.ActualValue.Value == 1) {
+        double bkQuality = BestKnownQualityParameter.ActualValue.Value;
+        double wkQuality = WorstKnownQualityParameter.ActualValue.Value;
+
+        if (MaximizationParameter.ActualValue.Value) {
+          if (worseParentCrossoverPerformancePlot.Max == double.MinValue) {
+            worseParentCrossoverPerformancePlot.Max = bkQuality - wkQuality;
+            betterParentCrossoverPerformancePlot.Max = bkQuality - wkQuality;
+            parentQualityHelper.Max = bkQuality - wkQuality;
+            worseParentCrossoverPerformancePlot.Min = 0;
+            betterParentCrossoverPerformancePlot.Min = 0;
+            parentQualityHelper.Min = 0;
+          }
+        } else {
+          if (worseParentCrossoverPerformancePlot.Min == double.MaxValue) {
+            worseParentCrossoverPerformancePlot.Max = wkQuality - bkQuality;
+            betterParentCrossoverPerformancePlot.Max = wkQuality - bkQuality;
+            parentQualityHelper.Max = wkQuality - bkQuality;
+            worseParentCrossoverPerformancePlot.Min = 0;
+            betterParentCrossoverPerformancePlot.Min = 0;
+            parentQualityHelper.Min = 0;
+          }
+        }
+      }
+
       if (GenerationsParameter.ActualValue.Value != 0) {
         if (GenerationsParameter.ActualValue.Value > lastGeneration) {
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers-3.3.csproj
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers-3.3.csproj	(revision 9184)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers-3.3.csproj	(revision 9185)
@@ -113,4 +113,5 @@
     <Compile Include="CombinedOperators\QAPAfterMutationCombinedOperator.cs" />
     <Compile Include="CombinedOperators\QAPAfterCrossoverCombinedOperator.cs" />
+    <Compile Include="WorstQualityAnalyzer.cs" />
     <Compile Include="InitializableOperator.cs" />
     <Compile Include="SolutionToPopulationAnalyzer.cs" />
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/MutationPerformanceAnalyzer.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/MutationPerformanceAnalyzer.cs	(revision 9184)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/MutationPerformanceAnalyzer.cs	(revision 9185)
@@ -63,4 +63,10 @@
     public IValueParameter<ISingleObjectiveSolutionSimilarityCalculator> SimilarityCalculatorParameter {
       get { return (IValueParameter<ISingleObjectiveSolutionSimilarityCalculator>)Parameters["SimilarityCalculator"]; }
+    }
+    public ILookupParameter<DoubleValue> BestKnownQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
+    }
+    public ILookupParameter<DoubleValue> WorstKnownQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["WorstKnownQuality"]; }
     }
     #endregion
@@ -111,4 +117,6 @@
       Parameters.Add(new LookupParameter<ItemCollection<IItem>>("Operators", "The operators and items that the problem provides to the algorithms."));
       Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, false otherwise"));
+      Parameters.Add(new LookupParameter<DoubleValue>("BestKnownQuality", "The quality of the best known solution of this problem."));
+      Parameters.Add(new LookupParameter<DoubleValue>("WorstKnownQuality", "The quality of the worst known solution of this problem."));
 
       diversityPlotHelper = new ScatterPlotHelper(false, true);
@@ -157,4 +165,21 @@
       }
 
+      if (GenerationsParameter.ActualValue.Value == 1) {
+        double bkQuality = BestKnownQualityParameter.ActualValue.Value;
+        double wkQuality = WorstKnownQualityParameter.ActualValue.Value;
+
+        if (MaximizationParameter.ActualValue.Value) {
+          if (qualityPlotHelper.Max == double.MinValue) {
+            qualityPlotHelper.Max = bkQuality - wkQuality;
+            qualityPlotHelper.Min = 0;
+          }
+        } else {
+          if (qualityPlotHelper.Min == double.MaxValue) {
+            qualityPlotHelper.Max = wkQuality - bkQuality;
+            qualityPlotHelper.Min = 0;
+          }
+        }
+      }
+
       if (GenerationsParameter.ActualValue.Value != 0) {
         if (GenerationsParameter.ActualValue.Value > lastGeneration) {
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/ScatterPlotHelper.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/ScatterPlotHelper.cs	(revision 9184)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/ScatterPlotHelper.cs	(revision 9185)
@@ -52,6 +52,15 @@
     [Storable]
     private double min;
+    public double Min {
+      get { return min; }
+      set { min = value; }
+    }
     [Storable]
     private double max;
+    public double Max {
+      get { return max; }
+      set { max = value; }
+    }
+
     [Storable]
     private ResultCollection Results;
@@ -70,4 +79,11 @@
       StoreHistory = original.StoreHistory;
       CreateDataTable = original.CreateDataTable;
+      min = original.min;
+      max = original.max;
+
+      chartName = original.chartName;
+      chartName = original.chartName;
+      xAxisTitle = original.xAxisTitle;
+      yAxisTitle = original.yAxisTitle;
     }
 
@@ -120,9 +136,4 @@
 
     public void AddPoint(string rowName, Point2D<double> point) {
-      if (point.Y > max)
-        max = point.Y;
-      if (point.Y < min)
-        min = point.Y;
-
       if (!Plot.Rows.ContainsKey(rowName)) {
         if (StoreHistory)
@@ -166,4 +177,6 @@
         plot = null;
       }
+      min = double.MaxValue;
+      max = double.MinValue;
     }
   }
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SolutionToPopulationAnalyzer.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SolutionToPopulationAnalyzer.cs	(revision 9184)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SolutionToPopulationAnalyzer.cs	(revision 9185)
@@ -61,4 +61,10 @@
     public IValueParameter<StringValue> ChartPostfixParameter {
       get { return (IValueParameter<StringValue>)Parameters["ChartPostfix"]; }
+    }
+    public ILookupParameter<DoubleValue> BestKnownQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
+    }
+    public ILookupParameter<DoubleValue> WorstKnownQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["WorstKnownQuality"]; }
     }
     #endregion
@@ -99,4 +105,6 @@
       Parameters.Add(new LookupParameter<ItemCollection<IItem>>("Operators", "The operators and items that the problem provides to the algorithms."));
       Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, false otherwise"));
+      Parameters.Add(new LookupParameter<DoubleValue>("BestKnownQuality", "The quality of the best known solution of this problem."));
+      Parameters.Add(new LookupParameter<DoubleValue>("WorstKnownQuality", "The quality of the worst known solution of this problem."));
 
       populationDiversityPlot = new ScatterPlotHelper(false, true);
@@ -154,4 +162,25 @@
         }
 
+        if (GenerationsParameter.ActualValue.Value == 1) {
+          double bkQuality = BestKnownQualityParameter.ActualValue.Value;
+          double wkQuality = WorstKnownQualityParameter.ActualValue.Value;
+
+          if (MaximizationParameter.ActualValue.Value) {
+            if (populationQualityPlot.Max == double.MinValue) {
+              populationQualityPlot.Max = bkQuality - wkQuality;
+              qualityPlot.Max = bkQuality;
+              populationQualityPlot.Min = 0;
+              qualityPlot.Min = wkQuality;
+            }
+          } else {
+            if (populationQualityPlot.Min == double.MaxValue) {
+              populationQualityPlot.Max = wkQuality - bkQuality;
+              qualityPlot.Max = wkQuality;
+              populationQualityPlot.Min = 0;
+              qualityPlot.Min = bkQuality;
+            }
+          }
+        }
+
         Point2D<double> popQualityPoint;
         if (MaximizationParameter.ActualValue.Value) {
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/WorstQualityAnalyzer.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/WorstQualityAnalyzer.cs	(revision 9185)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/WorstQualityAnalyzer.cs	(revision 9185)
@@ -0,0 +1,114 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis.AlgorithmBehavior.Analyzers {
+  [Item("WorstQualityAnalyzer", "An operator that collects the worst quality found.")]
+  [StorableClass]
+  public class WorstQualityAnalyzer : SingleSuccessorOperator, IStatefulItem {
+    private const string GenerationsParameterName = "Generations";
+
+    public IValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ILookupParameter<ItemArray<DoubleValue>> ParentsQualityParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["ParentsQuality"]; }
+    }
+    public ILookupParameter<IntValue> GenerationsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters[GenerationsParameterName]; }
+    }
+    public ILookupParameter<DoubleValue> WorstKnownQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["WorstKnownQuality"]; }
+    }
+    [Storable]
+    private double upperBound = double.MinValue;
+
+    [StorableConstructor]
+    private WorstQualityAnalyzer(bool deserializing) : base(deserializing) { }
+    private WorstQualityAnalyzer(WorstQualityAnalyzer original, Cloner cloner)
+      : base(original, cloner) {
+      upperBound = (double)original.upperBound;
+    }
+
+    public WorstQualityAnalyzer()
+      : base() {
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("ParentsQuality", "The quality of the parent solutions."));
+      ParentsQualityParameter.ActualName = "TSPTourLength";
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, false otherwise"));
+      Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "Nr of generations."));
+      Parameters.Add(new LookupParameter<DoubleValue>("WorstKnownQuality", "The quality of the worst known solution of this problem."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new WorstQualityAnalyzer(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var qualityParent1 = ParentsQualityParameter.ActualValue.First().Value;
+      var qualityParent2 = ParentsQualityParameter.ActualValue.Last().Value;
+
+      if (GenerationsParameter.ActualValue.Value == 0) {
+        if (MaximizationParameter.ActualValue.Value) {
+          if (upperBound > qualityParent1) {
+            upperBound = qualityParent1;
+          }
+          if (upperBound > qualityParent2) {
+            upperBound = qualityParent2;
+          }
+        } else {
+          if (upperBound < qualityParent1) {
+            upperBound = qualityParent1;
+          }
+          if (upperBound < qualityParent2) {
+            upperBound = qualityParent2;
+          }
+        }
+      } else {
+        if (WorstKnownQualityParameter.ActualValue == null)
+          AddVariableToGlobalScope("WorstKnownQuality", "The quality of the worst known solution of this problem.", new DoubleValue(upperBound));
+      }
+
+      return base.Apply();
+    }
+
+    public override void ClearState() {
+      upperBound = double.MinValue;
+    }
+
+    public override void InitializeState() { }
+
+    private void AddVariableToGlobalScope(string name, string description, DoubleValue value) {
+      var globalScope = ExecutionContext;
+      while (globalScope.Parent != null) {
+        globalScope = globalScope.Parent;
+      }
+
+      globalScope.Scope.Variables.Add(new Variable(name, description, value));
+    }
+  }
+}
