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 9053)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/AfterCrossoverCombinedOperator.cs	(revision 9054)
@@ -35,4 +35,7 @@
 
     [Storable]
+    protected SolutionToPopulationAnalyzer solToPopAnalyzer;
+
+    [Storable]
     protected VariableDuplicator varDuplicator;
 
@@ -50,4 +53,5 @@
       cxAnalyzer = original.cxAnalyzer != null ? (CrossoverPerformanceAnalyzer)original.cxAnalyzer.Clone(cloner) : null;
       varDuplicator = original.varDuplicator != null ? (VariableDuplicator)original.cxAnalyzer.Clone(cloner) : null;
+      solToPopAnalyzer = original.solToPopAnalyzer != null ? (SolutionToPopulationAnalyzer)original.solToPopAnalyzer.Clone(cloner) : null;
     }
 
@@ -73,8 +77,11 @@
       cxAnalyzer.SimilarityCalculatorParameter.Value = SimilarityCalculatorParameter.Value;
       varDuplicator = new VariableDuplicator();
+      solToPopAnalyzer = new SolutionToPopulationAnalyzer();
+      solToPopAnalyzer.ChartPostfixParameter.Value = new Data.StringValue("after Crossover");
 
       Operators.Add(EvaluatorParameter.ActualValue);
       Operators.Add(cxAnalyzer);
       Operators.Add(varDuplicator);
+      Operators.Add(solToPopAnalyzer);
     }
   }
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/AfterMutationCombinedOperator.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/AfterMutationCombinedOperator.cs	(revision 9053)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/AfterMutationCombinedOperator.cs	(revision 9054)
@@ -44,4 +44,6 @@
     [Storable]
     protected IEvaluator evaluatorClone;
+    [Storable]
+    protected SolutionToPopulationAnalyzer solToPopAnalyzer;
 
     [StorableConstructor]
@@ -49,6 +51,7 @@
     protected AfterMutationCombinedOperator(AfterMutationCombinedOperator original, Cloner cloner)
       : base(original, cloner) {
-      this.mAnalyzer = original.mAnalyzer != null ? (MutationPerformanceAnalyzer)original.mAnalyzer.Clone(cloner) : null;
-      this.varRemover = original.varRemover != null ? (VariableRemover)original.varRemover.Clone(cloner) : null;
+      mAnalyzer = original.mAnalyzer != null ? (MutationPerformanceAnalyzer)original.mAnalyzer.Clone(cloner) : null;
+      varRemover = original.varRemover != null ? (VariableRemover)original.varRemover.Clone(cloner) : null;
+      solToPopAnalyzer = original.solToPopAnalyzer != null ? (SolutionToPopulationAnalyzer)original.solToPopAnalyzer.Clone(cloner) : null;
     }
 
@@ -76,7 +79,11 @@
       varRemover = new VariableRemover();
 
+      solToPopAnalyzer = new SolutionToPopulationAnalyzer();
+      solToPopAnalyzer.ChartPostfixParameter.Value = new Data.StringValue("after Mutation");
+
       Operators.Add(evaluatorClone);
       Operators.Add(mAnalyzer);
       Operators.Add(varRemover);
+      Operators.Add(solToPopAnalyzer);
     }
   }
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 9053)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/QAPAfterCrossoverCombinedOperator.cs	(revision 9054)
@@ -60,4 +60,7 @@
       umAnalyzer.SolutionVariableName = "Assignment";
       cxAnalyzer.UnwantedMutationAnalyzerParameter.Value = umAnalyzer;
+
+      solToPopAnalyzer.SolutionParameter.ActualName = "Assignment";
+      solToPopAnalyzer.QualityParameter.ActualName = "Quality";
     }
   }
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/QAPAfterMutationCombinedOperator.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/QAPAfterMutationCombinedOperator.cs	(revision 9053)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/QAPAfterMutationCombinedOperator.cs	(revision 9054)
@@ -56,4 +56,6 @@
 
       varRemover.VariableNameParameter.Value.Value = "AssignmentClone";
+      solToPopAnalyzer.SolutionParameter.ActualName = "Assignment";
+      solToPopAnalyzer.QualityParameter.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 9053)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/TFAfterCrossoverCombinedOperator.cs	(revision 9054)
@@ -57,4 +57,6 @@
       varDuplicator.CloneParameter.ActualName = "PointClone";
 
+      solToPopAnalyzer.SolutionParameter.ActualName = "Point";
+      solToPopAnalyzer.QualityParameter.ActualName = "Quality";
       //TODO: add unwanted mutation analyzer for TF
     }
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/TFAfterMutationCombinedOperator.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/TFAfterMutationCombinedOperator.cs	(revision 9053)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/TFAfterMutationCombinedOperator.cs	(revision 9054)
@@ -58,4 +58,6 @@
 
       varRemover.VariableNameParameter.Value.Value = "PointClone";
+      solToPopAnalyzer.SolutionParameter.ActualName = "Point";
+      solToPopAnalyzer.QualityParameter.ActualName = "Quality";
     }
   }
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 9053)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/VRPAfterCrossoverCombinedOperator.cs	(revision 9054)
@@ -56,4 +56,7 @@
       varDuplicator.OriginalParameter.ActualName = "VRPTours";
       varDuplicator.CloneParameter.ActualName = "VRPToursClone";
+
+      solToPopAnalyzer.SolutionParameter.ActualName = "VRPTours";
+      solToPopAnalyzer.QualityParameter.ActualName = "Quality";
     }
   }
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/VRPAfterMutationCombinedOperator.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/VRPAfterMutationCombinedOperator.cs	(revision 9053)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CombinedOperators/VRPAfterMutationCombinedOperator.cs	(revision 9054)
@@ -56,4 +56,6 @@
 
       varRemover.VariableNameParameter.Value.Value = "VRPToursClone";
+      solToPopAnalyzer.SolutionParameter.ActualName = "VRPTours";
+      solToPopAnalyzer.QualityParameter.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 9053)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/CrossoverPerformanceAnalyzer.cs	(revision 9054)
@@ -73,18 +73,19 @@
       get { return ResultsParameter.ActualValue; }
     }
+
+    [Storable]
+    private ScatterPlotHelper worseParentCrossoverPerformancePlot, betterParentCrossoverPerformancePlot, childDiversityToWorseParentHelper, childDiversityToBetterParentHelper, parentDiversityHelper, parentQualityHelper, unwantedMutationsHelper;
+    [Storable]
+    private DataTableHelper successHelper, equalParentsHelper;
+    [Storable]
+    private int cnt = 0;
+    [Storable]
+    private int[] success;
+    [Storable]
+    private int lastGeneration = 0;
+    [Storable]
+    private int equalParents = 0;
     #endregion
 
-    [Storable]
-    private ScatterPlotHelper worseParentCrossoverPerformancePlot, betterParentCrossoverPerformancePlot, childDiversityToWorseParentHelper, childDiversityToBetterParentHelper, parentDiversityHelper, parentQualityHelper, unwantedMutationsHelper;
-    [Storable]
-    private DataTableHelper successHelper, equalParentsHelper;
-    [Storable]
-    private int cnt = 0;
-    [Storable]
-    private int[] success;
-    [Storable]
-    private int lastGeneration = 0;
-    [Storable]
-    private int equalParents = 0;
 
     [StorableConstructor]
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 9053)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers-3.3.csproj	(revision 9054)
@@ -134,4 +134,5 @@
     <Compile Include="CombinedOperators\QAPAfterCrossoverCombinedOperator.cs" />
     <Compile Include="InitializableOperator.cs" />
+    <Compile Include="SolutionToPopulationAnalyzer.cs" />
     <Compile Include="UnwantedMutationAnalyzers\PermutationUnwantedMutationAnalyzer.cs" />
     <Compile Include="UnwantedMutationAnalyzers\IUnwantedMutationAnalyzer.cs" />
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 9054)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SolutionToPopulationAnalyzer.cs	(revision 9054)
@@ -0,0 +1,181 @@
+﻿#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;
+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.AlgorithmBehavior.Analyzers {
+  [Item("SolutionToPopulationAnalyzer", "An operator that analyzes the diversity of solutions compared to the population.")]
+  [StorableClass]
+  public class SolutionToPopulationAnalyzer : InitializableOperator, IStatefulItem {
+    private const string ResultsParameterName = "Results";
+    private const string GenerationsParameterName = "Generations";
+
+    #region Parameter properties
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
+    }
+    public ILookupParameter<IntValue> GenerationsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters[GenerationsParameterName]; }
+    }
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<IItem> SolutionParameter {
+      get { return (ILookupParameter<IItem>)Parameters["Solution"]; }
+    }
+    public ILookupParameter<ItemCollection<IItem>> OperatorsParameter {
+      get { return (ILookupParameter<ItemCollection<IItem>>)Parameters["Operators"]; }
+    }
+    public IValueParameter<ISingleObjectiveSolutionSimilarityCalculator> SimilarityCalculatorParameter {
+      get { return (IValueParameter<ISingleObjectiveSolutionSimilarityCalculator>)Parameters["SimilarityCalculator"]; }
+    }
+    public IValueParameter<StringValue> ChartPostfixParameter {
+      get { return (IValueParameter<StringValue>)Parameters["ChartPostfix"]; }
+    }
+    #endregion
+
+    #region Properties
+    public ResultCollection Results {
+      get { return ResultsParameter.ActualValue; }
+    }
+    [Storable]
+    private ScatterPlotHelper populationDiversityPlot, populationQualityPlot;
+    [Storable]
+    private int cnt = 0;
+    [Storable]
+    private int lastGeneration = 0;
+    #endregion
+
+    [StorableConstructor]
+    private SolutionToPopulationAnalyzer(bool deserializing) : base(deserializing) { }
+    private SolutionToPopulationAnalyzer(SolutionToPopulationAnalyzer original, Cloner cloner)
+      : base(original, cloner) {
+      cnt = original.cnt;
+      lastGeneration = original.lastGeneration;
+      populationDiversityPlot = (ScatterPlotHelper)populationDiversityPlot.Clone(cloner);
+      populationQualityPlot = (ScatterPlotHelper)populationQualityPlot.Clone(cloner);
+    }
+
+    public SolutionToPopulationAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
+      Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "Nr of generations."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The evaluated quality of the child solution."));
+      QualityParameter.ActualName = "TSPTourLength";
+      Parameters.Add(new LookupParameter<IItem>("Solution"));
+      SolutionParameter.ActualName = "TSPTour";
+      Parameters.Add(new ValueParameter<ISingleObjectiveSolutionSimilarityCalculator>("SimilarityCalculator"));
+      Parameters.Add(new ValueParameter<StringValue>("ChartPostfix", new StringValue(string.Empty)));
+      Parameters.Add(new LookupParameter<ItemCollection<IItem>>("Operators", "The operators and items that the problem provides to the algorithms."));
+
+      populationDiversityPlot = new ScatterPlotHelper(false, true);
+      populationQualityPlot = new ScatterPlotHelper(false, true);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SolutionToPopulationAnalyzer(this, cloner);
+    }
+
+    protected override void InitializeAction() {
+      if (SimilarityCalculatorParameter.Value == null) {
+        SimilarityCalculatorParameter.Value = OperatorsParameter.ActualValue.OfType<ISingleObjectiveSolutionSimilarityCalculator>().FirstOrDefault();
+      }
+
+      populationDiversityPlot.InitializePlot(Results, "Solution to Population Diversity " + ChartPostfixParameter.Value.Value, "Solution Index", "Diversity");
+      populationQualityPlot.InitializePlot(Results, "Solution Quality Difference to Population " + ChartPostfixParameter.Value.Value, "Solution Index", "Quality Difference");
+
+      Reset();
+    }
+
+    public override IOperation Apply() {
+      Initialize();
+
+      string curGenStr = GenerationsParameter.ActualValue.Value.ToString();
+      double quality = QualityParameter.ActualValue.Value;
+      IItem solution = SolutionParameter.ActualValue;
+      string qualityVariableName = QualityParameter.ActualName;
+      string solutionVariableName = SolutionParameter.ActualName;
+      ISingleObjectiveSolutionSimilarityCalculator simCalc = SimilarityCalculatorParameter.Value;
+      Scope artificialSolutionScope = new Scope();
+      artificialSolutionScope.Variables.Add(new Variable(solutionVariableName, solution));
+
+
+      IScope oldPop = ReverseScopeTreeLookup("Remaining");
+      if (oldPop == null)
+        throw new Exception("Couldn't find the remaining scope");
+
+      if (GenerationsParameter.ActualValue.Value != 0) {
+        if (GenerationsParameter.ActualValue.Value > lastGeneration) {
+          Reset();
+        }
+
+        double oldPopQuality = 0.0;
+        double solToPopDiversity = 0.0;
+        int popSize = 0;
+        foreach (IScope oldSolScope in oldPop.SubScopes) {
+          double curQuality = ((DoubleValue)oldSolScope.Variables[qualityVariableName].Value).Value;
+          IItem curSol = oldSolScope.Variables[solutionVariableName].Value;
+          oldPopQuality += curQuality;
+          solToPopDiversity += simCalc.CalculateSolutionSimilarity(artificialSolutionScope, oldSolScope);
+          popSize++;
+        }
+
+        var diversityPoint = new Point2D<double>(cnt++, solToPopDiversity / popSize);
+        var qualityPoint = new Point2D<double>(cnt, Math.Abs((oldPopQuality / popSize) - quality));
+
+        populationDiversityPlot.AddPoint(curGenStr, diversityPoint);
+        populationQualityPlot.AddPoint(curGenStr, qualityPoint);
+      }
+
+      return base.Apply();
+    }
+
+    private void Reset() {
+      cnt = 0;
+      lastGeneration = GenerationsParameter.ActualValue.Value;
+    }
+
+    public override void ClearState() {
+      populationQualityPlot.CleanUp();
+      populationDiversityPlot.CleanUp();
+    }
+
+    private IScope ReverseScopeTreeLookup(string scopeName) {
+      var currentScope = ExecutionContext.Scope;
+      while (currentScope != null) {
+        var scopes = currentScope.SubScopes.Where(x => x.Name == scopeName);
+        if (scopes.Count() > 0)
+          return scopes.First();
+
+        currentScope = currentScope.Parent;
+      }
+      return null;
+    }
+  }
+}
