Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/RSquaredEvaluator.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/RSquaredEvaluator.cs	(revision 16022)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/RSquaredEvaluator.cs	(revision 16026)
@@ -1,5 +1,4 @@
 ﻿using System;
 using System.Diagnostics;
-using HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration.GrammarEnumeration;
 using HeuristicLab.Analysis;
 using HeuristicLab.Common;
@@ -51,5 +50,5 @@
     private void AlgorithmOnDistinctSentenceGenerated(object sender, PhraseAddedEventArgs phraseAddedEventArgs) {
       GrammarEnumerationAlgorithm algorithm = (GrammarEnumerationAlgorithm)sender;
-      EvaluateSentence(algorithm, phraseAddedEventArgs.NewPhrase, algorithm.OptimizeConstants);
+      EvaluateSentence(algorithm, phraseAddedEventArgs.NewPhrase, algorithm.OptimizeConstants, algorithm.ConstantOptimizationIterations);
     }
 
@@ -69,13 +68,13 @@
     }
 
-    private void EvaluateSentence(GrammarEnumerationAlgorithm algorithm, SymbolString symbolString, bool optimizeConstants) {
+    private void EvaluateSentence(GrammarEnumerationAlgorithm algorithm, SymbolList sentence, bool optimizeConstants, int maxIterations) {
       var results = algorithm.Results;
       var grammar = algorithm.Grammar;
       var problemData = algorithm.Problem.ProblemData;
 
-      SymbolicExpressionTree tree = algorithm.Grammar.ParseSymbolicExpressionTree(symbolString);
+      SymbolicExpressionTree tree = algorithm.Grammar.ParseSymbolicExpressionTree(sentence);
       Debug.Assert(SymbolicRegressionConstantOptimizationEvaluator.CanOptimizeConstants(tree));
 
-      double r2 = Evaluate(problemData, tree, optimizeConstants);
+      double r2 = Evaluate(problemData, tree, optimizeConstants, maxIterations);
       double bestR2 = results.ContainsKey(BestTrainingQualityResultName) ? GetValue<double>(results[BestTrainingQualityResultName].Value) : 0.0;
       if (r2 < bestR2)
@@ -83,8 +82,8 @@
 
       var bestComplexity = results.ContainsKey(BestComplexityResultName) ? GetValue<int>(results[BestComplexityResultName].Value) : int.MaxValue;
-      var complexity = grammar.GetComplexity(symbolString);
+      var complexity = sentence.Complexity;
 
       if (algorithm.BestTrainingSentence == null || r2 > bestR2 || (r2.IsAlmost(bestR2) && complexity < bestComplexity)) {
-        algorithm.BestTrainingSentence = symbolString;
+        algorithm.BestTrainingSentence = sentence;
 
         var model = new SymbolicRegressionModel(problemData.TargetVariable, tree, expressionTreeLinearInterpreter);
@@ -110,5 +109,5 @@
         dt = (DataTable)results[BestSolutions].Value;
         dt.Rows["Quality"].Values.Add(r2);
-        dt.Rows["Relative Length"].Values.Add((double)symbolString.Count() / algorithm.MaxSentenceLength);
+        dt.Rows["Relative Length"].Values.Add((double)sentence.Count);
         dt.Rows["Complexity"].Values.Add(complexity);
         dt.Rows["Timestamp"].Values.Add(algorithm.ExecutionTime.TotalMilliseconds / 1000d);
@@ -116,5 +115,5 @@
     }
 
-    public static double Evaluate(IRegressionProblemData problemData, SymbolicExpressionTree tree, bool optimizeConstants = true) {
+    public static double Evaluate(IRegressionProblemData problemData, SymbolicExpressionTree tree, bool optimizeConstants = true, int maxIterations = 10) {
       double r2;
 
@@ -127,5 +126,5 @@
           problemData.TrainingIndices,
           applyLinearScaling: true,
-          maxIterations: 10,
+          maxIterations: maxIterations,
           updateVariableWeights: false,
           updateConstantsInTree: true);
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/SearchGraphVisualizer.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/SearchGraphVisualizer.cs	(revision 16022)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/SearchGraphVisualizer.cs	(revision 16026)
@@ -55,5 +55,5 @@
       try {
         var alg = (GrammarEnumerationAlgorithm)sender;
-        var phrase0 = new SymbolString(new[] { alg.Grammar.StartSymbol });
+        var phrase0 = new SymbolList(new[] { alg.Grammar.StartSymbol });
         var phrase0Hash = alg.Grammar.Hasher.CalcHashCode(phrase0);
 
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/SentenceLogger.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/SentenceLogger.cs	(revision 16022)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/SentenceLogger.cs	(revision 16026)
@@ -89,5 +89,5 @@
       distinctSentencesFileTrace.WriteLine(ToCsvLine(
         ((uint)phraseAddedEventArgs.NewHash).ToString("D10"),
-        phraseAddedEventArgs.NewPhrase.Count().ToString("D3"),
+        phraseAddedEventArgs.NewPhrase.Count.ToString("D3"),
         //phraseAddedEventArgs.NewPhrase.ToString(),
         ((GrammarEnumerationAlgorithm)sender).Grammar.ToInfixString(phraseAddedEventArgs.NewPhrase)));
@@ -99,5 +99,5 @@
       allSentencesFileTrace.WriteLine(ToCsvLine(
         ((uint)phraseAddedEventArgs.NewHash).ToString("D10"),
-        phraseAddedEventArgs.NewPhrase.Count().ToString("D3"),
+        phraseAddedEventArgs.NewPhrase.Count.ToString("D3"),
         //phraseAddedEventArgs.NewPhrase.ToString(),
         ((GrammarEnumerationAlgorithm)sender).Grammar.ToInfixString(phraseAddedEventArgs.NewPhrase)));
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/Grammar.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/Grammar.cs	(revision 16022)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/Grammar.cs	(revision 16026)
@@ -28,5 +28,5 @@
     #region Symbols
 
-    public IReadOnlyDictionary<Symbol, IReadOnlyList<Production>> Productions { get; private set; }
+    public IReadOnlyDictionary<Symbol, IReadOnlyList<SymbolList>> Productions { get; private set; }
 
     public NonterminalSymbol Var;
@@ -85,5 +85,5 @@
       infixExpressionFormatter = cloner.Clone(original.infixExpressionFormatter);
 
-      Productions = original.Productions.ToDictionary(x => cloner.Clone(x.Key), x => (IReadOnlyList<Production>)x.Value.Select(cloner.Clone).ToList());
+      Productions = original.Productions.ToDictionary(x => cloner.Clone(x.Key), x => (IReadOnlyList<SymbolList>)x.Value.Select(cloner.Clone).ToList());
       VarTerminals = original.VarTerminals.Select(cloner.Clone).ToList();
 
@@ -144,60 +144,60 @@
       StartSymbol = Expr;
 
-      Dictionary<Symbol, IReadOnlyList<Production>> productions = new Dictionary<Symbol, IReadOnlyList<Production>>();
+      Dictionary<Symbol, IReadOnlyList<SymbolList>> productions = new Dictionary<Symbol, IReadOnlyList<SymbolList>>();
 
       // Map each variable to a separate production rule of the "Var" nonterminal symbol.
       VarTerminals = variables.Select(v => new VariableTerminalSymbol(v)).ToArray();
-      productions[Var] = VarTerminals.Select(v => new Production(v)).ToArray();
+      productions[Var] = VarTerminals.Select(v => new SymbolList(v)).ToArray();
 
       // Expression Grammar Rules
-      var exprProductions = new List<Production>();
+      var exprProductions = new List<SymbolList>();
       if (includedRules.Contains(GrammarRule.MultipleTerms))
-        exprProductions.Add(new Production(Const, Term, Multiplication, Expr, Addition));
-
-      exprProductions.Add(new Production(Const, Term, Multiplication, Const, Addition));
+        exprProductions.Add(new SymbolList(Const, Term, Multiplication, Expr, Addition));
+
+      exprProductions.Add(new SymbolList(Const, Term, Multiplication, Const, Addition));
       productions[Expr] = exprProductions.ToArray();
 
       // Term Grammar Rules
-      var termProductions = new List<Production>();
+      var termProductions = new List<SymbolList>();
       if (includedRules.Contains(GrammarRule.MultipleFactors))
-        termProductions.Add(new Production(Factor, Term, Multiplication));
+        termProductions.Add(new SymbolList(Factor, Term, Multiplication));
       if (includedRules.Contains(GrammarRule.InverseTerm))
-        termProductions.Add(new Production(InvExpr, Inv));
-      termProductions.Add(new Production(Factor));
+        termProductions.Add(new SymbolList(InvExpr, Inv));
+      termProductions.Add(new SymbolList(Factor));
       productions[Term] = termProductions.ToArray();
 
       // Factor Grammar Rules
-      var factorProductions = new List<Production>();
-      factorProductions.Add(new Production(Var));
+      var factorProductions = new List<SymbolList>();
+      factorProductions.Add(new SymbolList(Var));
       if (includedRules.Contains(GrammarRule.Logarithm))
-        factorProductions.Add(new Production(LogFactor));
+        factorProductions.Add(new SymbolList(LogFactor));
       if (includedRules.Contains(GrammarRule.Exponentiation))
-        factorProductions.Add(new Production(ExpFactor));
+        factorProductions.Add(new SymbolList(ExpFactor));
       if (includedRules.Contains(GrammarRule.Sine))
-        factorProductions.Add(new Production(SinFactor));
+        factorProductions.Add(new SymbolList(SinFactor));
       productions[Factor] = factorProductions.ToArray();
 
-      productions[LogFactor] = new[] { new Production(SimpleExpr, Log) };
-      productions[ExpFactor] = new[] { new Production(Const, SimpleTerm, Multiplication, Exp) };
-      productions[SinFactor] = new[] { new Production(SimpleExpr, Sin) };
+      productions[LogFactor] = new[] { new SymbolList(SimpleExpr, Log) };
+      productions[ExpFactor] = new[] { new SymbolList(Const, SimpleTerm, Multiplication, Exp) };
+      productions[SinFactor] = new[] { new SymbolList(SimpleExpr, Sin) };
 
       productions[SimpleExpr] = new[] {
-        new Production(Const, SimpleTerm, Multiplication, SimpleExpr, Addition),
-        new Production(Const, SimpleTerm, Multiplication, Const, Addition)
+        new SymbolList(Const, SimpleTerm, Multiplication, SimpleExpr, Addition),
+        new SymbolList(Const, SimpleTerm, Multiplication, Const, Addition)
       };
 
       productions[SimpleTerm] = new[] {
-        new Production(Var, SimpleTerm, Multiplication),
-        new Production(Var)
+        new SymbolList(Var, SimpleTerm, Multiplication),
+        new SymbolList(Var)
       };
 
       productions[InvExpr] = new[] {
-        new Production(Const, InvTerm, Multiplication, InvExpr, Addition),
-        new Production(Const, InvTerm, Multiplication, Const, Addition)
+        new SymbolList(Const, InvTerm, Multiplication, InvExpr, Addition),
+        new SymbolList(Const, InvTerm, Multiplication, Const, Addition)
       };
 
       productions[InvTerm] = new[] {
-        new Production(Factor, InvTerm, Multiplication),
-        new Production(Factor)
+        new SymbolList(Factor, InvTerm, Multiplication),
+        new SymbolList(Factor)
       };
 
@@ -234,50 +234,32 @@
     }
 
-    public int GetComplexity(SymbolString s) {
-      int c = 0;
-      int length = s.Count();
-      for (int i = 0; i < length; i++) {
-        if (s[i] is NonterminalSymbol || s[i] is VariableTerminalSymbol) c++;
-      }
-      return c;
-    }
-
     // returns the maximum achievable sentence length below the maximum complexity
     public int GetMaxSentenceLength(int maxComplexity) {
-      SymbolString s = new SymbolString(StartSymbol);
-
-      while (!s.IsSentence() && GetComplexity(s) <= maxComplexity) {
+      SymbolList s = new SymbolList(StartSymbol);
+
+      while (!s.IsSentence() && s.Complexity <= maxComplexity) {
         int expandedSymbolIndex = s.NextNonterminalIndex();
         NonterminalSymbol expandedSymbol = (NonterminalSymbol)s[expandedSymbolIndex];
 
         var productions = Productions[expandedSymbol];
-        var longestProduction = productions // Find production with most terminal symbols to expand as much as possible...
-          .OrderBy(CountTerminals)          // but with lowest complexity/nonterminal count to keep complexity low.                                                                                     
-          .ThenByDescending(CountNonTerminals)
+        var longestProduction = productions                // Find production with most terminal symbols to expand as much as possible...
+          .OrderBy(x => x.TerminalSymbolCount)             // but with lowest complexity/nonterminal count to keep complexity low.                                                                                     
+          .ThenByDescending(x => x.NonTerminalSymbolCount)
           .First();
 
         s = s.DerivePhrase(expandedSymbolIndex, longestProduction);
       }
-
-      return s.Count();
-    }
-
-    private int CountTerminals(Production p) {
-      return p.Count(s => s is TerminalSymbol);
-    }
-
-    private int CountNonTerminals(Production p) {
-      return p.Count(s => s is NonterminalSymbol);
-    }
-
-    public double EvaluatePhrase(SymbolString s, IRegressionProblemData problemData, bool optimizeConstants) {
+      return s.Count;
+    }
+
+    public double EvaluatePhrase(SymbolList s, IRegressionProblemData problemData, bool optimizeConstants, int iterations) {
       SymbolicExpressionTree tree = ParseSymbolicExpressionTree(s);
 
-      return RSquaredEvaluator.Evaluate(problemData, tree, optimizeConstants);
+      return RSquaredEvaluator.Evaluate(problemData, tree, optimizeConstants, iterations);
     }
 
     #region Parse to SymbolicExpressionTree
 
-    public string ToInfixString(SymbolString sentence) {
+    public string ToInfixString(SymbolList sentence) {
       Debug.Assert(sentence.Any(), "Trying to evaluate empty sentence!");
       Debug.Assert(sentence.All(s => s is TerminalSymbol), "Trying to evaluate symbol sequence with nonterminalsymbols!");
@@ -286,5 +268,5 @@
     }
 
-    public SymbolicExpressionTree ParseSymbolicExpressionTree(SymbolString sentence) {
+    public SymbolicExpressionTree ParseSymbolicExpressionTree(SymbolList sentence) {
       Debug.Assert(sentence.Any(), "Trying to evaluate empty sentence!");
 
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/GrammarEnumerationAlgorithm.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/GrammarEnumerationAlgorithm.cs	(revision 16022)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/GrammarEnumerationAlgorithm.cs	(revision 16026)
@@ -32,4 +32,5 @@
 
     private readonly string OptimizeConstantsParameterName = "Optimize Constants";
+    private readonly string ConstantOptimizationIterationsParameterName = "Constant Optimization Iterations";
     private readonly string ErrorWeightParameterName = "Error Weight";
     private readonly string SearchDataStructureParameterName = "Search Data Structure";
@@ -55,4 +56,13 @@
     }
 
+    public int ConstantOptimizationIterations {
+      get { return ConstantOptimizationIterationsParameter.Value.Value; }
+      set { ConstantOptimizationIterationsParameter.Value.Value = value; }
+    }
+
+    public IFixedValueParameter<IntValue> ConstantOptimizationIterationsParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[ConstantOptimizationIterationsParameterName]; }
+    }
+
     protected IFixedValueParameter<IntValue> MaxComplexityParameter {
       get { return (IFixedValueParameter<IntValue>)Parameters[MaxComplexityParameterName]; }
@@ -116,5 +126,5 @@
 
     [Storable]
-    public SymbolString BestTrainingSentence { get; set; }     // Currently set in RSquaredEvaluator: quite hacky, but makes testing much easier for now...
+    public SymbolList BestTrainingSentence { get; set; }     // Currently set in RSquaredEvaluator: quite hacky, but makes testing much easier for now...
     #endregion
 
@@ -185,4 +195,5 @@
       Parameters.Add(new FixedValueParameter<IntValue>(SearchDataStructureSizeParameterName, "The size of the search data structure.", new IntValue((int)1e5)));
       Parameters.Add(new FixedValueParameter<EnumValue<StorageType>>(SearchDataStructureParameterName, new EnumValue<StorageType>(StorageType.SortedSet)));
+      Parameters.Add(new FixedValueParameter<IntValue>(ConstantOptimizationIterationsParameterName, new IntValue(10)));
 
       SearchDataStructureParameter.Value.ValueChanged += (o, e) => Prepare();
@@ -240,7 +251,4 @@
     #endregion
 
-    [Storable]
-    private Dictionary<VariableTerminalSymbol, double> variableImportance;
-
     public override void Prepare() {
       DistinctSentencesComplexity = new Dictionary<int, int>();
@@ -259,5 +267,5 @@
       if (previousExecutionState != ExecutionState.Paused) {
         InitResults();
-        var phrase0 = new SymbolString(new[] { Grammar.StartSymbol });
+        var phrase0 = new SymbolList(new[] { Grammar.StartSymbol });
         var phrase0Hash = Grammar.Hasher.CalcHashCode(phrase0);
 
@@ -268,4 +276,5 @@
       var errorWeight = ErrorWeight;
       var optimizeConstants = OptimizeConstants; // cache value to avoid parameter lookup
+      var iterations = ConstantOptimizationIterations;
       // main search loop
       while (OpenPhrases.Count > 0) {
@@ -278,5 +287,5 @@
           continue;
 
-        SymbolString currPhrase = fetchedSearchNode.SymbolString;
+        SymbolList currPhrase = fetchedSearchNode.SymbolList;
 
         OnPhraseFetched(fetchedSearchNode.Hash, currPhrase);
@@ -292,6 +301,6 @@
           PhraseExpansionCount++;
 
-          SymbolString newPhrase = currPhrase.DerivePhrase(nonterminalSymbolIndex, appliedProductions[i]);
-          int newPhraseComplexity = Grammar.GetComplexity(newPhrase);
+          SymbolList newPhrase = currPhrase.DerivePhrase(nonterminalSymbolIndex, appliedProductions[i]);
+          int newPhraseComplexity = newPhrase.Complexity;
 
           if (newPhraseComplexity > MaxComplexity)
@@ -300,10 +309,10 @@
           var phraseHash = Grammar.Hasher.CalcHashCode(newPhrase);
 
-          OnPhraseDerived(fetchedSearchNode.Hash, fetchedSearchNode.SymbolString, phraseHash, newPhrase, expandedSymbol, appliedProductions[i]);
+          OnPhraseDerived(fetchedSearchNode.Hash, fetchedSearchNode.SymbolList, phraseHash, newPhrase, expandedSymbol, appliedProductions[i]);
 
           if (newPhrase.IsSentence()) {
             AllGeneratedSentencesCount++;
 
-            OnSentenceGenerated(fetchedSearchNode.Hash, fetchedSearchNode.SymbolString, phraseHash, newPhrase, expandedSymbol, appliedProductions[i]);
+            OnSentenceGenerated(fetchedSearchNode.Hash, fetchedSearchNode.SymbolList, phraseHash, newPhrase, expandedSymbol, appliedProductions[i]);
 
             // Is the best solution found? (only if RSquaredEvaluator is activated)
@@ -320,5 +329,5 @@
 
               DistinctSentencesComplexity[phraseHash] = newPhraseComplexity;
-              OnDistinctSentenceGenerated(fetchedSearchNode.Hash, fetchedSearchNode.SymbolString, phraseHash, newPhrase, expandedSymbol, appliedProductions[i]);
+              OnDistinctSentenceGenerated(fetchedSearchNode.Hash, fetchedSearchNode.SymbolList, phraseHash, newPhrase, expandedSymbol, appliedProductions[i]);
             }
             UpdateView();
@@ -327,6 +336,6 @@
 
             bool isCompleteSentence = IsCompleteSentence(newPhrase);
-            double r2 = isCompleteSentence ? Grammar.EvaluatePhrase(newPhrase, Problem.ProblemData, optimizeConstants) : fetchedSearchNode.R2;
-            double phrasePriority = GetPriority(newPhrase, r2, MaxSentenceLength);
+            double r2 = isCompleteSentence ? Grammar.EvaluatePhrase(newPhrase, Problem.ProblemData, optimizeConstants, iterations) : fetchedSearchNode.R2;
+            double phrasePriority = GetPriority(newPhrase, r2);
 
             SearchNode newSearchNode = new SearchNode(phraseHash, phrasePriority, r2, newPhrase);
@@ -338,9 +347,9 @@
     }
 
-    protected static double GetPriority(SymbolString phrase, double r2, int maxSentenceLength) {
-      return (1 - r2) * phrase.Count();
-    }
-
-    private bool IsCompleteSentence(SymbolString phrase) {
+    protected static double GetPriority(SymbolList phrase, double r2) {
+      return (1 - r2) * phrase.Count;
+    }
+
+    private bool IsCompleteSentence(SymbolList phrase) {
       return !phrase.Any(x => x is NonterminalSymbol && x != Grammar.Expr);
     }
@@ -386,5 +395,5 @@
         Problem.ProblemData.TrainingIndices,
         applyLinearScaling: true,
-        maxIterations: 10,
+        maxIterations: ConstantOptimizationIterations,
         updateVariableWeights: false,
         updateConstantsInTree: true);
@@ -395,5 +404,5 @@
       Results.AddOrUpdateResult(BestTrainingModelResultName, model);
       Results.AddOrUpdateResult(BestTrainingSolutionResultName, bestTrainingSolution);
-      Results.AddOrUpdateResult(BestComplexityResultName, new IntValue(Grammar.GetComplexity(BestTrainingSentence)));
+      Results.AddOrUpdateResult(BestComplexityResultName, new IntValue(BestTrainingSentence.Complexity));
       base.OnStopped();
     }
@@ -450,28 +459,28 @@
 
     public event EventHandler<PhraseEventArgs> PhraseFetched;
-    private void OnPhraseFetched(int hash, SymbolString symbolString) {
+    private void OnPhraseFetched(int hash, SymbolList phrase) {
       if (PhraseFetched != null) {
-        PhraseFetched(this, new PhraseEventArgs(hash, symbolString));
+        PhraseFetched(this, new PhraseEventArgs(hash, phrase));
       }
     }
 
     public event EventHandler<PhraseAddedEventArgs> PhraseDerived;
-    private void OnPhraseDerived(int parentHash, SymbolString parentSymbolString, int addedHash, SymbolString addedSymbolString, Symbol expandedSymbol, Production expandedProduction) {
+    private void OnPhraseDerived(int parentHash, SymbolList parentSymbolList, int addedHash, SymbolList addedSymbolList, Symbol expandedSymbol, SymbolList expandedProduction) {
       if (PhraseDerived != null) {
-        PhraseDerived(this, new PhraseAddedEventArgs(parentHash, parentSymbolString, addedHash, addedSymbolString, expandedSymbol, expandedProduction));
+        PhraseDerived(this, new PhraseAddedEventArgs(parentHash, parentSymbolList, addedHash, addedSymbolList, expandedSymbol, expandedProduction));
       }
     }
 
     public event EventHandler<PhraseAddedEventArgs> SentenceGenerated;
-    private void OnSentenceGenerated(int parentHash, SymbolString parentSymbolString, int addedHash, SymbolString addedSymbolString, Symbol expandedSymbol, Production expandedProduction) {
+    private void OnSentenceGenerated(int parentHash, SymbolList parentSymbolList, int addedHash, SymbolList addedSymbolList, Symbol expandedSymbol, SymbolList expandedProduction) {
       if (SentenceGenerated != null) {
-        SentenceGenerated(this, new PhraseAddedEventArgs(parentHash, parentSymbolString, addedHash, addedSymbolString, expandedSymbol, expandedProduction));
+        SentenceGenerated(this, new PhraseAddedEventArgs(parentHash, parentSymbolList, addedHash, addedSymbolList, expandedSymbol, expandedProduction));
       }
     }
 
     public event EventHandler<PhraseAddedEventArgs> DistinctSentenceGenerated;
-    private void OnDistinctSentenceGenerated(int parentHash, SymbolString parentSymbolString, int addedHash, SymbolString addedSymbolString, Symbol expandedSymbol, Production expandedProduction) {
+    private void OnDistinctSentenceGenerated(int parentHash, SymbolList parentSymbolList, int addedHash, SymbolList addedSymbolList, Symbol expandedSymbol, SymbolList expandedProduction) {
       if (DistinctSentenceGenerated != null) {
-        DistinctSentenceGenerated(this, new PhraseAddedEventArgs(parentHash, parentSymbolString, addedHash, addedSymbolString, expandedSymbol, expandedProduction));
+        DistinctSentenceGenerated(this, new PhraseAddedEventArgs(parentHash, parentSymbolList, addedHash, addedSymbolList, expandedSymbol, expandedProduction));
       }
     }
@@ -486,7 +495,7 @@
     public int Hash { get; }
 
-    public SymbolString Phrase { get; }
-
-    public PhraseEventArgs(int hash, SymbolString phrase) {
+    public SymbolList Phrase { get; }
+
+    public PhraseEventArgs(int hash, SymbolList phrase) {
       Hash = hash;
       Phrase = phrase;
@@ -498,12 +507,12 @@
     public int NewHash { get; }
 
-    public SymbolString ParentPhrase { get; }
-    public SymbolString NewPhrase { get; }
+    public SymbolList ParentPhrase { get; }
+    public SymbolList NewPhrase { get; }
 
     public Symbol ExpandedSymbol { get; }
 
-    public Production ExpandedProduction { get; }
-
-    public PhraseAddedEventArgs(int parentHash, SymbolString parentPhrase, int newHash, SymbolString newPhrase, Symbol expandedSymbol, Production expandedProduction) {
+    public SymbolList ExpandedProduction { get; }
+
+    public PhraseAddedEventArgs(int parentHash, SymbolList parentPhrase, int newHash, SymbolList newPhrase, Symbol expandedSymbol, SymbolList expandedProduction) {
       ParentHash = parentHash;
       ParentPhrase = parentPhrase;
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/SearchDataStructure.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/SearchDataStructure.cs	(revision 16022)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/SearchDataStructure.cs	(revision 16026)
@@ -13,5 +13,5 @@
 
     [Storable]
-    public readonly SymbolString SymbolString;
+    public readonly SymbolList SymbolList;
 
     [Storable]
@@ -23,8 +23,8 @@
     private SearchNode() { }
 
-    public SearchNode(int hash, double priority, double r2, SymbolString symbolString) {
+    public SearchNode(int hash, double priority, double r2, SymbolList symbolList) {
       Hash = hash;
       Priority = priority;
-      SymbolString = symbolString;
+      SymbolList = symbolList;
       R2 = r2;
     }
@@ -33,5 +33,5 @@
       Hash = original.Hash;
       Priority = original.Priority;
-      SymbolString = original.SymbolString;
+      SymbolList = original.SymbolList;
       R2 = original.R2;
     }
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/Sentence.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/Sentence.cs	(revision 16022)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/Sentence.cs	(revision 16026)
@@ -55,5 +55,5 @@
     }
 
-    public SymbolString DerivePhrase(int nonterminalSymbolIndex, Production production) {
+    public SymbolString DerivePhrase(int nonterminalSymbolIndex, SymbolList production) {
       int productionLength = production.Count;
       int newStringLength = Count() + productionLength - 1;
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/Symbol.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/Symbol.cs	(revision 16022)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/Symbol.cs	(revision 16026)
@@ -2,4 +2,5 @@
 using System.Collections;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Linq;
 using HeuristicLab.Common;
@@ -102,88 +103,4 @@
   }
 
-  [StorableClass]
-  public class Production : DeepCloneable, IList<Symbol> {
-    [Storable]
-    private List<Symbol> symbols;
-
-    public int Count { get { return symbols.Count; } }
-
-    public bool IsReadOnly {
-      get { return false; }
-    }
-
-    public Symbol this[int index] {
-      get { return symbols[index]; }
-      set { symbols[index] = value; }
-    }
-
-    public Production(params Symbol[] symbols) {
-      this.symbols = symbols.ToList();
-    }
-
-    public Production(IEnumerable<Symbol> symbols) {
-      this.symbols = symbols.ToList();
-    }
-
-    [StorableConstructor]
-    protected Production(bool deserializing) { }
-
-    protected Production(Production original, Cloner cloner) {
-      symbols = original.symbols.Select(cloner.Clone).ToList();
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new Production(this, cloner);
-    }
-
-    public override string ToString() {
-      return string.Join(" ", this);
-    }
-
-    #region IList<Symbol> methods
-    public IEnumerator<Symbol> GetEnumerator() {
-      return symbols.GetEnumerator();
-    }
-
-    IEnumerator IEnumerable.GetEnumerator() {
-      return GetEnumerator();
-    }
-
-    public int IndexOf(Symbol item) {
-      return symbols.IndexOf(item);
-    }
-
-    public void Insert(int index, Symbol item) {
-      symbols.Insert(index, item);
-    }
-
-    public void RemoveAt(int index) {
-      symbols.RemoveAt(index);
-    }
-
-    public void Add(Symbol item) {
-      symbols.Add(item);
-    }
-
-    public void Clear() {
-      symbols.Clear();
-    }
-
-    public bool Contains(Symbol item) {
-      return symbols.Contains(item);
-    }
-
-    public void CopyTo(Symbol[] array, int arrayIndex) {
-      symbols.CopyTo(array, arrayIndex);
-    }
-
-    public void CopyTo(int index, Symbol[] array, int arrayIndex, int count) {
-      symbols.CopyTo(index, array, arrayIndex, count);
-    }
-
-    public bool Remove(Symbol item) {
-      return symbols.Remove(item);
-    }
-    #endregion
-  }
+ 
 }
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/SymbolList.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/SymbolList.cs	(revision 16026)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/SymbolList.cs	(revision 16026)
@@ -0,0 +1,163 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration {
+  [StorableClass]
+  public class SymbolList : DeepCloneable, IList<Symbol> {
+    [Storable]
+    private List<Symbol> symbols;
+
+    public int Count { get { return symbols.Count; } }
+
+    public int TerminalSymbolCount { get { return symbols.Count(s => s is TerminalSymbol); } }
+    public int NonTerminalSymbolCount { get { return symbols.Count(s => s is NonterminalSymbol); } }
+
+    public bool IsReadOnly {
+      get { return false; }
+    }
+
+    /// <summary>
+    /// Return the complexity as the number of non-terminal or variable-terminal symbols
+    /// </summary>
+    public int Complexity {
+      get {
+        int c = 0;
+        foreach (var s in symbols) {
+          if (s is NonterminalSymbol || s is VariableTerminalSymbol) c++;
+        }
+        return c;
+      }
+    }
+
+    public Symbol this[int index] {
+      get { return symbols[index]; }
+      set { symbols[index] = value; }
+    }
+
+    public SymbolList(params Symbol[] symbols) {
+      this.symbols = symbols.ToList();
+    }
+
+    public SymbolList(IEnumerable<Symbol> symbols) {
+      this.symbols = symbols.ToList();
+    }
+
+    public SymbolList(List<Symbol> symbols) {
+      this.symbols = symbols;
+    }
+
+    [StorableConstructor]
+    protected SymbolList(bool deserializing) { }
+
+    protected SymbolList(SymbolList original, Cloner cloner) {
+      symbols = original.symbols.Select(cloner.Clone).ToList();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolList(this, cloner);
+    }
+
+    public override string ToString() {
+      return string.Join(" ", this);
+    }
+
+    public bool IsSentence() {
+      return !this.Any(sym => sym is NonterminalSymbol);
+    }
+
+    public int[] GetNonterminalSymbolIndexes() {
+      return Enumerable.Range(0, symbols.Count)
+        .Where(i => symbols[i] is NonterminalSymbol)
+        .ToArray();
+    }
+
+    public int NextNonterminalIndex() {
+      Debug.Assert(!IsSentence());
+      int firstNonTerminalIndex = 0;
+      while (firstNonTerminalIndex < symbols.Count && symbols[firstNonTerminalIndex] is TerminalSymbol) {
+        firstNonTerminalIndex++;
+      }
+      return firstNonTerminalIndex;
+    }
+
+    public SymbolList DerivePhrase(int nonTerminalSymbolIndex, SymbolList production) {
+      // derive a new phrase by replacing the non-terminal at the given index with the production
+      var derived = new List<Symbol>(Count + production.Count - 1);
+      derived.AddRange(symbols.Take(nonTerminalSymbolIndex));
+      derived.AddRange(production);
+      derived.AddRange(symbols.Skip(nonTerminalSymbolIndex + 1));
+      return new SymbolList(derived);
+    }
+
+    #region IList<Symbol> methods
+    public IEnumerator<Symbol> GetEnumerator() {
+      return symbols.GetEnumerator();
+    }
+
+    IEnumerator IEnumerable.GetEnumerator() {
+      return GetEnumerator();
+    }
+
+    public int IndexOf(Symbol item) {
+      return symbols.IndexOf(item);
+    }
+
+    public void Insert(int index, Symbol item) {
+      symbols.Insert(index, item);
+    }
+
+    public void RemoveAt(int index) {
+      symbols.RemoveAt(index);
+    }
+
+    public void Add(Symbol item) {
+      symbols.Add(item);
+    }
+
+    public void Clear() {
+      symbols.Clear();
+    }
+
+    public bool Contains(Symbol item) {
+      return symbols.Contains(item);
+    }
+
+    public void CopyTo(Symbol[] array, int arrayIndex) {
+      symbols.CopyTo(array, arrayIndex);
+    }
+
+    public void CopyTo(int index, Symbol[] array, int arrayIndex, int count) {
+      symbols.CopyTo(index, array, arrayIndex, count);
+    }
+
+    public bool Remove(Symbol item) {
+      return symbols.Remove(item);
+    }
+    #endregion
+  }
+}
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Hashing/Hasher.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Hashing/Hasher.cs	(revision 16022)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Hashing/Hasher.cs	(revision 16026)
@@ -22,5 +22,5 @@
     protected abstract THashType AggregateHashes(Symbol operatorSym, IList<THashType> hashes);
 
-    public int CalcHashCode(SymbolString sentence) {
+    public int CalcHashCode(SymbolList sentence) {
       Debug.Assert(sentence.Any(), "Trying to evaluate empty sentence!");
 
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration.csproj
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration.csproj	(revision 16022)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration.csproj	(revision 16026)
@@ -123,7 +123,7 @@
     <Compile Include="GrammarEnumeration\GrammarEnumerationAlgorithm.cs" />
     <Compile Include="GrammarEnumeration\LruCache.cs" />
+    <Compile Include="GrammarEnumeration\SymbolList.cs" />
     <Compile Include="Hashing\Hasher.cs" />
     <Compile Include="GrammarEnumeration\SearchDataStructure.cs" />
-    <Compile Include="GrammarEnumeration\Sentence.cs" />
     <Compile Include="ProblemInstances\AircraftMaximumLift.cs" />
     <Compile Include="ProblemInstances\FluidDynamics.cs" />
Index: branches/2886_SymRegGrammarEnumeration/Test/GrammarEnumerationTest.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/Test/GrammarEnumerationTest.cs	(revision 16022)
+++ branches/2886_SymRegGrammarEnumeration/Test/GrammarEnumerationTest.cs	(revision 16026)
@@ -44,5 +44,4 @@
     }
 
-
     private void EvaluateGrammarEnumeration() {
       // Evaluate results
@@ -55,5 +54,4 @@
       Assert.AreEqual(1.0, ((IRegressionSolution)alg.Results["Best solution (Training)"].Value).TestRSquared, eps, "Test quality too low!");
     }
-
 
     [TestMethod]
@@ -72,5 +70,5 @@
       TerminalSymbol addSymbol = alg.Grammar.Addition;
 
-      SymbolString targetSolution = new SymbolString(new[] {
+      SymbolList targetSolution = new SymbolList(new[] {
         constSymbol, varSymbol, varSymbol, varSymbol, mulSymbol, mulSymbol, mulSymbol,
         constSymbol, varSymbol, varSymbol, mulSymbol, mulSymbol, addSymbol,
@@ -132,5 +130,5 @@
 
       // c * sin(c x + c) + c * sin(c * x * x + c * x) + c
-      SymbolString targetSolution = new SymbolString(new[] {
+      SymbolList targetSolution = new SymbolList(new[] {
         varSymbol, constSymbol, mulSymbol, constSymbol, addSymbol, sinSymbol, constSymbol, mulSymbol,
         varSymbol, varSymbol, mulSymbol, constSymbol, mulSymbol, varSymbol, constSymbol, mulSymbol, addSymbol, constSymbol, addSymbol, sinSymbol, constSymbol, mulSymbol, addSymbol,
@@ -165,5 +163,5 @@
 
       // c*sin(c*x + c) + c*sin(c*y*y + c) + c
-      SymbolString targetSolution = new SymbolString(new[] {
+      SymbolList targetSolution = new SymbolList(new[] {
         xSymbol, constSymbol, mulSymbol, constSymbol, addSymbol, sinSymbol, constSymbol, mulSymbol,
         ySymbol, ySymbol, mulSymbol, constSymbol, mulSymbol, constSymbol, addSymbol, sinSymbol, constSymbol, mulSymbol, addSymbol,
@@ -222,5 +220,5 @@
       TerminalSymbol logSymbol = alg.Grammar.Log;
 
-      SymbolString targetSolution = new SymbolString(new[] {
+      SymbolList targetSolution = new SymbolList(new[] {
         varSymbol, constSymbol, mulSymbol, constSymbol, addSymbol, logSymbol, constSymbol, mulSymbol,
         varSymbol, varSymbol, mulSymbol, constSymbol, mulSymbol, constSymbol, addSymbol, logSymbol, constSymbol, mulSymbol, addSymbol,
@@ -266,5 +264,5 @@
       TerminalSymbol addSymbol = alg.Grammar.Addition;
 
-      SymbolString targetSolution = new SymbolString(new[] {
+      SymbolList targetSolution = new SymbolList(new[] {
         constSymbol, varSymbol, mulSymbol, constSymbol, addSymbol, alg.Grammar.Sin,
         varSymbol, mulSymbol,
@@ -303,5 +301,5 @@
       // 30 * x * z * 1/(x*y*y - 10*y*y)
       // --> x z * c *     x y * y * c *  y y * c * + c + inv c +
-      SymbolString targetSolution = new SymbolString(new[] {
+      SymbolList targetSolution = new SymbolList(new[] {
         xSymbol, zSymbol, mulSymbol, constSymbol, mulSymbol,
         xSymbol, ySymbol, mulSymbol, ySymbol, mulSymbol, constSymbol, mulSymbol,
@@ -337,5 +335,5 @@
       TerminalSymbol addSymbol = alg.Grammar.Addition;
 
-      SymbolString targetSolution = new SymbolString(new[] {
+      SymbolList targetSolution = new SymbolList(new[] {
         xSymbol, xSymbol, mulSymbol, xSymbol, mulSymbol, xSymbol, mulSymbol, constSymbol, mulSymbol,
         xSymbol, xSymbol, mulSymbol, xSymbol, mulSymbol, constSymbol, mulSymbol, addSymbol,
@@ -376,5 +374,5 @@
 
       // x x mul c mul y y mul c mul add const add inv const mul const add
-      SymbolString targetSolution = new SymbolString(new[] {
+      SymbolList targetSolution = new SymbolList(new[] {
         xSymbol, xSymbol, mulSymbol, constSymbol, mulSymbol,
         ySymbol, ySymbol, mulSymbol, constSymbol, mulSymbol, addSymbol,
@@ -412,5 +410,5 @@
 
       // x x * x * const * y y * y * const * + y const * + x const * const +
-      SymbolString targetSolution = new SymbolString(new[] {
+      SymbolList targetSolution = new SymbolList(new[] {
         xSymbol, xSymbol, mulSymbol, xSymbol, mulSymbol, constSymbol, mulSymbol,
         ySymbol, ySymbol, mulSymbol, ySymbol, mulSymbol, constSymbol, mulSymbol, addSymbol,
Index: branches/2886_SymRegGrammarEnumeration/Test/TreeHashingTest.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/Test/TreeHashingTest.cs	(revision 16022)
+++ branches/2886_SymRegGrammarEnumeration/Test/TreeHashingTest.cs	(revision 16026)
@@ -27,6 +27,6 @@
     [TestCategory("TreeHashing")]
     public void SimpleEqualityAddition() {
-      SymbolString s1 = new SymbolString(new[] { varA, varB, grammar.Addition, varC, grammar.Addition });
-      SymbolString s2 = new SymbolString(new[] { varA, varB, grammar.Addition, varC, grammar.Addition });
+      SymbolList s1 = new SymbolList(new[] { varA, varB, grammar.Addition, varC, grammar.Addition });
+      SymbolList s2 = new SymbolList(new[] { varA, varB, grammar.Addition, varC, grammar.Addition });
 
       int hash1 = grammar.Hasher.CalcHashCode(s1);
@@ -39,6 +39,6 @@
     [TestCategory("TreeHashing")]
     public void SimpleInequalityAddition() {
-      SymbolString s1 = new SymbolString(new[] { varA, varB, grammar.Addition, varC, grammar.Addition });
-      SymbolString s2 = new SymbolString(new[] { varB, varB, grammar.Addition, varB, grammar.Addition });
+      SymbolList s1 = new SymbolList(new[] { varA, varB, grammar.Addition, varC, grammar.Addition });
+      SymbolList s2 = new SymbolList(new[] { varB, varB, grammar.Addition, varB, grammar.Addition });
 
       int hash1 = grammar.Hasher.CalcHashCode(s1);
@@ -51,6 +51,6 @@
     [TestCategory("TreeHashing")]
     public void CommutativityAddition() {
-      SymbolString s1 = new SymbolString(new[] { varA, varB, grammar.Addition });
-      SymbolString s2 = new SymbolString(new[] { varB, varA, grammar.Addition });
+      SymbolList s1 = new SymbolList(new[] { varA, varB, grammar.Addition });
+      SymbolList s2 = new SymbolList(new[] { varB, varA, grammar.Addition });
 
       int hash1 = grammar.Hasher.CalcHashCode(s1);
@@ -63,6 +63,6 @@
     [TestCategory("TreeHashing")]
     public void AssociativityAddition() {
-      SymbolString s1 = new SymbolString(new[] { varA, varB, grammar.Addition, varA, grammar.Addition });
-      SymbolString s2 = new SymbolString(new[] { varA, varB, varA, grammar.Addition, grammar.Addition });
+      SymbolList s1 = new SymbolList(new[] { varA, varB, grammar.Addition, varA, grammar.Addition });
+      SymbolList s2 = new SymbolList(new[] { varA, varB, varA, grammar.Addition, grammar.Addition });
 
       int hash1 = grammar.Hasher.CalcHashCode(s1);
@@ -75,6 +75,6 @@
     [TestCategory("TreeHashing")]
     public void RepeatedAddition() {
-      SymbolString s1 = new SymbolString(new[] { varA, varA, grammar.Addition, varA, grammar.Addition });
-      SymbolString s2 = new SymbolString(new[] { varA });
+      SymbolList s1 = new SymbolList(new[] { varA, varA, grammar.Addition, varA, grammar.Addition });
+      SymbolList s2 = new SymbolList(new[] { varA });
 
       int hash1 = grammar.Hasher.CalcHashCode(s1);
@@ -87,6 +87,6 @@
     [TestCategory("TreeHashing")]
     public void ComplexInequality() {
-      SymbolString s1 = new SymbolString(new[] { varA, varA, varA, grammar.Multiplication, grammar.Multiplication });
-      SymbolString s2 = new SymbolString(new[] { varA, varA, varA, grammar.Multiplication, grammar.Addition });
+      SymbolList s1 = new SymbolList(new[] { varA, varA, varA, grammar.Multiplication, grammar.Multiplication });
+      SymbolList s2 = new SymbolList(new[] { varA, varA, varA, grammar.Multiplication, grammar.Addition });
 
       int hash1 = grammar.Hasher.CalcHashCode(s1);
@@ -99,6 +99,6 @@
     [TestCategory("TreeHashing")]
     public void NonterminalHashing() {
-      SymbolString s1 = new SymbolString(new Symbol[] { varA, varA, grammar.Expr, grammar.Addition, grammar.Addition });
-      SymbolString s2 = new SymbolString(new Symbol[] { varA, grammar.Expr, grammar.Addition });
+      SymbolList s1 = new SymbolList(new Symbol[] { varA, varA, grammar.Expr, grammar.Addition, grammar.Addition });
+      SymbolList s2 = new SymbolList(new Symbol[] { varA, grammar.Expr, grammar.Addition });
 
       int hash1 = grammar.Hasher.CalcHashCode(s1);
@@ -112,7 +112,7 @@
     public void InverseFactorCancelationSimple() {
       // 1/a * b * a * a
-      SymbolString s1 = new SymbolString(new Symbol[] { varA, grammar.Inv, varB, grammar.Multiplication, varA, grammar.Multiplication, varA, grammar.Multiplication });
+      SymbolList s1 = new SymbolList(new Symbol[] { varA, grammar.Inv, varB, grammar.Multiplication, varA, grammar.Multiplication, varA, grammar.Multiplication });
       // a * b
-      SymbolString s2 = new SymbolString(new Symbol[] { varA, varB, grammar.Multiplication });
+      SymbolList s2 = new SymbolList(new Symbol[] { varA, varB, grammar.Multiplication });
 
       int hash1 = grammar.Hasher.CalcHashCode(s1);
@@ -125,6 +125,6 @@
     [TestCategory("TreeHashing")]
     public void InverseFactorCancelationComplex() {
-      SymbolString s1 = new SymbolString(new Symbol[] { varA, grammar.Sin, varA, varA, grammar.Multiplication, varA, grammar.Addition, grammar.Sin, grammar.Addition });
-      SymbolString s2 = new SymbolString(new Symbol[] { varA, varA, varA, grammar.Multiplication, grammar.Addition, grammar.Sin, varA, grammar.Inv, varA, grammar.Sin, varA, grammar.Multiplication, grammar.Multiplication, grammar.Addition });
+      SymbolList s1 = new SymbolList(new Symbol[] { varA, grammar.Sin, varA, varA, grammar.Multiplication, varA, grammar.Addition, grammar.Sin, grammar.Addition });
+      SymbolList s2 = new SymbolList(new Symbol[] { varA, varA, varA, grammar.Multiplication, grammar.Addition, grammar.Sin, varA, grammar.Inv, varA, grammar.Sin, varA, grammar.Multiplication, grammar.Multiplication, grammar.Addition });
 
       int hash1 = grammar.Hasher.CalcHashCode(s1);
@@ -138,6 +138,6 @@
     [TestCategory("TreeHashing")]
     public void SimpleConst() {
-      SymbolString s1 = new SymbolString(new Symbol[] { c, varA, grammar.Multiplication, c, grammar.Addition});
-      SymbolString s2 = new SymbolString(new Symbol[] { c, varA, grammar.Multiplication, c, varA, grammar.Multiplication, grammar.Addition, c, grammar.Addition });
+      SymbolList s1 = new SymbolList(new Symbol[] { c, varA, grammar.Multiplication, c, grammar.Addition});
+      SymbolList s2 = new SymbolList(new Symbol[] { c, varA, grammar.Multiplication, c, varA, grammar.Multiplication, grammar.Addition, c, grammar.Addition });
 
       int hash1 = grammar.Hasher.CalcHashCode(s1);
@@ -151,6 +151,6 @@
     [TestCategory("TreeHashing")]
     public void CompoundInverseCancellationToSingleInverse() {
-      SymbolString s1 = new SymbolString(new Symbol[] { varA, varB, grammar.Addition, grammar.Inv, grammar.Inv, grammar.Inv });
-      SymbolString s2 = new SymbolString(new Symbol[] { varA, varB, grammar.Addition, grammar.Inv });
+      SymbolList s1 = new SymbolList(new Symbol[] { varA, varB, grammar.Addition, grammar.Inv, grammar.Inv, grammar.Inv });
+      SymbolList s2 = new SymbolList(new Symbol[] { varA, varB, grammar.Addition, grammar.Inv });
 
       int hash1 = grammar.CalcHashCode(s1);
@@ -163,6 +163,6 @@
     [TestCategory("TreeHashing")]
     public void CompoundInverseCancellationToDivisor() {
-      SymbolString s1 = new SymbolString(new Symbol[] { varA, varB, grammar.Addition, grammar.Inv, grammar.Inv });
-      SymbolString s2 = new SymbolString(new Symbol[] { varA, varB, grammar.Addition });
+      SymbolList s1 = new SymbolList(new Symbol[] { varA, varB, grammar.Addition, grammar.Inv, grammar.Inv });
+      SymbolList s2 = new SymbolList(new Symbol[] { varA, varB, grammar.Addition });
 
       int hash1 = grammar.CalcHashCode(s1);
@@ -176,7 +176,7 @@
     public void UncancelableCompoundInverse() {
       // 1 / ( 1/b + sin(a*c) )
-      SymbolString s1 = new SymbolString(new Symbol[] { varB, grammar.Inv, varA, varC, grammar.Multiplication, grammar.Sin, grammar.Addition, grammar.Inv });
+      SymbolList s1 = new SymbolList(new Symbol[] { varB, grammar.Inv, varA, varC, grammar.Multiplication, grammar.Sin, grammar.Addition, grammar.Inv });
       // b + sin(a*c)
-      SymbolString s2 = new SymbolString(new Symbol[] { varB, varA, varC, grammar.Multiplication, grammar.Sin, grammar.Addition });
+      SymbolList s2 = new SymbolList(new Symbol[] { varB, varA, varC, grammar.Multiplication, grammar.Sin, grammar.Addition });
 
       int hash1 = grammar.CalcHashCode(s1);
