Index: branches/2974_Constants_Optimization/ConstantsOptimization.sln
===================================================================
--- branches/2974_Constants_Optimization/ConstantsOptimization.sln	(revision 16460)
+++ branches/2974_Constants_Optimization/ConstantsOptimization.sln	(revision 16461)
@@ -15,4 +15,6 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.DataAnalysis.Symbolic-3.4", "HeuristicLab.Problems.DataAnalysis.Symbolic\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj", "{3D28463F-EC96-4D82-AFEE-38BE91A0CA00}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "UnitTests\UnitTests.csproj", "{9617D7C7-90FB-41BB-A9B2-6DAC68E15197}"
 EndProject
 Global
@@ -50,4 +52,16 @@
 		{3D28463F-EC96-4D82-AFEE-38BE91A0CA00}.Release|x86.ActiveCfg = Release|x86
 		{3D28463F-EC96-4D82-AFEE-38BE91A0CA00}.Release|x86.Build.0 = Release|x86
+		{9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Debug|x64.Build.0 = Debug|Any CPU
+		{9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Debug|x86.Build.0 = Debug|Any CPU
+		{9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Release|Any CPU.Build.0 = Release|Any CPU
+		{9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Release|x64.ActiveCfg = Release|Any CPU
+		{9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Release|x64.Build.0 = Release|Any CPU
+		{9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Release|x86.ActiveCfg = Release|Any CPU
+		{9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Release|x86.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj
===================================================================
--- branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj	(revision 16460)
+++ branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj	(revision 16461)
@@ -102,4 +102,8 @@
       <HintPath>..\..\..\..\trunk\bin\ALGLIB-3.7.0.dll</HintPath>
       <Private>False</Private>
+    </Reference>
+    <Reference Include="AutoDiff-1.0, Version=1.0.0.14388, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\AutoDiff-1.0.dll</HintPath>
     </Reference>
     <Reference Include="HeuristicLab.Analysis-3.3">
Index: branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/ConstantsOptimizationEvaluator.cs
===================================================================
--- branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/ConstantsOptimizationEvaluator.cs	(revision 16460)
+++ branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/ConstantsOptimizationEvaluator.cs	(revision 16461)
@@ -131,5 +131,4 @@
     }
 
-
     private static readonly object locker = new object();
     public override IOperation InstrumentedApply() {
@@ -189,4 +188,11 @@
     }
 
+    [ThreadStatic]
+    private static double[,] x = null;
+    [ThreadStatic]
+    private static IDataset ds = null;
+    [ThreadStatic]
+    private static Dictionary<DataForVariable, AutoDiff.Variable> parameters;
+
     public static double OptimizeConstants(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
       ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling,
@@ -195,4 +201,12 @@
       bool updateConstantsInTree = true, Action<double[], double, object> iterationCallback = null, EvaluationsCounter counter = null) {
 
+      if (ds == null || ds != problemData.Dataset) {
+        ds = problemData.Dataset;
+        parameters = ConstantsOptimization.Util.ExtractParameters(problemData.Dataset);
+        x = ConstantsOptimization.Util.ExtractData(ds, parameters.Keys, rows);
+        
+      }
+      double[] y = ds.GetDoubleValues(problemData.TargetVariable, rows).ToArray();
+
 
       // numeric constants in the tree become variables for constant opt
@@ -201,13 +215,12 @@
       // variable name, variable value (for factor vars) and lag as a DataForVariable object.
       // A dictionary is used to find parameters
-      double[] initialConstants;
-      var parameters = new List<TreeToAutoDiffTermConverter.DataForVariable>();
-
       TreeToAutoDiffTermConverter.ParametricFunction func;
       TreeToAutoDiffTermConverter.ParametricFunctionGradient func_grad;
-      if (!TreeToAutoDiffTermConverter.TryConvertToAutoDiff(tree, updateVariableWeights, applyLinearScaling, out parameters, out initialConstants, out func, out func_grad))
+
+      if (!TreeToAutoDiffTermConverter.TryConvertToAutoDiff(tree, updateVariableWeights, applyLinearScaling, parameters, out func, out func_grad))
         throw new NotSupportedException("Could not optimize constants of symbolic expression tree due to not supported symbols used in the tree.");
       if (parameters.Count == 0) return 0.0; // gkronber: constant expressions always have a R² of 0.0 
-      //var parameterEntries = parameters.ToArray(); // order of entries must be the same for x
+
+      var initialConstants = ConstantsOptimization.Util.ExtractConstants(tree);
 
       //extract inital constants
@@ -231,7 +244,5 @@
       int retVal;
 
-      IDataset ds = problemData.Dataset;
-      var x = ConstantsOptimization.Util.ExtractData(ds, parameters, rows);
-      double[] y = ds.GetDoubleValues(problemData.TargetVariable, rows).ToArray();
+
       int n = x.GetLength(0);
       int m = x.GetLength(1);
@@ -263,33 +274,17 @@
           var tmp = new double[c.Length - 2];
           Array.Copy(c, 2, tmp, 0, tmp.Length);
-          UpdateConstants(tree, tmp, updateVariableWeights);
-        } else UpdateConstants(tree, c, updateVariableWeights);
+          ConstantsOptimization.Util.UpdateConstants(tree, tmp);
+        } else ConstantsOptimization.Util.UpdateConstants(tree, c);
       }
       var quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, tree, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling);
 
-      if (!updateConstantsInTree) UpdateConstants(tree, initialConstants, updateVariableWeights);
+      if (!updateConstantsInTree)
+        ConstantsOptimization.Util.UpdateConstants(tree, initialConstants);
 
       if (originalQuality - quality > 0.001 || double.IsNaN(quality)) {
-        UpdateConstants(tree, initialConstants, updateVariableWeights);
+        ConstantsOptimization.Util.UpdateConstants(tree, initialConstants);
         return originalQuality;
       }
       return quality;
-    }
-
-    private static void UpdateConstants(ISymbolicExpressionTree tree, double[] constants, bool updateVariableWeights) {
-      int i = 0;
-      foreach (var node in tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>()) {
-        ConstantTreeNode constantTreeNode = node as ConstantTreeNode;
-        VariableTreeNodeBase variableTreeNodeBase = node as VariableTreeNodeBase;
-        FactorVariableTreeNode factorVarTreeNode = node as FactorVariableTreeNode;
-        if (constantTreeNode != null)
-          constantTreeNode.Value = constants[i++];
-        else if (updateVariableWeights && variableTreeNodeBase != null)
-          variableTreeNodeBase.Weight = constants[i++];
-        else if (factorVarTreeNode != null) {
-          for (int j = 0; j < factorVarTreeNode.Weights.Length; j++)
-            factorVarTreeNode.Weights[j] = constants[i++];
-        }
-      }
     }
 
Index: branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Constants Optimization/Util.cs
===================================================================
--- branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Constants Optimization/Util.cs	(revision 16460)
+++ branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Constants Optimization/Util.cs	(revision 16461)
@@ -37,5 +37,5 @@
         foreach (var variable in variables) {
           if (dataset.VariableHasType<double>(variable.variableName)) {
-            x[row, col] = dataset.GetDoubleValue(variable.variableName, r+variable.lag);
+            x[row, col] = dataset.GetDoubleValue(variable.variableName, r + variable.lag);
           } else if (dataset.VariableHasType<string>(variable.variableName)) {
             x[row, col] = dataset.GetStringValue(variable.variableName, r) == variable.variableValue ? 1 : 0;
@@ -50,13 +50,13 @@
     public static Dictionary<DataForVariable, AutoDiff.Variable> ExtractParameters(IDataset dataset) {
       var parameters = new Dictionary<DataForVariable, AutoDiff.Variable>();
-      foreach(var doubleVariable in dataset.DoubleVariables) {
+      foreach (var doubleVariable in dataset.DoubleVariables) {
         var data = new DataForVariable(doubleVariable, string.Empty, 0);
         var param = new AutoDiff.Variable();
-        parameters.Add(data,param);
+        parameters.Add(data, param);
       }
 
-      foreach(var stringVariable in dataset.StringVariables) {
-        foreach(var stringValue in dataset.GetStringValues(stringVariable).Distinct()) {
-          var data = new DataForVariable(stringVariable, stringVariable, 0);
+      foreach (var stringVariable in dataset.StringVariables) {
+        foreach (var stringValue in dataset.GetStringValues(stringVariable).Distinct()) {
+          var data = new DataForVariable(stringVariable, stringValue, 0);
           var param = new AutoDiff.Variable();
           parameters.Add(data, param);
@@ -64,4 +64,22 @@
       }
       return parameters;
+    }
+
+    public static double[] ExtractConstants(ISymbolicExpressionTree tree) {
+      var constants = new List<double>();
+      foreach (var node in tree.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>()) {
+        ConstantTreeNode constantTreeNode = node as ConstantTreeNode;
+        VariableTreeNodeBase variableTreeNodeBase = node as VariableTreeNodeBase;
+        FactorVariableTreeNode factorVarTreeNode = node as FactorVariableTreeNode;
+        if (constantTreeNode != null)
+          constants.Add(constantTreeNode.Value);
+        else if (variableTreeNodeBase != null)
+          constants.Add(variableTreeNodeBase.Weight);
+        else if (factorVarTreeNode != null) {
+          for (int j = 0; j < factorVarTreeNode.Weights.Length; j++)
+            constants.Add(factorVarTreeNode.Weights[j]);
+        }        
+      }
+      return constants.ToArray();
     }
 
Index: branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs
===================================================================
--- branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs	(revision 16460)
+++ branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs	(revision 16461)
@@ -131,4 +131,38 @@
     }
 
+    public static bool TryConvertToAutoDiff(ISymbolicExpressionTree tree, bool makeVariableWeightsVariable, bool addLinearScalingTerms, Dictionary<DataForVariable, AutoDiff.Variable> parameters,
+      out ParametricFunction func,
+      out ParametricFunctionGradient func_grad
+  ) {
+
+      // use a transformator object which holds the state (variable list, parameter list, ...) for recursive transformation of the tree
+      var transformator = new TreeToAutoDiffTermConverter(makeVariableWeightsVariable, parameters);
+      AutoDiff.Term term;
+      try {
+        term = transformator.ConvertToAutoDiff(tree.Root.GetSubtree(0));
+
+        if (addLinearScalingTerms) {
+          // scaling variables α, β are given at the beginning of the parameter vector
+          var alpha = new AutoDiff.Variable();
+          var beta = new AutoDiff.Variable();
+          transformator.variables.Insert(0, alpha);
+          transformator.variables.Insert(0, beta);
+
+          term = term * alpha + beta;
+        }
+        
+        var compiledTerm = term.Compile(transformator.variables.ToArray(), parameters.Select(kvp => kvp.Value).ToArray());
+
+
+        func = (vars, @params) => compiledTerm.Evaluate(vars, @params);
+        func_grad = (vars, @params) => compiledTerm.Differentiate(vars, @params);
+        return true;
+      } catch (ConversionException) {
+        func = null;
+        func_grad = null;
+      }
+      return false;
+    }
+
     // state for recursive transformation of trees 
     private readonly List<double> initialConstants;
@@ -137,8 +171,11 @@
     private readonly bool makeVariableWeightsVariable;
 
-    private TreeToAutoDiffTermConverter(bool makeVariableWeightsVariable) {
+    private TreeToAutoDiffTermConverter(bool makeVariableWeightsVariable, Dictionary<DataForVariable, AutoDiff.Variable> parameters = null) {
       this.makeVariableWeightsVariable = makeVariableWeightsVariable;
       this.initialConstants = new List<double>();
-      this.parameters = new Dictionary<DataForVariable, AutoDiff.Variable>();
+      if (parameters == null)
+        this.parameters = new Dictionary<DataForVariable, AutoDiff.Variable>();
+      else
+        this.parameters = parameters;
       this.variables = new List<AutoDiff.Variable>();
     }
Index: branches/2974_Constants_Optimization/UnitTests/ConstantsOptimizationTests.cs
===================================================================
--- branches/2974_Constants_Optimization/UnitTests/ConstantsOptimizationTests.cs	(revision 16461)
+++ branches/2974_Constants_Optimization/UnitTests/ConstantsOptimizationTests.cs	(revision 16461)
@@ -0,0 +1,236 @@
+﻿#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Persistence.Default.Xml;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.ConstantsOptimization;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+
+
+using HeuristicLab.Problems.Instances.DataAnalysis;
+
+using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm;
+
+namespace UnitTests {
+  [TestClass]
+  public class ConstantsOptimizationTests {
+    private static readonly int seed = 1234;
+
+
+    public static void CompareConstantsOptimizationResults(IRegressionProblemData problemData, ISymbolicExpressionTree tree) {
+      var old_optimizedTree = (ISymbolicExpressionTree)tree.Clone();
+      var old_result = SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(
+        new SymbolicDataAnalysisExpressionTreeLinearInterpreter(),
+        old_optimizedTree, problemData, problemData.TrainingIndices, applyLinearScaling: true, maxIterations: 10);
+
+
+      var new_optimizedTree = (ISymbolicExpressionTree)tree.Clone();
+      var new_result = ConstantsOptimizationEvaluator.OptimizeConstants(
+        new SymbolicDataAnalysisExpressionTreeLinearInterpreter(),
+        new_optimizedTree, problemData, problemData.TrainingIndices, applyLinearScaling: true, maxIterations: 10);
+
+      //check R² values
+      Assert.AreEqual(old_result, new_result);
+
+      //check numeric values of constants
+      var old_constants = Util.ExtractConstants(old_optimizedTree);
+      var new_constants = Util.ExtractConstants(new_optimizedTree);
+      Assert.IsTrue(old_constants.SequenceEqual(new_constants));
+    }
+
+   
+
+    [TestMethod]
+    [TestCategory("Problems.DataAnalysis.Symbolic.Regression")]
+    [TestProperty("Time", "short")]
+    public void ConstantsOptimizationTest_Nguyen01() {
+      var problemData = new NguyenFunctionOne(seed).GenerateRegressionData();
+      var modelTemplate = "({0})* CUBE(X) + ({1}) * SQR(X) + ({2}) * X";
+
+      string modelString;
+      object[] constants;
+      ISymbolicExpressionTree modelTree;
+
+      constants = new object[] { 1.0, 2.0, 3.0 };
+      modelString = string.Format(modelTemplate, constants);
+      modelTree = new InfixExpressionParser().Parse(modelString);
+      CompareConstantsOptimizationResults(problemData, modelTree);
+
+      constants = new object[] { 5.0, -2.0, 500.362 };
+      modelString = string.Format(modelTemplate, constants);
+      modelTree = new InfixExpressionParser().Parse(modelString);
+      CompareConstantsOptimizationResults(problemData, modelTree);
+
+      constants = new object[] { -6987.25, 1, -888 };
+      modelString = string.Format(modelTemplate, constants);
+      modelTree = new InfixExpressionParser().Parse(modelString);
+      CompareConstantsOptimizationResults(problemData, modelTree);
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.DataAnalysis.Symbolic.Regression")]
+    [TestProperty("Time", "short")]
+    public void ConstantsOptimizationTest_Nguyen03() {
+      var problemData = new NguyenFunctionThree(seed).GenerateRegressionData();
+      var modelTemplate = "({0})* X*X*X*X*X + ({1}) * X*X*X*X + ({2}) * X*X*X + ({3}) * X*X + ({4}) * X + {5}";
+
+      string modelString;
+      object[] constants;
+      ISymbolicExpressionTree modelTree;
+
+      constants = new object[] { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 };
+      modelString = string.Format(modelTemplate, constants);
+      modelTree = new InfixExpressionParser().Parse(modelString);
+      CompareConstantsOptimizationResults(problemData, modelTree);
+
+      constants = new object[] { 5.0, -2.0, 500.362, -5646, 0.0001, 1234 };
+      modelString = string.Format(modelTemplate, constants);
+      modelTree = new InfixExpressionParser().Parse(modelString);
+      CompareConstantsOptimizationResults(problemData, modelTree);
+
+      constants = new object[] { -6987.25, 1, -888, +888, -1, 6987.25, 0, 25 };
+      modelString = string.Format(modelTemplate, constants);
+      modelTree = new InfixExpressionParser().Parse(modelString);
+      CompareConstantsOptimizationResults(problemData, modelTree);
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.DataAnalysis.Symbolic.Regression")]
+    [TestProperty("Time", "short")]
+    public void ConstantsOptimizationTest_Nguyen05() {
+      var problemData = new NguyenFunctionFive(seed).GenerateRegressionData();
+      var modelTemplate = "({0}) * SIN(({1})*X*X) * COS(({2})*X) + ({3})";
+
+      string modelString;
+      object[] constants;
+      ISymbolicExpressionTree modelTree;
+
+      constants = new object[] { 1.0, 2.0, 3.0, 4.0 };
+      modelString = string.Format(modelTemplate, constants);
+      modelTree = new InfixExpressionParser().Parse(modelString);
+      CompareConstantsOptimizationResults(problemData, modelTree);
+
+      constants = new object[] { 5.0, -2.0, -3.0, 5.0 };
+      modelString = string.Format(modelTemplate, constants);
+      modelTree = new InfixExpressionParser().Parse(modelString);
+      CompareConstantsOptimizationResults(problemData, modelTree);
+
+      constants = new object[] { 0.5, 1, 1, 3 };
+      modelString = string.Format(modelTemplate, constants);
+      modelTree = new InfixExpressionParser().Parse(modelString);
+      CompareConstantsOptimizationResults(problemData, modelTree);
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.DataAnalysis.Symbolic.Regression")]
+    [TestProperty("Time", "short")]
+    public void ConstantsOptimizationTest_Nguyen07() {
+      var problemData = new NguyenFunctionFive(seed).GenerateRegressionData();
+      var modelTemplate = "({0}) * LOG(({1})*X + ({2})) + ({3}) * LOG(({4})*X*X + ({5})) + ({6})";
+
+      string modelString;
+      object[] constants;
+      ISymbolicExpressionTree modelTree;
+
+      constants = new object[] { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0 };
+      modelString = string.Format(modelTemplate, constants);
+      modelTree = new InfixExpressionParser().Parse(modelString);
+      CompareConstantsOptimizationResults(problemData, modelTree);
+
+      constants = new object[] { 5.0, 2.0, 500.362, -5646, 0.0001, 1234, 421 };
+      modelString = string.Format(modelTemplate, constants);
+      modelTree = new InfixExpressionParser().Parse(modelString);
+      CompareConstantsOptimizationResults(problemData, modelTree);
+
+      constants = new object[] { -6987.25, 1, 888, +888, -1, 6987.25, 0, 25 };
+      modelString = string.Format(modelTemplate, constants);
+      modelTree = new InfixExpressionParser().Parse(modelString);
+      CompareConstantsOptimizationResults(problemData, modelTree);
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.DataAnalysis.Symbolic.Regression")]
+    [TestProperty("Time", "short")]
+    public void ConstantsOptimizationTest_Nguyen08() {
+      var problemData = new NguyenFunctionEight(seed).GenerateRegressionData();
+      var modelTemplate = "({0})* SQRT(({1}) * X) + ({2})";
+
+      string modelString;
+      object[] constants;
+      ISymbolicExpressionTree modelTree;
+
+      constants = new object[] { 1.0, 2.0, 3.0 };
+      modelString = string.Format(modelTemplate, constants);
+      modelTree = new InfixExpressionParser().Parse(modelString);
+      CompareConstantsOptimizationResults(problemData, modelTree);
+
+      constants = new object[] { 5.0, 20.0, -500.362 };
+      modelString = string.Format(modelTemplate, constants);
+      modelTree = new InfixExpressionParser().Parse(modelString);
+      CompareConstantsOptimizationResults(problemData, modelTree);
+
+      constants = new object[] { -6987.25, 1, -888 };
+      modelString = string.Format(modelTemplate, constants);
+      modelTree = new InfixExpressionParser().Parse(modelString);
+      CompareConstantsOptimizationResults(problemData, modelTree);
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.DataAnalysis.Symbolic.Regression")]
+    [TestProperty("Time", "short")]
+    public void ConstantsOptimizationTest_Keijzer05() {
+      var problemData = new KeijzerFunctionFive(seed).GenerateRegressionData();
+      var modelTemplate = "( ({0}) * X * Z ) / ( (({1}) * X + ({2})) * ({3}) * SQR(Y) ) + ({4})";
+
+      string modelString;
+      object[] constants;
+      ISymbolicExpressionTree modelTree;
+
+      constants = new object[] { 1.0, 2.0, 3.0, 4.0, 5.0 };
+      modelString = string.Format(modelTemplate, constants);
+      modelTree = new InfixExpressionParser().Parse(modelString);
+      CompareConstantsOptimizationResults(problemData, modelTree);
+
+      constants = new object[] { 5.0, -2.0, 500.362, -5646, 0.0001 };
+      modelString = string.Format(modelTemplate, constants);
+      modelTree = new InfixExpressionParser().Parse(modelString);
+      CompareConstantsOptimizationResults(problemData, modelTree);
+
+      constants = new object[] { -6987.25, 1, -888, +888, -1, 6987.25, 0 };
+      modelString = string.Format(modelTemplate, constants);
+      modelTree = new InfixExpressionParser().Parse(modelString);
+      CompareConstantsOptimizationResults(problemData, modelTree);
+    }
+  }
+}
Index: branches/2974_Constants_Optimization/UnitTests/PerformanceTest.cs
===================================================================
--- branches/2974_Constants_Optimization/UnitTests/PerformanceTest.cs	(revision 16461)
+++ branches/2974_Constants_Optimization/UnitTests/PerformanceTest.cs	(revision 16461)
@@ -0,0 +1,207 @@
+﻿using System;
+using HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.Xml;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+using HeuristicLab.Selection;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System.Linq;
+using HeuristicLab.Problems.Instances.DataAnalysis;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Optimization;
+using HeuristicLab.ParallelEngine;
+
+namespace UnitTests {
+  [TestClass]
+  public class PerformanceTest {
+    private static int seed = 1234;
+
+    //TODO remove performance test 
+    [TestMethod]
+    [TestCategory("Problems.DataAnalysis.Symbolic.Regression")]
+    [TestProperty("Time", "long")]
+    public void ConstantsOptimization_Tower_Algorithm() {
+      var algorithm = CreateGpSymbolicRegressionSample();
+      var problem = (SymbolicRegressionSingleObjectiveProblem)algorithm.Problem;
+
+      algorithm.MaximumGenerations.Value = 1;
+      var evaluator = new ConstantsOptimizationEvaluator();
+      evaluator.ConstantOptimizationIterations.Value = 5;
+      problem.EvaluatorParameter.Value = evaluator;
+
+      algorithm.Prepare();
+      algorithm.Start();
+    }
+
+    private OffspringSelectionGeneticAlgorithm CreateGpSymbolicRegressionSample() {
+      var osga = new OffspringSelectionGeneticAlgorithm();
+      #region Problem Configuration
+      var provider = new RegressionRealWorldInstanceProvider();
+      var problemData =  provider.LoadData(new Tower());
+      var problem = new SymbolicRegressionSingleObjectiveProblem();
+      problem.ProblemData = problemData;
+      problem.Load(problemData);
+      problem.BestKnownQuality.Value = 1.0;
+
+      #region configure grammar
+
+      var grammar = (TypeCoherentExpressionGrammar)problem.SymbolicExpressionTreeGrammar;
+      grammar.ConfigureAsDefaultRegressionGrammar();
+
+      //symbols square, power, squareroot, root, log, exp, sine, cosine, tangent, variable
+      var square = grammar.Symbols.OfType<Square>().Single();
+      var power = grammar.Symbols.OfType<Power>().Single();
+      var squareroot = grammar.Symbols.OfType<SquareRoot>().Single();
+      var root = grammar.Symbols.OfType<Root>().Single();
+      var cube = grammar.Symbols.OfType<Cube>().Single();
+      var cuberoot = grammar.Symbols.OfType<CubeRoot>().Single();
+      var log = grammar.Symbols.OfType<Logarithm>().Single();
+      var exp = grammar.Symbols.OfType<Exponential>().Single();
+      var sine = grammar.Symbols.OfType<Sine>().Single();
+      var cosine = grammar.Symbols.OfType<Cosine>().Single();
+      var tangent = grammar.Symbols.OfType<Tangent>().Single();
+      var variable = grammar.Symbols.OfType<HeuristicLab.Problems.DataAnalysis.Symbolic.Variable>().Single();
+      var powerSymbols = grammar.Symbols.Single(s => s.Name == "Power Functions");
+      powerSymbols.Enabled = true;
+
+      square.Enabled = true;
+      square.InitialFrequency = 1.0;
+      foreach (var allowed in grammar.GetAllowedChildSymbols(square))
+        grammar.RemoveAllowedChildSymbol(square, allowed);
+      foreach (var allowed in grammar.GetAllowedChildSymbols(square, 0))
+        grammar.RemoveAllowedChildSymbol(square, allowed, 0);
+      grammar.AddAllowedChildSymbol(square, variable);
+
+      power.Enabled = false;
+
+      squareroot.Enabled = false;
+      foreach (var allowed in grammar.GetAllowedChildSymbols(squareroot))
+        grammar.RemoveAllowedChildSymbol(squareroot, allowed);
+      foreach (var allowed in grammar.GetAllowedChildSymbols(squareroot, 0))
+        grammar.RemoveAllowedChildSymbol(squareroot, allowed, 0);
+      grammar.AddAllowedChildSymbol(squareroot, variable);
+
+      cube.Enabled = false;
+      cuberoot.Enabled = false;
+      root.Enabled = false;
+
+      log.Enabled = true;
+      log.InitialFrequency = 1.0;
+      foreach (var allowed in grammar.GetAllowedChildSymbols(log))
+        grammar.RemoveAllowedChildSymbol(log, allowed);
+      foreach (var allowed in grammar.GetAllowedChildSymbols(log, 0))
+        grammar.RemoveAllowedChildSymbol(log, allowed, 0);
+      grammar.AddAllowedChildSymbol(log, variable);
+
+      exp.Enabled = true;
+      exp.InitialFrequency = 1.0;
+      foreach (var allowed in grammar.GetAllowedChildSymbols(exp))
+        grammar.RemoveAllowedChildSymbol(exp, allowed);
+      foreach (var allowed in grammar.GetAllowedChildSymbols(exp, 0))
+        grammar.RemoveAllowedChildSymbol(exp, allowed, 0);
+      grammar.AddAllowedChildSymbol(exp, variable);
+
+      sine.Enabled = false;
+      foreach (var allowed in grammar.GetAllowedChildSymbols(sine))
+        grammar.RemoveAllowedChildSymbol(sine, allowed);
+      foreach (var allowed in grammar.GetAllowedChildSymbols(sine, 0))
+        grammar.RemoveAllowedChildSymbol(sine, allowed, 0);
+      grammar.AddAllowedChildSymbol(sine, variable);
+
+      cosine.Enabled = false;
+      foreach (var allowed in grammar.GetAllowedChildSymbols(cosine))
+        grammar.RemoveAllowedChildSymbol(cosine, allowed);
+      foreach (var allowed in grammar.GetAllowedChildSymbols(cosine, 0))
+        grammar.RemoveAllowedChildSymbol(cosine, allowed, 0);
+      grammar.AddAllowedChildSymbol(cosine, variable);
+
+      tangent.Enabled = false;
+      foreach (var allowed in grammar.GetAllowedChildSymbols(tangent))
+        grammar.RemoveAllowedChildSymbol(tangent, allowed);
+      foreach (var allowed in grammar.GetAllowedChildSymbols(tangent, 0))
+        grammar.RemoveAllowedChildSymbol(tangent, allowed, 0);
+      grammar.AddAllowedChildSymbol(tangent, variable);
+      #endregion
+
+      problem.SymbolicExpressionTreeGrammar = grammar;
+
+      // configure remaining problem parameters
+      problem.MaximumSymbolicExpressionTreeLength.Value = 50;
+      problem.MaximumSymbolicExpressionTreeDepth.Value = 12;
+      problem.MaximumFunctionDefinitions.Value = 0;
+      problem.MaximumFunctionArguments.Value = 0;
+
+      var evaluator = new SymbolicRegressionConstantOptimizationEvaluator();
+      evaluator.ConstantOptimizationIterations.Value = 5;
+      problem.EvaluatorParameter.Value = evaluator;
+      problem.RelativeNumberOfEvaluatedSamplesParameter.Hidden = true;
+      problem.SolutionCreatorParameter.Hidden = true;
+      #endregion
+
+      #region Algorithm Configuration
+      osga.Problem = problem;
+      osga.Name = "Offspring Selection Genetic Programming - Symbolic Regression";
+      osga.Description = "Genetic programming with strict offspring selection for solving a benchmark regression problem.";
+      ConfigureOsGeneticAlgorithmParameters<GenderSpecificSelector, SubtreeCrossover, MultiSymbolicExpressionTreeManipulator>(osga, 100, 1, 25, 0.2, 50);
+      var mutator = (MultiSymbolicExpressionTreeManipulator)osga.Mutator;
+      mutator.Operators.OfType<FullTreeShaker>().Single().ShakingFactor = 0.1;
+      mutator.Operators.OfType<OnePointShaker>().Single().ShakingFactor = 1.0;
+
+      osga.Analyzer.Operators.SetItemCheckedState(
+        osga.Analyzer.Operators
+          .OfType<SymbolicRegressionSingleObjectiveOverfittingAnalyzer>()
+          .Single(), false);
+      osga.Analyzer.Operators.SetItemCheckedState(
+        osga.Analyzer.Operators
+          .OfType<SymbolicDataAnalysisAlleleFrequencyAnalyzer>()
+          .First(), false);
+
+      osga.ComparisonFactorModifierParameter.Hidden = true;
+      osga.ComparisonFactorLowerBoundParameter.Hidden = true;
+      osga.ComparisonFactorUpperBoundParameter.Hidden = true;
+      osga.OffspringSelectionBeforeMutationParameter.Hidden = true;
+      osga.SuccessRatioParameter.Hidden = true;
+      osga.SelectedParentsParameter.Hidden = true;
+      osga.ElitesParameter.Hidden = true;
+
+      #endregion
+      return osga;
+    }
+
+
+    public static void ConfigureOsGeneticAlgorithmParameters<S, C, M>(OffspringSelectionGeneticAlgorithm ga, int popSize, int elites, int maxGens, double mutationRate = 0.05, double maxSelPres = 100, int tournGroupSize = 0)
+      where S : ISelector
+      where C : ICrossover
+      where M : IManipulator {
+      ga.Elites.Value = elites;
+      ga.MaximumGenerations.Value = maxGens;
+      ga.MutationProbability.Value = mutationRate;
+      ga.PopulationSize.Value = popSize;
+      ga.MaximumSelectionPressure.Value = maxSelPres;
+      ga.Seed.Value = 0;
+      ga.SetSeedRandomly.Value = true;
+      ga.ComparisonFactorLowerBound.Value = 1;
+      ga.ComparisonFactorUpperBound.Value = 1;
+
+      ga.Selector = ga.SelectorParameter.ValidValues
+        .OfType<S>()
+        .First();
+
+      ga.Crossover = ga.CrossoverParameter.ValidValues
+        .OfType<C>()
+        .First();
+
+      ga.Mutator = ga.MutatorParameter.ValidValues
+        .OfType<M>()
+        .First();
+
+      var tSelector = ga.Selector as TournamentSelector;
+      if (tSelector != null) {
+        tSelector.GroupSizeParameter.Value.Value = tournGroupSize;
+      }
+      ga.Engine = new ParallelEngine();
+    }
+
+  }
+}
Index: branches/2974_Constants_Optimization/UnitTests/Properties/AssemblyInfo.cs
===================================================================
--- branches/2974_Constants_Optimization/UnitTests/Properties/AssemblyInfo.cs	(revision 16461)
+++ branches/2974_Constants_Optimization/UnitTests/Properties/AssemblyInfo.cs	(revision 16461)
@@ -0,0 +1,20 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("UnitTests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("FH-Hagenberg")]
+[assembly: AssemblyProduct("UnitTests")]
+[assembly: AssemblyCopyright("Copyright Â© FH-Hagenberg 2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+
+[assembly: Guid("9617d7c7-90fb-41bb-a9b2-6dac68e15197")]
+
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
Index: branches/2974_Constants_Optimization/UnitTests/UnitTests.csproj
===================================================================
--- branches/2974_Constants_Optimization/UnitTests/UnitTests.csproj	(revision 16461)
+++ branches/2974_Constants_Optimization/UnitTests/UnitTests.csproj	(revision 16461)
@@ -0,0 +1,161 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.props" Condition="Exists('..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.props')" />
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{9617D7C7-90FB-41BB-A9B2-6DAC68E15197}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>UnitTests</RootNamespace>
+    <AssemblyName>UnitTests</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
+    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+    <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
+    <IsCodedUITest>False</IsCodedUITest>
+    <TestProjectType>UnitTest</TestProjectType>
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="ALGLIB-3.7.0">
+      <HintPath>..\..\..\trunk\bin\ALGLIB-3.7.0.dll</HintPath>
+    </Reference>
+    <Reference Include="AutoDiff-1.0">
+      <HintPath>..\..\..\trunk\bin\AutoDiff-1.0.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Algorithms.DataAnalysis-3.4">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Algorithms.DataAnalysis-3.4.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Algorithms.GeneticAlgorithm-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Algorithms.GeneticAlgorithm-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Analysis-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Collections-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Common-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Common.Resources-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Core-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Data-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Operators-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Operators.Views.GraphVisualization-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Operators.Views.GraphVisualization-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization.Operators-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Optimization.Operators-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.ParallelEngine-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.ParallelEngine-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Parameters-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis-3.4">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Problems.DataAnalysis-3.4.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.Instances-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.Instances.DataAnalysis-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Problems.Instances.DataAnalysis-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Random-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Random-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Selection-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.Selection-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.SequentialEngine-3.3">
+      <HintPath>..\..\..\trunk\bin\HeuristicLab.SequentialEngine-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ConstantsOptimizationTests.cs" />
+    <Compile Include="PerformanceTest.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\HeuristicLab.Problems.DataAnalysis.Symbolic.Regression\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj">
+      <Project>{5ac82412-911b-4fa2-a013-edc5e3f3fcc2}</Project>
+      <Name>HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Problems.DataAnalysis.Symbolic\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj">
+      <Project>{3d28463f-ec96-4d82-afee-38be91a0ca00}</Project>
+      <Name>HeuristicLab.Problems.DataAnalysis.Symbolic-3.4</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.props'))" />
+    <Error Condition="!Exists('..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.targets'))" />
+  </Target>
+  <Import Project="..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.targets" Condition="Exists('..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.targets')" />
+</Project>
Index: branches/2974_Constants_Optimization/UnitTests/packages.config
===================================================================
--- branches/2974_Constants_Optimization/UnitTests/packages.config	(revision 16461)
+++ branches/2974_Constants_Optimization/UnitTests/packages.config	(revision 16461)
@@ -0,0 +1,5 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="MSTest.TestAdapter" version="1.3.2" targetFramework="net461" />
+  <package id="MSTest.TestFramework" version="1.3.2" targetFramework="net461" />
+</packages>
