Index: branches/symbreg-factors-2650/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestModel.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestModel.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestModel.cs	(revision 14399)
@@ -202,4 +202,5 @@
 
     public ISymbolicExpressionTree ExtractTree(int treeIdx) {
+      var rf = RandomForest;
       // hoping that the internal representation of alglib is stable
 
@@ -214,5 +215,5 @@
       int offset = 0;
       for (int i = 0; i < treeIdx - 1; i++) {
-        offset = offset + (int)Math.Round(randomForest.innerobj.trees[offset]);
+        offset = offset + (int)Math.Round(rf.innerobj.trees[offset]);
       }
 
@@ -220,5 +221,5 @@
       var varCondSy = new VariableCondition() { IgnoreSlope = true };
 
-      var node = CreateRegressionTreeRec(randomForest.innerobj.trees, offset, offset + 1, constSy, varCondSy);
+      var node = CreateRegressionTreeRec(rf.innerobj.trees, offset, offset + 1, constSy, varCondSy);
 
       var startNode = new StartSymbol().CreateTreeNode();
Index: branches/symbreg-factors-2650/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingChartView.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingChartView.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingChartView.cs	(revision 14399)
@@ -75,5 +75,5 @@
           PreprocessingDataTable pdt = new PreprocessingDataTable(variableName);
           pdt.Rows.Add(row);
-          // dataTablePerVariable does not contain unchecked variables => reduce insert position by number of uncheckt variables to correct the index
+          // dataTablePerVariable does not contain unchecked variables => reduce insert position by number of unchecked variables to correct the index
           int uncheckedUntilVariable = checkedItemList.Content.TakeWhile(x => x.Value != variableName).Count(x => !checkedItemList.Content.ItemChecked(x));
           dataTablePerVariable.Insert(item.Index - uncheckedUntilVariable, pdt);
Index: branches/symbreg-factors-2650/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Grammars/GrammarUtils.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Grammars/GrammarUtils.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Grammars/GrammarUtils.cs	(revision 14399)
@@ -25,52 +25,96 @@
 using System.Collections.Generic;
 using System.Linq;
-
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
   public static class GrammarUtils {
+    private static IEnumerable<ISymbol> GetTopmostSymbols(this ISymbolicExpressionGrammarBase grammar) {
+      // build parents list so we can find out the topmost symbol(s)
+      var parents = new Dictionary<ISymbol, List<ISymbol>>();
+      foreach (var symbol in grammar.Symbols.Where(x => grammar.GetMinimumSubtreeCount(x) > 0)) {
+        var minSubtreeCount = grammar.GetMinimumSubtreeCount(symbol);
+        for (int argIndex = 0; argIndex < minSubtreeCount; ++argIndex) {
+          foreach (var childSymbol in grammar.GetAllowedActiveSymbols(symbol, argIndex)) {
+            if (!parents.ContainsKey(childSymbol))
+              parents[childSymbol] = new List<ISymbol>();
+            parents[childSymbol].Add(symbol);
+          }
+        }
+      }
+      // the topmost symbols have no parents
+      return parents.Values.SelectMany(x => x).Distinct().Where(x => !parents.ContainsKey(x));
+    }
+
+    private static IReadOnlyCollection<ISymbol> IterateBreadthReverse(this ISymbolicExpressionGrammarBase grammar, ISymbol topSymbol) {
+      // sort symbols in reverse breadth order (starting from the topSymbol)
+      // each symbol is visited only once (this avoids infinite recursion)
+      var symbols = new List<ISymbol> { topSymbol };
+      var visited = new HashSet<ISymbol> { topSymbol };
+      int i = 0;
+      while (i < symbols.Count) {
+        var symbol = symbols[i];
+        var minSubtreeCount = grammar.GetMinimumSubtreeCount(symbol);
+
+        for (int argIndex = 0; argIndex < minSubtreeCount; ++argIndex) {
+          foreach (var childSymbol in grammar.GetAllowedActiveSymbols(symbol, argIndex)) {
+            if (grammar.GetMinimumSubtreeCount(childSymbol) == 0)
+              continue;
+
+            if (visited.Add(childSymbol))
+              symbols.Add(childSymbol);
+          }
+        }
+        ++i;
+      }
+      symbols.Reverse();
+      return symbols;
+    }
+
+    private static IEnumerable<ISymbol> GetAllowedActiveSymbols(this ISymbolicExpressionGrammarBase grammar, ISymbol symbol, int argIndex) {
+      return grammar.GetAllowedChildSymbols(symbol, argIndex).Where(s => s.InitialFrequency > 0);
+    }
 
     public static void CalculateMinimumExpressionLengths(ISymbolicExpressionGrammarBase grammar,
       Dictionary<string, int> minimumExpressionLengths) {
-
       minimumExpressionLengths.Clear();
       //terminal symbols => minimum expression length = 1
-      foreach (var s in grammar.Symbols.Where(s => grammar.GetMinimumSubtreeCount(s) == 0))
-        minimumExpressionLengths[s.Name] = 1;
+      foreach (var s in grammar.Symbols) {
+        if (grammar.GetMinimumSubtreeCount(s) == 0)
+          minimumExpressionLengths[s.Name] = 1;
+        else
+          minimumExpressionLengths[s.Name] = int.MaxValue;
+      }
 
-      var symbolAdded = true;
-      while (symbolAdded) {
-        symbolAdded = false;
-        foreach (var remainingSymbol in grammar.Symbols) {
-          if (minimumExpressionLengths.ContainsKey(remainingSymbol.Name)) continue;
-
-          var arguments = grammar.GetMinimumSubtreeCount(remainingSymbol);
-          int minLength = 1;
-
-          foreach (int argumentIndex in Enumerable.Range(0, arguments)) {
-            var capturedMinimumLengths = minimumExpressionLengths;
-            var childSymbols = grammar.GetAllowedChildSymbols(remainingSymbol, argumentIndex)
-              .Where(c => c.InitialFrequency > 0.0 && capturedMinimumLengths.ContainsKey(c.Name));
-
-            if (!childSymbols.Any()) {
-              minLength = -1;
-              break;
+      foreach (var topSymbol in grammar.GetTopmostSymbols()) {
+        // get all symbols below in reverse breadth order
+        // this way we ensure lengths are calculated bottom-up
+        var symbols = grammar.IterateBreadthReverse(topSymbol);
+        foreach (var symbol in symbols) {
+          long minLength = 1;
+          for (int argIndex = 0; argIndex < grammar.GetMinimumSubtreeCount(symbol); ++argIndex) {
+            long length = grammar.GetAllowedActiveSymbols(symbol, argIndex)
+              .Where(x => minimumExpressionLengths.ContainsKey(x.Name))
+              .Select(x => minimumExpressionLengths[x.Name]).DefaultIfEmpty(int.MaxValue).Min();
+            minLength += length;
+          }
+          int oldLength;
+          if (minimumExpressionLengths.TryGetValue(symbol.Name, out oldLength))
+            minLength = Math.Min(minLength, oldLength);
+          minimumExpressionLengths[symbol.Name] = (int)Math.Min(int.MaxValue, minLength);
+        }
+        // correction step for cycles
+        bool changed = true;
+        while (changed) {
+          changed = false;
+          foreach (var symbol in symbols) {
+            long minLength = Enumerable.Range(0, grammar.GetMinimumSubtreeCount(symbol))
+              .Sum(x => grammar.GetAllowedActiveSymbols(symbol, x)
+              .Select(s => (long)minimumExpressionLengths[s.Name]).DefaultIfEmpty(int.MaxValue).Min()) + 1;
+            if (minLength < minimumExpressionLengths[symbol.Name]) {
+              minimumExpressionLengths[symbol.Name] = (int)Math.Min(minLength, int.MaxValue);
+              changed = true;
             }
-            var minLengthPerArgument = childSymbols.Min(c => capturedMinimumLengths[c.Name]);
-            minLength += minLengthPerArgument;
-          }
-
-          if (minLength != -1) {
-            minimumExpressionLengths[remainingSymbol.Name] = minLength;
-            symbolAdded = true;
           }
         }
       }
-
-      //set minLength to int.Maxvalue for all symbols that are not reacheable
-      foreach (var remainingSymbols in grammar.Symbols) {
-        if (!minimumExpressionLengths.ContainsKey(remainingSymbols.Name))
-          minimumExpressionLengths[remainingSymbols.Name] = int.MaxValue;
-      }
     }
-
 
     public static void CalculateMinimumExpressionDepth(ISymbolicExpressionGrammarBase grammar,
@@ -79,39 +123,42 @@
       minimumExpressionDepths.Clear();
       //terminal symbols => minimum expression depth = 1
-      foreach (var s in grammar.Symbols.Where(s => grammar.GetMinimumSubtreeCount(s) == 0))
-        minimumExpressionDepths[s.Name] = 1;
+      foreach (var s in grammar.Symbols) {
+        if (grammar.GetMinimumSubtreeCount(s) == 0)
+          minimumExpressionDepths[s.Name] = 1;
+        else
+          minimumExpressionDepths[s.Name] = int.MaxValue;
+      }
 
-      var symbolAdded = true;
-      while (symbolAdded) {
-        symbolAdded = false;
-        foreach (var remainingSymbol in grammar.Symbols) {
-          if (minimumExpressionDepths.ContainsKey(remainingSymbol.Name)) continue;
-
-          var arguments = grammar.GetMinimumSubtreeCount(remainingSymbol);
-          int minDepth = -1;
-
-          foreach (int argumentIndex in Enumerable.Range(0, arguments)) {
-            var capturedMinimumDepths = minimumExpressionDepths;
-            var childSymbols = grammar.GetAllowedChildSymbols(remainingSymbol, argumentIndex)
-              .Where(c => c.InitialFrequency > 0.0 && capturedMinimumDepths.ContainsKey(c.Name));
-            if (!childSymbols.Any()) {
-              minDepth = -1;
-              break;
+      foreach (var topSymbol in grammar.GetTopmostSymbols()) {
+        // get all symbols below in reverse breadth order
+        // this way we ensure lengths are calculated bottom-up
+        var symbols = grammar.IterateBreadthReverse(topSymbol);
+        foreach (var symbol in symbols) {
+          long minDepth = -1;
+          for (int argIndex = 0; argIndex < grammar.GetMinimumSubtreeCount(symbol); ++argIndex) {
+            long depth = grammar.GetAllowedActiveSymbols(symbol, argIndex)
+              .Where(x => minimumExpressionDepths.ContainsKey(x.Name))
+              .Select(x => (long)minimumExpressionDepths[x.Name]).DefaultIfEmpty(int.MaxValue).Min() + 1;
+            minDepth = Math.Max(minDepth, depth);
+          }
+          int oldDepth;
+          if (minimumExpressionDepths.TryGetValue(symbol.Name, out oldDepth))
+            minDepth = Math.Min(minDepth, oldDepth);
+          minimumExpressionDepths[symbol.Name] = (int)Math.Min(int.MaxValue, minDepth);
+        }
+        // correction step for cycles
+        bool changed = true;
+        while (changed) {
+          changed = false;
+          foreach (var symbol in symbols) {
+            long minDepth = Enumerable.Range(0, grammar.GetMinimumSubtreeCount(symbol))
+              .Max(x => grammar.GetAllowedActiveSymbols(symbol, x)
+              .Select(s => (long)minimumExpressionDepths[s.Name]).DefaultIfEmpty(int.MaxValue).Min()) + 1;
+            if (minDepth < minimumExpressionDepths[symbol.Name]) {
+              minimumExpressionDepths[symbol.Name] = (int)Math.Min(minDepth, int.MaxValue);
+              changed = true;
             }
-            var minDepthPerArgument = childSymbols.Min(c => capturedMinimumDepths[c.Name]);
-            minDepth = Math.Max(minDepth, 1 + minDepthPerArgument);
-          }
-
-          if (minDepth != -1) {
-            minimumExpressionDepths[remainingSymbol.Name] = minDepth;
-            symbolAdded = true;
           }
         }
-      }
-
-      //set minDepth to int.Maxvalue for all symbols that are not reacheable
-      foreach (var remainingSymbols in grammar.Symbols) {
-        if (!minimumExpressionDepths.ContainsKey(remainingSymbols.Name))
-          minimumExpressionDepths[remainingSymbols.Name] = int.MaxValue;
       }
     }
Index: branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 14399)
@@ -332,5 +332,5 @@
           term = AutoDiff.TermBuilder.Product(w, par);
         } else {
-          term = par;
+          term = varNode.Weight * par;
         }
         return true;
@@ -362,5 +362,5 @@
           term = AutoDiff.TermBuilder.Product(w, par);
         } else {
-          term = par;
+          term = varNode.Weight * par;
         }
         return true;
Index: branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs	(revision 14399)
@@ -113,5 +113,5 @@
       } else if (node.Symbol is Division) {
         if (node.SubtreeCount == 1) {
-          strBuilder.Append(@" \cfrac{1");
+          strBuilder.Append(@" \cfrac{1}{");
         } else {
           strBuilder.Append(@" \cfrac{ ");
@@ -182,7 +182,12 @@
         var constName = "c_{" + constIndex + "}";
         constIndex++;
-        strBuilder.Append(constName + " ");
         var constNode = node as ConstantTreeNode;
-        constants.Add(new KeyValuePair<string, double>(constName, constNode.Value));
+        if (constNode.Value.IsAlmost(1.0)) {
+          strBuilder.Append("1 ");
+        } else {
+          strBuilder.Append(constName);
+          constants.Add(new KeyValuePair<string, double>(constName, constNode.Value));
+        }
+
       } else if (node.Symbol is FactorVariable) {
         var factorNode = node as FactorVariableTreeNode;
Index: branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/ClassificationPerformanceMeasuresCalculator.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/ClassificationPerformanceMeasuresCalculator.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/ClassificationPerformanceMeasuresCalculator.cs	(revision 14399)
@@ -25,5 +25,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  public class ClassificationPerformanceMeasuresCalculator : IDeepCloneable {
+  public class ClassificationPerformanceMeasuresCalculator : DeepCloneable {
 
     public ClassificationPerformanceMeasuresCalculator(string positiveClassName, double positiveClassValue) {
@@ -33,5 +33,5 @@
     }
 
-    protected ClassificationPerformanceMeasuresCalculator(ClassificationPerformanceMeasuresCalculator original, Cloner cloner = null) {
+    protected ClassificationPerformanceMeasuresCalculator(ClassificationPerformanceMeasuresCalculator original, Cloner cloner) {
       positiveClassName = original.positiveClassName;
       positiveClassValue = original.positiveClassValue;
@@ -148,16 +148,6 @@
     }
 
-    // IDeepCloneable interface members
-    public object Clone() {
-      return new ClassificationPerformanceMeasuresCalculator(this);
-    }
-
-    public IDeepCloneable Clone(Cloner cloner) {
-      var clone = cloner.GetClone(this);
-      if (clone == null) {
-        clone = new ClassificationPerformanceMeasuresCalculator(this);
-        cloner.RegisterClonedObject(this, clone);
-      }
-      return clone;
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ClassificationPerformanceMeasuresCalculator(this, cloner);
     }
   }
Index: branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineAccuracyCalculator.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineAccuracyCalculator.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineAccuracyCalculator.cs	(revision 14399)
@@ -25,5 +25,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  public class OnlineAccuracyCalculator : IOnlineCalculator, IDeepCloneable {
+  public class OnlineAccuracyCalculator : DeepCloneable, IOnlineCalculator {
 
     private int correctlyClassified;
@@ -39,10 +39,15 @@
     }
 
-    // private constructor used internally by the Clone() method
-    protected OnlineAccuracyCalculator(OnlineAccuracyCalculator other, Cloner cloner = null) {
-      correctlyClassified = other.correctlyClassified;
-      n = other.n;
-      errorState = other.errorState;
+    protected OnlineAccuracyCalculator(OnlineAccuracyCalculator original, Cloner cloner)
+      : base(original, cloner) {
+      correctlyClassified = original.correctlyClassified;
+      n = original.n;
+      errorState = original.errorState;
     }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OnlineAccuracyCalculator(this, cloner);
+    }
+
 
     #region IOnlineCalculator Members
@@ -98,17 +103,4 @@
     }
 
-    // IDeepCloneable interface members
-    public object Clone() {
-      return new OnlineAccuracyCalculator(this);
-    }
-
-    public IDeepCloneable Clone(Cloner cloner) {
-      var clone = cloner.GetClone(this);
-      if (clone == null) {
-        clone = new OnlineAccuracyCalculator(this);
-        cloner.RegisterClonedObject(this, clone);
-      }
-      return clone;
-    }
   }
 }
Index: branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineBoundedMeanSquaredErrorCalculator.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineBoundedMeanSquaredErrorCalculator.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineBoundedMeanSquaredErrorCalculator.cs	(revision 14399)
@@ -25,5 +25,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  public class OnlineBoundedMeanSquaredErrorCalculator : IOnlineCalculator, IDeepCloneable {
+  public class OnlineBoundedMeanSquaredErrorCalculator : DeepCloneable, IOnlineCalculator {
 
     private double errorSum;
@@ -45,5 +45,5 @@
     }
 
-    protected OnlineBoundedMeanSquaredErrorCalculator(OnlineBoundedMeanSquaredErrorCalculator original, Cloner cloner = null) {
+    protected OnlineBoundedMeanSquaredErrorCalculator(OnlineBoundedMeanSquaredErrorCalculator original, Cloner cloner) {
       LowerBound = original.LowerBound;
       UpperBound = original.UpperBound;
@@ -107,15 +107,6 @@
 
     // IDeepCloneable interface members
-    public object Clone() {
-      return new OnlineBoundedMeanSquaredErrorCalculator(this);
-    }
-
-    public IDeepCloneable Clone(Cloner cloner) {
-      var clone = cloner.GetClone(this);
-      if (clone == null) {
-        clone = new OnlineBoundedMeanSquaredErrorCalculator(this);
-        cloner.RegisterClonedObject(this, clone);
-      }
-      return clone;
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OnlineBoundedMeanSquaredErrorCalculator(this, cloner);
     }
   }
Index: branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineCovarianceCalculator.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineCovarianceCalculator.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineCovarianceCalculator.cs	(revision 14399)
@@ -25,5 +25,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  public class OnlineCovarianceCalculator : IOnlineCalculator, IDeepCloneable {
+  public class OnlineCovarianceCalculator : DeepCloneable, IOnlineCalculator {
 
     private double xMean, yMean, Cn;
@@ -39,5 +39,5 @@
     }
 
-    protected OnlineCovarianceCalculator(OnlineCovarianceCalculator other, Cloner cloner = null) {
+    protected OnlineCovarianceCalculator(OnlineCovarianceCalculator other, Cloner cloner) {
       Cn = other.Cn;
       xMean = other.xMean;
@@ -104,16 +104,6 @@
     }
 
-    // IDeepCloneable interface members
-    public object Clone() {
-      return new OnlineCovarianceCalculator(this);
-    }
-
-    public IDeepCloneable Clone(Cloner cloner) {
-      var clone = cloner.GetClone(this);
-      if (clone == null) {
-        clone = new OnlineCovarianceCalculator(this);
-        cloner.RegisterClonedObject(this, clone);
-      }
-      return clone;
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OnlineCovarianceCalculator(this, cloner);
     }
   }
Index: branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineDirectionalSymmetryCalculator.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineDirectionalSymmetryCalculator.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineDirectionalSymmetryCalculator.cs	(revision 14399)
@@ -26,5 +26,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  public class OnlineDirectionalSymmetryCalculator : IOnlineTimeSeriesCalculator, IDeepCloneable {
+  public class OnlineDirectionalSymmetryCalculator : DeepCloneable, IOnlineTimeSeriesCalculator {
     private int n;
     private int nCorrect;
@@ -123,16 +123,6 @@
     }
 
-    // IDeepCloneable interface members
-    public object Clone() {
-      return new OnlineDirectionalSymmetryCalculator(this);
-    }
-
-    public IDeepCloneable Clone(Cloner cloner) {
-      var clone = cloner.GetClone(this);
-      if (clone == null) {
-        clone = new OnlineDirectionalSymmetryCalculator(this);
-        cloner.RegisterClonedObject(this, clone);
-      }
-      return clone;
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OnlineDirectionalSymmetryCalculator(this, cloner);
     }
   }
Index: branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineLinearScalingParameterCalculator.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineLinearScalingParameterCalculator.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineLinearScalingParameterCalculator.cs	(revision 14399)
@@ -25,5 +25,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  public class OnlineLinearScalingParameterCalculator : IDeepCloneable {
+  public class OnlineLinearScalingParameterCalculator : DeepCloneable {
 
     /// <summary>
@@ -126,17 +126,6 @@
     }
 
-    // IDeepCloneable interface members
-    public object Clone() {
-      var cloner = new Cloner();
+    public override IDeepCloneable Clone(Cloner cloner) {
       return new OnlineLinearScalingParameterCalculator(this, cloner);
-    }
-
-    public IDeepCloneable Clone(Cloner cloner) {
-      var clone = cloner.GetClone(this);
-      if (clone == null) {
-        clone = new OnlineLinearScalingParameterCalculator(this, cloner);
-        cloner.RegisterClonedObject(this, clone);
-      }
-      return clone;
     }
   }
Index: branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMaxAbsoluteErrorCalculator.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMaxAbsoluteErrorCalculator.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMaxAbsoluteErrorCalculator.cs	(revision 14399)
@@ -25,5 +25,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  public class OnlineMaxAbsoluteErrorCalculator : IOnlineCalculator, IDeepCloneable {
+  public class OnlineMaxAbsoluteErrorCalculator : DeepCloneable, IOnlineCalculator {
 
     private double mae;
@@ -96,16 +96,6 @@
     }
 
-    // IDeepCloneable interface members
-    public object Clone() {
-      return new OnlineMaxAbsoluteErrorCalculator(this);
-    }
-
-    public IDeepCloneable Clone(Cloner cloner) {
-      var clone = cloner.GetClone(this);
-      if (clone == null) {
-        clone = new OnlineMaxAbsoluteErrorCalculator(this);
-        cloner.RegisterClonedObject(this, clone);
-      }
-      return clone;
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OnlineMaxAbsoluteErrorCalculator(this, cloner);
     }
   }
Index: branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsoluteErrorCalculator.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsoluteErrorCalculator.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsoluteErrorCalculator.cs	(revision 14399)
@@ -25,5 +25,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  public class OnlineMeanAbsoluteErrorCalculator : IOnlineCalculator, IDeepCloneable {
+  public class OnlineMeanAbsoluteErrorCalculator : DeepCloneable, IOnlineCalculator {
 
     private double sae;
@@ -95,16 +95,6 @@
     }
 
-    // IDeepCloneable interface members
-    public object Clone() {
-      return new OnlineMeanAbsoluteErrorCalculator(this);
-    }
-
-    public IDeepCloneable Clone(Cloner cloner) {
-      var clone = cloner.GetClone(this);
-      if (clone == null) {
-        clone = new OnlineMeanAbsoluteErrorCalculator(this);
-        cloner.RegisterClonedObject(this, clone);
-      }
-      return clone;
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OnlineMeanAbsoluteErrorCalculator(this, cloner);
     }
   }
Index: branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsolutePercentageErrorCalculator.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsolutePercentageErrorCalculator.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsolutePercentageErrorCalculator.cs	(revision 14399)
@@ -25,5 +25,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  public class OnlineMeanAbsolutePercentageErrorCalculator : IOnlineCalculator, IDeepCloneable {
+  public class OnlineMeanAbsolutePercentageErrorCalculator : DeepCloneable, IOnlineCalculator {
 
     private double sre;
@@ -96,16 +96,6 @@
     }
 
-    // IDeepCloneable interface members
-    public object Clone() {
-      return new OnlineMeanAbsolutePercentageErrorCalculator(this);
-    }
-
-    public IDeepCloneable Clone(Cloner cloner) {
-      var clone = cloner.GetClone(this);
-      if (clone == null) {
-        clone = new OnlineMeanAbsolutePercentageErrorCalculator(this);
-        cloner.RegisterClonedObject(this, clone);
-      }
-      return clone;
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OnlineMeanAbsolutePercentageErrorCalculator(this, cloner);
     }
   }
Index: branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAndVarianceCalculator.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAndVarianceCalculator.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAndVarianceCalculator.cs	(revision 14399)
@@ -24,5 +24,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  public class OnlineMeanAndVarianceCalculator : IDeepCloneable {
+  public class OnlineMeanAndVarianceCalculator : DeepCloneable {
 
     private double m_oldM, m_newM, m_oldS, m_newS;
@@ -118,16 +118,6 @@
     }
 
-    // IDeepCloneable members
-    public object Clone() {
-      return new OnlineMeanAndVarianceCalculator(this);
-    }
-
-    public IDeepCloneable Clone(Cloner cloner) {
-      var clone = cloner.GetClone(this);
-      if (clone == null) {
-        clone = new OnlineMeanAndVarianceCalculator(this);
-        cloner.RegisterClonedObject(this, clone);
-      }
-      return clone;
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OnlineMeanAndVarianceCalculator(this, cloner);
     }
   }
Index: branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanErrorCalculator.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanErrorCalculator.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanErrorCalculator.cs	(revision 14399)
@@ -25,5 +25,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  public class OnlineMeanErrorCalculator : IOnlineCalculator, IDeepCloneable {
+  public class OnlineMeanErrorCalculator : DeepCloneable, IOnlineCalculator {
 
     private readonly OnlineMeanAndVarianceCalculator meanAndVarianceCalculator;
@@ -80,17 +80,6 @@
     }
 
-    // IDeepCloneable members
-    public object Clone() {
-      var cloner = new Cloner();
+    public override IDeepCloneable Clone(Cloner cloner) {
       return new OnlineMeanErrorCalculator(this, cloner);
-    }
-
-    public IDeepCloneable Clone(Cloner cloner) {
-      var clone = cloner.GetClone(this);
-      if (clone == null) {
-        clone = new OnlineMeanErrorCalculator(this, cloner);
-        cloner.RegisterClonedObject(this, clone);
-      }
-      return clone;
     }
   }
Index: branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanSquaredErrorCalculator.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanSquaredErrorCalculator.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanSquaredErrorCalculator.cs	(revision 14399)
@@ -25,5 +25,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  public class OnlineMeanSquaredErrorCalculator : IOnlineCalculator, IDeepCloneable {
+  public class OnlineMeanSquaredErrorCalculator : DeepCloneable, IOnlineCalculator {
 
     private double sse;
@@ -95,16 +95,6 @@
     }
 
-    // IDeepCloneable members
-    public object Clone() {
-      return new OnlineMeanSquaredErrorCalculator(this);
-    }
-
-    public IDeepCloneable Clone(Cloner cloner) {
-      var clone = cloner.GetClone(this);
-      if (clone == null) {
-        clone = new OnlineMeanSquaredErrorCalculator(this);
-        cloner.RegisterClonedObject(this, clone);
-      }
-      return clone;
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OnlineMeanSquaredErrorCalculator(this, cloner);
     }
   }
Index: branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineNormalizedMeanSquaredErrorCalculator.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineNormalizedMeanSquaredErrorCalculator.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineNormalizedMeanSquaredErrorCalculator.cs	(revision 14399)
@@ -25,5 +25,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  public class OnlineNormalizedMeanSquaredErrorCalculator : IOnlineCalculator, IDeepCloneable {
+  public class OnlineNormalizedMeanSquaredErrorCalculator : DeepCloneable, IOnlineCalculator {
     private OnlineMeanAndVarianceCalculator meanSquaredErrorCalculator;
     private OnlineMeanAndVarianceCalculator originalVarianceCalculator;
@@ -99,17 +99,6 @@
     }
 
-    // IDeepCloneable members
-    public object Clone() {
-      var cloner = new Cloner();
+    public override IDeepCloneable Clone(Cloner cloner) {
       return new OnlineNormalizedMeanSquaredErrorCalculator(this, cloner);
-    }
-
-    public IDeepCloneable Clone(Cloner cloner) {
-      var clone = cloner.GetClone(this);
-      if (clone == null) {
-        clone = new OnlineNormalizedMeanSquaredErrorCalculator(this, cloner);
-        cloner.RegisterClonedObject(this, clone);
-      }
-      return clone;
     }
   }
Index: branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlinePearsonsRCalculator.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlinePearsonsRCalculator.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlinePearsonsRCalculator.cs	(revision 14399)
@@ -25,5 +25,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  public class OnlinePearsonsRCalculator : IOnlineCalculator, IDeepCloneable {
+  public class OnlinePearsonsRCalculator : DeepCloneable, IOnlineCalculator {
     private OnlineCovarianceCalculator covCalculator = new OnlineCovarianceCalculator();
     private OnlineMeanAndVarianceCalculator sxCalculator = new OnlineMeanAndVarianceCalculator();
@@ -98,17 +98,6 @@
     }
 
-    // IDeepCloneable members
-    public object Clone() {
-      var cloner = new Cloner();
+    public override IDeepCloneable Clone(Cloner cloner) {
       return new OnlinePearsonsRCalculator(this, cloner);
-    }
-
-    public IDeepCloneable Clone(Cloner cloner) {
-      var clone = cloner.GetClone(this);
-      if (clone == null) {
-        clone = new OnlinePearsonsRCalculator(this, cloner);
-        cloner.RegisterClonedObject(this, clone);
-      }
-      return clone;
     }
   }
Index: branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlinePearsonsRSquaredCalculator.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlinePearsonsRSquaredCalculator.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlinePearsonsRSquaredCalculator.cs	(revision 14399)
@@ -26,5 +26,5 @@
 namespace HeuristicLab.Problems.DataAnalysis {
   [Obsolete("Use OnlinePearsonsRCalculator directly")]
-  public class OnlinePearsonsRSquaredCalculator : IOnlineCalculator, IDeepCloneable {
+  public class OnlinePearsonsRSquaredCalculator : DeepCloneable, IOnlineCalculator {
     private readonly OnlinePearsonsRCalculator rCalculator = new OnlinePearsonsRCalculator();
 
@@ -64,17 +64,6 @@
     }
 
-    // IDeepCloneable members
-    public object Clone() {
-      var cloner = new Cloner();
+    public override IDeepCloneable Clone(Cloner cloner) {
       return new OnlinePearsonsRSquaredCalculator(this, cloner);
-    }
-
-    public IDeepCloneable Clone(Cloner cloner) {
-      var clone = cloner.GetClone(this);
-      if (clone == null) {
-        clone = new OnlinePearsonsRSquaredCalculator(this, cloner);
-        cloner.RegisterClonedObject(this, clone);
-      }
-      return clone;
     }
   }
Index: branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs	(revision 14399)
@@ -25,5 +25,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  public class OnlineTheilsUStatisticCalculator : IOnlineTimeSeriesCalculator, IDeepCloneable {
+  public class OnlineTheilsUStatisticCalculator : DeepCloneable, IOnlineTimeSeriesCalculator {
     private OnlineMeanAndVarianceCalculator squaredErrorMeanCalculator;
     private OnlineMeanAndVarianceCalculator unbiasedEstimatorMeanCalculator;
@@ -132,17 +132,6 @@
     }
 
-    // IDeepCloneable members
-    public object Clone() {
-      var cloner = new Cloner();
+    public override IDeepCloneable Clone(Cloner cloner) {
       return new OnlineTheilsUStatisticCalculator(this, cloner);
-    }
-
-    public IDeepCloneable Clone(Cloner cloner) {
-      var clone = cloner.GetClone(this);
-      if (clone == null) {
-        clone = new OnlineTheilsUStatisticCalculator(this, cloner);
-        cloner.RegisterClonedObject(this, clone);
-      }
-      return clone;
     }
   }
Index: branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineWeightedDirectionalSymmetryCalculator.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineWeightedDirectionalSymmetryCalculator.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineWeightedDirectionalSymmetryCalculator.cs	(revision 14399)
@@ -26,5 +26,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  public class OnlineWeightedDirectionalSymmetryCalculator : IOnlineTimeSeriesCalculator, IDeepCloneable {
+  public class OnlineWeightedDirectionalSymmetryCalculator : DeepCloneable, IOnlineTimeSeriesCalculator {
     private int n;
     private double correctSum;
@@ -42,5 +42,5 @@
     }
 
-    protected OnlineWeightedDirectionalSymmetryCalculator(OnlineWeightedDirectionalSymmetryCalculator other, Cloner cloner = null) {
+    protected OnlineWeightedDirectionalSymmetryCalculator(OnlineWeightedDirectionalSymmetryCalculator other, Cloner cloner) {
       n = other.n;
       correctSum = other.correctSum;
@@ -126,16 +126,6 @@
     }
 
-    // IDeepCloneable members
-    public object Clone() {
-      return new OnlineWeightedDirectionalSymmetryCalculator(this);
-    }
-
-    public IDeepCloneable Clone(Cloner cloner) {
-      var clone = cloner.GetClone(this);
-      if (clone == null) {
-        clone = new OnlineWeightedDirectionalSymmetryCalculator(this);
-        cloner.RegisterClonedObject(this, clone);
-      }
-      return clone;
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OnlineWeightedDirectionalSymmetryCalculator(this, cloner);
     }
   }
Index: branches/symbreg-factors-2650/HeuristicLab.Tests/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4/GrammarsTest.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Tests/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4/GrammarsTest.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Tests/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4/GrammarsTest.cs	(revision 14399)
@@ -30,13 +30,81 @@
     [TestProperty("Time", "short")]
     public void MinimumExpressionLengthTest() {
-      var grammar = CreateAbstractGrammar();
-
-      var prs = grammar.ProgramRootSymbol;
-      var a = grammar.Symbols.First(s => s.Name == "<a>");
-      var b = grammar.Symbols.First(s => s.Name == "<b>");
-
-      Assert.AreEqual(4, grammar.GetMinimumExpressionLength(prs));
-      Assert.AreEqual(4, grammar.GetMinimumExpressionLength(a));
-      Assert.AreEqual(3, grammar.GetMinimumExpressionLength(b));
+      {
+        var grammar = CreateTestGrammar1();
+
+        var prs = grammar.ProgramRootSymbol;
+        var ss = grammar.StartSymbol;
+        var x = grammar.Symbols.First(s => s.Name == "<x>");
+
+        Assert.AreEqual(8, grammar.GetMinimumExpressionLength(prs));
+        Assert.AreEqual(7, grammar.GetMinimumExpressionLength(ss));
+        Assert.AreEqual(6, grammar.GetMinimumExpressionLength(x));
+      }
+
+      {
+        var grammar = CreateTestGrammar2();
+
+        var prs = grammar.ProgramRootSymbol;
+        var ss = grammar.StartSymbol;
+        var x = grammar.Symbols.First(s => s.Name == "<x>");
+
+        Assert.AreEqual(13, grammar.GetMinimumExpressionLength(prs));
+        Assert.AreEqual(12, grammar.GetMinimumExpressionLength(ss));
+        Assert.AreEqual(11, grammar.GetMinimumExpressionLength(x));
+      }
+
+      {
+        var grammar = CreateTestGrammar3();
+        var prs = grammar.ProgramRootSymbol;
+        var ss = grammar.StartSymbol;
+        var x = grammar.Symbols.First(s => s.Name == "<x>");
+        Assert.AreEqual(int.MaxValue, grammar.GetMinimumExpressionLength(prs));
+        Assert.AreEqual(int.MaxValue, grammar.GetMinimumExpressionLength(ss));
+        Assert.AreEqual(int.MaxValue, grammar.GetMinimumExpressionLength(x));
+      }
+
+      {
+        var grammar = CreateTestGrammar4();
+        var prs = grammar.ProgramRootSymbol;
+        var ss = grammar.StartSymbol;
+        var x = grammar.Symbols.First(s => s.Name == "<x>");
+        var y = grammar.Symbols.First(s => s.Name == "<y>");
+        Assert.AreEqual(int.MaxValue, grammar.GetMinimumExpressionLength(prs));
+        Assert.AreEqual(int.MaxValue, grammar.GetMinimumExpressionLength(ss));
+        Assert.AreEqual(int.MaxValue, grammar.GetMinimumExpressionLength(x));
+        Assert.AreEqual(int.MaxValue, grammar.GetMinimumExpressionLength(y));
+      }
+
+      {
+        var grammar = CreateTestGrammar5();
+        var prs = grammar.ProgramRootSymbol;
+        var ss = grammar.StartSymbol;
+        var x = grammar.Symbols.First(s => s.Name == "<x>");
+        var y = grammar.Symbols.First(s => s.Name == "<y>");
+        Assert.AreEqual(5, grammar.GetMinimumExpressionLength(prs));
+        Assert.AreEqual(4, grammar.GetMinimumExpressionLength(ss));
+        Assert.AreEqual(3, grammar.GetMinimumExpressionLength(x));
+        Assert.AreEqual(2, grammar.GetMinimumExpressionLength(y));
+      }
+
+      {
+        var grammar = CreateTestGrammar6();
+        var prs = grammar.ProgramRootSymbol;
+        var ss = grammar.StartSymbol;
+        var x = grammar.Symbols.First(s => s.Name == "<x>");
+        var s_ = grammar.Symbols.First(s => s.Name == "<s>");
+        var a = grammar.Symbols.First(s => s.Name == "<a>");
+        var b = grammar.Symbols.First(s => s.Name == "<b>");
+        var c = grammar.Symbols.First(s => s.Name == "<c>");
+        var d = grammar.Symbols.First(s => s.Name == "<d>");
+        Assert.AreEqual(4, grammar.GetMinimumExpressionLength(prs));
+        Assert.AreEqual(3, grammar.GetMinimumExpressionLength(ss));
+        Assert.AreEqual(2, grammar.GetMinimumExpressionLength(x));
+        Assert.AreEqual(5, grammar.GetMinimumExpressionLength(s_));
+        Assert.AreEqual(4, grammar.GetMinimumExpressionLength(a));
+        Assert.AreEqual(3, grammar.GetMinimumExpressionLength(b));
+        Assert.AreEqual(4, grammar.GetMinimumExpressionLength(c));
+        Assert.AreEqual(3, grammar.GetMinimumExpressionLength(d));
+      }
     }
 
@@ -45,16 +113,219 @@
     [TestProperty("Time", "short")]
     public void MinimumExpressionDepthTest() {
-      var grammar = CreateAbstractGrammar();
-
-      var prs = grammar.ProgramRootSymbol;
-      var a = grammar.Symbols.First(s => s.Name == "<a>");
-      var b = grammar.Symbols.First(s => s.Name == "<b>");
-
-      Assert.AreEqual(4, grammar.GetMinimumExpressionDepth(prs));
-      Assert.AreEqual(4, grammar.GetMinimumExpressionDepth(a));
-      Assert.AreEqual(3, grammar.GetMinimumExpressionDepth(b));
-    }
-
-    private static ISymbolicExpressionGrammar CreateAbstractGrammar() {
+      {
+        var grammar = CreateTestGrammar1();
+
+        var prs = grammar.ProgramRootSymbol;
+        var ss = grammar.StartSymbol;
+        var a = grammar.Symbols.First(s => s.Name == "<a>");
+        var b = grammar.Symbols.First(s => s.Name == "<b>");
+        var c = grammar.Symbols.First(s => s.Name == "<c>");
+        var d = grammar.Symbols.First(s => s.Name == "<d>");
+        var x = grammar.Symbols.First(s => s.Name == "x");
+        var y = grammar.Symbols.First(s => s.Name == "y");
+
+        Assert.AreEqual(5, grammar.GetMinimumExpressionDepth(prs));
+        Assert.AreEqual(4, grammar.GetMinimumExpressionDepth(ss));
+        Assert.AreEqual(5, grammar.GetMinimumExpressionDepth(a));
+        Assert.AreEqual(4, grammar.GetMinimumExpressionDepth(b));
+        Assert.AreEqual(3, grammar.GetMinimumExpressionDepth(c));
+        Assert.AreEqual(2, grammar.GetMinimumExpressionDepth(d));
+        Assert.AreEqual(1, grammar.GetMinimumExpressionDepth(x));
+        Assert.AreEqual(1, grammar.GetMinimumExpressionDepth(y));
+      }
+
+      {
+        var grammar = CreateTestGrammar2();
+
+        var prs = grammar.ProgramRootSymbol;
+        var ss = grammar.StartSymbol;
+        var a = grammar.Symbols.First(s => s.Name == "<a>");
+        var b = grammar.Symbols.First(s => s.Name == "<b>");
+        var c = grammar.Symbols.First(s => s.Name == "<c>");
+        var d = grammar.Symbols.First(s => s.Name == "<d>");
+        var x = grammar.Symbols.First(s => s.Name == "x");
+        var y = grammar.Symbols.First(s => s.Name == "y");
+
+        Assert.AreEqual(5, grammar.GetMinimumExpressionDepth(prs));
+        Assert.AreEqual(4, grammar.GetMinimumExpressionDepth(ss));
+        Assert.AreEqual(5, grammar.GetMinimumExpressionDepth(a));
+        Assert.AreEqual(4, grammar.GetMinimumExpressionDepth(b));
+        Assert.AreEqual(3, grammar.GetMinimumExpressionDepth(c));
+        Assert.AreEqual(2, grammar.GetMinimumExpressionDepth(d));
+        Assert.AreEqual(1, grammar.GetMinimumExpressionDepth(x));
+        Assert.AreEqual(1, grammar.GetMinimumExpressionDepth(y));
+      }
+
+      {
+        var grammar = CreateTestGrammar3();
+        var prs = grammar.ProgramRootSymbol;
+        var ss = grammar.StartSymbol;
+        var x = grammar.Symbols.First(s => s.Name == "<x>");
+        Assert.AreEqual(int.MaxValue, grammar.GetMinimumExpressionDepth(prs));
+        Assert.AreEqual(int.MaxValue, grammar.GetMinimumExpressionDepth(ss));
+        Assert.AreEqual(int.MaxValue, grammar.GetMinimumExpressionDepth(x));
+      }
+
+      {
+        var grammar = CreateTestGrammar4();
+        var prs = grammar.ProgramRootSymbol;
+        var ss = grammar.StartSymbol;
+        var x = grammar.Symbols.First(s => s.Name == "<x>");
+        var y = grammar.Symbols.First(s => s.Name == "<y>");
+        Assert.AreEqual(int.MaxValue, grammar.GetMinimumExpressionDepth(prs));
+        Assert.AreEqual(int.MaxValue, grammar.GetMinimumExpressionDepth(ss));
+        Assert.AreEqual(int.MaxValue, grammar.GetMinimumExpressionDepth(x));
+        Assert.AreEqual(int.MaxValue, grammar.GetMinimumExpressionDepth(y));
+      }
+
+      {
+        var grammar = CreateTestGrammar5();
+        var prs = grammar.ProgramRootSymbol;
+        var ss = grammar.StartSymbol;
+        var x = grammar.Symbols.First(s => s.Name == "<x>");
+        var y = grammar.Symbols.First(s => s.Name == "<y>");
+        Assert.AreEqual(5, grammar.GetMinimumExpressionDepth(prs));
+        Assert.AreEqual(4, grammar.GetMinimumExpressionDepth(ss));
+        Assert.AreEqual(3, grammar.GetMinimumExpressionDepth(x));
+        Assert.AreEqual(2, grammar.GetMinimumExpressionDepth(y));
+      }
+
+      {
+        var grammar = CreateTestGrammar6();
+        var prs = grammar.ProgramRootSymbol;
+        var ss = grammar.StartSymbol;
+        var x = grammar.Symbols.First(s => s.Name == "<x>");
+        var s_ = grammar.Symbols.First(s => s.Name == "<s>");
+        var a = grammar.Symbols.First(s => s.Name == "<a>");
+        var b = grammar.Symbols.First(s => s.Name == "<b>");
+        var c = grammar.Symbols.First(s => s.Name == "<c>");
+        var d = grammar.Symbols.First(s => s.Name == "<d>");
+        Assert.AreEqual(4, grammar.GetMinimumExpressionDepth(prs));
+        Assert.AreEqual(3, grammar.GetMinimumExpressionDepth(ss));
+        Assert.AreEqual(2, grammar.GetMinimumExpressionDepth(x));
+        Assert.AreEqual(5, grammar.GetMinimumExpressionDepth(s_));
+        Assert.AreEqual(4, grammar.GetMinimumExpressionDepth(a));
+        Assert.AreEqual(3, grammar.GetMinimumExpressionDepth(b));
+        Assert.AreEqual(4, grammar.GetMinimumExpressionDepth(c));
+        Assert.AreEqual(3, grammar.GetMinimumExpressionDepth(d));
+      }
+    }
+
+    private static ISymbolicExpressionGrammar CreateTestGrammar1() {
+      var grammar = new SimpleSymbolicExpressionGrammar();
+      var x = new SimpleSymbol("<x>", 1);
+      var z = new SimpleSymbol("<z>", 6);
+      var a = new SimpleSymbol("<a>", 1);
+      var b = new SimpleSymbol("<b>", 1);
+      var c = new SimpleSymbol("<c>", 1);
+      var d = new SimpleSymbol("<d>", 1);
+
+      var _x = new SimpleSymbol("x", 0);
+      var _y = new SimpleSymbol("y", 0);
+
+      grammar.AddSymbol(x);
+      grammar.AddSymbol(z);
+      grammar.AddSymbol(a);
+      grammar.AddSymbol(b);
+      grammar.AddSymbol(c);
+      grammar.AddSymbol(d);
+      grammar.AddSymbol(_x);
+      grammar.AddSymbol(_y);
+
+      grammar.AddAllowedChildSymbol(grammar.StartSymbol, x);
+      //uncommenting the line below changes the minimum expression length for the symbol <x>
+      grammar.AddAllowedChildSymbol(x, z);
+      grammar.AddAllowedChildSymbol(z, _x);
+      grammar.AddAllowedChildSymbol(x, a);
+      grammar.AddAllowedChildSymbol(a, b);
+      grammar.AddAllowedChildSymbol(b, c);
+      grammar.AddAllowedChildSymbol(c, d);
+      grammar.AddAllowedChildSymbol(d, _y);
+
+      return grammar;
+    }
+
+    private static ISymbolicExpressionGrammar CreateTestGrammar2() {
+      var grammar = new SimpleSymbolicExpressionGrammar();
+      var x = new SimpleSymbol("<x>", 2);
+      var z = new SimpleSymbol("<z>", 6);
+      var a = new SimpleSymbol("<a>", 1);
+      var b = new SimpleSymbol("<b>", 1);
+      var c = new SimpleSymbol("<c>", 1);
+      var d = new SimpleSymbol("<d>", 1);
+
+      var _x = new SimpleSymbol("x", 0);
+      var _y = new SimpleSymbol("y", 0);
+
+      grammar.AddSymbol(x);
+      grammar.AddSymbol(z);
+      grammar.AddSymbol(a);
+      grammar.AddSymbol(b);
+      grammar.AddSymbol(c);
+      grammar.AddSymbol(d);
+      grammar.AddSymbol(_x);
+      grammar.AddSymbol(_y);
+
+      grammar.AddAllowedChildSymbol(grammar.StartSymbol, x);
+      //uncommenting the line below changes the minimum expression length for the symbol <x>
+      grammar.AddAllowedChildSymbol(x, z);
+      grammar.AddAllowedChildSymbol(z, _x);
+      grammar.AddAllowedChildSymbol(x, a);
+      grammar.AddAllowedChildSymbol(a, b);
+      grammar.AddAllowedChildSymbol(b, c);
+      grammar.AddAllowedChildSymbol(c, d);
+      grammar.AddAllowedChildSymbol(d, _y);
+
+      return grammar;
+    }
+
+    private static ISymbolicExpressionGrammar CreateTestGrammar3() {
+      var grammar = new SimpleSymbolicExpressionGrammar();
+      var x = new SimpleSymbol("<x>", 1);
+
+      grammar.AddSymbol(x);
+
+      grammar.AddAllowedChildSymbol(grammar.StartSymbol, x);
+      grammar.AddAllowedChildSymbol(x, x);
+      return grammar;
+    }
+
+
+    private static ISymbolicExpressionGrammar CreateTestGrammar4() {
+      var grammar = new SimpleSymbolicExpressionGrammar();
+      var x = new SimpleSymbol("<x>", 1);
+      var y = new SimpleSymbol("<y>", 1);
+
+      grammar.AddSymbol(x);
+      grammar.AddSymbol(y);
+
+      grammar.AddAllowedChildSymbol(grammar.StartSymbol, x);
+      grammar.AddAllowedChildSymbol(x, x);
+      grammar.AddAllowedChildSymbol(x, y);
+      grammar.AddAllowedChildSymbol(y, x);
+      grammar.AddAllowedChildSymbol(y, y);
+      return grammar;
+    }
+
+    private static ISymbolicExpressionGrammar CreateTestGrammar5() {
+      var grammar = new SimpleSymbolicExpressionGrammar();
+      var x = new SimpleSymbol("<x>", 1);
+      var y = new SimpleSymbol("<y>", 1);
+      var _x = new SimpleSymbol("x", 0);
+
+      grammar.AddSymbol(x);
+      grammar.AddSymbol(y);
+      grammar.AddSymbol(_x);
+
+      grammar.AddAllowedChildSymbol(grammar.StartSymbol, x);
+      grammar.AddAllowedChildSymbol(x, x);
+      grammar.AddAllowedChildSymbol(x, y);
+      grammar.AddAllowedChildSymbol(y, x);
+      grammar.AddAllowedChildSymbol(y, y);
+      grammar.AddAllowedChildSymbol(y, _x);
+      return grammar;
+    }
+
+    private static ISymbolicExpressionGrammar CreateTestGrammar6() {
       var grammar = new SimpleSymbolicExpressionGrammar();
       var x = new SimpleSymbol("<x>", 1);
Index: branches/symbreg-factors-2650/HeuristicLab.Visualization.ChartControlsExtensions/3.3/EnhancedChart.cs
===================================================================
--- branches/symbreg-factors-2650/HeuristicLab.Visualization.ChartControlsExtensions/3.3/EnhancedChart.cs	(revision 14351)
+++ branches/symbreg-factors-2650/HeuristicLab.Visualization.ChartControlsExtensions/3.3/EnhancedChart.cs	(revision 14399)
@@ -28,10 +28,14 @@
 namespace HeuristicLab.Visualization.ChartControlsExtensions {
   public partial class EnhancedChart : Chart {
+
     private ImageExportDialog exportDialog;
+
+    private ImageExportDialog ExportDialog {
+      get { return exportDialog ?? (exportDialog = new ImageExportDialog(this)); }
+    }
 
     public EnhancedChart()
       : base() {
       InitializeComponent();
-      exportDialog = new ImageExportDialog(this);
       EnableDoubleClickResetsZoom = true;
       EnableMiddleClickPanning = true;
@@ -166,5 +170,5 @@
 
     private void exportToolStripMenuItem_Click(object sender, EventArgs e) {
-      exportDialog.ShowDialog();
+      ExportDialog.ShowDialog();
     }
 
