Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/GenealogyGraphChart.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/GenealogyGraphChart.cs	(revision 9083)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/GenealogyGraphChart.cs	(revision 9084)
@@ -28,9 +28,10 @@
 using HeuristicLab.Common;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
 using HeuristicLab.Visualization;
 
 namespace HeuristicLab.EvolutionaryTracking.Views {
   public partial class GenealogyGraphChart : ChartControl {
-    private Dictionary<IGenealogyGraphNode, VisualGenealogyGraphNode> visualNodeMap;
+    private Dictionary<string, VisualGenealogyGraphNode> visualNodeMap; // map the uid of the genealogy graph vertex with a visual node (in this way each node is uniquely determined)
     private Dictionary<Tuple<VisualGenealogyGraphNode, VisualGenealogyGraphNode>, VisualGenealogyGraphArc> visualArcMap;
     private const int Diameter = 20; // node diameter
@@ -46,8 +47,22 @@
       internal set {
         graph = value;
-        visualNodeMap = new Dictionary<IGenealogyGraphNode, VisualGenealogyGraphNode>();
+        // TODO: should move the subtree sorting code out of here and int the view
+        var canonicalSorter = new SymbolicExpressionTreeCanonicalSorter();
+        // sort subtrees in order to improve matching
+        foreach (var tree in graph.Nodes.Select(n => n.SymbolicExpressionTree))
+          canonicalSorter.SortSubtrees(tree);
+
+        visualNodeMap = new Dictionary<string, VisualGenealogyGraphNode>();
         visualArcMap = new Dictionary<Tuple<VisualGenealogyGraphNode, VisualGenealogyGraphNode>, VisualGenealogyGraphArc>();
+
+        Chart.Group.Clear();
         DrawGraph();
       }
+    }
+
+    private VisualGenealogyGraphNode GetVisualGenealogyGraphNode(IVertex node) {
+      VisualGenealogyGraphNode visualNode;
+      visualNodeMap.TryGetValue(node.Id, out visualNode);
+      return visualNode;
     }
 
@@ -68,10 +83,10 @@
       Chart.UpdateEnabled = false;
 
-      var layers = Graph.Nodes.GroupBy(n => n.Ranks[0]).OrderBy(g => g.Key).Select(g => new { Rank = g.Key, Nodes = g.ToList() }).ToList();
+      var layers = Graph.Nodes.GroupBy(n => n.Rank).OrderBy(g => g.Key).Select(g => new { Rank = g.Key, Nodes = g.ToList() }).ToList();
+
       for (int i = 0; i != layers.Count; ++i) {
         // sort descending by quality (using comparison defined in GenealogyGraphNode class)
         layers[i].Nodes.Sort((b, a) => Graph.Compare(a, b));
         x = 0; // reset horizontal coordinate
-        // start laying out visual nodes
         foreach (var node in layers[i].Nodes) {
           var pen = new Pen(Color.LightGray);
@@ -80,11 +95,10 @@
             Data = node,
             ToolTipText = "Id: " + node.Label + nl +
-                          "Ranks: " + string.Join(",", node.Ranks) + nl +
+                          "Rank: " + node.Rank + nl +
                           "Quality: " + String.Format("{0:0.0000}", node.Quality) + nl +
                           "IsElite: " + node.IsElite
           };
           Chart.Group.Add(visualNode);
-          if (!visualNodeMap.ContainsKey(node))
-            visualNodeMap[node] = visualNode;
+          visualNodeMap.Add(node.Id, visualNode);
 
           x += Cx; // increment horizontal coordinate
@@ -94,23 +108,25 @@
 
         // connect elites from successive layers with visual arcs
-        if (i > 0) {
-          for (int m = 0; m != layers[i].Nodes.Count; ++m)
-            for (int n = 0; n != layers[i - 1].Nodes.Count; ++n) {
-              if (layers[i].Nodes[m].SymbolicExpressionTree == layers[i - 1].Nodes[n].SymbolicExpressionTree) {
-                var v1 = visualNodeMap[layers[i].Nodes[m]];
-                var v2 = visualNodeMap[layers[i - 1].Nodes[n]];
-                var pen = new Pen(Color.LightGray);
-                visualArcMap[Tuple.Create(v2, v1)] = AddArc(Chart, v2, v1, pen);
-              }
-            }
+        if (i == 0) continue;
+        var currLayer = layers[i].Nodes;
+        var prevLayer = layers[i - 1].Nodes;
+        foreach (var n in currLayer) {
+          foreach (var m in prevLayer) {
+            if (n.SymbolicExpressionTree != m.SymbolicExpressionTree) continue;
+            var v1 = GetVisualGenealogyGraphNode(n);
+            var v2 = GetVisualGenealogyGraphNode(m);
+
+            var pen = new Pen(Color.LightGray);
+            visualArcMap[Tuple.Create(v2, v1)] = AddArc(Chart, v2, v1, pen);
+          }
         }
       }
       // add arcs separately (to avoid some ordering problems)
-      foreach (var node in visualNodeMap.Keys) {
-        var visualNode = visualNodeMap[node];
+      foreach (SymbolicExpressionGenealogyGraphNode node in Graph.Nodes) {
+        VisualGenealogyGraphNode visualNode = GetVisualGenealogyGraphNode(node);
         if (node.InEdges == null) continue;
 
-        foreach (var arc in node.InEdges) {
-          var visualParent = visualNodeMap[arc.Target];
+        foreach (Arc arc in node.InEdges) {
+          var visualParent = GetVisualGenealogyGraphNode(arc.Source);
           var pen = new Pen(Color.Transparent);
           visualArcMap[Tuple.Create(visualParent, visualNode)] = AddArc(Chart, visualParent, visualNode, pen);
@@ -134,72 +150,64 @@
 
     protected override void pictureBox_MouseUp(object sender, MouseEventArgs e) {
-      if (Chart.Mode != ChartMode.Select)
+      if (Chart.Mode != ChartMode.Select) {
         base.pictureBox_MouseUp(sender, e);
-      else { // select mode
-        // get selected node
-        var visualNodes = Chart.GetAllPrimitives(e.Location).Where(p => p is VisualGenealogyGraphNode).ToList();
-        if (visualNodes.Count > 0) {
-          if (selectedGenealogyGraphNode == visualNodes[0]) return;
-          selectedGenealogyGraphNode = visualNodes[0] as VisualGenealogyGraphNode;
-          if (selectedGenealogyGraphNode == null) return;
-          // new node has been selected, clean up
-          Chart.UpdateEnabled = false;
-          // clear colors
-          ClearAllNodes();
-          // use a rectangle to highlight the currently selected genealogy graph node
-          var center = selectedGenealogyGraphNode.Center;
-          var size = selectedGenealogyGraphNode.Size;
-          double x1 = center.X - size.Width / 2;
-          double x2 = x1 + size.Width;
-          double y1 = center.Y - size.Height / 2;
-          double y2 = y1 + size.Height;
-          if (targetRectangle == null) {
-            targetRectangle = new Visualization.Rectangle(Chart, x1, y1, x2, y2, new Pen(Color.Black), null);
-            Chart.Group.Add(targetRectangle);
-          } else {
-            targetRectangle.SetPosition(x1, y1, x2, y2);
-          }
-          var gNode = selectedGenealogyGraphNode.Data; // genealogy graph node (representing an individual in the population) 
-          //          double rank = Graph[gNode].Ranks[0];
-          double rank = ((SymbolicExpressionGenealogyGraphNode)gNode).Ranks[0];
-          // ancestors
-          var ancestors = gNode.Ancestors().Where(n => ((SymbolicExpressionGenealogyGraphNode)n).Ranks.Last() < rank).ToList();
-          ancestors.Add(gNode);
-          // descendants
-          var descendants = gNode.Descendants().Where(n => ((SymbolicExpressionGenealogyGraphNode)n).Ranks.Last() > rank).ToList();
-          descendants.Add(gNode);
-          // highlight ancestors
-          foreach (var node in ancestors.Select(n => visualNodeMap[n])) {
-            node.Brush = new SolidBrush(((SymbolicExpressionGenealogyGraphNode)node.Data).GetColor());
-            if (node.IncomingArcs != null)
-              foreach (var arc in node.IncomingArcs) {
-                var start = new Point((int)arc.Start.X, (int)arc.Start.Y);
-                var end = new Point((int)arc.End.X, (int)arc.End.Y);
-                var srcNode = arc.Source.Data as SymbolicExpressionGenealogyGraphNode;
-                var destNode = arc.Target.Data as SymbolicExpressionGenealogyGraphNode;
-                arc.Pen.Brush = new LinearGradientBrush(start, end, srcNode.GetColor(), destNode.GetColor());
-              }
-          }
-          // highlight descendants
-          foreach (var node in descendants.Select(n => visualNodeMap[n])) {
-            node.Brush = new SolidBrush((node.Data as SymbolicExpressionGenealogyGraphNode).GetColor());
-            if (node.OutgoingArcs != null)
-              foreach (var arc in node.OutgoingArcs) {
-                var start = new Point((int)arc.Start.X, (int)arc.Start.Y);
-                var end = new Point((int)arc.End.X, (int)arc.End.Y);
-                var srcNode = arc.Source.Data as SymbolicExpressionGenealogyGraphNode;
-                var destNode = arc.Target.Data as SymbolicExpressionGenealogyGraphNode;
-                arc.Pen.Brush = new LinearGradientBrush(start, end, srcNode.GetColor(), destNode.GetColor());
-              }
-          }
-        } else {
-          selectedGenealogyGraphNode = null;
-        }
-        // update
-        Chart.UpdateEnabled = true;
-        Chart.EnforceUpdate();
-        if (selectedGenealogyGraphNode != null)
-          /* emit clicked event */
-          OnGenealogyGraphNodeClicked(selectedGenealogyGraphNode, e);
+        return;
+      }
+      var visualNodes = Chart.GetAllPrimitives(e.Location).Where(p => p is VisualGenealogyGraphNode).ToList();
+      if (visualNodes.Count <= 0) {
+        selectedGenealogyGraphNode = null;
+        return;
+      }
+      if (selectedGenealogyGraphNode == visualNodes[0]) return;
+      selectedGenealogyGraphNode = visualNodes[0] as VisualGenealogyGraphNode;
+      if (selectedGenealogyGraphNode == null) return;
+      // new node has been selected, clean up
+      Chart.UpdateEnabled = false;
+      // clear colors
+      ClearAllNodes();
+      // use a rectangle to highlight the currently selected genealogy graph node
+      MarkSelectedNode();
+      var gNode = selectedGenealogyGraphNode.Data;
+      var visualNode = GetVisualGenealogyGraphNode(gNode);
+
+      DrawLineage(visualNode, n => n.IncomingArcs, a => a.Source);
+      DrawLineage(visualNode, n => n.OutgoingArcs, a => a.Target);
+
+      // update
+      Chart.UpdateEnabled = true;
+      Chart.EnforceUpdate();
+
+      if (selectedGenealogyGraphNode != null)
+        /* emit clicked event */
+        OnGenealogyGraphNodeClicked(selectedGenealogyGraphNode, e);
+    }
+
+    private void DrawLineage(VisualGenealogyGraphNode node,
+                             Func<VisualGenealogyGraphNode, IEnumerable<VisualGenealogyGraphArc>> arcSelector,
+                             Func<VisualGenealogyGraphArc, VisualGenealogyGraphNode> nodeSelector) {
+      node.Brush = new SolidBrush(node.Data.GetColor());
+      var arcs = arcSelector(node);
+      foreach (var arc in arcs) {
+        var source = arc.Source.Data;
+        var target = arc.Target.Data;
+        var start = new Point((int)arc.Start.X, (int)arc.Start.Y);
+        var end = new Point((int)arc.End.X, (int)arc.End.Y);
+        arc.Pen.Brush = new LinearGradientBrush(start, end, source.GetColor(), target.GetColor());
+        DrawLineage(nodeSelector(arc), arcSelector, nodeSelector);
+      }
+    }
+
+    void MarkSelectedNode() {
+      var center = selectedGenealogyGraphNode.Center;
+      var size = selectedGenealogyGraphNode.Size;
+      double x1 = center.X - size.Width / 2;
+      double x2 = x1 + size.Width;
+      double y1 = center.Y - size.Height / 2;
+      double y2 = y1 + size.Height;
+      if (targetRectangle == null) {
+        targetRectangle = new Visualization.Rectangle(Chart, x1, y1, x2, y2, new Pen(Color.Black), null);
+        Chart.Group.Add(targetRectangle);
+      } else {
+        targetRectangle.SetPosition(x1, y1, x2, y2);
       }
     }
@@ -209,11 +217,7 @@
         if (primitive is VisualGenealogyGraphArc) {
           var arc = primitive as VisualGenealogyGraphArc;
-          var sourceData = (arc.Source.Data as SymbolicExpressionGenealogyGraphNode).SymbolicExpressionTree;
-          var targetData = (arc.Target.Data as SymbolicExpressionGenealogyGraphNode).SymbolicExpressionTree;
-          if (sourceData != targetData) {
-            primitive.Pen.Brush = new SolidBrush(Color.Transparent);
-          } else {
-            primitive.Pen.Brush = new SolidBrush(Color.LightGray);
-          }
+          var sourceData = arc.Source.Data.SymbolicExpressionTree;
+          var targetData = arc.Target.Data.SymbolicExpressionTree;
+          primitive.Pen.Brush = sourceData != targetData ? new SolidBrush(Color.Transparent) : new SolidBrush(Color.LightGray);
         } else {
           primitive.Brush = null;
@@ -222,32 +226,16 @@
     }
 
-    public void HighlightLineage(IEnumerable<GenealogyGraphNode> nodes) {
-      foreach (var node in nodes.Select(n => visualNodeMap[n])) {
-        node.Brush = new SolidBrush((node.Data as SymbolicExpressionGenealogyGraphNode).GetColor());
-        if (node.IncomingArcs == null || node != visualNodeMap[node.Data]) continue;
-        foreach (var arc in node.IncomingArcs) {
-          if (arc.Source.Data == node.Data) continue;
-          var start = new Point((int)arc.Start.X, (int)arc.Start.Y);
-          var end = new Point((int)arc.End.X, (int)arc.End.Y);
-          var srcNode = arc.Source.Data as SymbolicExpressionGenealogyGraphNode;
-          var destNode = arc.Target.Data as SymbolicExpressionGenealogyGraphNode;
-          arc.Pen.Brush = new LinearGradientBrush(start, end, srcNode.GetColor(), destNode.GetColor());
-        }
-      }
-    }
-
     // TODO: optimize and reduce complexity of this method
     public void HighlightNodes(IEnumerable<ISymbolicExpressionTree> trees, Color color) {
-      foreach (var tree in trees)
-        foreach (var graphNode in Graph.Nodes) {
-          if (graphNode.SymbolicExpressionTree == tree) {
-            var visualNode = visualNodeMap[graphNode];
-            visualNode.Brush = new SolidBrush(color);
-          }
-        }
+      foreach (var tree in trees) {
+        var graphNodes = graph.GetGraphNodes(tree);
+        foreach (var graphNode in graphNodes) {
+          GetVisualGenealogyGraphNode(graphNode).Brush = new SolidBrush(color);
+        }
+      }
     }
 
     public void HighlightNode(SymbolicExpressionGenealogyGraphNode graphNode, Color color) {
-      visualNodeMap[graphNode].Brush = new SolidBrush(color);
+      GetVisualGenealogyGraphNode(graphNode).Brush = new SolidBrush(color);
     }
 
@@ -257,5 +245,5 @@
       double max = Graph.Nodes.Max(x => x.InEdges == null ? 0 : x.InEdges.Count);
       foreach (var graphNode in Graph.Nodes) {
-        var visualNode = visualNodeMap[graphNode];
+        var visualNode = GetVisualGenealogyGraphNode(graphNode);
         double deg = graphNode.InEdges == null ? 0 : graphNode.InEdges.Count;
         int index = (int)(deg / max * ColorGradient.Colors.Count);
@@ -274,5 +262,5 @@
       double max = graphNodes.Max(x => x.OutEdges == null ? 0 : x.OutEdges.Count);
       foreach (var graphNode in graphNodes) {
-        var visualNode = visualNodeMap[graphNode];
+        var visualNode = GetVisualGenealogyGraphNode(graphNode);
         double deg = graphNode.OutEdges == null ? 0 : graphNode.OutEdges.Count;
         int index = (int)(deg / max * ColorGradient.Colors.Count);
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/GenealogyGraphView.Designer.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/GenealogyGraphView.Designer.cs	(revision 9083)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/GenealogyGraphView.Designer.cs	(revision 9084)
@@ -25,16 +25,19 @@
     /// </summary>
     private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
       this.mainTableLayout = new System.Windows.Forms.TableLayoutPanel();
       this.splitContainer = new System.Windows.Forms.SplitContainer();
       this.genealogyTableLayout = new System.Windows.Forms.TableLayoutPanel();
+      this.genealogyGraphChart = new HeuristicLab.EvolutionaryTracking.Views.GenealogyGraphChart();
       this.symbolicExpressionTreeChart = new HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views.SymbolicExpressionTreeChart();
       this.topControlBox = new System.Windows.Forms.GroupBox();
+      this.matchVariableNamesCheckBox = new System.Windows.Forms.CheckBox();
+      this.matchVariableWeightsCheckBox = new System.Windows.Forms.CheckBox();
+      this.matchConstantsCheckBox = new System.Windows.Forms.CheckBox();
+      this.similarityLabel = new System.Windows.Forms.Label();
       this.graphControlsPanel = new System.Windows.Forms.Panel();
-      this.similarityModeLabel = new System.Windows.Forms.Label();
-      this.similarityModeSelector = new System.Windows.Forms.ComboBox();
       this.selectModeButton = new System.Windows.Forms.RadioButton();
       this.moveModeButton = new System.Windows.Forms.RadioButton();
       this.zoomModeButton = new System.Windows.Forms.RadioButton();
-      this.genealogyGraphChart = new HeuristicLab.EvolutionaryTracking.Views.GenealogyGraphChart();
       this.mainTableLayout.SuspendLayout();
       ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
@@ -97,4 +100,14 @@
       this.genealogyTableLayout.TabIndex = 4;
       // 
+      // genealogyGraphChart
+      // 
+      this.genealogyGraphChart.BackColor = System.Drawing.SystemColors.Control;
+      this.genealogyGraphChart.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.genealogyGraphChart.Location = new System.Drawing.Point(3, 3);
+      this.genealogyGraphChart.Name = "genealogyGraphChart";
+      this.genealogyGraphChart.ScaleOnResize = true;
+      this.genealogyGraphChart.Size = new System.Drawing.Size(352, 520);
+      this.genealogyGraphChart.TabIndex = 2;
+      // 
       // symbolicExpressionTreeChart
       // 
@@ -113,7 +126,9 @@
       // topControlBox
       // 
+      this.topControlBox.Controls.Add(this.matchVariableNamesCheckBox);
+      this.topControlBox.Controls.Add(this.matchVariableWeightsCheckBox);
+      this.topControlBox.Controls.Add(this.matchConstantsCheckBox);
+      this.topControlBox.Controls.Add(this.similarityLabel);
       this.topControlBox.Controls.Add(this.graphControlsPanel);
-      this.topControlBox.Controls.Add(this.similarityModeLabel);
-      this.topControlBox.Controls.Add(this.similarityModeSelector);
       this.topControlBox.Dock = System.Windows.Forms.DockStyle.Fill;
       this.topControlBox.Location = new System.Drawing.Point(3, 3);
@@ -124,4 +139,52 @@
       this.topControlBox.Text = "Controls";
       // 
+      // matchVariableNamesCheckBox
+      // 
+      this.matchVariableNamesCheckBox.AutoSize = true;
+      this.matchVariableNamesCheckBox.Checked = true;
+      this.matchVariableNamesCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.matchVariableNamesCheckBox.Location = new System.Drawing.Point(436, 23);
+      this.matchVariableNamesCheckBox.Name = "matchVariableNamesCheckBox";
+      this.matchVariableNamesCheckBox.Size = new System.Drawing.Size(98, 17);
+      this.matchVariableNamesCheckBox.TabIndex = 7;
+      this.matchVariableNamesCheckBox.Text = "Variable names";
+      this.matchVariableNamesCheckBox.UseVisualStyleBackColor = true;
+      this.matchVariableNamesCheckBox.CheckedChanged += new System.EventHandler(this.matchVariableNamesCheckBox_CheckedChanged);
+      // 
+      // matchVariableWeightsCheckBox
+      // 
+      this.matchVariableWeightsCheckBox.AutoSize = true;
+      this.matchVariableWeightsCheckBox.Checked = true;
+      this.matchVariableWeightsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.matchVariableWeightsCheckBox.Location = new System.Drawing.Point(327, 23);
+      this.matchVariableWeightsCheckBox.Name = "matchVariableWeightsCheckBox";
+      this.matchVariableWeightsCheckBox.Size = new System.Drawing.Size(103, 17);
+      this.matchVariableWeightsCheckBox.TabIndex = 6;
+      this.matchVariableWeightsCheckBox.Text = "Variable weights";
+      this.matchVariableWeightsCheckBox.UseVisualStyleBackColor = true;
+      this.matchVariableWeightsCheckBox.CheckedChanged += new System.EventHandler(this.matchVariableWeightsCheckBox_CheckedChanged);
+      // 
+      // matchConstantsCheckBox
+      // 
+      this.matchConstantsCheckBox.AutoSize = true;
+      this.matchConstantsCheckBox.Checked = true;
+      this.matchConstantsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.matchConstantsCheckBox.Location = new System.Drawing.Point(219, 23);
+      this.matchConstantsCheckBox.Name = "matchConstantsCheckBox";
+      this.matchConstantsCheckBox.Size = new System.Drawing.Size(102, 17);
+      this.matchConstantsCheckBox.TabIndex = 5;
+      this.matchConstantsCheckBox.Text = "Constant values";
+      this.matchConstantsCheckBox.UseVisualStyleBackColor = true;
+      this.matchConstantsCheckBox.CheckedChanged += new System.EventHandler(this.matchConstantsCheckBox_CheckedChanged);
+      // 
+      // similarityLabel
+      // 
+      this.similarityLabel.AutoSize = true;
+      this.similarityLabel.Location = new System.Drawing.Point(105, 24);
+      this.similarityLabel.Name = "similarityLabel";
+      this.similarityLabel.Size = new System.Drawing.Size(108, 13);
+      this.similarityLabel.TabIndex = 3;
+      this.similarityLabel.Text = "Matching constraints:";
+      // 
       // graphControlsPanel
       // 
@@ -129,30 +192,8 @@
       this.graphControlsPanel.Controls.Add(this.moveModeButton);
       this.graphControlsPanel.Controls.Add(this.zoomModeButton);
-      this.graphControlsPanel.Location = new System.Drawing.Point(246, 14);
+      this.graphControlsPanel.Location = new System.Drawing.Point(6, 14);
       this.graphControlsPanel.Name = "graphControlsPanel";
       this.graphControlsPanel.Size = new System.Drawing.Size(93, 30);
       this.graphControlsPanel.TabIndex = 2;
-      // 
-      // similarityModeLabel
-      // 
-      this.similarityModeLabel.AutoSize = true;
-      this.similarityModeLabel.Location = new System.Drawing.Point(6, 20);
-      this.similarityModeLabel.Name = "similarityModeLabel";
-      this.similarityModeLabel.Size = new System.Drawing.Size(80, 13);
-      this.similarityModeLabel.TabIndex = 1;
-      this.similarityModeLabel.Text = "Similarity Mode:";
-      // 
-      // similarityModeSelector
-      // 
-      this.similarityModeSelector.FormattingEnabled = true;
-      this.similarityModeSelector.Items.AddRange(new object[] {
-            "Exact",
-            "High",
-            "Relaxed"});
-      this.similarityModeSelector.Location = new System.Drawing.Point(92, 17);
-      this.similarityModeSelector.Name = "similarityModeSelector";
-      this.similarityModeSelector.Size = new System.Drawing.Size(148, 21);
-      this.similarityModeSelector.TabIndex = 0;
-      this.similarityModeSelector.SelectedIndexChanged += new System.EventHandler(this.similarityModeSelector_SelectedIndexChanged);
       // 
       // selectModeButton
@@ -188,14 +229,4 @@
       this.zoomModeButton.UseVisualStyleBackColor = true;
       this.zoomModeButton.CheckedChanged += new System.EventHandler(this.zoomModeButton_CheckedChanged);
-      // 
-      // genealogyGraphChart
-      // 
-      this.genealogyGraphChart.BackColor = System.Drawing.SystemColors.Control;
-      this.genealogyGraphChart.Dock = System.Windows.Forms.DockStyle.Fill;
-      this.genealogyGraphChart.Location = new System.Drawing.Point(3, 3);
-      this.genealogyGraphChart.Name = "genealogyGraphChart";
-      this.genealogyGraphChart.ScaleOnResize = true;
-      this.genealogyGraphChart.Size = new System.Drawing.Size(352, 520);
-      this.genealogyGraphChart.TabIndex = 2;
       // 
       // GenealogyGraphView
@@ -224,6 +255,4 @@
     private System.Windows.Forms.SplitContainer splitContainer;
     private System.Windows.Forms.GroupBox topControlBox;
-    private System.Windows.Forms.Label similarityModeLabel;
-    private System.Windows.Forms.ComboBox similarityModeSelector;
     private Encodings.SymbolicExpressionTreeEncoding.Views.SymbolicExpressionTreeChart symbolicExpressionTreeChart;
     private System.Windows.Forms.TableLayoutPanel genealogyTableLayout;
@@ -233,4 +262,8 @@
     private System.Windows.Forms.RadioButton moveModeButton;
     private System.Windows.Forms.RadioButton zoomModeButton;
+    private System.Windows.Forms.Label similarityLabel;
+    private System.Windows.Forms.CheckBox matchVariableNamesCheckBox;
+    private System.Windows.Forms.CheckBox matchVariableWeightsCheckBox;
+    private System.Windows.Forms.CheckBox matchConstantsCheckBox;
 
   }
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/GenealogyGraphView.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/GenealogyGraphView.cs	(revision 9083)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/GenealogyGraphView.cs	(revision 9084)
@@ -37,10 +37,11 @@
   public sealed partial class GenealogyGraphView : ItemView {
     private VisualSymbolicExpressionTreeNode selectedVisualSymbExprTreeNode;
+    private SymbolicExpressionTreeNodeSimilarityComparer comparer;
+    private Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> clonedNodes;
+
     public new SymbolicExpressionTreeGenealogyGraph Content {
       get { return (SymbolicExpressionTreeGenealogyGraph)base.Content; }
       set { base.Content = value; }
     }
-
-    private Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> clonedNodeMap;
 
     public GenealogyGraphView()
@@ -51,7 +52,9 @@
       this.zoomModeButton.Image = Common.Resources.VSImageLibrary.Zoom;
       this.selectModeButton.Image = Common.Resources.VSImageLibrary.Object;
-
-
-      similarityModeSelector.SelectedIndex = 0; // set default similarity mode to "exact"
+      comparer = new SymbolicExpressionTreeNodeSimilarityComparer {
+        MatchConstantValues = true,
+        MatchVariableWeights = true,
+        MatchVariableNames = true
+      };
     }
 
@@ -97,51 +100,17 @@
     // TODO: Put event handlers of child controls here.
     private void graphChart_GenealogyGraphNodeClicked(object sender, MouseEventArgs e) {
-      // the type hierarchy goes like this: VisualGenealogyGraphNode --> GenealogyGraphNode --> symbolicExpressionTree
+      // the type hierarchy goes like this: VisualGenealogyGraphNode --> GenealogyGraphNode --> SymbolicExpressionTree
       var visualGenealogyGraphNode = (VisualGenealogyGraphNode)sender;
-      var genealogyGraphNode = (SymbolicExpressionGenealogyGraphNode)visualGenealogyGraphNode.Data;
+      var genealogyGraphNode = visualGenealogyGraphNode.Data;
       symbolicExpressionTreeChart.Tree = genealogyGraphNode.SymbolicExpressionTree;
-      // highlight the relevant fragment in the symbolic expression tree
-      selectedVisualSymbExprTreeNode = null;
-
-      bool repaint = false;
-
-      // paint highlighted nodes in symbolic expression tree
-      if (selectedVisualSymbExprTreeNode != null) {
-        // clear selected subtree from the tree chart
-        var nodes = symbolicExpressionTreeChart.Tree.IterateNodesBreadth() as List<ISymbolicExpressionTreeNode>;
-        var fragments = selectedVisualSymbExprTreeNode.SymbolicExpressionTreeNode.IterateNodesBreadth() as List<ISymbolicExpressionTreeNode>;
-        var similarityLevel = Enum.GetNames(typeof(SimilarityLevel))[similarityModeSelector.SelectedIndex];
-        int index = SymbolicExpressionTreeMatching.FindMatch(nodes, fragments, (SimilarityLevel)Enum.Parse(typeof(SimilarityLevel), similarityLevel));
-        if (index != -1) {
-          selectedVisualSymbExprTreeNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(nodes[index]);
-          var subtree = selectedVisualSymbExprTreeNode.SymbolicExpressionTreeNode;
-          foreach (var node in subtree.IterateNodesBreadth()) {
-            var visualNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node);
-            visualNode.LineColor = Color.Blue;
-          }
-          repaint = true;
-        }
+      if (genealogyGraphNode.InEdges == null) return;
+      var arc = genealogyGraphNode.InEdges.First(x => x.Source != x.Target && x.Data != null);
+      if (arc == null) return;
+      var fragment = (IFragment)arc.Data;
+      foreach (var node in fragment.Root.IterateNodesBreadth()) {
+        var visualSymbExprTreeNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node);
+        visualSymbExprTreeNode.LineColor = Color.OrangeRed;
       }
-      // paint graph nodes
-      var tree = symbolicExpressionTreeChart.Tree;
-      var graphNodes = Content.Nodes.Where(n => n.SymbolicExpressionTree == tree).ToList();
-      if (graphNodes.Count > 0) {
-        foreach (var graphNode in graphNodes)
-          if (graphNode != null && graphNode.InEdges != null) {
-            var arc = graphNode.InEdges.Find(a => a.Data != null);
-            if (arc != null) {
-              var fragment = arc.Data as ISymbolicExpressionTreeNode;
-              foreach (var node in fragment.IterateNodesBreadth()) {
-                var visualNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node);
-                if (visualNode == null)
-                  continue;
-                visualNode.LineColor = Color.Orange;
-              }
-            }
-            repaint = true;
-          }
-      }
-      if (repaint)
-        symbolicExpressionTreeChart.Repaint();
+      symbolicExpressionTreeChart.Repaint(); // pain orange nodes
     }
 
@@ -162,5 +131,4 @@
 
     private void treeChart_SymbolicExpressionTreeNodeClicked(object sender, MouseEventArgs e) {
-      ISymbolicExpressionTreeNode selectedSubtree = null;
       genealogyGraphChart.Chart.UpdateEnabled = false;
       switch (e.Button) {
@@ -168,98 +136,74 @@
             selectedVisualSymbExprTreeNode = (VisualSymbolicExpressionTreeNode)sender;
             if (selectedVisualSymbExprTreeNode == null) return;
-            // find out which individuals in the genealogy graph contain this specific subtree
-            selectedSubtree = selectedVisualSymbExprTreeNode.SymbolicExpressionTreeNode;
-            // clone every node in the selected subtree so that edit operations are possible without altering the original subtree
-            // save the originalNode-->clone mapping to make it easier to work with subtrees
-            if (clonedNodeMap == null)
-              clonedNodeMap = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>();
-            clonedNodeMap.Clear();
-            var selectedSubtreeClone = selectedSubtree.Clone() as SymbolicExpressionTreeNode;
-            var subtreeNodes = selectedSubtree.IterateNodesPostfix().ToList();
-            var cloneNodes = selectedSubtreeClone.IterateNodesPostfix().ToList();
-            for (int i = 0; i != subtreeNodes.Count; ++i)
-              clonedNodeMap.Add(subtreeNodes[i], cloneNodes[i]);
-            // highlight subtree nodes in the tree chart
-            foreach (var node in symbolicExpressionTreeChart.Tree.IterateNodesPostfix()) {
-              var visualNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node);
-              visualNode.FillColor = Color.Transparent;
+            ISymbolicExpressionTreeNode selectedSubtree = selectedVisualSymbExprTreeNode.SymbolicExpressionTreeNode;
+            var clonedSubtree = (ISymbolicExpressionTreeNode)selectedSubtree.Clone();
+            // map original nodes to cloned nodes
+            clonedNodes = selectedSubtree.IterateNodesPrefix()
+                                         .Zip(clonedSubtree.IterateNodesPrefix(), (original, clone) => new { original, clone })
+                                         .ToDictionary(p => p.original, p => p.clone);
+
+            foreach (var node in symbolicExpressionTreeChart.Tree.IterateNodesPrefix()) {
+              symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node).FillColor = Color.Transparent;
             }
-            selectedSubtree.ForEachNodePostfix(node => {
+            foreach (var node in selectedSubtree.IterateNodesPrefix()) {
               symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node).FillColor = Color.LightBlue;
-            });
+            }
+            break;
           }
-          break;
         case MouseButtons.Middle: {
             var visualNode = (VisualSymbolicExpressionTreeNode)sender;
-            if (selectedVisualSymbExprTreeNode == null || selectedVisualSymbExprTreeNode == visualNode)
-              return;
-            selectedSubtree = clonedNodeMap[selectedVisualSymbExprTreeNode.SymbolicExpressionTreeNode];
+            if (selectedVisualSymbExprTreeNode == null || selectedVisualSymbExprTreeNode == visualNode) return;
             var selectedNode = visualNode.SymbolicExpressionTreeNode;
-            if (clonedNodeMap.ContainsKey(selectedNode)) {
-              var selected = clonedNodeMap[selectedNode];
-              var parent = selected.Parent;
-              parent.RemoveSubtree(parent.IndexOfSubtree(selected));
-              selectedNode.ForEachNodePostfix(node => {
+            if (clonedNodes.ContainsKey(selectedNode)) {
+              var selectedClone = clonedNodes[selectedNode];
+              var parent = selectedClone.Parent;
+              parent.RemoveSubtree(parent.IndexOfSubtree(selectedClone));
+              foreach (var node in selectedNode.IterateNodesPrefix()) {
                 symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node).FillColor = Color.Transparent;
-                clonedNodeMap.Remove(node);
-              });
+              }
             }
-          }
-          break;
-      }
-      // update visual graph nodes that contain matching trees
-      Color[] colors = { Color.LightSkyBlue, Color.PaleGreen, Color.Tan };
-      genealogyGraphChart.ClearAllNodes(); // clear node colors
-      // color each graph node according to the degree to which it matches the selected tree fragment 
-      var similarityValues = Enum.GetValues(typeof(SimilarityLevel)).Cast<SimilarityLevel>().ToList();
-      foreach (var graphNode in genealogyGraphChart.Graph.Nodes) {
-        var tree = graphNode.SymbolicExpressionTree;
-        for (int i = 0; i != similarityValues.Count; ++i) {
-          if (tree.ContainsFragment(selectedSubtree, similarityValues[i])) {
-            genealogyGraphChart.HighlightNode(graphNode, colors[i]);
             break;
           }
-        }
       }
+      if (selectedVisualSymbExprTreeNode == null || clonedNodes == null) return;
+      // update visual graph nodes that contain matching trees
+      MatchNodesAndRepaint();
+      // refresh the tree chart
+      symbolicExpressionTreeChart.Repaint();
+    }
+
+    void MatchNodesAndRepaint() {
+      genealogyGraphChart.Chart.UpdateEnabled = false;
+      genealogyGraphChart.ClearAllNodes(); // clear node colors
+      var fragment = new Fragment(clonedNodes[selectedVisualSymbExprTreeNode.SymbolicExpressionTreeNode]);
+      var fragmentLength = fragment.Length;
+      genealogyGraphChart.HighlightNodes(from node in genealogyGraphChart.Graph.Nodes
+                                         let tree = node.SymbolicExpressionTree
+                                         where tree.Length >= fragmentLength
+                                         where tree.Root.ContainsFragment(fragment, comparer)
+                                         select tree, Color.DodgerBlue);
       genealogyGraphChart.Chart.UpdateEnabled = true;
       genealogyGraphChart.Chart.EnforceUpdate();
-      // refresh the tree chart
-      symbolicExpressionTreeChart.Repaint();
     }
 
     private void treeChart_SymbolicExpressionTreeNodeDoubleClicked(object sender, MouseEventArgs e) {
     }
-
-    private void similarityModeSelector_SelectedIndexChanged(object sender, EventArgs e) {
-      if (selectedVisualSymbExprTreeNode == null) return;
-      var treeNode = selectedVisualSymbExprTreeNode.SymbolicExpressionTreeNode;
-      var similarityLevel = Enum.GetNames(typeof(SimilarityLevel))[similarityModeSelector.SelectedIndex];
-      var owners = genealogyGraphChart.Graph.TraceFragment(treeNode, (SimilarityLevel)Enum.Parse(typeof(SimilarityLevel), similarityLevel)).ToList();
-      if (owners.Any()) {
-        genealogyGraphChart.Chart.UpdateEnabled = false;
-        genealogyGraphChart.ClearAllNodes(); // clear the fill color of all nodes
-        genealogyGraphChart.HighlightNodes(owners, Color.LightSkyBlue);
-        // highlight matching individuals from the genealogy
-        genealogyGraphChart.Chart.UpdateEnabled = true;
-      }
-      genealogyGraphChart.Chart.EnforceUpdate();
-      // highlight subtree nodes in the tree chart
-      foreach (var node in symbolicExpressionTreeChart.Tree.IterateNodesPostfix()) {
-        var visualNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node);
-        visualNode.FillColor = Color.Transparent;
-      }
-      foreach (var node in treeNode.IterateNodesPostfix()) {
-        var visualNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node);
-        visualNode.FillColor = Color.LightBlue;
-      }
-    }
     #endregion
-
-    private void inDegreeButton_Click(object sender, EventArgs e) {
-      genealogyGraphChart.HighlightInDegree();
-    }
-
-    private void outDegreeButton_Click(object sender, EventArgs e) {
-      genealogyGraphChart.HighlightOutDegree();
+    private void matchConstantsCheckBox_CheckedChanged(object sender, EventArgs e) {
+      comparer.MatchConstantValues = matchConstantsCheckBox.Checked;
+      if (selectedVisualSymbExprTreeNode != null)
+        MatchNodesAndRepaint();
+    }
+
+    private void matchVariableWeightsCheckBox_CheckedChanged(object sender, EventArgs e) {
+      comparer.MatchVariableWeights = matchVariableWeightsCheckBox.Checked;
+      if (selectedVisualSymbExprTreeNode != null)
+        MatchNodesAndRepaint();
+    }
+
+    private void matchVariableNamesCheckBox_CheckedChanged(object sender, EventArgs e) {
+      comparer.MatchVariableNames = matchVariableNamesCheckBox.Checked;
+      if (selectedVisualSymbExprTreeNode != null)
+        MatchNodesAndRepaint();
     }
   }
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/VisualGenealogyGraphArc.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/VisualGenealogyGraphArc.cs	(revision 9083)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/VisualGenealogyGraphArc.cs	(revision 9084)
@@ -49,4 +49,5 @@
 
     internal void UpdatePosition() {
+      if (Source.Equals(Target)) return;
       // calculate the positions of the arc ends so that virtually the line will go through the centers of the two elliptical node shapes
       PointD c1 = Source.Center;
@@ -74,4 +75,6 @@
         p2Y = c2.Y - p1.Y;
       }
+      if (double.IsNaN(p1X) || double.IsNaN(p1Y) || double.IsNaN(p2X) || double.IsNaN(p2Y))
+        throw new Exception("Error calculating arc position.");
       p1.X = p1X;
       p1.Y = p1Y;
Index: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/VisualGenealogyGraphNode.cs
===================================================================
--- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/VisualGenealogyGraphNode.cs	(revision 9083)
+++ branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/VisualGenealogyGraphNode.cs	(revision 9084)
@@ -27,15 +27,15 @@
 namespace HeuristicLab.EvolutionaryTracking.Views {
   public class VisualGenealogyGraphNode : Ellipse {
-    public IGenealogyGraphNode Data { get; internal set; }
-    private List<VisualGenealogyGraphArc> _incomingArcs = new List<VisualGenealogyGraphArc>();
-    private List<VisualGenealogyGraphArc> _outgoingArgs = new List<VisualGenealogyGraphArc>();
+    public SymbolicExpressionGenealogyGraphNode Data { get; internal set; }
+    private List<VisualGenealogyGraphArc> incomingArcs = new List<VisualGenealogyGraphArc>();
+    private List<VisualGenealogyGraphArc> outgoingArcs = new List<VisualGenealogyGraphArc>();
 
     public List<VisualGenealogyGraphArc> IncomingArcs {
-      get { return _incomingArcs; }
-      set { _incomingArcs = value; }
+      get { return incomingArcs; }
+      set { incomingArcs = value; }
     }
     public List<VisualGenealogyGraphArc> OutgoingArcs {
-      get { return _outgoingArgs; }
-      set { _outgoingArgs = value; }
+      get { return outgoingArcs; }
+      set { outgoingArcs = value; }
     }
 
@@ -81,5 +81,5 @@
         graphics.FillEllipse(Brush, p.X, p.Y, s.Width, s.Height);
       graphics.DrawEllipse(Pen, p.X, p.Y, s.Width, s.Height);
-      if (((SymbolicExpressionGenealogyGraphNode)Data).IsElite) {
+      if (Data.IsElite) {
         graphics.DrawEllipse(Pen, p.X + 2, p.Y + 2, s.Width - 4, s.Height - 4);
       }
