Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/AlgorithmBehaviorUnitTests.csproj
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/AlgorithmBehaviorUnitTests.csproj	(revision 9731)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/AlgorithmBehaviorUnitTests.csproj	(revision 9754)
@@ -72,4 +72,5 @@
   </Choose>
   <ItemGroup>
+    <Compile Include="UnitTest2.cs" />
     <Compile Include="UnitTest1.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/UnitTest2.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/UnitTest2.cs	(revision 9754)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/UnitTest2.cs	(revision 9754)
@@ -0,0 +1,56 @@
+﻿using System.Linq;
+using HeuristicLab.Analysis.AlgorithmBehavior.Analyzers;
+using HeuristicLab.Encodings.PermutationEncoding;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace AlgorithmBehaviorUnitTests {
+  [TestClass]
+  public class UnitTest2 {
+    [TestMethod]
+    public void TestPermutationSolutionDictionary() {
+      var rand = new HeuristicLab.Random.FastRandom();
+      PermutationWrapperEqualityComparer comp = new PermutationWrapperEqualityComparer();
+      PermutationSolutionDictionary dict = new PermutationSolutionDictionary();
+      int realDuplicates = 0;
+      int noDuplicates = 0;
+
+      PermutationWrapper[] permutations = new PermutationWrapper[500];
+      for (int i = 0; i < permutations.Length; i += 2) {
+        var p = new Permutation(PermutationTypes.RelativeUndirected, 21, rand);
+        var pw = new PermutationWrapper(p);
+        permutations[i] = pw;
+        permutations[i + 1] = pw;
+
+        PermutationInformation pi = new PermutationInformation();
+        pi.Generation = rand.Next(0, 100);
+        pi.ProducedBy = ProducedBy.Mutation;
+
+        dict.Add(pw, pi);
+      }
+
+      for (int i = 0; i < permutations.Length; i++) {
+        for (int j = i + 1; j < permutations.Length; j++) {
+          if (comp.Equals(permutations[i], permutations[j])) {
+            realDuplicates++;
+            break;
+          }
+
+        }
+      }
+
+      for (int i = 0; i < dict.SolutionDictionary.Keys.Count; i++) {
+        for (int j = i + 1; j < dict.SolutionDictionary.Keys.Count; j++) {
+          if (comp.Equals(dict.SolutionDictionary.Keys.ElementAt(i), dict.SolutionDictionary.Keys.ElementAt(j))) {
+            noDuplicates++;
+            break;
+          }
+
+        }
+      }
+
+      Assert.AreNotEqual(0, realDuplicates);
+      Assert.AreEqual(0, noDuplicates);
+      Assert.AreEqual(250, dict.SolutionDictionary.Keys.Count);
+    }
+  }
+}
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers.Views/3.3/ConvexHullView.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers.Views/3.3/ConvexHullView.cs	(revision 9731)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers.Views/3.3/ConvexHullView.cs	(revision 9754)
@@ -30,5 +30,5 @@
 namespace HeuristicLab.Analysis.AlgorithmBehavior.Analyzers.Views {
   [View("ConvexHull View")]
-  [Content(typeof(PermutationSolutionDictionary<PermutationWrapper, PermutationInformation>), false)]
+  [Content(typeof(PermutationSolutionDictionary), false)]
   public partial class ConvexHullView : ItemView {
     public ConvexHullView() {
@@ -36,6 +36,6 @@
     }
 
-    public new PermutationSolutionDictionary<PermutationWrapper, PermutationInformation> Content {
-      get { return (PermutationSolutionDictionary<PermutationWrapper, PermutationInformation>)base.Content; }
+    public new PermutationSolutionDictionary Content {
+      get { return (PermutationSolutionDictionary)base.Content; }
       set { base.Content = value; }
     }
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers.Views/3.3/PermutationSolutionDictionaryView.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers.Views/3.3/PermutationSolutionDictionaryView.cs	(revision 9731)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers.Views/3.3/PermutationSolutionDictionaryView.cs	(revision 9754)
@@ -29,5 +29,5 @@
 namespace HeuristicLab.Analysis.AlgorithmBehavior.Analyzers.Views {
   [View("PermutationSolutionDictionary View")]
-  [Content(typeof(PermutationSolutionDictionary<PermutationWrapper, PermutationInformation>), true)]
+  [Content(typeof(PermutationSolutionDictionary), true)]
   public partial class PermutationSolutionDictionaryView : ItemView {
     public PermutationSolutionDictionaryView() {
@@ -35,6 +35,6 @@
     }
 
-    public new PermutationSolutionDictionary<PermutationWrapper, PermutationInformation> Content {
-      get { return (PermutationSolutionDictionary<PermutationWrapper, PermutationInformation>)base.Content; }
+    public new PermutationSolutionDictionary Content {
+      get { return (PermutationSolutionDictionary)base.Content; }
       set { base.Content = value; }
     }
@@ -55,5 +55,5 @@
     protected override void OnInitialized(EventArgs e) {
       base.OnInitialized(e);
-      var viewTypes = MainFormManager.GetViewTypes(typeof(PermutationSolutionDictionary<PermutationWrapper, PermutationInformation>), true);
+      var viewTypes = MainFormManager.GetViewTypes(typeof(PermutationSolutionDictionary), true);
       foreach (Type viewType in viewTypes.OrderBy(x => ViewAttribute.GetViewName(x))) {
         if ((viewType != typeof(PermutationSolutionDictionaryView)) && (viewType != typeof(ViewHost))) {
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 9731)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers-3.3.csproj	(revision 9754)
@@ -113,4 +113,5 @@
     <Compile Include="CombinedOperators\QAPAfterMutationCombinedOperator.cs" />
     <Compile Include="CombinedOperators\QAPAfterCrossoverCombinedOperator.cs" />
+    <Compile Include="SolutionsCaching\AfterCrossoverSolutionCachingAnalyzer.cs" />
     <Compile Include="SolutionsCaching\SolutionCachingAnalyzer.cs" />
     <Compile Include="SolutionsCaching\PermutationSolutionDictionary.cs" />
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SolutionsCaching/AfterCrossoverSolutionCachingAnalyzer.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SolutionsCaching/AfterCrossoverSolutionCachingAnalyzer.cs	(revision 9754)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SolutionsCaching/AfterCrossoverSolutionCachingAnalyzer.cs	(revision 9754)
@@ -0,0 +1,103 @@
+﻿#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.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis.AlgorithmBehavior.Analyzers {
+  [Item("AfterCrossoverSolutionCachingAnalyzer", "An operator that records solutions.")]
+  [StorableClass]
+  public class AfterCrossoverSolutionCachingAnalyzer : SingleSuccessorOperator {
+    private const string ResultsParameterName = "Results";
+
+    #region Parameter properties
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
+    }
+    public ILookupParameter<IntValue> GenerationsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["Generations"]; }
+    }
+    public ILookupParameter<Permutation> SolutionParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Solution"]; }
+    }
+    #endregion
+
+    #region Properties
+    public ResultCollection Results {
+      get { return ResultsParameter.ActualValue; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private AfterCrossoverSolutionCachingAnalyzer(bool deserializing) : base(deserializing) { }
+
+    private AfterCrossoverSolutionCachingAnalyzer(AfterCrossoverSolutionCachingAnalyzer original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    public AfterCrossoverSolutionCachingAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
+      Parameters.Add(new LookupParameter<IntValue>("Generations", "Nr of generations."));
+      Parameters.Add(new LookupParameter<Permutation>("Solution"));
+      SolutionParameter.ActualName = "TSPTour";
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new AfterCrossoverSolutionCachingAnalyzer(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var solution = SolutionParameter.ActualValue;
+      var parent2 = ExecutionContext.Scope.SubScopes.First();
+      var parent1 = ExecutionContext.Scope.SubScopes.Last();
+      PermutationSolutionDictionary solDict;
+
+      if (!Results.ContainsKey("SolutionCache")) {
+        solDict = new PermutationSolutionDictionary();
+        Results.Add(new Result("SolutionCache", solDict));
+      } else {
+        solDict = (PermutationSolutionDictionary)Results["SolutionCache"].Value;
+      }
+
+      PermutationInformation info = new PermutationInformation();
+      info.Generation = GenerationsParameter.ActualValue.Value;
+      info.ProducedBy = ProducedBy.Crossover;
+      info.ParentList = new List<PermutationWrapper>();
+      //TODO: solution name should be a parameter
+      var p1Pw = solDict.GetPermutationWrapperOfPermutation(parent1.Variables["TSPTour"].Value as Permutation);
+      var p2Pw = solDict.GetPermutationWrapperOfPermutation(parent2.Variables["TSPTour"].Value as Permutation);
+      info.ParentList.Add(p1Pw);
+      info.ParentList.Add(p2Pw);
+      solDict.Add(new PermutationWrapper(solution), info);
+
+      return base.Apply();
+    }
+  }
+}
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SolutionsCaching/PermutationSolutionDictionary.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SolutionsCaching/PermutationSolutionDictionary.cs	(revision 9731)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SolutionsCaching/PermutationSolutionDictionary.cs	(revision 9754)
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -30,19 +31,41 @@
   [Item("PermutationSolutionDictionary", "Stores permutations generated by an algorithm.")]
   [StorableClass]
-  public class PermutationSolutionDictionary<TKey, TValue> : SolutionDictionary<TKey, TValue>
-    where TKey : PermutationWrapper
-    where TValue : PermutationInformation {
+  public class PermutationSolutionDictionary : SolutionDictionary<PermutationWrapper, PermutationInformation> {
+    [Storable]
+    protected Dictionary<PermutationWrapper, List<PermutationInformation>> solutionDictionary;
+    public Dictionary<PermutationWrapper, List<PermutationInformation>> SolutionDictionary { get { return solutionDictionary; } }
 
     public PermutationSolutionDictionary() {
-      solutionDictionary = new Dictionary<TKey, List<TValue>>(new PermutationWrapperEqualityComparer());
+      solutionDictionary = new Dictionary<PermutationWrapper, List<PermutationInformation>>(new PermutationWrapperEqualityComparer());
     }
 
     [StorableConstructor]
     protected PermutationSolutionDictionary(bool deserializing) : base(deserializing) { }
-    protected PermutationSolutionDictionary(PermutationSolutionDictionary<TKey, TValue> original, Cloner cloner)
+    protected PermutationSolutionDictionary(PermutationSolutionDictionary original, Cloner cloner)
       : base(original, cloner) {
+      this.solutionDictionary = new Dictionary<PermutationWrapper, List<PermutationInformation>>(original.solutionDictionary, new PermutationWrapperEqualityComparer());
     }
 
-    protected override void InsertKeyValue(TKey key, TValue value) {
+    public override int Size() {
+      return solutionDictionary.Count;
+    }
+
+    public override void Add(PermutationWrapper key, PermutationInformation value) {
+      if (solutionDictionary.Count == 0) {
+        var lst = new List<PermutationInformation>();
+        lst.Add(value);
+        solutionDictionary.Add(key, lst);
+        return;
+      }
+
+      if (ContainsKey(key)) {
+        if (!solutionDictionary[key].Contains(value))
+          solutionDictionary[key].Add(value);
+      } else {
+        InsertKeyValue(key, value);
+      }
+    }
+
+    protected override void InsertKeyValue(PermutationWrapper key, PermutationInformation value) {
       int diffCnt;
       Permutation p = key.GetPermutation();
@@ -53,5 +76,5 @@
       }
 
-      var lst = new List<TValue>();
+      var lst = new List<PermutationInformation>();
       lst.Add(value);
       solutionDictionary.Add(key, lst);
@@ -81,6 +104,18 @@
     }
 
+    public PermutationWrapper GetPermutationWrapperOfPermutation(Permutation permutation) {
+      PermutationEqualityComparer peq = new PermutationEqualityComparer();
+      var res = solutionDictionary.Where(x => peq.GetHashCode(x.Key.GetPermutation()) == peq.GetHashCode(permutation));
+
+      //TODO: fix this
+      if (res.Count() > 1) {
+        throw new Exception("ERROR: Cannot conatin duplicates!");
+      }
+
+      return res.First().Key;
+    }
+
     public override IDeepCloneable Clone(Cloner cloner) {
-      return new PermutationSolutionDictionary<TKey, TValue>(this, cloner);
+      return new PermutationSolutionDictionary(this, cloner);
     }
 
@@ -96,4 +131,8 @@
       return solutionDictionary.Where(x => x.Value.Where(y => y.Generation == generation).Count() != 0).Select(x => x.Key).ToList<PermutationWrapper>();
     }
+
+    public override bool ContainsKey(PermutationWrapper key) {
+      return solutionDictionary.ContainsKey(key);
+    }
   }
 }
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SolutionsCaching/SolutionCachingAnalyzer.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SolutionsCaching/SolutionCachingAnalyzer.cs	(revision 9731)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SolutionsCaching/SolutionCachingAnalyzer.cs	(revision 9754)
@@ -79,11 +79,11 @@
     public override IOperation Apply() {
       ItemArray<Permutation> solutions = SolutionParameter.ActualValue;
-      PermutationSolutionDictionary<PermutationWrapper, PermutationInformation> solDict;
+      PermutationSolutionDictionary solDict;
 
       if (!Results.ContainsKey("SolutionCache")) {
-        solDict = new PermutationSolutionDictionary<PermutationWrapper, PermutationInformation>();
+        solDict = new PermutationSolutionDictionary();
         Results.Add(new Result("SolutionCache", solDict));
       } else {
-        solDict = (PermutationSolutionDictionary<PermutationWrapper, PermutationInformation>)Results["SolutionCache"].Value;
+        solDict = (PermutationSolutionDictionary)Results["SolutionCache"].Value;
       }
 
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SolutionsCaching/SolutionDictionary.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SolutionsCaching/SolutionDictionary.cs	(revision 9731)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SolutionsCaching/SolutionDictionary.cs	(revision 9754)
@@ -20,5 +20,4 @@
 #endregion
 
-using System.Collections.Generic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -31,10 +30,6 @@
   [NonDiscoverableType]
   public abstract class SolutionDictionary<TKey, TValue> : Item {
-    [Storable]
-    protected Dictionary<TKey, List<TValue>> solutionDictionary;
 
-    public SolutionDictionary() {
-      solutionDictionary = new Dictionary<TKey, List<TValue>>();
-    }
+    public SolutionDictionary() { }
 
     [StorableConstructor]
@@ -42,32 +37,13 @@
     protected SolutionDictionary(SolutionDictionary<TKey, TValue> original, Cloner cloner)
       : base(original, cloner) {
-      this.solutionDictionary = new Dictionary<TKey, List<TValue>>(original.solutionDictionary);
     }
 
-    public void Add(TKey key, TValue value) {
-      if (solutionDictionary.Count == 0) {
-        var lst = new List<TValue>();
-        lst.Add(value);
-        solutionDictionary.Add(key, lst);
-        return;
-      }
-
-      if (ContainsKey(key)) {
-        if (!solutionDictionary[key].Contains(value))
-          solutionDictionary[key].Add(value);
-      } else {
-        InsertKeyValue(key, value);
-      }
-    }
+    public abstract void Add(TKey key, TValue value);
 
     protected abstract void InsertKeyValue(TKey key, TValue value);
 
-    public virtual bool ContainsKey(TKey key) {
-      return solutionDictionary.ContainsKey(key);
-    }
+    public abstract bool ContainsKey(TKey key);
 
-    public int Size() {
-      return solutionDictionary.Count;
-    }
+    public abstract int Size();
   }
 }
