Index: /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
===================================================================
--- /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 14426)
+++ /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 14427)
@@ -317,4 +317,5 @@
     <Compile Include="Tracking\SchemaDiversification\SchemaEvaluator.cs" />
     <Compile Include="Tracking\SchemaDiversification\SchemaCreator.cs" />
+    <Compile Include="Tracking\SchemaDiversification\SchemaUtil.cs" />
     <Compile Include="Tracking\SchemaDiversification\UpdateQualityOperator.cs" />
     <Compile Include="Tracking\SymbolicDataAnalysisExpressionAfterCrossoverOperator.cs" />
Index: /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/Wildcards/AnyNodeSymbol.cs
===================================================================
--- /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/Wildcards/AnyNodeSymbol.cs	(revision 14426)
+++ /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/Wildcards/AnyNodeSymbol.cs	(revision 14427)
@@ -41,5 +41,5 @@
     }
 
-    private AnyNodeSymbol() : base("=", "A wildcard symbol that can match any node of the same type (function or leaf node)") { }
+    public AnyNodeSymbol() : base("=", "A wildcard symbol that can match any node of the same type (function or leaf node)") { }
 
     public AnyNodeSymbol(int minimumArity, int maximumArity)
Index: /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/Analyzers/SymbolicDataAnalysisSchemaFrequencyAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/Analyzers/SymbolicDataAnalysisSchemaFrequencyAnalyzer.cs	(revision 14426)
+++ /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/Analyzers/SymbolicDataAnalysisSchemaFrequencyAnalyzer.cs	(revision 14427)
@@ -23,5 +23,4 @@
 using System.Collections.Generic;
 using System.Linq;
-using System.Text;
 using System.Threading.Tasks;
 using HeuristicLab.Common;
@@ -34,5 +33,5 @@
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
-namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Tracking.Analyzers {
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
   [Item("SymbolicDataAnalysisSchemaFrequencyAnalyzer", "An analyzer which counts schema frequencies in the population.")]
   [StorableClass]
@@ -157,5 +156,5 @@
       var generation = Generation.Value;
 
-      var population = PopulationGraph.GetByRank(generation).Cast<IGenealogyGraphNode<ISymbolicExpressionTree>>().ToList();
+      var population = PopulationGraph.Vertices.Where(x => x.InDegree == 2 && x.Rank > generation - 1).ToList();
       var vertices = population.Where(x => x.InDegree == 2).OrderByDescending(x => x.Quality).ToList();
       ResultCollection resultCollection;
@@ -182,5 +181,5 @@
       }
       var schemas = SchemaCreator.GenerateSchemas(vertices, MinimumSchemaLength, StrictSchemaMatching).ToList();
-      var schemaStrings = schemas.Select(x => SubtreeToString(x.Root.GetSubtree(0).GetSubtree(0), StrictSchemaMatching)).ToList();
+      var schemaStrings = schemas.Select(x => x.Root.GetSubtree(0).GetSubtree(0).FormatToString(StrictSchemaMatching)).ToList();
       int[][] matchingIndices;
       if (ExecuteInParallel) {
@@ -188,8 +187,8 @@
         Parallel.For(0, schemas.Count, new ParallelOptions { MaxDegreeOfParallelism = MaximumDegreeOfParallelism }, i => {
           var schema = schemas[i];
-          matchingIndices[i] = Enumerable.Range(0, trees.Count).Where(v => qm.Match(trees[v].Root, schema.Root)).ToArray();
+          matchingIndices[i] = Enumerable.Range(0, trees.Count).Where(v => qm.Match(trees[v], schema)).ToArray();
         });
       } else {
-        matchingIndices = schemas.Select(x => Enumerable.Range(0, trees.Count).Where(v => qm.Match(trees[v].Root, x.Root)).ToArray()).ToArray();
+        matchingIndices = schemas.Select(x => Enumerable.Range(0, trees.Count).Where(v => qm.Match(trees[v], x)).ToArray()).ToArray();
       }
 
@@ -230,8 +229,9 @@
       if (!schemaStatistics.Any()) return base.Apply(); // shouldn't ever happen
       var columnNames = new[] { "Count", "Avg Quality", "Avg Length", "Avg Genotype Similarity", "Avg Phenotype Similarity", "Avg Population Quality" };
-      var mostFrequent = new DoubleMatrix(schemaStatistics.Count, schemaStatistics[0].Item2.Length);
-      mostFrequent.SortableView = true;
+      var mostFrequent = new DoubleMatrix(schemaStatistics.Count, schemaStatistics[0].Item2.Length) {
+        SortableView = true
+      };
       schemaStatistics.Sort((a, b) => { if (a.Item2[0].Equals(b.Item2[0])) return b.Item2[1].CompareTo(a.Item2[1]); return b.Item2[0].CompareTo(a.Item2[0]); });
-      mostFrequentPerGeneration.Add(new Tuple<string, double[]>(schemaStatistics[0].Item1, new[] { (double)generation }.Concat(schemaStatistics[0].Item2).ToArray()));
+      mostFrequentPerGeneration.Add(Tuple.Create(schemaStatistics[0].Item1, new[] { (double)generation }.Concat(schemaStatistics[0].Item2).ToArray()));
       mostFrequent.RowNames = schemaStatistics.Select(x => x.Item1);
       mostFrequent.ColumnNames = columnNames;
@@ -301,5 +301,6 @@
         for (int j = i + 1; j < indices.Length; ++j) {
           var b = indices[j];
-          if (double.IsNaN(similarityMatrix[a, b])) similarityMatrix[a, b] = similarityFunction(trees[a], trees[b]);
+          if (double.IsNaN(similarityMatrix[a, b]))
+            similarityMatrix[a, b] = similarityFunction(trees[a], trees[b]);
           agg += similarityMatrix[a, b];
         }
@@ -307,46 +308,4 @@
       return agg / count;
     }
-
-    private static string SubtreeToString(ISymbolicExpressionTreeNode node, bool strict = false) {
-      StringBuilder strBuilder = new StringBuilder();
-      // internal nodes or leaf nodes?
-      if (node is AnySubtree)
-        return "# ";
-
-      if (node.SubtreeCount > 0) {
-        strBuilder.Append("(");
-        // symbol on same line as '('
-        string label = string.Empty;
-        if (node is AnyNode)
-          label = "=";
-        else {
-          var name = node.Symbol.Name;
-          label = ShortNames.ContainsKey(name) ? ShortNames[name] : name;
-        }
-        strBuilder.Append(label + " ");
-        // each subtree expression on a new line
-        // and closing ')' also on new line
-        foreach (var subtree in node.Subtrees) {
-          strBuilder.Append(SubtreeToString(subtree, strict));
-        }
-        strBuilder.Append(") ");
-      } else {
-        // symbol in the same line with as '(' and ')'
-        var v = node as VariableTreeNode;
-        var c = node as ConstantTreeNode;
-        var w = node as AnyNode; // wildcard
-        string label = string.Empty;
-        if (w != null)
-          label = "=";
-        else if (v != null)
-          label = strict ? string.Format("{0:0.00}_{1}", v.Weight, v.VariableName) : string.Format("{0}", v.VariableName);
-        else if (c != null)
-          label = strict ? string.Format("{0:0.00}", c.Value) : "C";
-        strBuilder.Append(label);
-        if (node.Parent != null && node != node.Parent.Subtrees.Last())
-          strBuilder.Append(" ");
-      }
-      return strBuilder.ToString();
-    }
   }
 }
Index: /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/SchemaDiversification/SchemaCreator.cs
===================================================================
--- /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/SchemaDiversification/SchemaCreator.cs	(revision 14426)
+++ /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/SchemaDiversification/SchemaCreator.cs	(revision 14427)
@@ -23,5 +23,4 @@
 using System.Collections.Generic;
 using System.Linq;
-using System.Text;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -202,5 +201,5 @@
                      select v;
 
-      var schemas = new List<ISymbolicExpressionTree>(GenerateSchemas(vertices, MinimumSchemaLength, StrictSchemaMatching));
+      var schemas = GenerateSchemas(vertices, MinimumSchemaLength, StrictSchemaMatching).ToList();
 
       #region create schemas and add subscopes representing the individuals
@@ -226,8 +225,6 @@
     public static IEnumerable<ISymbolicExpressionTree> GenerateSchemas(IEnumerable<IGenealogyGraphNode<ISymbolicExpressionTree>> vertices, int minimumSchemaLength, bool strict = true) {
       var anySubtreeSymbol = new AnySubtreeSymbol();
-      //            var anyNodeSymbol = new AnyNodeSymbol();
-      var groups = vertices.GroupBy(x => x.Parents.First()).OrderByDescending(g => g.Count()).ToList();
+      var groups = vertices.GroupBy(x => x.Parents.First()).OrderByDescending(g => g.Count());
       var hash = new HashSet<string>();
-      //      var formatter = new SymbolicExpressionTreeStringFormatter { Indent = false, AppendNewLines = false };
       foreach (var g in groups) {
         var parent = g.Key;
@@ -237,21 +234,19 @@
         var schema = (ISymbolicExpressionTree)parent.Data.Clone();
         var nodes = schema.IterateNodesPrefix().ToList();
-        var arcs = g.Select(x => x.InArcs.Last()).Where(x => x.Data != null);
-        var indices = (from arc in arcs
-                       let fragment = (IFragment<ISymbolicExpressionTreeNode>)arc.Data
-                       select fragment.Index1).Distinct().ToArray();
-        var levels = indices.Select(x => schema.Root.GetBranchLevel(nodes[x])).ToArray();
-        Array.Sort(levels, indices);
-        // order nodes by their depth so that cutpoints are replaced with wildcards from the bottom up
-        var nodesToReplace = indices.Select(x => nodes[x]).ToList();
-        for (int i = nodesToReplace.Count - 1; i >= 0; --i) {
-          var node = nodesToReplace[i];
-
+        var fragments = g.Select(x => x.InArcs.Last().Data).Where(x => x != null).Cast<IFragment<ISymbolicExpressionTreeNode>>();
+        var indices = fragments.Select(x => x.Index1).Distinct().OrderByDescending(x => schema.Root.GetBranchLevel(nodes[x]));
+        foreach (var i in indices) {
+          var node = nodes[i];
           // do not replace the node with a wildcard if it would result in a length < MinimumSchemaLength
-          if (schema.Length - node.GetLength() + 1 < minimumSchemaLength)
-            continue;
-
-          var replacement = anySubtreeSymbol.CreateTreeNode();
-          ReplaceSubtree(node, replacement, false);
+          //          if (schema.Length - node.GetLength() + 1 < minimumSchemaLength)
+          //            continue;
+          ISymbolicExpressionTreeNode replacement;
+          if (node.SubtreeCount > 0) {
+            var anyNodeSymbol = new AnyNodeSymbol(node.Symbol.MinimumArity, node.Symbol.MaximumArity);
+            replacement = anyNodeSymbol.CreateTreeNode();
+          } else {
+            replacement = anySubtreeSymbol.CreateTreeNode();
+          }
+          SchemaUtil.ReplaceSubtree(node, replacement, true);
           //          var replacement = new AnyNodeSymbol(node.Symbol.MinimumArity, node.Symbol.MinimumArity).CreateTreeNode();
           //          ReplaceSubtree(node, replacement, true);
@@ -259,74 +254,10 @@
         }
         if (replaced) {
-          //          var str = formatter.Format(schema.Root.GetSubtree(0).GetSubtree(0));
-          var str = SubtreeToString(schema.Root.GetSubtree(0).GetSubtree(0), strict);
-          if (hash.Contains(str)) continue;
-          yield return schema;
-          hash.Add(str);
+          var str = schema.Root.GetSubtree(0).GetSubtree(0).FormatToString(strict);
+          if (hash.Add(str))
+            yield return schema;
         }
       }
     }
-
-    private static void ReplaceSubtree(ISymbolicExpressionTreeNode original, ISymbolicExpressionTreeNode replacement, bool preserveChildren = true) {
-      var parent = original.Parent;
-      if (parent == null)
-        throw new ArgumentException("Parent cannot be null for node " + original);
-      var index = parent.IndexOfSubtree(original);
-      parent.RemoveSubtree(index);
-      parent.InsertSubtree(index, replacement);
-
-      if (preserveChildren) {
-        var subtrees = original.Subtrees.ToList();
-
-        for (int i = subtrees.Count - 1; i >= 0; --i)
-          original.RemoveSubtree(i);
-
-        for (int i = 0; i < subtrees.Count; ++i) {
-          replacement.AddSubtree(subtrees[i]);
-        }
-      }
-    }
-
-    private static string SubtreeToString(ISymbolicExpressionTreeNode node, bool strict = false) {
-      StringBuilder strBuilder = new StringBuilder();
-      // internal nodes or leaf nodes?
-      if (node is AnySubtree)
-        return "# ";
-
-      if (node.SubtreeCount > 0) {
-        strBuilder.Append("(");
-        // symbol on same line as '('
-        string label = string.Empty;
-        if (node is AnyNode)
-          label = "=";
-        else {
-          label = node.Symbol.Name;
-        }
-        strBuilder.Append(label + " ");
-        // each subtree expression on a new line
-        // and closing ')' also on new line
-        foreach (var subtree in node.Subtrees) {
-          strBuilder.Append(SubtreeToString(subtree, strict));
-        }
-        strBuilder.Append(") ");
-      } else {
-        // symbol in the same line with as '(' and ')'
-        var v = node as VariableTreeNode;
-        var c = node as ConstantTreeNode;
-        var w = node as AnyNode; // wildcard
-        string label = string.Empty;
-        if (w != null)
-          label = "=";
-        else if (v != null)
-          label = strict ? string.Format("{0:0.00}_{1}", v.Weight, v.VariableName) : string.Format("{0}", v.VariableName);
-        else if (c != null)
-          label = strict ? string.Format("{0:0.00}", c.Value) : "C";
-        strBuilder.Append(label);
-        if (node.Parent != null && node != node.Parent.Subtrees.Last())
-          strBuilder.Append(" ");
-        //strBuilder.Append(")");
-      }
-      return strBuilder.ToString();
-    }
   }
 }
Index: /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/SchemaDiversification/SchemaEvaluator.cs
===================================================================
--- /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/SchemaDiversification/SchemaEvaluator.cs	(revision 14426)
+++ /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/SchemaDiversification/SchemaEvaluator.cs	(revision 14427)
@@ -234,5 +234,5 @@
         var t = trees[i];
         var tRoot = t.Root.GetSubtree(0).GetSubtree(0);
-        if (t.Length < s.Length || !qm.Comparer.Equals(tRoot, sRoot)) continue;
+        if (t.Length < s.Length || !qm.EqualityComparer.Equals(tRoot, sRoot)) continue;
         filtered.Add(i);
       }
Index: /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/SchemaDiversification/SchemaUtil.cs
===================================================================
--- /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/SchemaDiversification/SchemaUtil.cs	(revision 14427)
+++ /branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tracking/SchemaDiversification/SchemaUtil.cs	(revision 14427)
@@ -0,0 +1,103 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 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.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  public static class SchemaUtil {
+    private static readonly Dictionary<string, string> ShortNames = new Dictionary<string, string> {
+      { "Addition", "+" },
+      { "Subtraction", "-" },
+      { "Multiplication", "*" },
+      { "Division", "/" },
+      { "Logarithm", "Log" },
+      { "Exponential", "Exp" }
+    };
+
+    public static void ReplaceSubtree(ISymbolicExpressionTreeNode original, ISymbolicExpressionTreeNode replacement, bool preserveChildren = true) {
+      var parent = original.Parent;
+      if (parent == null)
+        throw new ArgumentException("Parent cannot be null for node " + original);
+      var index = parent.IndexOfSubtree(original);
+      parent.RemoveSubtree(index);
+      parent.InsertSubtree(index, replacement);
+
+      if (preserveChildren) {
+        var subtrees = original.Subtrees.ToList();
+
+        for (int i = subtrees.Count - 1; i >= 0; --i)
+          original.RemoveSubtree(i);
+
+        for (int i = 0; i < subtrees.Count; ++i) {
+          replacement.AddSubtree(subtrees[i]);
+        }
+      }
+    }
+
+    public static string FormatToString(this ISymbolicExpressionTreeNode node, bool strict = false) {
+      StringBuilder strBuilder = new StringBuilder();
+      // internal nodes or leaf nodes?
+      if (node is AnySubtree)
+        return "# ";
+
+      if (node.SubtreeCount > 0) {
+        strBuilder.Append("(");
+        // symbol on same line as '('
+        string label = string.Empty;
+        if (node is AnyNode)
+          label = "=";
+        else {
+          string shortName;
+          ShortNames.TryGetValue(node.Symbol.Name, out shortName);
+          label = string.IsNullOrEmpty(shortName) ? node.Symbol.Name : shortName;
+        }
+        strBuilder.Append(label + " ");
+        // each subtree expression on a new line
+        // and closing ')' also on new line
+        foreach (var subtree in node.Subtrees) {
+          strBuilder.Append(subtree.FormatToString(strict));
+        }
+        strBuilder.Append(") ");
+      } else {
+        // symbol in the same line with as '(' and ')'
+        var v = node as VariableTreeNode;
+        var c = node as ConstantTreeNode;
+        var w = node as AnyNode; // wildcard
+        string label = string.Empty;
+        if (w != null)
+          label = "=";
+        else if (v != null)
+          label = strict ? string.Format("{0:0.00}_{1}", v.Weight, v.VariableName) : string.Format("{0}", v.VariableName);
+        else if (c != null)
+          label = strict ? string.Format("{0:0.00}", c.Value) : "C";
+        strBuilder.Append(label);
+        if (node.Parent != null && node != node.Parent.Subtrees.Last())
+          strBuilder.Append(" ");
+        //strBuilder.Append(")");
+      }
+      return strBuilder.ToString();
+    }
+  }
+}
