Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/CutPoint.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/CutPoint.cs	(revision 7779)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/CutPoint.cs	(revision 7785)
@@ -64,4 +64,29 @@
       }
     }
+
+    public static CutPoint GetCutPoint(ISymbolicExpressionTree parent, ISymbolicExpressionTree child) {
+      return GetCutPoint(parent.Root, child.Root);
+    }
+
+    public static CutPoint GetCutPoint(ISymbolicExpressionTree parent, ISymbolicExpressionTreeNode child) {
+      return GetCutPoint(parent.Root, child);
+    }
+
+    public static CutPoint GetCutPoint(ISymbolicExpressionTreeNode parent, ISymbolicExpressionTree child) {
+      return GetCutPoint(parent, child.Root);
+    }
+
+    // child is the result of a genetic operation on parent
+    // this method returns the index on which the two individuals start to differ
+    public static CutPoint GetCutPoint(ISymbolicExpressionTreeNode parent, ISymbolicExpressionTreeNode child) {
+      var e1 = parent.IterateNodesPostfix().GetEnumerator();
+      var e2 = child.IterateNodesPostfix().GetEnumerator();
+      int pos = -1;
+      var comparer = new SymbolicExpressionTreeNodeComparer((int)SymbolicExpressionTreeMatching.SimilarityLevel.Exact);
+      while (e1.MoveNext() && e2.MoveNext())
+        if (comparer.Equals(e1.Current, e2.Current))
+          ++pos;
+      return pos == -1 ? null : new CutPoint(parent, pos);
+    }
   }
 }
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj	(revision 7779)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj	(revision 7785)
@@ -133,4 +133,8 @@
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
     </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis.Symbolic-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.dll</HintPath>
+    </Reference>
     <Reference Include="HeuristicLab.Random-3.3">
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Random-3.3.dll</HintPath>
@@ -174,4 +178,5 @@
     </Compile>
     <Compile Include="Creators\RampedHalfAndHalfTreeCreator.cs" />
+    <Compile Include="Crossovers\AssortativeSymbolicExpressionTreeCrossover.cs" />
     <Compile Include="Crossovers\TracingSymbolicExpressionTreeCrossover.cs" />
     <Compile Include="Interfaces\IReadOnlySymbol.cs" />
@@ -206,4 +211,5 @@
     <Compile Include="SymbolicExpressionGrammar.cs" />
     <Compile Include="SymbolicExpressionTreeGrammar.cs" />
+    <Compile Include="SymbolicExpressionTreeMatching.cs" />
     <Compile Include="SymbolicExpressionTreeTopLevelNode.cs" />
     <Compile Include="Crossovers\SubtreeCrossover.cs">
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj.user
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj.user	(revision 7779)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj.user	(revision 7785)
@@ -7,5 +7,5 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
     <StartAction>Program</StartAction>
-    <StartProgram>C:\Users\bburlacu\Desktop\HL-Core\trunk\sources\bin\HeuristicLab 3.3.exe</StartProgram>
+    <StartProgram>C:\Users\Bogdan\Desktop\Trunk\sources\bin\HeuristicLab 3.3.exe</StartProgram>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Plugin.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Plugin.cs	(revision 7779)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Plugin.cs	(revision 7785)
@@ -26,5 +26,5 @@
 
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
-  [Plugin("HeuristicLab.Encodings.SymbolicExpressionTreeEncoding","Provides operators and related classes for the symbolic expression tree encoding.", "3.4.2.7522")]
+  [Plugin("HeuristicLab.Encodings.SymbolicExpressionTreeEncoding","Provides operators and related classes for the symbolic expression tree encoding.", "3.4.2.7779")]
   [PluginFile("HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.dll", PluginFileType.Assembly)]
   [PluginDependency("HeuristicLab.Analysis", "3.3")]
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeMatching.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeMatching.cs	(revision 7785)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeMatching.cs	(revision 7785)
@@ -0,0 +1,163 @@
+﻿using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
+  public class SymbolicExpressionTreeNodeComparer : IEqualityComparer<ISymbolicExpressionTreeNode> {
+
+    public SymbolicExpressionTreeNodeComparer(int similarityLevel) {
+      _similarityLevel = similarityLevel;
+    }
+
+    public int GetHashCode(ISymbolicExpressionTreeNode n) {
+      return n.ToString().ToLower().GetHashCode();
+    }
+
+    public bool Equals(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
+      if (a.SubtreeCount != b.SubtreeCount) { return false; }
+      if (a.SubtreeCount > 0) { return a.Symbol.ToString().Equals(b.Symbol.ToString()); }
+      // compare leaf nodes according to desired similarity level
+      switch (_similarityLevel) {
+        case ((int)SymbolicExpressionTreeMatching.SimilarityLevel.Exact):
+          if (a is ConstantTreeNode && b is ConstantTreeNode) {
+            return ((ConstantTreeNode)a).Value.Equals(((ConstantTreeNode)b).Value);
+          }
+          if (a is VariableTreeNode && b is VariableTreeNode) {
+            return (a as VariableTreeNode).Weight.Equals((b as VariableTreeNode).Weight);
+          }
+          return false;
+        case ((int)SymbolicExpressionTreeMatching.SimilarityLevel.High):
+          return (a is ConstantTreeNode && b is ConstantTreeNode) || (a is VariableTreeNode && b is VariableTreeNode);
+        case ((int)SymbolicExpressionTreeMatching.SimilarityLevel.Relaxed):
+          return true;
+        default:
+          return false;
+      }
+    }
+
+    private readonly int _similarityLevel;
+  }
+
+  // tree equality
+  public class SymbolicExpressionTreeComparer : IEqualityComparer<ISymbolicExpressionTree> {
+    public bool Equals(ISymbolicExpressionTree a, ISymbolicExpressionTree b) {
+      return SymbolicExpressionTreeMatching.FindMatch(a, b, _mode) == 0;
+    }
+
+    public int GetHashCode(ISymbolicExpressionTree tree) {
+      return tree.Length;
+    }
+
+    private int _mode;
+    public void SetComparisonMode(int mode) {
+      _mode = mode;
+    }
+  }
+
+  public static class SymbolicExpressionTreeMatching {
+    public enum SimilarityLevel {
+      Exact,   // everything is matched bit by bit (functions and terminals)
+      High,    // symbols are matched. leaf node types are matched
+      Relaxed  // only symbols are matched, leafs count as wildcards
+    }
+
+    public static bool IsSimilarTo(this ISymbolicExpressionTree t1, ISymbolicExpressionTree t2, int mode) {
+      return FindMatch(t1, t2, mode) == 0;
+    }
+    public static bool IsSimilarTo(this ISymbolicExpressionTreeNode t1, ISymbolicExpressionTreeNode t2, int mode) {
+      return FindMatch(t1, t2, mode) == 0;
+    }
+
+    public static bool ContainsFragment(this ISymbolicExpressionTree tree, ISymbolicExpressionTreeNode fragment, int mode) {
+      var nodes = tree.IterateNodesPostfix().ToArray();
+      var fragments = fragment.IterateNodesPostfix().ToArray();
+      return FindMatch(nodes, fragments, mode) != -1;
+    }
+
+    #region FindMatch signatures
+    public static int FindMatch(ISymbolicExpressionTree t0, ISymbolicExpressionTree t1, int mode) {
+      return FindMatch(t0.IterateNodesPostfix().ToArray(), t1.IterateNodesPostfix().ToArray(), mode);
+    }
+    private static int FindMatch(ISymbolicExpressionTreeNode t0, ISymbolicExpressionTreeNode t1, int mode) {
+      return FindMatch(t0.IterateNodesPostfix().ToArray(), t1.IterateNodesPostfix().ToArray(), mode);
+    }
+    private static int FindMatch(ISymbolicExpressionTree t0, ISymbolicExpressionTreeNode t1, int mode) {
+      return FindMatch(t0.IterateNodesPostfix().ToArray(), t1.IterateNodesPostfix().ToArray(), mode);
+    }
+    private static int FindMatch(ISymbolicExpressionTreeNode t0, ISymbolicExpressionTree t1, int mode) {
+      return FindMatch(t0.IterateNodesPostfix().ToArray(), t1.IterateNodesPostfix().ToArray(), mode);
+    }
+    #endregion
+
+    // convenience methods for less typing :)
+    private static IEnumerator<ISymbolicExpressionTreeNode> Enumerator(this ISymbolicExpressionTree tree) {
+      return tree.IterateNodesPostfix().GetEnumerator();
+    }
+    private static IEnumerator<ISymbolicExpressionTreeNode> Enumerator(this ISymbolicExpressionTreeNode tree) {
+      return tree.IterateNodesPostfix().GetEnumerator();
+    }
+    // method for breath-width iteration of nodes
+    private static IEnumerable<ISymbolicExpressionTreeNode> IterateNodes(this ISymbolicExpressionTree tree) {
+      return IterateNodes(tree.Root);
+    }
+
+    private static IEnumerable<ISymbolicExpressionTreeNode> IterateNodes(this ISymbolicExpressionTreeNode root) {
+      var list = new List<ISymbolicExpressionTreeNode> { root };
+      int offset = 0, count = 1;
+      while (offset != count) {
+        var c = count;
+        for (int i = offset; i != count; ++i) {
+          yield return list[i]; // TODO: look into yield performance (vs returning the whole list at the end)
+          if (!list[i].Subtrees.Any()) continue;
+          list.AddRange(list[i].Subtrees);
+        }
+        offset = c;
+        count = list.Count;
+      }
+      //return list;
+    }
+
+    /// <summary>
+    /// This method finds the point where parent and child differ. For instance in the case of crossover, 
+    /// it will return the node that was swapped into parent0 from parent1
+    /// Prerequisites: as the naming implies, heredity should exist between parent and child,
+    /// otherwise this method would not make much sense (it would always return the root of child)
+    /// </summary>
+    /// <param name="parent">The individual from the previous generation that was crossed over or mutated to produce child</param>
+    /// <param name="child">The result of a genetic operation applied on parent</param>
+    /// <returns>A symbolic expression tree node representing the difference fragment between parent and child</returns>
+    public static ISymbolicExpressionTreeNode GetFragmentDiff(ISymbolicExpressionTree parent, ISymbolicExpressionTree child) {
+      var e1 = parent.Enumerator();
+      var e2 = child.Enumerator();
+      while (e1.MoveNext() && e2.MoveNext()) {
+        var comparer = new SymbolicExpressionTreeNodeComparer((int)SimilarityLevel.Exact);
+        if (!comparer.Equals(e1.Current, e2.Current)) { return e2.Current; } // return the fragment by which child differs from parent
+      }
+      return null;
+    }
+
+    // returns the index in the sequence 'seq', where pattern 'pat' is matched, or -1 for no match
+    // -1 means no match, 0 means perfect match (the sequences overlap, hence the match index is 0)
+    public static int FindMatch(ISymbolicExpressionTreeNode[] seq, ISymbolicExpressionTreeNode[] pat, int mode) {
+      int patlen = pat.Length;
+      int seqlen = seq.Length;
+      if (patlen == 0 || seqlen == 0) return -1;
+      var comparer = new SymbolicExpressionTreeNodeComparer(mode);
+      if (patlen == seqlen) return seq.SequenceEqual(pat, comparer) ? 0 : -1;
+      //int i = patlen;            
+      //while (i <= seqlen) {
+      //  var ch = seq[i - 1];
+      //  if (comparer.Equals(ch, pat.Last()))
+      //    if (seq.Skip(i - patlen).Take(patlen).SequenceEqual(pat, comparer))
+      //      return i - patlen;
+      //  ++i;
+      //}
+      for (int i = patlen; i <= seqlen; ++i) {
+        if (comparer.Equals(seq[i - 1], pat.Last())) // first check if last element is a match
+          if (seq.Skip(i - patlen).Take(patlen).SequenceEqual(pat, comparer)) // then check the whole sequence
+            return i - patlen;
+      }
+      return -1;
+    }
+  }
+}
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/GenealogyGraphChart.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/GenealogyGraphChart.cs	(revision 7779)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/GenealogyGraphChart.cs	(revision 7785)
@@ -177,5 +177,5 @@
           foreach (var node in ancestors.SelectMany(n => _visualNodeMap[n])) {
             node.Brush = new SolidBrush(node.ToColor());
-            if (node.IncomingArcs != null && node == _visualNodeMap[node.Data].First())
+            if (node.IncomingArcs != null && node == _visualNodeMap[node.Data].First()) {
               foreach (var arc in node.IncomingArcs) {
                 if (arc.Source.Data == node.Data) continue;
@@ -183,5 +183,6 @@
                 var end = new Point((int)arc.End.X, (int)arc.End.Y);
                 arc.Pen.Brush = new LinearGradientBrush(start, end, arc.Source.ToColor(), arc.Target.ToColor());
-                if (node.Data.CutpointIndex == -1) { // if the cut index wasn't computed yet
+                if (node.Data.CutpointIndex == -1) {
+                  // if the cut index wasn't computed yet
                   var parent = arc.Source.Data.Data as ISymbolicExpressionTree;
                   var child = node.Data.Data as ISymbolicExpressionTree;
@@ -189,4 +190,5 @@
                 }
               }
+            }
           }
           // highlight the descendants
@@ -208,5 +210,7 @@
         Chart.UpdateEnabled = true;
         Chart.EnforceUpdate();
-        if (_selectedGenealogyGraphNode != null) /* emit clicked event */ OnGenealogyGraphNodeClicked(_selectedGenealogyGraphNode, e);
+        if (_selectedGenealogyGraphNode != null)
+          /* emit clicked event */
+          OnGenealogyGraphNodeClicked(_selectedGenealogyGraphNode, e);
       }
     }
@@ -238,8 +242,11 @@
       var e1 = parent.IterateNodesPostfix().GetEnumerator();
       var e2 = child.IterateNodesPostfix().GetEnumerator();
-      int pos = -1;
-      var comparer = new SymbolicExpressionTreeGenealogyGraph.SymbolicExpressionTreeNodeComparer(0);
+      int pos = 0;
+      var comparer = new SymbolicExpressionTreeNodeComparer((int)SymbolicExpressionTreeMatching.SimilarityLevel.Exact);
       while (e1.MoveNext() && e2.MoveNext() && comparer.Equals(e1.Current, e2.Current)) ++pos;
+      if (pos == 0) return -1;
+      if (pos == child.Length) return 0;
       return pos;
+      //return pos == 0 ? -1 : pos;
     }
   }
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/GenealogyGraphView.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/GenealogyGraphView.cs	(revision 7779)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/GenealogyGraphView.cs	(revision 7785)
@@ -94,5 +94,5 @@
         var nodes = symbolicExpressionTreeChart.Tree.IterateNodesPostfix().ToArray();
         var fragments = _selectedVisualSymbolicExpressionTreeNode.SymbolicExpressionTreeNode.IterateNodesPostfix().ToArray();
-        int index = SymbolicExpressionTreeGenealogyGraph.FindMatch(nodes, fragments, similarityModeSelector.SelectedIndex);
+        int index = SymbolicExpressionTreeMatching.FindMatch(nodes, fragments, similarityModeSelector.SelectedIndex);
         if (index != -1) {
           _selectedVisualSymbolicExpressionTreeNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(nodes[index + fragments.Count() - 1]);
@@ -143,5 +143,5 @@
       genealogyGraphChart.ClearAllNodes(); // clear node colors
       // color each graph node according to the degree to which it matches the selected tree fragment
-      foreach (var i in Enum.GetValues(typeof(SymbolicExpressionTreeGenealogyGraph.SimilarityLevel)).Cast<int>().Reverse()) {
+      foreach (var i in Enum.GetValues(typeof(SymbolicExpressionTreeMatching.SimilarityLevel)).Cast<int>().Reverse()) {
         var owners = genealogyGraphChart.Graph.TraceFragment(treeNode, i).ToList();
         if (owners.Any()) genealogyGraphChart.HighlightNodes(owners, colors[i]); // highlight matching individuals from the genealogy
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreeFragmentsAnalyzer.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreeFragmentsAnalyzer.cs	(revision 7785)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreeFragmentsAnalyzer.cs	(revision 7785)
@@ -0,0 +1,331 @@
+﻿#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.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+// type definitions for ease of use
+using CloneMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItem>;
+using TraceMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItemList<HeuristicLab.Core.IItem>>;
+
+namespace HeuristicLab.EvolutionaryTracking {
+  /// <summary>
+  /// An operator that gathers information on tree fragments that get passed from one generation to the next via genetic operators
+  /// (Tracking of genetic variance and heredity)
+  /// </summary>
+  /// [Item("SymbolicExpressionTreeGenealogyAnalyzer", "An operator that tracks tree lengths of Symbolic Expression Trees")]
+  [StorableClass]
+  public sealed class SymbolicExpressionTreeFragmentsAnalyzer : SingleSuccessorOperator, IAnalyzer {
+    private const string UpdateIntervalParameterName = "UpdateInterval";
+    private const string UpdateCounterParameterName = "UpdateCounter";
+    private const string ResultsParameterName = "Results";
+    private const string GlobalTraceMapParameterName = "GlobalTraceMap";
+    private const string GlobalCloneMapParameterName = "GlobalCloneMap";
+    private const string GenerationsParameterName = "Generations";
+    private const string FragmentStatisticsParameterName = "FragmentStatistics";
+
+    #region Parameter properties
+    public ValueParameter<IntValue> UpdateIntervalParameter {
+      get { return (ValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; }
+    }
+    public ValueParameter<IntValue> UpdateCounterParameter {
+      get { return (ValueParameter<IntValue>)Parameters[UpdateCounterParameterName]; }
+    }
+    public LookupParameter<ResultCollection> ResultsParameter {
+      get { return (LookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
+    }
+    public LookupParameter<TraceMapType> GlobalTraceMapParameter {
+      get { return (LookupParameter<TraceMapType>)Parameters[GlobalTraceMapParameterName]; }
+    }
+    public LookupParameter<CloneMapType> GlobalCloneMapParameter {
+      get { return (LookupParameter<CloneMapType>)Parameters[GlobalCloneMapParameterName]; }
+    }
+    public LookupParameter<IntValue> GenerationsParameter {
+      get { return (LookupParameter<IntValue>)Parameters[GenerationsParameterName]; }
+    }
+    public LookupParameter<DataTable> FragmentStatisticsParameter {
+      get { return (LookupParameter<DataTable>)Parameters[FragmentStatisticsParameterName]; }
+
+    }
+    #endregion
+
+    #region Parameters
+    public bool EnabledByDefault {
+      get { return true; }
+    }
+    public IntValue UpdateInterval {
+      get { return UpdateIntervalParameter.Value; }
+    }
+    public IntValue UpdateCounter {
+      get { return UpdateCounterParameter.Value; }
+    }
+    public ResultCollection Results {
+      get { return ResultsParameter.ActualValue; }
+    }
+    public CloneMapType GlobalCloneMap {
+      get { return GlobalCloneMapParameter.ActualValue; }
+    }
+    public TraceMapType GlobalTraceMap {
+      get { return GlobalTraceMapParameter.ActualValue; }
+    }
+    public IntValue Generations {
+      get { return GenerationsParameter.ActualValue; }
+    }
+    public DataTable FragmentStatistics {
+      get { return FragmentStatisticsParameter.ActualValue; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private SymbolicExpressionTreeFragmentsAnalyzer(bool deserializing)
+      : base() {
+    }
+    private SymbolicExpressionTreeFragmentsAnalyzer(SymbolicExpressionTreeFragmentsAnalyzer original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicExpressionTreeFragmentsAnalyzer(this, cloner);
+    }
+    public SymbolicExpressionTreeFragmentsAnalyzer()
+      : base() {
+      Parameters.Add(new ValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
+      Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called since the last update", new IntValue(0)));
+      Parameters.Add(new LookupParameter<TraceMapType>(GlobalTraceMapParameterName, "A global cache containing the whole genealogy."));
+      Parameters.Add(new LookupParameter<CloneMapType>(GlobalCloneMapParameterName, "A global map keeping track of trees and their clones (made during selection)."));
+      Parameters.Add(new ValueLookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
+      Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "The number of generations so far."));
+      Parameters.Add(new LookupParameter<DataTable>(FragmentStatisticsParameterName, "The data table to store the fragment statistics."));
+      UpdateCounterParameter.Hidden = true;
+      UpdateIntervalParameter.Hidden = true;
+    }
+    #region After deserialization code
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // check if all the parameters are present and accounted for 
+      if (!Parameters.ContainsKey(UpdateIntervalParameterName)) {
+        Parameters.Add(new ValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
+      }
+      if (Parameters.ContainsKey(UpdateCounterParameterName)) return;
+      Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called since the last update", new IntValue(0)));
+      UpdateCounterParameter.Hidden = true;
+    }
+    #endregion
+    #region IStatefulItem members
+    public override void InitializeState() {
+      base.InitializeState();
+      UpdateCounter.Value = 0;
+    }
+
+    public override void ClearState() {
+      base.ClearState();
+      UpdateCounter.Value = 0;
+    }
+    #endregion
+
+    public override IOperation Apply() {
+      if (Generations.Value == 0) return base.Apply();
+      UpdateCounter.Value++;
+      if (UpdateCounter.Value == UpdateInterval.Value) {
+        ResultCollection results = ResultsParameter.ActualValue;
+        if (FragmentStatistics == null) {
+          FragmentStatisticsParameter.ActualValue = new DataTable("Fragment Statistics", "Statistical measurements of fragments aggregated over the whole population");
+          FragmentStatistics.VisualProperties.YAxisTitle = "Fragment length/Similarities";
+          results.Add(new Result("Fragment Statistics", FragmentStatistics));
+        }
+
+        int numberOfValues = FragmentStatistics.Rows.Select(r => r.Values.Count).DefaultIfEmpty().First();
+
+        UpdateCounter.Value = 0; // reset counter
+        var gScope = ExecutionContext.Scope;
+        while (gScope.Parent != null) gScope = gScope.Parent;
+
+        #region Fragment Statistics
+        // write these to file for now, later we will use a DataTable and display the results inside HeuristicLab
+        var path = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
+        //using (var file = System.IO.File.AppendText(path + @"\tracking.csv")) {
+        var fragments = new List<ISymbolicExpressionTreeNode>();
+        var parents = new List<ISymbolicExpressionTree>();
+        double best = gScope.SubScopes.Select(x => x.Variables["Quality"].Value as DoubleValue).Max(x => x.Value);
+        var trees = (from s in gScope.SubScopes select s.Variables.First().Value as ISymbolicExpressionTree).ToList();
+        foreach (var tree in trees.Where(x => GlobalTraceMap.ContainsKey(x))) {
+          var parent0 = (ISymbolicExpressionTree)GlobalTraceMap[tree][0];
+          var fragment = SymbolicExpressionTreeMatching.GetFragmentDiff(parent0, tree);
+          if (fragment != null) {
+            parents.Add(parent0);
+            fragments.Add(fragment);
+            if (GlobalTraceMap.ContainsKey(parent0)) {
+              var p = (ISymbolicExpressionTree)GlobalTraceMap[parent0][0];
+              fragment = SymbolicExpressionTreeMatching.GetFragmentDiff(p, parent0);
+              if (fragment != null) {
+                parents.Add(p);
+                fragments.Add(fragment);
+              }
+            }
+          }
+        }
+
+        // write values to file
+        double a1 = fragments.Average(x => x.GetLength());
+        double a2 = trees.Average(x => x.Length);
+        double a3 = parents.Average(x => x.Length);
+        double s1 = CalculateSimilarity(fragments, (int)SymbolicExpressionTreeMatching.SimilarityLevel.Exact);
+        double s2 = CalculateSimilarity(fragments, (int)SymbolicExpressionTreeMatching.SimilarityLevel.High);
+        double s3 = CalculateSimilarity(fragments, (int)SymbolicExpressionTreeMatching.SimilarityLevel.Relaxed);
+
+        #region Table data
+        // fragments
+        if (!FragmentStatistics.Rows.ContainsKey("Average fragment length")) {
+          DataRow row = new DataRow("Average fragment length", "");
+          row.VisualProperties.StartIndexZero = true;
+          FragmentStatistics.Rows.Add(row);
+        }
+        FragmentStatistics.Rows["Average fragment length"].Values.Add(a1);
+        // child trees
+        if (!FragmentStatistics.Rows.ContainsKey("Average child length")) {
+          DataRow row = new DataRow("Average child length", "");
+          row.VisualProperties.StartIndexZero = true;
+          FragmentStatistics.Rows.Add(row);
+        }
+        FragmentStatistics.Rows["Average child length"].Values.Add(a2);
+        // parents
+        if (!FragmentStatistics.Rows.ContainsKey("Average parent length")) {
+          DataRow row = new DataRow("Average parent length", "");
+          row.VisualProperties.StartIndexZero = true;
+          FragmentStatistics.Rows.Add(row);
+        }
+        FragmentStatistics.Rows["Average parent length"].Values.Add(a3);
+        // exact similarity
+        if (!FragmentStatistics.Rows.ContainsKey("Similarity (exact)")) {
+          DataRow row = new DataRow("Similarity (exact)", "");
+          row.VisualProperties.StartIndexZero = true;
+          FragmentStatistics.Rows.Add(row);
+        }
+        FragmentStatistics.Rows["Similarity (exact)"].Values.Add(s1);
+        // exact similarity
+        if (!FragmentStatistics.Rows.ContainsKey("Similarity (high)")) {
+          DataRow row = new DataRow("Similarity (high)", "");
+          row.VisualProperties.StartIndexZero = true;
+          FragmentStatistics.Rows.Add(row);
+        }
+        FragmentStatistics.Rows["Similarity (high)"].Values.Add(s2);
+        // exact similarity
+        if (!FragmentStatistics.Rows.ContainsKey("Similarity (relaxed)")) {
+          DataRow row = new DataRow("Similarity (relaxed)", "");
+          row.VisualProperties.StartIndexZero = true;
+          FragmentStatistics.Rows.Add(row);
+        }
+        FragmentStatistics.Rows["Similarity (relaxed)"].Values.Add(s3);
+
+        //file.WriteLine(best * 10.0 + " " + a1 + " " + a2 + " " + a3 + " " + s1 + " " + s2 + " " + s3);
+        //}
+        #endregion
+        #endregion
+        // clear the global maps to save memory
+        GlobalCloneMap.Clear();
+        GlobalTraceMap.Clear();
+      }
+      return base.Apply();
+    }
+
+    #region Similarity computations
+    #region Obsolete code
+    private void CalculateDiversityIndicators(IEnumerable<ISymbolicExpressionTreeNode> fragments, out double a, out double b, out double c) {
+      //var frags = fragments.Where(x => x.GetLength() > 1).ToList();
+      var frags = fragments.ToList();
+      var sieve = new bool[frags.Count];
+      int max = 0;
+      for (int i = 0; i != frags.Count - 1; ++i) {
+        if (sieve[i]) continue;
+        int count = 0;
+        for (int j = i + 1; j != frags.Count; ++j) {
+          if (sieve[j]) continue;
+          if (frags[i].IsSimilarTo(frags[j], (int)SymbolicExpressionTreeMatching.SimilarityLevel.Exact)) {
+            ++count;
+            sieve[i] = true;
+            sieve[j] = true;
+          }
+        }
+        if (max < count) max = count;
+      }
+      a = (double)sieve.Count(x => x) / sieve.Length;
+      sieve = new bool[frags.Count];
+      max = 0;
+      for (int i = 0; i != frags.Count - 1; ++i) {
+        if (sieve[i]) continue;
+        int count = 0;
+        for (int j = i + 1; j != frags.Count; ++j) {
+          if (sieve[j]) continue;
+          if (frags[i].IsSimilarTo(frags[j], (int)SymbolicExpressionTreeMatching.SimilarityLevel.High)) {
+            ++count;
+            sieve[i] = true;
+            sieve[j] = true;
+          }
+        }
+        if (max < count) max = count;
+      }
+      b = (double)sieve.Count(x => x) / sieve.Length;
+      sieve = new bool[frags.Count];
+      max = 0;
+      for (int i = 0; i != frags.Count - 1; ++i) {
+        if (sieve[i]) continue;
+        int count = 0;
+        for (int j = i + 1; j != frags.Count; ++j) {
+          if (sieve[j]) continue;
+          if (frags[i].IsSimilarTo(frags[j], (int)SymbolicExpressionTreeMatching.SimilarityLevel.Relaxed)) {
+            ++count;
+            sieve[i] = true;
+            sieve[j] = true;
+          }
+        }
+        if (max < count) max = count;
+      }
+      c = (double)sieve.Count(x => x) / max;
+    }
+    #endregion
+
+    private double CalculateSimilarity(List<ISymbolicExpressionTreeNode> fragments, int mode) {
+      bool[] visited = new bool[fragments.Count];
+      int count = 0;
+      for (int i = 0; i != fragments.Count - 1; ++i) {
+        if (visited[i]) continue;
+        for (int j = i + 1; j != fragments.Count; ++j) {
+          if (visited[j]) continue;
+          if (fragments[i].IsSimilarTo(fragments[j], mode)) visited[j] = true;
+        }
+        ++count;
+      }
+      return (double)fragments.Count / count;
+    }
+    #endregion
+  } //SymbolicExpressionTreeFragmentsAnalyzer
+}
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreeGenealogyAnalyzer.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreeGenealogyAnalyzer.cs	(revision 7779)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/Analyzers/SymbolicExpressionTreeGenealogyAnalyzer.cs	(revision 7785)
@@ -37,4 +37,5 @@
 using HeuristicLab.Problems.DataAnalysis;
 using HeuristicLab.Problems.DataAnalysis.Symbolic;
+// type definitions for ease of use
 using CloneMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItem>;
 using TraceMapType = HeuristicLab.Core.ItemDictionary<HeuristicLab.Core.IItem, HeuristicLab.Core.IItemList<HeuristicLab.Core.IItem>>;
@@ -47,6 +48,4 @@
   [StorableClass]
   public sealed class SymbolicExpressionTreeGenealogyAnalyzer : SingleSuccessorOperator, IAnalyzer {
-    public enum GeneticOperator { Crossover, Mutation }
-
     private const string UpdateIntervalParameterName = "UpdateInterval";
     private const string UpdateCounterParameterName = "UpdateCounter";
@@ -220,7 +219,8 @@
           Results.Add(new Result(PopulationGraphResultParameterName, PopulationGraphResultParameterDescription, graph));
         } else {
-          graph = (SymbolicExpressionTreeGenealogyGraph)Results[PopulationGraphResultParameterName].Value;
-        }
-        // get tree quality values
+          //graph = (SymbolicExpressionTreeGenealogyGraph)Results[PopulationGraphResultParameterName].Value;
+          graph = (SymbolicExpressionTreeGenealogyGraph)(Results[PopulationGraphResultParameterName].Value);
+        }
+        // get tree quality values (Key => Individual, Value => Quality)
         var qualities = (from s in gScope.SubScopes
                          let individual = s.Variables.First().Value
@@ -232,5 +232,4 @@
         int generation = Generations.Value;
         string label;
-
         if (generation == 0) {
           // at generation 0 no trace map is present (since no reproduction has taken place yet), so we only add the initial trees as nodes in the genealogy graph
@@ -252,5 +251,4 @@
 
           foreach (var parent in parents) {
-            int opType;
             if (GlobalTraceMap.ContainsKey(parent)) {
               double quality = Evaluate((ISymbolicExpressionTree)parent);
@@ -258,10 +256,8 @@
               var pp = GlobalTraceMap[parent];
               foreach (var p in pp) {
-                opType = pp.Count == 2 ? (int)GeneticOperator.Crossover : (int)GeneticOperator.Mutation;
-                graph.AddArc((ISymbolicExpressionTree)p, (ISymbolicExpressionTree)parent, opType);
+                graph.AddArc((ISymbolicExpressionTree)p, (ISymbolicExpressionTree)parent);
               }
             }
-            opType = parents.Count == 2 ? (int)GeneticOperator.Crossover : (int)GeneticOperator.Mutation;
-            graph.AddArc((ISymbolicExpressionTree)parent, child, opType);
+            graph.AddArc((ISymbolicExpressionTree)parent, child);
           }
         }
@@ -319,4 +315,6 @@
     }
 
+  
+
     private double Evaluate(ISymbolicExpressionTree tree) {
       // we perform evaluation by adding a temporary subscope with the tree in it, and calling evaluator.Apply()
@@ -368,26 +366,4 @@
     }
     #endregion
-
-    #region Extra / not really needed
-    // method of iterating tree nodes in a breadth-wise manner
-    private IEnumerable<ISymbolicExpressionTreeNode> IterateNodes(ISymbolicExpressionTree tree) {
-      return IterateNodes(tree.Root);
-    }
-
-    private static IEnumerable<ISymbolicExpressionTreeNode> IterateNodes(ISymbolicExpressionTreeNode root) {
-      var list = new List<ISymbolicExpressionTreeNode> { root };
-      int offset = 0, count = 1;
-      while (offset != count) {
-        var c = count;
-        for (int i = offset; i != count; ++i) {
-          yield return list[i];
-          if (!list[i].Subtrees.Any()) continue;
-          list.AddRange(list[i].Subtrees);
-        }
-        offset = c;
-        count = list.Count;
-      }
-    }
-    #endregion
   }
 }
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/GenealogyGraph.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/GenealogyGraph.cs	(revision 7779)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/GenealogyGraph.cs	(revision 7785)
@@ -50,5 +50,5 @@
 
     [StorableConstructor]
-    private GenealogyGraph(bool serializing)
+    protected GenealogyGraph(bool serializing)
       : base(serializing) {
     }
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/GenealogyGraphView.Designer.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/GenealogyGraphView.Designer.cs	(revision 7779)
+++ 	(revision )
@@ -1,33 +1,0 @@
-﻿
-namespace HeuristicLab.EvolutionaryTracking {
-  partial class GenealogyGraphView {
-    /// <summary> 
-    /// Required designer variable.
-    /// </summary>
-    private System.ComponentModel.IContainer components = null;
-
-    /// <summary> 
-    /// Clean up any resources being used.
-    /// </summary>
-    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
-    protected override void Dispose(bool disposing) {
-      if (disposing && (components != null)) {
-        components.Dispose();
-      }
-      base.Dispose(disposing);
-    }
-
-    #region Component Designer generated code
-
-    /// <summary> 
-    /// Required method for Designer support - do not modify 
-    /// the contents of this method with the code editor.
-    /// </summary>
-    private void InitializeComponent() {
-      components = new System.ComponentModel.Container();
-      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-    }
-
-    #endregion
-  }
-}
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/GenealogyGraphView.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/GenealogyGraphView.cs	(revision 7779)
+++ 	(revision )
@@ -1,109 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Drawing;
-using System.Data;
-using System.Drawing.Imaging;
-using System.Linq;
-using System.Text;
-using System.Windows.Forms;
-using HeuristicLab.Core.Views;
-using HeuristicLab.MainForm;
-using Microsoft.Glee.Drawing;
-using Microsoft.Glee.GraphViewerGdi;
-
-namespace HeuristicLab.EvolutionaryTracking {
-  [View("GenealogyGraphView")]
-  [Content(typeof(GenealogyGraph), IsDefaultView = true)]
-  public sealed partial class GenealogyGraphView : ItemView {
-    private readonly GViewer _gViewer;
-
-    public new GenealogyGraph Content {
-      get { return (GenealogyGraph)base.Content; }
-      set { base.Content = value; }
-    }
-
-    public GenealogyGraphView()
-      : base() {
-      InitializeComponent();
-      _gViewer = new GViewer() { Dock = DockStyle.Fill };
-      this.Controls.Add(_gViewer);
-    }
-
-    protected override void DeregisterContentEvents() {
-      // TODO: Deregister your event handlers here
-      base.DeregisterContentEvents();
-    }
-
-    protected override void RegisterContentEvents() {
-      base.RegisterContentEvents();
-      // TODO: Register your event handlers here
-    }
-
-    #region Event Handlers (Content)
-    // TODO: Put event handlers of the content here
-    #endregion
-
-    protected override void OnContentChanged() {
-      base.OnContentChanged();
-      if (Content == null) {
-        // TODO: Add code when content has been changed and is null
-      } else {
-        // TODO: Add code when content has been changed and is not null
-        if (InvokeRequired) {
-          Invoke(new EventHandler(Content_GraphChanged), this, null);
-        } else {
-          SetEnabledStateOfControls();
-          Content_GraphChanged(this, null);
-        }
-      }
-    }
-
-    private void Content_GraphChanged(object sender, EventArgs e) {
-      var graph = Content;
-      var nodes = graph.Values;
-      var gleeGraph = new Microsoft.Glee.Drawing.Graph("PopulationGraph") {
-        GraphAttr = {
-          Backgroundcolor = Microsoft.Glee.Drawing.Color.White,
-          NodeAttr = { Shape = Shape.Circle, Label = String.Empty, Padding = 40 },
-          AspectRatio = 2
-        }
-      };
-
-      foreach (var node in nodes) {
-        var n = gleeGraph.AddNode(node.Id); // Glee does not actually add a new node if the node already exists in the graph
-        n.Attr.Fillcolor = new Microsoft.Glee.Drawing.Color((byte)((1 - node.Quality) * 255), (byte)(255 * node.Quality), 0);
-        n.Attr.Color = new Microsoft.Glee.Drawing.Color((byte)((1 - node.Quality) * 255), (byte)(255 * node.Quality), 0);
-        n.Attr.Label = node.Label;
-        n.Attr.Fontsize = 8;
-        n.Attr.FontName = "Consolas";
-        if (node.IsElite) {
-          n.Attr.Color = Microsoft.Glee.Drawing.Color.DodgerBlue;
-          n.Attr.Shape = Shape.Box;
-        }
-
-        if (node.OutEdges == null) continue;
-        foreach (var arc in node.OutEdges) {
-          var edge = gleeGraph.AddEdge(node.Id, arc.Target.Id);
-          edge.Attr.LineWidth = 1;
-          byte r = (byte)((edge.SourceNode.Attr.Color.R + edge.TargetNode.Attr.Color.R) / 2);
-          byte g = (byte)((edge.SourceNode.Attr.Color.G + edge.TargetNode.Attr.Color.G) / 2);
-          byte b = (byte)((edge.SourceNode.Attr.Color.B + edge.TargetNode.Attr.Color.B) / 2);
-          edge.Attr.Color = new Microsoft.Glee.Drawing.Color(r, g, b);
-        }
-      }
-      _gViewer.Graph = gleeGraph;
-      _gViewer.Refresh();
-    }
-
-    protected override void SetEnabledStateOfControls() {
-      base.SetEnabledStateOfControls();
-      // TODO: Enable or disable controls based on whether the content is null or the view is set readonly
-    }
-
-    #region Event Handlers (child controls)
-    // TODO: Put event handlers of child controls here.
-    #endregion
-  }
-
-}
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/HeuristicLab.EvolutionaryTracking-3.4.csproj
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/HeuristicLab.EvolutionaryTracking-3.4.csproj	(revision 7779)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/HeuristicLab.EvolutionaryTracking-3.4.csproj	(revision 7785)
@@ -38,4 +38,5 @@
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="HeuristicLab.Collections-3.3">
       <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
@@ -83,4 +84,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Analyzers\SymbolicExpressionTreeFragmentsAnalyzer.cs" />
     <Compile Include="Analyzers\SymbolicExpressionTreeGenealogyAnalyzer.cs" />
     <Compile Include="GenealogyGraph.cs" />
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/SymbolicExpressionTreeGenealogyGraph.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/SymbolicExpressionTreeGenealogyGraph.cs	(revision 7779)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking/3.4/SymbolicExpressionTreeGenealogyGraph.cs	(revision 7785)
@@ -1,118 +1,23 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Globalization;
+﻿using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
 namespace HeuristicLab.EvolutionaryTracking {
   public class SymbolicExpressionTreeGenealogyGraph : GenealogyGraph<ISymbolicExpressionTree> {
-    public enum SimilarityLevel { Exact, High, Relaxed }
+    public SymbolicExpressionTreeGenealogyGraph() {
+    }
 
-    private readonly Dictionary<int, Func<ISymbolicExpressionTreeNode, string>> _dispatcher;
-
-    public delegate string HashFunction(ISymbolicExpressionTreeNode node);
-
-    public SymbolicExpressionTreeGenealogyGraph() {
-      _dispatcher = new Dictionary<int, Func<ISymbolicExpressionTreeNode, string>>();
-      _dispatcher[(int)SimilarityLevel.Exact] = GetExactString;
-      _dispatcher[(int)SimilarityLevel.High] = GetHighLevelString;
-      _dispatcher[(int)SimilarityLevel.Relaxed] = GetRelaxedString;
+    [StorableConstructor]
+    public SymbolicExpressionTreeGenealogyGraph(bool serializing)
+      : base(serializing) {
     }
 
     #region Fragment tracing
     public IEnumerable<ISymbolicExpressionTree> TraceFragment(ISymbolicExpressionTreeNode fragment, int mode = 0) {
-      return Keys.Where(tree => ContainsFragment(tree, fragment, mode) != -1);
+      //return Keys.Where(tree => ContainsFragment(tree, fragment, mode) != -1);
+      return Keys.Where(tree => tree.ContainsFragment(fragment, mode));
     }
-
-    public static bool CheckSimilarity(ISymbolicExpressionTree t1, ISymbolicExpressionTree t2, int mode) {
-      return FindMatch(t1, t2, mode) == 0;
-    }
-
-    public static int ContainsFragment(ISymbolicExpressionTree tree, ISymbolicExpressionTreeNode fragment, int mode) {
-      var nodes = tree.IterateNodesPostfix().ToArray();
-      var fragments = fragment.IterateNodesPostfix().ToArray();
-      return FindMatch(nodes, fragments, mode);
-    }
-
-    // Build a string hash out of all node symbols and parameter values (trimmed to 4 decimal places)
-    private static string GetExactString(ISymbolicExpressionTreeNode node) {
-      if (node is ConstantTreeNode) {
-        var constant = node as ConstantTreeNode;
-        return (constant.Symbol + string.Format("{0:0.0000}", constant.Value));
-      }
-      if (node is VariableTreeNode) {
-        var variable = node as VariableTreeNode;
-        return (variable.Symbol + variable.VariableName + variable.Weight);
-      }
-      return (node.Symbol.ToString());
-    }
-
-    // Build a string hash out of all node symbols in their respective order
-    private static string GetHighLevelString(ISymbolicExpressionTreeNode node) {
-      return (node.Symbol.ToString());
-    }
-
-    // Build a string hash which only considers function symbols and function arities. leaf nodes are taken as "wildcards"
-    private static string GetRelaxedString(ISymbolicExpressionTreeNode node) {
-      if (node.SubtreeCount != 0) /* function node */ {
-        return (node.Symbol + node.SubtreeCount.ToString(CultureInfo.InvariantCulture));
-      }
-      return string.Empty;
-    }
-
     #endregion
-    public class SymbolicExpressionTreeNodeComparer : IEqualityComparer<ISymbolicExpressionTreeNode> {
-      public SymbolicExpressionTreeNodeComparer(int similarityLevel) { _similarityLevel = similarityLevel; }
-
-      public int GetHashCode(ISymbolicExpressionTreeNode n) { return n.ToString().ToLower().GetHashCode(); }
-
-      public bool Equals(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
-        if (a.SubtreeCount != b.SubtreeCount) { return false; }
-        if (a.SubtreeCount > 0) { return a.Symbol.ToString().Equals(b.Symbol.ToString()); }
-        switch (_similarityLevel) {
-          case ((int)SimilarityLevel.Exact):
-            if (a is ConstantTreeNode && b is ConstantTreeNode) { return (a as ConstantTreeNode).Value.Equals((b as ConstantTreeNode).Value); }
-            if (a is VariableTreeNode && b is VariableTreeNode) { return (a as VariableTreeNode).Weight.Equals((b as VariableTreeNode).Weight); }
-            return false;
-          case ((int)SimilarityLevel.High):
-            return (a is ConstantTreeNode && b is ConstantTreeNode) || (a is VariableTreeNode && b is VariableTreeNode);
-          case ((int)SimilarityLevel.Relaxed):
-            return true;
-          default:
-            return false;
-        }
-      }
-      private readonly int _similarityLevel;
-    }
-
-    private static int FindMatch(ISymbolicExpressionTree t0, ISymbolicExpressionTree t1, int mode) {
-      return FindMatch(t0.IterateNodesPostfix().ToArray(), t1.IterateNodesPostfix().ToArray(), mode);
-    }
-
-    private static int FindMatch(ISymbolicExpressionTreeNode t0, ISymbolicExpressionTreeNode t1, int mode) {
-      return FindMatch(t0.IterateNodesPostfix().ToArray(), t1.IterateNodesPostfix().ToArray(), mode);
-    }
-
-    // returns the index in the sequence 'seq', where pattern 'pat' is matched, or -1 for no match
-    // -1 means no match, 0 means perfect match (the sequences overlap, hence the match index is 0)
-    public static int FindMatch(ISymbolicExpressionTreeNode[] seq, ISymbolicExpressionTreeNode[] pat, int mode) {
-      int patlen = pat.Length;
-      int seqlen = seq.Length;
-      if (patlen == 0 || seqlen == 0) return -1;
-      var comparer = new SymbolicExpressionTreeNodeComparer(mode);
-      if (patlen == seqlen) return seq.SequenceEqual(pat, comparer) ? 0 : -1;
-      int i = patlen;
-      while (i <= seqlen) {
-        var ch = seq[i - 1];
-        if (comparer.Equals(ch, pat.Last())) {
-          if (seq.Skip(i - patlen).Take(patlen).SequenceEqual(pat, comparer)) {
-            return i - patlen;
-          }
-        }
-        ++i;
-      }
-      return -1;
-    }
   }
 }
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Selection/3.3/Plugin.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Selection/3.3/Plugin.cs	(revision 7779)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Selection/3.3/Plugin.cs	(revision 7785)
@@ -26,5 +26,5 @@
   /// Plugin class for HeuristicLab.Selection plugin.
   /// </summary>
-  [Plugin("HeuristicLab.Selection", "3.3.6.0")]
+  [Plugin("HeuristicLab.Selection", "3.3.6.7779")]
   [PluginFile("HeuristicLab.Selection-3.3.dll", PluginFileType.Assembly)]
   [PluginDependency("HeuristicLab.Collections", "3.3")]
