Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/BestSolutionAnalyzer.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/BestSolutionAnalyzer.cs	(revision 16053)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/BestSolutionAnalyzer.cs	(revision 16053)
@@ -0,0 +1,128 @@
+﻿#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;
+using System.Diagnostics;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+
+namespace HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration {
+  [Item("Best Solution Analyzer", "Returns the characteristics of the best solution so far.")]
+  [StorableClass]
+  public class BestSolutionAnalyzer : Item, IGrammarEnumerationAnalyzer {
+    public static readonly string BestTrainingQualityResultName = "Best R² (Training)";
+    public static readonly string BestTestQualityResultName = "Best R² (Test)";
+    public static readonly string BestTrainingModelResultName = "Best model (Training)";
+    public static readonly string BestTrainingSolutionResultName = "Best solution (Training)";
+    public static readonly string BestComplexityResultName = "Best solution complexity";
+    public static readonly string BestSolutions = "Best solutions";
+
+    private static readonly ISymbolicDataAnalysisExpressionTreeInterpreter expressionTreeLinearInterpreter = new SymbolicDataAnalysisExpressionTreeLinearInterpreter();
+
+    public BestSolutionAnalyzer() { }
+
+    [StorableConstructor]
+    protected BestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
+
+    protected BestSolutionAnalyzer(BestSolutionAnalyzer original, Cloner cloner) : base(original, cloner) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BestSolutionAnalyzer(this, cloner);
+    }
+
+    public void Deregister(GrammarEnumerationAlgorithm algorithm) {
+      algorithm.DistinctSentenceGenerated -= AlgorithmDistinctSentenceGenerated;
+    }
+
+    public void Register(GrammarEnumerationAlgorithm algorithm) {
+      algorithm.DistinctSentenceGenerated += AlgorithmDistinctSentenceGenerated;
+    }
+
+    private void AlgorithmDistinctSentenceGenerated(object sender, PhraseAddedEventArgs args) {
+      var algorithm = (GrammarEnumerationAlgorithm)sender;
+      var sentence = args.NewPhrase;
+
+      var results = algorithm.Results;
+      var grammar = algorithm.Grammar;
+      var problemData = algorithm.Problem.ProblemData;
+
+      SymbolicExpressionTree tree = algorithm.Grammar.ParseSymbolicExpressionTree(sentence);
+      Debug.Assert(SymbolicRegressionConstantOptimizationEvaluator.CanOptimizeConstants(tree));
+
+      double r2 = algorithm.Evaluator.Evaluate(problemData, tree);
+      double bestR2 = results.ContainsKey(BestTrainingQualityResultName) ? GetValue<double>(results[BestTrainingQualityResultName].Value) : 0.0;
+      if (r2 < bestR2)
+        return;
+
+      var bestComplexity = results.ContainsKey(BestComplexityResultName) ? GetValue<int>(results[BestComplexityResultName].Value) : int.MaxValue;
+      var complexity = sentence.Complexity;
+
+      if (algorithm.BestTrainingSentence == null || r2 > bestR2 || (r2.IsAlmost(bestR2) && complexity < bestComplexity)) {
+        algorithm.BestTrainingSentence = sentence;
+
+        var model = new SymbolicRegressionModel(problemData.TargetVariable, tree, expressionTreeLinearInterpreter);
+        model.Scale(problemData);
+        var bestSolution = model.CreateRegressionSolution(problemData);
+
+        results.AddOrUpdateResult(BestTrainingQualityResultName, new DoubleValue(bestSolution.TrainingRSquared));
+        results.AddOrUpdateResult(BestTestQualityResultName, new DoubleValue(bestSolution.TestRSquared));
+        results.AddOrUpdateResult(BestTrainingModelResultName, bestSolution.Model);
+        results.AddOrUpdateResult(BestTrainingSolutionResultName, bestSolution);
+        results.AddOrUpdateResult(BestComplexityResultName, new IntValue(complexity));
+
+        // record best sentence quality & length
+        DataTable dt;
+        if (!results.ContainsKey(BestSolutions)) {
+          var names = new[] { "Quality", "Length", "Complexity", "Timestamp" };
+          dt = new DataTable();
+          foreach (var name in names) {
+            dt.Rows.Add(new DataRow(name) { VisualProperties = { StartIndexZero = true } });
+          }
+          results.AddOrUpdateResult(BestSolutions, dt);
+        }
+        dt = (DataTable)results[BestSolutions].Value;
+        dt.Rows["Quality"].Values.Add(r2);
+        dt.Rows["Length"].Values.Add((double)sentence.Count);
+        dt.Rows["Complexity"].Values.Add(complexity);
+        dt.Rows["Timestamp"].Values.Add(algorithm.ExecutionTime.TotalMilliseconds / 1000d);
+      }
+
+      // stop the algorithm if the best quality was already achieved
+      if (r2.IsAlmost(1d)) {
+        algorithm.Stop();
+      }
+    }
+
+    private T GetValue<T>(IItem value) where T : struct {
+      var v = value as ValueTypeValue<T>;
+      if (v == null)
+        throw new ArgumentException(string.Format("Item is not of type {0}", typeof(ValueTypeValue<T>)));
+      return v.Value;
+    }
+  }
+}
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/IGrammarEnumerationAnalyzer.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/IGrammarEnumerationAnalyzer.cs	(revision 16026)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/IGrammarEnumerationAnalyzer.cs	(revision 16053)
@@ -1,7 +1,28 @@
-﻿using HeuristicLab.Core;
+﻿#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 HeuristicLab.Core;
 
 namespace HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration {
   public interface IGrammarEnumerationAnalyzer : IItem {
-    void Register(GrammarEnumerationAlgorithm g);
+    void Register(GrammarEnumerationAlgorithm algorithm);
     void Deregister(GrammarEnumerationAlgorithm algorithm);
   }
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/IGrammarEnumerationEvaluator.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/IGrammarEnumerationEvaluator.cs	(revision 16053)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/IGrammarEnumerationEvaluator.cs	(revision 16053)
@@ -0,0 +1,29 @@
+﻿#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 HeuristicLab.Core;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration {
+  public interface IGrammarEnumerationEvaluator : IItem {
+    double Evaluate(IRegressionProblemData problemData, Grammar grammar, SymbolList sentence);
+  }
+}
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/RSquaredEvaluator.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/RSquaredEvaluator.cs	(revision 16026)
+++ 	(revision )
@@ -1,150 +1,0 @@
-﻿using System;
-using System.Diagnostics;
-using HeuristicLab.Analysis;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Problems.DataAnalysis;
-using HeuristicLab.Problems.DataAnalysis.Symbolic;
-using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
-
-namespace HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration {
-  [Item("RSquaredEvaluator", "")]
-  [StorableClass]
-  public class RSquaredEvaluator : Item, IGrammarEnumerationAnalyzer {
-    public static readonly string BestTrainingQualityResultName = "Best R² (Training)";
-    public static readonly string BestTestQualityResultName = "Best R² (Test)";
-    public static readonly string BestTrainingModelResultName = "Best model (Training)";
-    public static readonly string BestTrainingSolutionResultName = "Best solution (Training)";
-    public static readonly string BestComplexityResultName = "Best solution complexity";
-    public static readonly string BestSolutions = "Best solutions";
-
-    private static readonly ISymbolicDataAnalysisExpressionTreeInterpreter expressionTreeLinearInterpreter = new SymbolicDataAnalysisExpressionTreeLinearInterpreter();
-
-    public RSquaredEvaluator() { }
-
-    [StorableConstructor]
-    protected RSquaredEvaluator(bool deserializing) : base(deserializing) { }
-
-    protected RSquaredEvaluator(RSquaredEvaluator original, Cloner cloner) : base(original, cloner) {
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new RSquaredEvaluator(this, cloner);
-    }
-
-    public void Register(GrammarEnumerationAlgorithm algorithm) {
-      algorithm.Started += OnStarted;
-      algorithm.Stopped += OnStopped;
-      algorithm.DistinctSentenceGenerated += AlgorithmOnDistinctSentenceGenerated;
-    }
-
-    public void Deregister(GrammarEnumerationAlgorithm algorithm) {
-      algorithm.Started -= OnStarted;
-      algorithm.Stopped -= OnStopped;
-      algorithm.DistinctSentenceGenerated -= AlgorithmOnDistinctSentenceGenerated;
-    }
-
-    private void AlgorithmOnDistinctSentenceGenerated(object sender, PhraseAddedEventArgs phraseAddedEventArgs) {
-      GrammarEnumerationAlgorithm algorithm = (GrammarEnumerationAlgorithm)sender;
-      EvaluateSentence(algorithm, phraseAddedEventArgs.NewPhrase, algorithm.OptimizeConstants, algorithm.ConstantOptimizationIterations);
-    }
-
-    private void OnStarted(object sender, EventArgs eventArgs) {
-      GrammarEnumerationAlgorithm algorithm = (GrammarEnumerationAlgorithm)sender;
-
-      algorithm.BestTrainingSentence = null;
-    }
-
-    private void OnStopped(object sender, EventArgs eventArgs) { }
-
-    private T GetValue<T>(IItem value) where T : struct {
-      var v = value as ValueTypeValue<T>;
-      if (v == null)
-        throw new ArgumentException(string.Format("Item is not of type {0}", typeof(ValueTypeValue<T>)));
-      return v.Value;
-    }
-
-    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(sentence);
-      Debug.Assert(SymbolicRegressionConstantOptimizationEvaluator.CanOptimizeConstants(tree));
-
-      double r2 = Evaluate(problemData, tree, optimizeConstants, maxIterations);
-      double bestR2 = results.ContainsKey(BestTrainingQualityResultName) ? GetValue<double>(results[BestTrainingQualityResultName].Value) : 0.0;
-      if (r2 < bestR2)
-        return;
-
-      var bestComplexity = results.ContainsKey(BestComplexityResultName) ? GetValue<int>(results[BestComplexityResultName].Value) : int.MaxValue;
-      var complexity = sentence.Complexity;
-
-      if (algorithm.BestTrainingSentence == null || r2 > bestR2 || (r2.IsAlmost(bestR2) && complexity < bestComplexity)) {
-        algorithm.BestTrainingSentence = sentence;
-
-        var model = new SymbolicRegressionModel(problemData.TargetVariable, tree, expressionTreeLinearInterpreter);
-        model.Scale(problemData);
-        var bestSolution = model.CreateRegressionSolution(problemData);
-
-        results.AddOrUpdateResult(BestTrainingQualityResultName, new DoubleValue(bestSolution.TrainingRSquared));
-        results.AddOrUpdateResult(BestTestQualityResultName, new DoubleValue(bestSolution.TestRSquared));
-        results.AddOrUpdateResult(BestTrainingModelResultName, bestSolution.Model);
-        results.AddOrUpdateResult(BestTrainingSolutionResultName, bestSolution);
-        results.AddOrUpdateResult(BestComplexityResultName, new IntValue(complexity));
-
-        // record best sentence quality & length
-        DataTable dt;
-        if (!results.ContainsKey(BestSolutions)) {
-          var names = new[] { "Quality", "Relative Length", "Complexity", "Timestamp" };
-          dt = new DataTable();
-          foreach (var name in names) {
-            dt.Rows.Add(new DataRow(name) { VisualProperties = { StartIndexZero = true } });
-          }
-          results.AddOrUpdateResult(BestSolutions, dt);
-        }
-        dt = (DataTable)results[BestSolutions].Value;
-        dt.Rows["Quality"].Values.Add(r2);
-        dt.Rows["Relative Length"].Values.Add((double)sentence.Count);
-        dt.Rows["Complexity"].Values.Add(complexity);
-        dt.Rows["Timestamp"].Values.Add(algorithm.ExecutionTime.TotalMilliseconds / 1000d);
-      }
-    }
-
-    public static double Evaluate(IRegressionProblemData problemData, SymbolicExpressionTree tree, bool optimizeConstants = true, int maxIterations = 10) {
-      double r2;
-
-      // TODO: Initialize constant values randomly
-      // TODO: Restarts
-      if (optimizeConstants) {
-        r2 = SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(expressionTreeLinearInterpreter,
-          tree,
-          problemData,
-          problemData.TrainingIndices,
-          applyLinearScaling: true,
-          maxIterations: maxIterations,
-          updateVariableWeights: false,
-          updateConstantsInTree: true);
-
-        foreach (var symbolicExpressionTreeNode in tree.IterateNodesPostfix()) {
-          ConstantTreeNode constTreeNode = symbolicExpressionTreeNode as ConstantTreeNode;
-          if (constTreeNode != null && constTreeNode.Value.IsAlmost(0.0)) {
-            constTreeNode.Value = 0.0;
-          }
-        }
-      } else {
-        r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(expressionTreeLinearInterpreter,
-          tree,
-          double.MinValue,
-          double.MaxValue,
-          problemData,
-          problemData.TrainingIndices,
-          applyLinearScaling: true);
-      }
-      return double.IsNaN(r2) ? 0.0 : r2;
-    }
-  }
-}
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/SearchGraphVisualizer.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/SearchGraphVisualizer.cs	(revision 16026)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/SearchGraphVisualizer.cs	(revision 16053)
@@ -1,6 +1,26 @@
-﻿using System;
+﻿#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;
 using System.Diagnostics;
 using System.IO;
-using HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration.GrammarEnumeration;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/SentenceLogger.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/SentenceLogger.cs	(revision 16026)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Analysis/SentenceLogger.cs	(revision 16053)
@@ -1,3 +1,24 @@
-﻿using System;
+﻿#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;
 using System.Diagnostics;
 using System.IO;
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/Grammar.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/Grammar.cs	(revision 16026)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/Grammar.cs	(revision 16053)
@@ -1,7 +1,27 @@
-﻿using System;
+﻿#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;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Linq;
-using HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration.GrammarEnumeration;
 using HeuristicLab.Common;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
@@ -234,5 +254,10 @@
     }
 
-    // returns the maximum achievable sentence length below the maximum complexity
+    /// <summary>
+    /// returns the maximum achievable sentence length below the maximum complexity
+    /// TODO: figure out a way to calculate this accurately
+    /// </summary>
+    /// <param name="maxComplexity"></param>
+    /// <returns>Maximum sentence length according to the grammar and the maximum complexity</returns>
     public int GetMaxSentenceLength(int maxComplexity) {
       SymbolList s = new SymbolList(StartSymbol);
@@ -253,8 +278,8 @@
     }
 
-    public double EvaluatePhrase(SymbolList s, IRegressionProblemData problemData, bool optimizeConstants, int iterations) {
+    public double EvaluatePhrase(SymbolList s, IRegressionProblemData problemData, bool optimizeConstants, int iterations, bool applyLinearScaling) {
       SymbolicExpressionTree tree = ParseSymbolicExpressionTree(s);
 
-      return RSquaredEvaluator.Evaluate(problemData, tree, optimizeConstants, iterations);
+      return RSquaredEvaluator.Evaluate(problemData, tree, optimizeConstants, iterations, applyLinearScaling);
     }
 
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/GrammarEnumerationAlgorithm.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/GrammarEnumerationAlgorithm.cs	(revision 16026)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/GrammarEnumerationAlgorithm.cs	(revision 16053)
@@ -1,7 +1,27 @@
-﻿using System;
+﻿#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;
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
-using HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration.GrammarEnumeration;
 using HeuristicLab.Collections;
 using HeuristicLab.Common;
@@ -31,6 +51,6 @@
     private readonly string ExpansionsPerSecondName = "Expansions per second";
 
-    private readonly string OptimizeConstantsParameterName = "Optimize Constants";
-    private readonly string ConstantOptimizationIterationsParameterName = "Constant Optimization Iterations";
+    private readonly string EvaluatorParameterName = "Evaluator";
+
     private readonly string ErrorWeightParameterName = "Error Weight";
     private readonly string SearchDataStructureParameterName = "Search Data Structure";
@@ -47,20 +67,10 @@
     public override bool SupportsPause { get { return true; } }
 
-    protected IFixedValueParameter<BoolValue> OptimizeConstantsParameter {
-      get { return (IFixedValueParameter<BoolValue>)Parameters[OptimizeConstantsParameterName]; }
-    }
-
-    public bool OptimizeConstants {
-      get { return OptimizeConstantsParameter.Value.Value; }
-      set { OptimizeConstantsParameter.Value.Value = value; }
-    }
-
-    public int ConstantOptimizationIterations {
-      get { return ConstantOptimizationIterationsParameter.Value.Value; }
-      set { ConstantOptimizationIterationsParameter.Value.Value = value; }
-    }
-
-    public IFixedValueParameter<IntValue> ConstantOptimizationIterationsParameter {
-      get { return (IFixedValueParameter<IntValue>)Parameters[ConstantOptimizationIterationsParameterName]; }
+    public IFixedValueParameter<RSquaredEvaluator> EvaluatorParameter {
+      get { return (IFixedValueParameter<RSquaredEvaluator>)Parameters[EvaluatorParameterName]; }
+    }
+
+    public RSquaredEvaluator Evaluator {
+      get { return EvaluatorParameter.Value; }
     }
 
@@ -102,4 +112,5 @@
     public int SearchDataStructureSize {
       get { return SearchDataStructureSizeParameter.Value.Value; }
+      set { SearchDataStructureSizeParameter.Value.Value = value; }
     }
 
@@ -189,5 +200,4 @@
 
     public GrammarEnumerationAlgorithm() {
-      Parameters.Add(new FixedValueParameter<BoolValue>(OptimizeConstantsParameterName, "Run constant optimization in sentence evaluation.", new BoolValue(false)));
       Parameters.Add(new FixedValueParameter<DoubleValue>(ErrorWeightParameterName, "Defines, how much weight is put on a phrase's r² value when priorizing phrases during search.", new DoubleValue(0.8)));
       Parameters.Add(new FixedValueParameter<IntValue>(MaxComplexityParameterName, "The maximum number of variable symbols in a sentence.", new IntValue(12)));
@@ -195,5 +205,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)));
+      Parameters.Add(new FixedValueParameter<RSquaredEvaluator>(EvaluatorParameterName, new RSquaredEvaluator()));
 
       SearchDataStructureParameter.Value.ValueChanged += (o, e) => Prepare();
@@ -203,5 +213,5 @@
         new SearchGraphVisualizer(),
         new SentenceLogger(),
-        new RSquaredEvaluator()
+        new BestSolutionAnalyzer()
       };
 
@@ -215,5 +225,5 @@
         Analyzers.SetItemCheckedState(analyzer, false);
       }
-      Analyzers.SetItemCheckedState(Analyzers.First(analyzer => analyzer is RSquaredEvaluator), true);
+      Analyzers.SetItemCheckedState(Analyzers.First(analyzer => analyzer is BestSolutionAnalyzer), true);
 
       var grammarSymbols = Enum.GetValues(typeof(GrammarRule))
@@ -275,6 +285,7 @@
       MaxSentenceLength = Grammar.GetMaxSentenceLength(MaxComplexity);
       var errorWeight = ErrorWeight;
-      var optimizeConstants = OptimizeConstants; // cache value to avoid parameter lookup
-      var iterations = ConstantOptimizationIterations;
+      var evaluator = EvaluatorParameter.Value;
+      var problemData = Problem.ProblemData;
+
       // main search loop
       while (OpenPhrases.Count > 0) {
@@ -317,11 +328,11 @@
 
             // Is the best solution found? (only if RSquaredEvaluator is activated)
-            if (Results.ContainsKey(RSquaredEvaluator.BestTrainingQualityResultName)) {
-              double r2 = ((DoubleValue)Results[RSquaredEvaluator.BestTrainingQualityResultName].Value).Value;
-              if (r2.IsAlmost(1.0)) {
-                UpdateView(force: true);
-                return;
-              }
-            }
+            //if (Results.ContainsKey(RSquaredEvaluator.BestTrainingQualityResultName)) {
+            //  double r2 = ((DoubleValue)Results[RSquaredEvaluator.BestTrainingQualityResultName].Value).Value;
+            //  if (r2.IsAlmost(1.0)) {
+            //    UpdateView(force: true);
+            //    return;
+            //  }
+            //}
 
             if (!DistinctSentencesComplexity.ContainsKey(phraseHash) || DistinctSentencesComplexity[phraseHash] > newPhraseComplexity) {
@@ -334,7 +345,5 @@
 
           } else if (!OpenPhrases.Contains(phraseHash) && !ArchivedPhrases.Contains(phraseHash)) {
-
-            bool isCompleteSentence = IsCompleteSentence(newPhrase);
-            double r2 = isCompleteSentence ? Grammar.EvaluatePhrase(newPhrase, Problem.ProblemData, optimizeConstants, iterations) : fetchedSearchNode.R2;
+            double r2 = IsCompleteSentence(newPhrase) ? evaluator.Evaluate(problemData, Grammar, newPhrase) : fetchedSearchNode.R2;
             double phrasePriority = GetPriority(newPhrase, r2);
 
@@ -389,4 +398,7 @@
       var model = new SymbolicRegressionModel(Problem.ProblemData.TargetVariable, tree, interpreter);
 
+      var iterations = EvaluatorParameter.Value.ConstantOptimizationIterations;
+      var applyLinearScaling = EvaluatorParameter.Value.ApplyLinearScaling;
+
       SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(
         interpreter,
@@ -394,6 +406,6 @@
         Problem.ProblemData,
         Problem.ProblemData.TrainingIndices,
-        applyLinearScaling: true,
-        maxIterations: ConstantOptimizationIterations,
+        applyLinearScaling: applyLinearScaling,
+        maxIterations: iterations,
         updateVariableWeights: false,
         updateConstantsInTree: true);
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/LruCache.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/LruCache.cs	(revision 16026)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/LruCache.cs	(revision 16053)
@@ -1,3 +1,24 @@
-﻿using System;
+﻿#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;
 using System.Collections;
 using System.Collections.Generic;
@@ -6,5 +27,5 @@
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
-namespace HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration.GrammarEnumeration {
+namespace HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration {
   /// <summary>
   /// A least-recently-used cache stored like a dictionary.
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/RSquaredEvaluator.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/RSquaredEvaluator.cs	(revision 16053)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/RSquaredEvaluator.cs	(revision 16053)
@@ -0,0 +1,129 @@
+﻿#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+
+namespace HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration {
+  [Item("RSquaredEvaluator", "")]
+  [StorableClass]
+  public class RSquaredEvaluator : ParameterizedNamedItem, IGrammarEnumerationEvaluator {
+    private readonly string OptimizeConstantsParameterName = "Optimize Constants";
+    private readonly string ApplyLinearScalingParameterName = "Apply Linear Scaling";
+    private readonly string ConstantOptimizationIterationsParameterName = "Constant Optimization Iterations";
+
+    #region parameter properties
+    public IFixedValueParameter<BoolValue> OptimizeConstantsParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[OptimizeConstantsParameterName]; }
+    }
+
+    public IFixedValueParameter<BoolValue> ApplyLinearScalingParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
+    }
+
+    public IFixedValueParameter<IntValue> ConstantOptimizationIterationsParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[ConstantOptimizationIterationsParameterName]; }
+    }
+
+    public bool OptimizeConstants {
+      get { return OptimizeConstantsParameter.Value.Value; }
+      set { OptimizeConstantsParameter.Value.Value = value; }
+    }
+
+    public bool ApplyLinearScaling {
+      get { return ApplyLinearScalingParameter.Value.Value; }
+      set { ApplyLinearScalingParameter.Value.Value = value; }
+    }
+
+    public int ConstantOptimizationIterations {
+      get { return ConstantOptimizationIterationsParameter.Value.Value; }
+      set { ConstantOptimizationIterationsParameter.Value.Value = value; }
+    }
+    #endregion
+
+    private static readonly ISymbolicDataAnalysisExpressionTreeInterpreter expressionTreeLinearInterpreter = new SymbolicDataAnalysisExpressionTreeLinearInterpreter();
+
+    public RSquaredEvaluator() {
+      Parameters.Add(new FixedValueParameter<BoolValue>(OptimizeConstantsParameterName, "Run constant optimization in sentence evaluation.", new BoolValue(false)));
+      Parameters.Add(new FixedValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Apply linear scaling on the tree model during evaluation.", new BoolValue(false)));
+      Parameters.Add(new FixedValueParameter<IntValue>(ConstantOptimizationIterationsParameterName, new IntValue(10)));
+    }
+
+    [StorableConstructor]
+    protected RSquaredEvaluator(bool deserializing) : base(deserializing) { }
+
+    protected RSquaredEvaluator(RSquaredEvaluator original, Cloner cloner) : base(original, cloner) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RSquaredEvaluator(this, cloner);
+    }
+
+    public double Evaluate(IRegressionProblemData problemData, Grammar grammar, SymbolList sentence) {
+      var tree = grammar.ParseSymbolicExpressionTree(sentence);
+      return Evaluate(problemData, tree, OptimizeConstants, ConstantOptimizationIterations, ApplyLinearScaling);
+    }
+
+    public double Evaluate(IRegressionProblemData problemData, ISymbolicExpressionTree tree) {
+      return Evaluate(problemData, tree, OptimizeConstants, ConstantOptimizationIterations, ApplyLinearScaling);
+    }
+
+    public static double Evaluate(IRegressionProblemData problemData, ISymbolicExpressionTree tree, bool optimizeConstants = true, int maxIterations = 10, bool applyLinearScaling = false) {
+      double r2;
+
+      // TODO: Initialize constant values randomly
+      // TODO: Restarts
+      if (optimizeConstants) {
+        r2 = SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(expressionTreeLinearInterpreter,
+          tree,
+          problemData,
+          problemData.TrainingIndices,
+          applyLinearScaling: applyLinearScaling,
+          maxIterations: maxIterations,
+          updateVariableWeights: false,
+          updateConstantsInTree: true);
+
+        foreach (var symbolicExpressionTreeNode in tree.IterateNodesPostfix()) {
+          ConstantTreeNode constTreeNode = symbolicExpressionTreeNode as ConstantTreeNode;
+          if (constTreeNode != null && constTreeNode.Value.IsAlmost(0.0)) {
+            constTreeNode.Value = 0.0;
+          }
+        }
+      } else {
+        r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(expressionTreeLinearInterpreter,
+          tree,
+          double.MinValue,
+          double.MaxValue,
+          problemData,
+          problemData.TrainingIndices,
+          applyLinearScaling: applyLinearScaling);
+      }
+      return double.IsNaN(r2) ? 0.0 : r2;
+    }
+  }
+}
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/SearchDataStructure.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/SearchDataStructure.cs	(revision 16026)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/SearchDataStructure.cs	(revision 16053)
@@ -1,3 +1,24 @@
-﻿using System;
+﻿#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;
 using System.Collections;
 using System.Collections.Generic;
@@ -6,5 +27,5 @@
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
-namespace HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration.GrammarEnumeration {
+namespace HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration {
   [StorableClass]
   public class SearchNode : DeepCloneable {
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/Sentence.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/Sentence.cs	(revision 16026)
+++ 	(revision )
@@ -1,90 +1,0 @@
-﻿using System;
-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.GrammarEnumeration {
-  [StorableClass]
-  public class SymbolString : DeepCloneable, IEnumerable<Symbol> {
-    [Storable]
-    private readonly Symbol[] symbols;
-
-    public Symbol this[int index] {
-      get { return symbols[index]; }
-    }
-
-    public SymbolString(IEnumerable<Symbol> s) {
-      symbols = s.ToArray();
-    }
-
-    public SymbolString(params Symbol[] s) {
-      symbols = s;
-    }
-
-    [StorableConstructor]
-    protected SymbolString(bool deserializing) { }
-
-    protected SymbolString(SymbolString original, Cloner cloner) : base(original, cloner) {
-      symbols = original.symbols.Select(cloner.Clone).ToArray();
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new SymbolString(this, cloner);
-    }
-
-    public bool IsSentence() {
-      return !this.Any(sym => sym is NonterminalSymbol);
-    }
-
-    public int[] GetNonterminalSymbolIndexes() {
-      return Enumerable.Range(0, symbols.Length)
-        .Where(i => symbols[i] is NonterminalSymbol)
-        .ToArray();
-    }
-
-    public int NextNonterminalIndex() {
-      Debug.Assert(!IsSentence());
-      int firstNonTerminalIndex = 0;
-      while (firstNonTerminalIndex < symbols.Length && symbols[firstNonTerminalIndex] is TerminalSymbol) {
-        firstNonTerminalIndex++;
-      }
-      return firstNonTerminalIndex;
-    }
-
-    public SymbolString DerivePhrase(int nonterminalSymbolIndex, SymbolList production) {
-      int productionLength = production.Count;
-      int newStringLength = Count() + productionLength - 1;
-      Symbol[] newPhrase = new Symbol[newStringLength];
-
-      // Copy "left" part of the phrase
-      Array.Copy(symbols, 0, newPhrase, 0, nonterminalSymbolIndex);
-      // Copy production and overwrite nonterminalsymbol
-      production.CopyTo(0, newPhrase, nonterminalSymbolIndex, productionLength);
-      // Copy "right" part of the original phrase
-      Array.Copy(symbols, nonterminalSymbolIndex + 1, newPhrase, nonterminalSymbolIndex + productionLength, symbols.Length - nonterminalSymbolIndex - 1);
-
-      return new SymbolString(newPhrase);
-    }
-
-    public override string ToString() {
-      return string.Join<Symbol>(" ", symbols);
-    }
-
-    #region Enumerable interface
-    IEnumerator IEnumerable.GetEnumerator() {
-      return GetEnumerator();
-    }
-
-    public IEnumerator<Symbol> GetEnumerator() {
-      return ((IEnumerable<Symbol>)symbols).GetEnumerator();
-    }
-
-    public int Count() {
-      return symbols.Length;
-    }
-    #endregion
-  }
-}
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/Symbol.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/Symbol.cs	(revision 16026)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/Symbol.cs	(revision 16053)
@@ -1,7 +1,24 @@
-﻿using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
+﻿#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;
 using HeuristicLab.Common;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
@@ -103,4 +120,4 @@
   }
 
- 
+
 }
Index: branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Hashing/Hasher.cs
===================================================================
--- branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Hashing/Hasher.cs	(revision 16026)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/Hashing/Hasher.cs	(revision 16053)
@@ -1,3 +1,24 @@
-﻿using System;
+﻿#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;
 using System.Collections.Generic;
 using System.Diagnostics;
@@ -6,5 +27,5 @@
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
-namespace HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration.GrammarEnumeration {
+namespace HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration {
   [StorableClass]
   public abstract class Hasher<THashType> : DeepCloneable {
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 16026)
+++ branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration.csproj	(revision 16053)
@@ -116,6 +116,8 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Analysis\BestSolutionAnalyzer.cs" />
     <Compile Include="Analysis\IGrammarEnumerationAnalyzer.cs" />
-    <Compile Include="Analysis\RSquaredEvaluator.cs" />
+    <Compile Include="Analysis\IGrammarEnumerationEvaluator.cs" />
+    <Compile Include="GrammarEnumeration\RSquaredEvaluator.cs" />
     <Compile Include="Analysis\SentenceLogger.cs" />
     <Compile Include="Analysis\SearchGraphVisualizer.cs" />
