Index: branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/ConstantOptimizationAnalyzer.cs
===================================================================
--- branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/ConstantOptimizationAnalyzer.cs	(revision 16134)
+++ branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/ConstantOptimizationAnalyzer.cs	(revision 17687)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -28,5 +28,5 @@
 using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
@@ -35,5 +35,5 @@
   /// </summary>
   [Item("ConstantOptimizationAnalyzer", "An operator that performs a constant optimization on the best symbolic expression trees.")]
-  [StorableClass]
+  [StorableType("9FB87E7B-A9E2-49DD-A92A-78BD9FC17916")]
   public sealed class ConstantOptimizationAnalyzer : SymbolicDataAnalysisSingleObjectiveAnalyzer, IStatefulItem {
     private const string PercentageOfBestSolutionsParameterName = "PercentageOfBestSolutions";
@@ -87,5 +87,5 @@
 
     [StorableConstructor]
-    private ConstantOptimizationAnalyzer(bool deserializing) : base(deserializing) { }
+    private ConstantOptimizationAnalyzer(StorableConstructorFlag _) : base(_) { }
     private ConstantOptimizationAnalyzer(ConstantOptimizationAnalyzer original, Cloner cloner) : base(original, cloner) { }
     public override IDeepCloneable Clone(Cloner cloner) { return new ConstantOptimizationAnalyzer(this, cloner); }
Index: branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs
===================================================================
--- branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 16134)
+++ branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 17687)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -23,15 +23,15 @@
 using System.Collections.Generic;
 using System.Linq;
-using AutoDiff;
+using HEAL.Attic;
 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;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
   [Item("Constant Optimization Evaluator", "Calculates Pearson R² of a symbolic regression solution and optimizes the constant used.")]
-  [StorableClass]
+  [StorableType("24B68851-036D-4446-BD6F-3823E9028FF4")]
   public class SymbolicRegressionConstantOptimizationEvaluator : SymbolicRegressionSingleObjectiveEvaluator {
     private const string ConstantOptimizationIterationsParameterName = "ConstantOptimizationIterations";
@@ -40,4 +40,9 @@
     private const string ConstantOptimizationRowsPercentageParameterName = "ConstantOptimizationRowsPercentage";
     private const string UpdateConstantsInTreeParameterName = "UpdateConstantsInSymbolicExpressionTree";
+    private const string UpdateVariableWeightsParameterName = "Update Variable Weights";
+
+    private const string FunctionEvaluationsResultParameterName = "Constants Optimization Function Evaluations";
+    private const string GradientEvaluationsResultParameterName = "Constants Optimization Gradient Evaluations";
+    private const string CountEvaluationsParameterName = "Count Function and Gradient Evaluations";
 
     public IFixedValueParameter<IntValue> ConstantOptimizationIterationsParameter {
@@ -56,4 +61,18 @@
       get { return (IFixedValueParameter<BoolValue>)Parameters[UpdateConstantsInTreeParameterName]; }
     }
+    public IFixedValueParameter<BoolValue> UpdateVariableWeightsParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[UpdateVariableWeightsParameterName]; }
+    }
+
+    public IResultParameter<IntValue> FunctionEvaluationsResultParameter {
+      get { return (IResultParameter<IntValue>)Parameters[FunctionEvaluationsResultParameterName]; }
+    }
+    public IResultParameter<IntValue> GradientEvaluationsResultParameter {
+      get { return (IResultParameter<IntValue>)Parameters[GradientEvaluationsResultParameterName]; }
+    }
+    public IFixedValueParameter<BoolValue> CountEvaluationsParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[CountEvaluationsParameterName]; }
+    }
+
 
     public IntValue ConstantOptimizationIterations {
@@ -74,4 +93,14 @@
     }
 
+    public bool UpdateVariableWeights {
+      get { return UpdateVariableWeightsParameter.Value.Value; }
+      set { UpdateVariableWeightsParameter.Value.Value = value; }
+    }
+
+    public bool CountEvaluations {
+      get { return CountEvaluationsParameter.Value.Value; }
+      set { CountEvaluationsParameter.Value.Value = value; }
+    }
+
     public override bool Maximization {
       get { return true; }
@@ -79,5 +108,5 @@
 
     [StorableConstructor]
-    protected SymbolicRegressionConstantOptimizationEvaluator(bool deserializing) : base(deserializing) { }
+    protected SymbolicRegressionConstantOptimizationEvaluator(StorableConstructorFlag _) : base(_) { }
     protected SymbolicRegressionConstantOptimizationEvaluator(SymbolicRegressionConstantOptimizationEvaluator original, Cloner cloner)
       : base(original, cloner) {
@@ -85,9 +114,14 @@
     public SymbolicRegressionConstantOptimizationEvaluator()
       : base() {
-      Parameters.Add(new FixedValueParameter<IntValue>(ConstantOptimizationIterationsParameterName, "Determines how many iterations should be calculated while optimizing the constant of a symbolic expression tree (0 indicates other or default stopping criterion).", new IntValue(10), true));
-      Parameters.Add(new FixedValueParameter<DoubleValue>(ConstantOptimizationImprovementParameterName, "Determines the relative improvement which must be achieved in the constant optimization to continue with it (0 indicates other or default stopping criterion).", new DoubleValue(0), true));
-      Parameters.Add(new FixedValueParameter<PercentValue>(ConstantOptimizationProbabilityParameterName, "Determines the probability that the constants are optimized", new PercentValue(1), true));
-      Parameters.Add(new FixedValueParameter<PercentValue>(ConstantOptimizationRowsPercentageParameterName, "Determines the percentage of the rows which should be used for constant optimization", new PercentValue(1), true));
-      Parameters.Add(new FixedValueParameter<BoolValue>(UpdateConstantsInTreeParameterName, "Determines if the constants in the tree should be overwritten by the optimized constants.", new BoolValue(true)));
+      Parameters.Add(new FixedValueParameter<IntValue>(ConstantOptimizationIterationsParameterName, "Determines how many iterations should be calculated while optimizing the constant of a symbolic expression tree (0 indicates other or default stopping criterion).", new IntValue(10)));
+      Parameters.Add(new FixedValueParameter<DoubleValue>(ConstantOptimizationImprovementParameterName, "Determines the relative improvement which must be achieved in the constant optimization to continue with it (0 indicates other or default stopping criterion).", new DoubleValue(0)) { Hidden = true });
+      Parameters.Add(new FixedValueParameter<PercentValue>(ConstantOptimizationProbabilityParameterName, "Determines the probability that the constants are optimized", new PercentValue(1)));
+      Parameters.Add(new FixedValueParameter<PercentValue>(ConstantOptimizationRowsPercentageParameterName, "Determines the percentage of the rows which should be used for constant optimization", new PercentValue(1)));
+      Parameters.Add(new FixedValueParameter<BoolValue>(UpdateConstantsInTreeParameterName, "Determines if the constants in the tree should be overwritten by the optimized constants.", new BoolValue(true)) { Hidden = true });
+      Parameters.Add(new FixedValueParameter<BoolValue>(UpdateVariableWeightsParameterName, "Determines if the variable weights in the tree should be  optimized.", new BoolValue(true)) { Hidden = true });
+
+      Parameters.Add(new FixedValueParameter<BoolValue>(CountEvaluationsParameterName, "Determines if function and gradient evaluation should be counted.", new BoolValue(false)));
+      Parameters.Add(new ResultParameter<IntValue>(FunctionEvaluationsResultParameterName, "The number of function evaluations performed by the constants optimization evaluator", "Results", new IntValue()));
+      Parameters.Add(new ResultParameter<IntValue>(GradientEvaluationsResultParameterName, "The number of gradient evaluations performed by the constants optimization evaluator", "Results", new IntValue()));
     }
 
@@ -100,6 +134,17 @@
       if (!Parameters.ContainsKey(UpdateConstantsInTreeParameterName))
         Parameters.Add(new FixedValueParameter<BoolValue>(UpdateConstantsInTreeParameterName, "Determines if the constants in the tree should be overwritten by the optimized constants.", new BoolValue(true)));
-    }
-
+      if (!Parameters.ContainsKey(UpdateVariableWeightsParameterName))
+        Parameters.Add(new FixedValueParameter<BoolValue>(UpdateVariableWeightsParameterName, "Determines if the variable weights in the tree should be  optimized.", new BoolValue(true)));
+
+      if (!Parameters.ContainsKey(CountEvaluationsParameterName))
+        Parameters.Add(new FixedValueParameter<BoolValue>(CountEvaluationsParameterName, "Determines if function and gradient evaluation should be counted.", new BoolValue(false)));
+
+      if (!Parameters.ContainsKey(FunctionEvaluationsResultParameterName))
+        Parameters.Add(new ResultParameter<IntValue>(FunctionEvaluationsResultParameterName, "The number of function evaluations performed by the constants optimization evaluator", "Results", new IntValue()));
+      if (!Parameters.ContainsKey(GradientEvaluationsResultParameterName))
+        Parameters.Add(new ResultParameter<IntValue>(GradientEvaluationsResultParameterName, "The number of gradient evaluations performed by the constants optimization evaluator", "Results", new IntValue()));
+    }
+
+    private static readonly object locker = new object();
     public override IOperation InstrumentedApply() {
       var solution = SymbolicExpressionTreeParameter.ActualValue;
@@ -107,7 +152,7 @@
       if (RandomParameter.ActualValue.NextDouble() < ConstantOptimizationProbability.Value) {
         IEnumerable<int> constantOptimizationRows = GenerateRowsToEvaluate(ConstantOptimizationRowsPercentage.Value);
+        var counter = new EvaluationsCounter();
         quality = OptimizeConstants(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, ProblemDataParameter.ActualValue,
-           constantOptimizationRows, ApplyLinearScalingParameter.ActualValue.Value, ConstantOptimizationIterations.Value,
-           EstimationLimitsParameter.ActualValue.Upper, EstimationLimitsParameter.ActualValue.Lower, UpdateConstantsInTree);
+           constantOptimizationRows, ApplyLinearScalingParameter.ActualValue.Value, ConstantOptimizationIterations.Value, updateVariableWeights: UpdateVariableWeights, lowerEstimationLimit: EstimationLimitsParameter.ActualValue.Lower, upperEstimationLimit: EstimationLimitsParameter.ActualValue.Upper, updateConstantsInTree: UpdateConstantsInTree, counter: counter);
 
         if (ConstantOptimizationRowsPercentage.Value != RelativeNumberOfEvaluatedSamplesParameter.ActualValue.Value) {
@@ -115,4 +160,12 @@
           quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, evaluationRows, ApplyLinearScalingParameter.ActualValue.Value);
         }
+
+        if (CountEvaluations) {
+          lock (locker) {
+            FunctionEvaluationsResultParameter.ActualValue.Value += counter.FunctionEvaluations;
+            GradientEvaluationsResultParameter.ActualValue.Value += counter.GradientEvaluations;
+          }
+        }
+
       } else {
         var evaluationRows = GenerateRowsToEvaluate();
@@ -128,4 +181,6 @@
       EstimationLimitsParameter.ExecutionContext = context;
       ApplyLinearScalingParameter.ExecutionContext = context;
+      FunctionEvaluationsResultParameter.ExecutionContext = context;
+      GradientEvaluationsResultParameter.ExecutionContext = context;
 
       // Pearson R² evaluator is used on purpose instead of the const-opt evaluator, 
@@ -137,78 +192,68 @@
       EstimationLimitsParameter.ExecutionContext = null;
       ApplyLinearScalingParameter.ExecutionContext = null;
+      FunctionEvaluationsResultParameter.ExecutionContext = null;
+      GradientEvaluationsResultParameter.ExecutionContext = null;
 
       return r2;
     }
 
-    #region derivations of functions
-    // create function factory for arctangent
-    private readonly Func<Term, UnaryFunc> arctan = UnaryFunc.Factory(
-      eval: Math.Atan,
-      diff: x => 1 / (1 + x * x));
-    private static readonly Func<Term, UnaryFunc> sin = UnaryFunc.Factory(
-      eval: Math.Sin,
-      diff: Math.Cos);
-    private static readonly Func<Term, UnaryFunc> cos = UnaryFunc.Factory(
-       eval: Math.Cos,
-       diff: x => -Math.Sin(x));
-    private static readonly Func<Term, UnaryFunc> tan = UnaryFunc.Factory(
-      eval: Math.Tan,
-      diff: x => 1 + Math.Tan(x) * Math.Tan(x));
-    private static readonly Func<Term, UnaryFunc> square = UnaryFunc.Factory(
-       eval: x => x * x,
-       diff: x => 2 * x);
-    private static readonly Func<Term, UnaryFunc> erf = UnaryFunc.Factory(
-      eval: alglib.errorfunction,
-      diff: x => 2.0 * Math.Exp(-(x * x)) / Math.Sqrt(Math.PI));
-    private static readonly Func<Term, UnaryFunc> norm = UnaryFunc.Factory(
-      eval: alglib.normaldistribution,
-      diff: x => -(Math.Exp(-(x * x)) * Math.Sqrt(Math.Exp(x * x)) * x) / Math.Sqrt(2 * Math.PI));
-    #endregion
-
-
-    public static double OptimizeConstants(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree tree, IRegressionProblemData problemData,
-      IEnumerable<int> rows, bool applyLinearScaling, int maxIterations, double upperEstimationLimit = double.MaxValue, double lowerEstimationLimit = double.MinValue, bool updateConstantsInTree = true) {
-
-      List<AutoDiff.Variable> variables = new List<AutoDiff.Variable>();
-      List<AutoDiff.Variable> parameters = new List<AutoDiff.Variable>();
-      List<string> variableNames = new List<string>();
-
-      AutoDiff.Term func;
-      if (!TryTransformToAutoDiff(tree.Root.GetSubtree(0), variables, parameters, variableNames, out func))
+    public class EvaluationsCounter {
+      public int FunctionEvaluations = 0;
+      public int GradientEvaluations = 0;
+    }
+
+    public static double OptimizeConstants(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
+      ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling,
+      int maxIterations, bool updateVariableWeights = true,
+      double lowerEstimationLimit = double.MinValue, double upperEstimationLimit = double.MaxValue,
+      bool updateConstantsInTree = true, Action<double[], double, object> iterationCallback = null, EvaluationsCounter counter = null) {
+
+      // numeric constants in the tree become variables for constant opt
+      // variables in the tree become parameters (fixed values) for constant opt
+      // for each parameter (variable in the original tree) we store the 
+      // 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))
         throw new NotSupportedException("Could not optimize constants of symbolic expression tree due to not supported symbols used in the tree.");
-      if (variableNames.Count == 0) return 0.0;
-
-      AutoDiff.IParametricCompiledTerm compiledFunc = AutoDiff.TermUtils.Compile(func, variables.ToArray(), parameters.ToArray());
-
-      List<SymbolicExpressionTreeTerminalNode> terminalNodes = tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>().ToList();
-      double[] c = new double[variables.Count];
-
-      {
+      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
+
+      //extract inital constants
+      double[] c;
+      if (applyLinearScaling) {
+        c = new double[initialConstants.Length + 2];
         c[0] = 0.0;
         c[1] = 1.0;
-        //extract inital constants
-        int i = 2;
-        foreach (var node in terminalNodes) {
-          ConstantTreeNode constantTreeNode = node as ConstantTreeNode;
-          VariableTreeNode variableTreeNode = node as VariableTreeNode;
-          if (constantTreeNode != null)
-            c[i++] = constantTreeNode.Value;
-          else if (variableTreeNode != null)
-            c[i++] = variableTreeNode.Weight;
-        }
-      }
-      double[] originalConstants = (double[])c.Clone();
+        Array.Copy(initialConstants, 0, c, 2, initialConstants.Length);
+      } else {
+        c = (double[])initialConstants.Clone();
+      }
+
       double originalQuality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, tree, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling);
+
+      if (counter == null) counter = new EvaluationsCounter();
+      var rowEvaluationsCounter = new EvaluationsCounter();
 
       alglib.lsfitstate state;
       alglib.lsfitreport rep;
-      int info;
-
-      Dataset ds = problemData.Dataset;
-      double[,] x = new double[rows.Count(), variableNames.Count];
+      int retVal;
+
+      IDataset ds = problemData.Dataset;
+      double[,] x = new double[rows.Count(), parameters.Count];
       int row = 0;
       foreach (var r in rows) {
-        for (int col = 0; col < variableNames.Count; col++) {
-          x[row, col] = ds.GetDoubleValue(variableNames[col], r);
+        int col = 0;
+        foreach (var info in parameterEntries) {
+          if (ds.VariableHasType<double>(info.variableName)) {
+            x[row, col] = ds.GetDoubleValue(info.variableName, r + info.lag);
+          } else if (ds.VariableHasType<string>(info.variableName)) {
+            x[row, col] = ds.GetStringValue(info.variableName, r) == info.variableValue ? 1 : 0;
+          } else throw new InvalidProgramException("found a variable of unknown type");
+          col++;
         }
         row++;
@@ -219,28 +264,38 @@
       int k = c.Length;
 
-      alglib.ndimensional_pfunc function_cx_1_func = CreatePFunc(compiledFunc);
-      alglib.ndimensional_pgrad function_cx_1_grad = CreatePGrad(compiledFunc);
+      alglib.ndimensional_pfunc function_cx_1_func = CreatePFunc(func);
+      alglib.ndimensional_pgrad function_cx_1_grad = CreatePGrad(func_grad);
+      alglib.ndimensional_rep xrep = (p, f, obj) => iterationCallback(p, f, obj);
 
       try {
         alglib.lsfitcreatefg(x, y, c, n, m, k, false, out state);
         alglib.lsfitsetcond(state, 0.0, 0.0, maxIterations);
+        alglib.lsfitsetxrep(state, iterationCallback != null);
         //alglib.lsfitsetgradientcheck(state, 0.001);
-        alglib.lsfitfit(state, function_cx_1_func, function_cx_1_grad, null, null);
-        alglib.lsfitresults(state, out info, out c, out rep);
-      }
-      catch (ArithmeticException) {
+        alglib.lsfitfit(state, function_cx_1_func, function_cx_1_grad, xrep, rowEvaluationsCounter);
+        alglib.lsfitresults(state, out retVal, out c, out rep);
+      } catch (ArithmeticException) {
         return originalQuality;
-      }
-      catch (alglib.alglibexception) {
+      } catch (alglib.alglibexception) {
         return originalQuality;
       }
 
-      //info == -7  => constant optimization failed due to wrong gradient
-      if (info != -7) UpdateConstants(tree, c.Skip(2).ToArray());
+      counter.FunctionEvaluations += rowEvaluationsCounter.FunctionEvaluations / n;
+      counter.GradientEvaluations += rowEvaluationsCounter.GradientEvaluations / n;
+
+      //retVal == -7  => constant optimization failed due to wrong gradient
+      if (retVal != -7) {
+        if (applyLinearScaling) {
+          var tmp = new double[c.Length - 2];
+          Array.Copy(c, 2, tmp, 0, tmp.Length);
+          UpdateConstants(tree, tmp, updateVariableWeights);
+        } else UpdateConstants(tree, c, updateVariableWeights);
+      }
       var quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, tree, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling);
 
-      if (!updateConstantsInTree) UpdateConstants(tree, originalConstants.Skip(2).ToArray());
+      if (!updateConstantsInTree) UpdateConstants(tree, initialConstants, updateVariableWeights);
+
       if (originalQuality - quality > 0.001 || double.IsNaN(quality)) {
-        UpdateConstants(tree, originalConstants.Skip(2).ToArray());
+        UpdateConstants(tree, initialConstants, updateVariableWeights);
         return originalQuality;
       }
@@ -248,230 +303,40 @@
     }
 
-    private static void UpdateConstants(ISymbolicExpressionTree tree, double[] constants) {
+    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;
-        VariableTreeNode variableTreeNode = node as VariableTreeNode;
+        VariableTreeNodeBase variableTreeNodeBase = node as VariableTreeNodeBase;
+        FactorVariableTreeNode factorVarTreeNode = node as FactorVariableTreeNode;
         if (constantTreeNode != null)
           constantTreeNode.Value = constants[i++];
-        else if (variableTreeNode != null)
-          variableTreeNode.Weight = constants[i++];
-      }
-    }
-
-    private static alglib.ndimensional_pfunc CreatePFunc(AutoDiff.IParametricCompiledTerm compiledFunc) {
-      return (double[] c, double[] x, ref double func, object o) => {
-        func = compiledFunc.Evaluate(c, x);
+        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++];
+        }
+      }
+    }
+
+    private static alglib.ndimensional_pfunc CreatePFunc(TreeToAutoDiffTermConverter.ParametricFunction func) {
+      return (double[] c, double[] x, ref double fx, object o) => {
+        fx = func(c, x);
+        var counter = (EvaluationsCounter)o;
+        counter.FunctionEvaluations++;
       };
     }
 
-    private static alglib.ndimensional_pgrad CreatePGrad(AutoDiff.IParametricCompiledTerm compiledFunc) {
-      return (double[] c, double[] x, ref double func, double[] grad, object o) => {
-        var tupel = compiledFunc.Differentiate(c, x);
-        func = tupel.Item2;
-        Array.Copy(tupel.Item1, grad, grad.Length);
+    private static alglib.ndimensional_pgrad CreatePGrad(TreeToAutoDiffTermConverter.ParametricFunctionGradient func_grad) {
+      return (double[] c, double[] x, ref double fx, double[] grad, object o) => {
+        var tuple = func_grad(c, x);
+        fx = tuple.Item2;
+        Array.Copy(tuple.Item1, grad, grad.Length);
+        var counter = (EvaluationsCounter)o;
+        counter.GradientEvaluations++;
       };
     }
-
-    private static bool TryTransformToAutoDiff(ISymbolicExpressionTreeNode node, List<AutoDiff.Variable> variables, List<AutoDiff.Variable> parameters, List<string> variableNames, out AutoDiff.Term term) {
-      if (node.Symbol is Constant) {
-        var var = new AutoDiff.Variable();
-        variables.Add(var);
-        term = var;
-        return true;
-      }
-      if (node.Symbol is Variable) {
-        var varNode = node as VariableTreeNode;
-        var par = new AutoDiff.Variable();
-        parameters.Add(par);
-        variableNames.Add(varNode.VariableName);
-        var w = new AutoDiff.Variable();
-        variables.Add(w);
-        term = AutoDiff.TermBuilder.Product(w, par);
-        return true;
-      }
-      if (node.Symbol is Addition) {
-        List<AutoDiff.Term> terms = new List<Term>();
-        foreach (var subTree in node.Subtrees) {
-          AutoDiff.Term t;
-          if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out t)) {
-            term = null;
-            return false;
-          }
-          terms.Add(t);
-        }
-        term = AutoDiff.TermBuilder.Sum(terms);
-        return true;
-      }
-      if (node.Symbol is Subtraction) {
-        List<AutoDiff.Term> terms = new List<Term>();
-        for (int i = 0; i < node.SubtreeCount; i++) {
-          AutoDiff.Term t;
-          if (!TryTransformToAutoDiff(node.GetSubtree(i), variables, parameters, variableNames, out t)) {
-            term = null;
-            return false;
-          }
-          if (i > 0) t = -t;
-          terms.Add(t);
-        }
-        term = AutoDiff.TermBuilder.Sum(terms);
-        return true;
-      }
-      if (node.Symbol is Multiplication) {
-        AutoDiff.Term a, b;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out a) ||
-          !TryTransformToAutoDiff(node.GetSubtree(1), variables, parameters, variableNames, out b)) {
-          term = null;
-          return false;
-        } else {
-          List<AutoDiff.Term> factors = new List<Term>();
-          foreach (var subTree in node.Subtrees.Skip(2)) {
-            AutoDiff.Term f;
-            if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out f)) {
-              term = null;
-              return false;
-            }
-            factors.Add(f);
-          }
-          term = AutoDiff.TermBuilder.Product(a, b, factors.ToArray());
-          return true;
-        }
-      }
-      if (node.Symbol is Division) {
-        // only works for at least two subtrees
-        AutoDiff.Term a, b;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out a) ||
-          !TryTransformToAutoDiff(node.GetSubtree(1), variables, parameters, variableNames, out b)) {
-          term = null;
-          return false;
-        } else {
-          List<AutoDiff.Term> factors = new List<Term>();
-          foreach (var subTree in node.Subtrees.Skip(2)) {
-            AutoDiff.Term f;
-            if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out f)) {
-              term = null;
-              return false;
-            }
-            factors.Add(1.0 / f);
-          }
-          term = AutoDiff.TermBuilder.Product(a, 1.0 / b, factors.ToArray());
-          return true;
-        }
-      }
-      if (node.Symbol is Logarithm) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
-          term = null;
-          return false;
-        } else {
-          term = AutoDiff.TermBuilder.Log(t);
-          return true;
-        }
-      }
-      if (node.Symbol is Exponential) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
-          term = null;
-          return false;
-        } else {
-          term = AutoDiff.TermBuilder.Exp(t);
-          return true;
-        }
-      } if (node.Symbol is Sine) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
-          term = null;
-          return false;
-        } else {
-          term = sin(t);
-          return true;
-        }
-      } if (node.Symbol is Cosine) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
-          term = null;
-          return false;
-        } else {
-          term = cos(t);
-          return true;
-        }
-      } if (node.Symbol is Tangent) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
-          term = null;
-          return false;
-        } else {
-          term = tan(t);
-          return true;
-        }
-      }
-      if (node.Symbol is Square) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
-          term = null;
-          return false;
-        } else {
-          term = square(t);
-          return true;
-        }
-      } if (node.Symbol is Erf) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
-          term = null;
-          return false;
-        } else {
-          term = erf(t);
-          return true;
-        }
-      } if (node.Symbol is Norm) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
-          term = null;
-          return false;
-        } else {
-          term = norm(t);
-          return true;
-        }
-      }
-      if (node.Symbol is StartSymbol) {
-        var alpha = new AutoDiff.Variable();
-        var beta = new AutoDiff.Variable();
-        variables.Add(beta);
-        variables.Add(alpha);
-        AutoDiff.Term branchTerm;
-        if (TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out branchTerm)) {
-          term = branchTerm * alpha + beta;
-          return true;
-        } else {
-          term = null;
-          return false;
-        }
-      }
-      term = null;
-      return false;
-    }
-
     public static bool CanOptimizeConstants(ISymbolicExpressionTree tree) {
-      var containsUnknownSymbol = (
-        from n in tree.Root.GetSubtree(0).IterateNodesPrefix()
-        where
-         !(n.Symbol is Variable) &&
-         !(n.Symbol is Constant) &&
-         !(n.Symbol is Addition) &&
-         !(n.Symbol is Subtraction) &&
-         !(n.Symbol is Multiplication) &&
-         !(n.Symbol is Division) &&
-         !(n.Symbol is Logarithm) &&
-         !(n.Symbol is Exponential) &&
-         !(n.Symbol is Sine) &&
-         !(n.Symbol is Cosine) &&
-         !(n.Symbol is Tangent) &&
-         !(n.Symbol is Square) &&
-         !(n.Symbol is Erf) &&
-         !(n.Symbol is Norm) &&
-         !(n.Symbol is StartSymbol)
-        select n).
-      Any();
-      return !containsUnknownSymbol;
+      return TreeToAutoDiffTermConverter.IsCompatible(tree);
     }
   }
Index: branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionLogResidualEvaluator.cs
===================================================================
--- branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionLogResidualEvaluator.cs	(revision 16134)
+++ branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionLogResidualEvaluator.cs	(revision 17687)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -27,5 +27,5 @@
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
@@ -38,8 +38,8 @@
                                   "This effects GP convergence because functional fragments which are necessary to explain small variations are also more likely" +
                                   " to stay in the population. This is useful even when the actual objective function is mean of squared errors.")]
-  [StorableClass]
+  [StorableType("8CEA1A56-167D-481B-9167-C1DED8E06680")]
   public class SymbolicRegressionLogResidualEvaluator : SymbolicRegressionSingleObjectiveEvaluator {
     [StorableConstructor]
-    protected SymbolicRegressionLogResidualEvaluator(bool deserializing) : base(deserializing) { }
+    protected SymbolicRegressionLogResidualEvaluator(StorableConstructorFlag _) : base(_) { }
     protected SymbolicRegressionLogResidualEvaluator(SymbolicRegressionLogResidualEvaluator original, Cloner cloner)
       : base(original, cloner) {
Index: branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionMeanRelativeErrorEvaluator.cs
===================================================================
--- branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionMeanRelativeErrorEvaluator.cs	(revision 16134)
+++ branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionMeanRelativeErrorEvaluator.cs	(revision 17687)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -27,5 +27,5 @@
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
@@ -33,9 +33,9 @@
                                          "The +1 is necessary to handle data with the value of 0.0 correctly. " +
                                          "Notice: Linear scaling is ignored for this evaluator.")]
-  [StorableClass]
+  [StorableType("8A5AAF93-5338-4E11-B3B2-3D9274329E5F")]
   public class SymbolicRegressionMeanRelativeErrorEvaluator : SymbolicRegressionSingleObjectiveEvaluator {
     public override bool Maximization { get { return false; } }
     [StorableConstructor]
-    protected SymbolicRegressionMeanRelativeErrorEvaluator(bool deserializing) : base(deserializing) { }
+    protected SymbolicRegressionMeanRelativeErrorEvaluator(StorableConstructorFlag _) : base(_) { }
     protected SymbolicRegressionMeanRelativeErrorEvaluator(SymbolicRegressionMeanRelativeErrorEvaluator original, Cloner cloner)
       : base(original, cloner) {
Index: branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveEvaluator.cs
===================================================================
--- branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveEvaluator.cs	(revision 16134)
+++ branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveEvaluator.cs	(revision 17687)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -20,17 +20,11 @@
 #endregion
 
-using System;
-using System.Collections.Generic;
-using System.Linq;
 using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
-  [StorableClass]
+  [StorableType("7EB90F03-4385-474F-BDE7-3B133E8FEAAB")]
   public abstract class SymbolicRegressionSingleObjectiveEvaluator : SymbolicDataAnalysisSingleObjectiveEvaluator<IRegressionProblemData>, ISymbolicRegressionSingleObjectiveEvaluator {  
     [StorableConstructor]
-    protected SymbolicRegressionSingleObjectiveEvaluator(bool deserializing) : base(deserializing) { }
+    protected SymbolicRegressionSingleObjectiveEvaluator(StorableConstructorFlag _) : base(_) { }
     protected SymbolicRegressionSingleObjectiveEvaluator(SymbolicRegressionSingleObjectiveEvaluator original, Cloner cloner) : base(original, cloner) { }
     protected SymbolicRegressionSingleObjectiveEvaluator(): base() {}    
Index: branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMaxAbsoluteErrorEvaluator.cs
===================================================================
--- branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMaxAbsoluteErrorEvaluator.cs	(revision 16134)
+++ branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMaxAbsoluteErrorEvaluator.cs	(revision 17687)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -25,13 +25,13 @@
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
   [Item("Maximum absolute error Evaluator", "Calculates the maximum squared error of a symbolic regression solution.")]
-  [StorableClass]
+  [StorableType("256A6405-D1EE-4D8D-963A-42C56FEE8571")]
   public class SymbolicRegressionSingleObjectiveMaxAbsoluteErrorEvaluator : SymbolicRegressionSingleObjectiveEvaluator {
     public override bool Maximization { get { return false; } }
     [StorableConstructor]
-    protected SymbolicRegressionSingleObjectiveMaxAbsoluteErrorEvaluator(bool deserializing) : base(deserializing) { }
+    protected SymbolicRegressionSingleObjectiveMaxAbsoluteErrorEvaluator(StorableConstructorFlag _) : base(_) { }
     protected SymbolicRegressionSingleObjectiveMaxAbsoluteErrorEvaluator(SymbolicRegressionSingleObjectiveMaxAbsoluteErrorEvaluator original, Cloner cloner)
       : base(original, cloner) {
Index: branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMeanAbsoluteErrorEvaluator.cs
===================================================================
--- branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMeanAbsoluteErrorEvaluator.cs	(revision 16134)
+++ branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMeanAbsoluteErrorEvaluator.cs	(revision 17687)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -25,13 +25,13 @@
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
   [Item("Mean absolute error Evaluator", "Calculates the mean absolute error of a symbolic regression solution.")]
-  [StorableClass]
+  [StorableType("8ABB1AC3-0ACE-43AB-8E6B-B0FC925429DC")]
   public class SymbolicRegressionSingleObjectiveMeanAbsoluteErrorEvaluator : SymbolicRegressionSingleObjectiveEvaluator {
     public override bool Maximization { get { return false; } }
     [StorableConstructor]
-    protected SymbolicRegressionSingleObjectiveMeanAbsoluteErrorEvaluator(bool deserializing) : base(deserializing) { }
+    protected SymbolicRegressionSingleObjectiveMeanAbsoluteErrorEvaluator(StorableConstructorFlag _) : base(_) { }
     protected SymbolicRegressionSingleObjectiveMeanAbsoluteErrorEvaluator(SymbolicRegressionSingleObjectiveMeanAbsoluteErrorEvaluator original, Cloner cloner)
       : base(original, cloner) {
Index: branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator.cs
===================================================================
--- branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator.cs	(revision 16134)
+++ branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator.cs	(revision 17687)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -25,13 +25,13 @@
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
   [Item("Mean squared error Evaluator", "Calculates the mean squared error of a symbolic regression solution.")]
-  [StorableClass]
+  [StorableType("8D4B5243-1635-46A6-AEF9-18C9BCB725DD")]
   public class SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator : SymbolicRegressionSingleObjectiveEvaluator {
     public override bool Maximization { get { return false; } }
     [StorableConstructor]
-    protected SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator(bool deserializing) : base(deserializing) { }
+    protected SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator(StorableConstructorFlag _) : base(_) { }
     protected SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator(SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator original, Cloner cloner)
       : base(original, cloner) {
Index: branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.cs
===================================================================
--- branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.cs	(revision 16134)
+++ branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.cs	(revision 17687)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -25,12 +25,12 @@
 using HeuristicLab.Data;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
   [Item("Pearson R² Evaluator", "Calculates the square of the pearson correlation coefficient (also known as coefficient of determination) of a symbolic regression solution.")]
-  [StorableClass]
+  [StorableType("6FAEC6C2-C747-452A-A60D-29AE37898A90")]
   public class SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator : SymbolicRegressionSingleObjectiveEvaluator {
     [StorableConstructor]
-    protected SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator(bool deserializing) : base(deserializing) { }
+    protected SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator(StorableConstructorFlag _) : base(_) { }
     protected SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator(SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator original, Cloner cloner)
       : base(original, cloner) {
@@ -59,16 +59,16 @@
       OnlineCalculatorError errorState;
 
-      double r2;
+      double r;
       if (applyLinearScaling) {
-        var r2Calculator = new OnlinePearsonsRSquaredCalculator();
-        CalculateWithScaling(targetValues, estimatedValues, lowerEstimationLimit, upperEstimationLimit, r2Calculator, problemData.Dataset.Rows);
-        errorState = r2Calculator.ErrorState;
-        r2 = r2Calculator.RSquared;
+        var rCalculator = new OnlinePearsonsRCalculator();
+        CalculateWithScaling(targetValues, estimatedValues, lowerEstimationLimit, upperEstimationLimit, rCalculator, problemData.Dataset.Rows);
+        errorState = rCalculator.ErrorState;
+        r = rCalculator.R;
       } else {
         IEnumerable<double> boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
-        r2 = OnlinePearsonsRSquaredCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
+        r = OnlinePearsonsRCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
       }
       if (errorState != OnlineCalculatorError.None) return double.NaN;
-      return r2;
+      return r*r;
     }
 
Index: branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveOverfittingAnalyzer.cs
===================================================================
--- branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveOverfittingAnalyzer.cs	(revision 16134)
+++ branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveOverfittingAnalyzer.cs	(revision 17687)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -28,9 +28,9 @@
 using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
   [Item("SymbolicRegressionSingleObjectiveOverfittingAnalyzer", "Calculates and tracks correlation of training and validation fitness of symbolic regression models.")]
-  [StorableClass]
+  [StorableType("AE1F0A23-BEB1-47AF-8ECF-DBCFD32AA5A9")]
   public sealed class SymbolicRegressionSingleObjectiveOverfittingAnalyzer : SymbolicDataAnalysisSingleObjectiveValidationAnalyzer<ISymbolicRegressionSingleObjectiveEvaluator, IRegressionProblemData> {
     private const string TrainingValidationCorrelationParameterName = "Training and validation fitness correlation";
@@ -59,5 +59,5 @@
 
     [StorableConstructor]
-    private SymbolicRegressionSingleObjectiveOverfittingAnalyzer(bool deserializing) : base(deserializing) { }
+    private SymbolicRegressionSingleObjectiveOverfittingAnalyzer(StorableConstructorFlag _) : base(_) { }
     private SymbolicRegressionSingleObjectiveOverfittingAnalyzer(SymbolicRegressionSingleObjectiveOverfittingAnalyzer original, Cloner cloner) : base(original, cloner) { }
     public SymbolicRegressionSingleObjectiveOverfittingAnalyzer()
Index: branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveProblem.cs
===================================================================
--- branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveProblem.cs	(revision 16134)
+++ branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveProblem.cs	(revision 17687)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -23,11 +23,12 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
-  [Item("Symbolic Regression Problem (single objective)", "Represents a single objective symbolic regression problem.")]
-  [StorableClass]
-  [Creatable("Problems")]
+  [Item("Symbolic Regression Problem (single-objective)", "Represents a single objective symbolic regression problem.")]
+  [StorableType("7DDCF683-96FC-4F70-BF4F-FE3A0B0DE6E0")]
+  [Creatable(CreatableAttribute.Categories.GeneticProgrammingProblems, Priority = 100)]
   public class SymbolicRegressionSingleObjectiveProblem : SymbolicDataAnalysisSingleObjectiveProblem<IRegressionProblemData, ISymbolicRegressionSingleObjectiveEvaluator, ISymbolicDataAnalysisSolutionCreator>, IRegressionProblem {
     private const double PunishmentFactor = 10;
@@ -48,5 +49,5 @@
     #endregion
     [StorableConstructor]
-    protected SymbolicRegressionSingleObjectiveProblem(bool deserializing) : base(deserializing) { }
+    protected SymbolicRegressionSingleObjectiveProblem(StorableConstructorFlag _) : base(_) { }
     protected SymbolicRegressionSingleObjectiveProblem(SymbolicRegressionSingleObjectiveProblem original, Cloner cloner)
       : base(original, cloner) {
@@ -111,5 +112,6 @@
       Operators.Add(new SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer());
       Operators.Add(new SymbolicRegressionSolutionsAnalyzer());
-
+      Operators.Add(new SymbolicExpressionTreePhenotypicSimilarityCalculator());
+      Operators.Add(new SymbolicRegressionPhenotypicDiversityAnalyzer(Operators.OfType<SymbolicExpressionTreePhenotypicSimilarityCalculator>()) { DiversityResultName = "Phenotypic Diversity" });
       ParameterizeOperators();
     }
@@ -141,4 +143,15 @@
         }
       }
+
+      foreach (var op in Operators.OfType<ISolutionSimilarityCalculator>()) {
+        op.SolutionVariableName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
+        op.QualityVariableName = Evaluator.QualityParameter.ActualName;
+
+        if (op is SymbolicExpressionTreePhenotypicSimilarityCalculator) {
+          var phenotypicSimilarityCalculator = (SymbolicExpressionTreePhenotypicSimilarityCalculator)op;
+          phenotypicSimilarityCalculator.ProblemData = ProblemData;
+          phenotypicSimilarityCalculator.Interpreter = SymbolicExpressionTreeInterpreter;
+        }
+      }
     }
   }
Index: branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveTrainingBestSolutionAnalyzer.cs
===================================================================
--- branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 16134)
+++ branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 17687)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -24,5 +24,5 @@
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
@@ -31,5 +31,5 @@
   /// </summary>
   [Item("SymbolicRegressionSingleObjectiveTrainingBestSolutionAnalyzer", "An operator that analyzes the training best symbolic regression solution for single objective symbolic regression problems.")]
-  [StorableClass]
+  [StorableType("85786F8E-F84D-4909-9A66-620668B0C7FB")]
   public sealed class SymbolicRegressionSingleObjectiveTrainingBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer<ISymbolicRegressionSolution>,
   ISymbolicDataAnalysisInterpreterOperator, ISymbolicDataAnalysisBoundedOperator {
@@ -50,5 +50,5 @@
 
     [StorableConstructor]
-    private SymbolicRegressionSingleObjectiveTrainingBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
+    private SymbolicRegressionSingleObjectiveTrainingBestSolutionAnalyzer(StorableConstructorFlag _) : base(_) { }
     private SymbolicRegressionSingleObjectiveTrainingBestSolutionAnalyzer(SymbolicRegressionSingleObjectiveTrainingBestSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { }
     public SymbolicRegressionSingleObjectiveTrainingBestSolutionAnalyzer()
@@ -63,5 +63,5 @@
 
     protected override ISymbolicRegressionSolution CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality) {
-      var model = new SymbolicRegressionModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      var model = new SymbolicRegressionModel(ProblemDataParameter.ActualValue.TargetVariable, (ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
       if (ApplyLinearScalingParameter.ActualValue.Value) model.Scale(ProblemDataParameter.ActualValue);
       return new SymbolicRegressionSolution(model, (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone());
Index: branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer.cs
===================================================================
--- branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer.cs	(revision 16134)
+++ branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer.cs	(revision 17687)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -23,5 +23,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
@@ -30,9 +30,9 @@
   /// </summary>
   [Item("SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer", "An operator that collects the training Pareto-best symbolic regression solutions for single objective symbolic regression problems.")]
-  [StorableClass]
+  [StorableType("8FDF5528-8E95-44D6-AFFD-433B4AA55559")]
   public sealed class SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveTrainingParetoBestSolutionAnalyzer<IRegressionProblemData, ISymbolicRegressionSolution> {
 
     [StorableConstructor]
-    private SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
+    private SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer(StorableConstructorFlag _) : base(_) { }
     private SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer(SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { }
     public SymbolicRegressionSingleObjectiveTrainingParetoBestSolutionAnalyzer() : base() { }
@@ -42,5 +42,5 @@
 
     protected override ISymbolicRegressionSolution CreateSolution(ISymbolicExpressionTree bestTree) {
-      var model = new SymbolicRegressionModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      var model = new SymbolicRegressionModel(ProblemDataParameter.ActualValue.TargetVariable, (ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
       if (ApplyLinearScalingParameter.ActualValue.Value) model.Scale(ProblemDataParameter.ActualValue);
       return new SymbolicRegressionSolution(model, (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone());
Index: branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveValidationBestSolutionAnalyzer.cs
===================================================================
--- branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveValidationBestSolutionAnalyzer.cs	(revision 16134)
+++ branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveValidationBestSolutionAnalyzer.cs	(revision 17687)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -24,5 +24,5 @@
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
@@ -31,5 +31,5 @@
   /// </summary>
   [Item("SymbolicRegressionSingleObjectiveValidationBestSolutionAnalyzer", "An operator that analyzes the validation best symbolic regression solution for single objective symbolic regression problems.")]
-  [StorableClass]
+  [StorableType("75E2AFFF-95B2-4FA4-8544-CF2025B65820")]
   public sealed class SymbolicRegressionSingleObjectiveValidationBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveValidationBestSolutionAnalyzer<ISymbolicRegressionSolution, ISymbolicRegressionSingleObjectiveEvaluator, IRegressionProblemData>,
     ISymbolicDataAnalysisBoundedOperator {
@@ -43,5 +43,5 @@
 
     [StorableConstructor]
-    private SymbolicRegressionSingleObjectiveValidationBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
+    private SymbolicRegressionSingleObjectiveValidationBestSolutionAnalyzer(StorableConstructorFlag _) : base(_) { }
     private SymbolicRegressionSingleObjectiveValidationBestSolutionAnalyzer(SymbolicRegressionSingleObjectiveValidationBestSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { }
     public SymbolicRegressionSingleObjectiveValidationBestSolutionAnalyzer()
@@ -55,5 +55,5 @@
 
     protected override ISymbolicRegressionSolution CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality) {
-      var model = new SymbolicRegressionModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      var model = new SymbolicRegressionModel(ProblemDataParameter.ActualValue.TargetVariable, (ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
       if (ApplyLinearScalingParameter.ActualValue.Value) model.Scale(ProblemDataParameter.ActualValue);
       return new SymbolicRegressionSolution(model, (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone());
Index: branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer.cs
===================================================================
--- branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer.cs	(revision 16134)
+++ branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer.cs	(revision 17687)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -23,5 +23,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
@@ -30,8 +30,8 @@
   /// </summary>
   [Item("SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer", "An operator that collects the validation Pareto-best symbolic regression solutions for single objective symbolic regression problems.")]
-  [StorableClass]
+  [StorableType("B58782FE-FAC0-4B03-9210-CAE5CF74357B")]
   public sealed class SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveValidationParetoBestSolutionAnalyzer<ISymbolicRegressionSolution, ISymbolicRegressionSingleObjectiveEvaluator, IRegressionProblemData> {
     [StorableConstructor]
-    private SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
+    private SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer(StorableConstructorFlag _) : base(_) { }
     private SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer(SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { }
     public SymbolicRegressionSingleObjectiveValidationParetoBestSolutionAnalyzer() : base() { }
@@ -42,5 +42,5 @@
 
     protected override ISymbolicRegressionSolution CreateSolution(ISymbolicExpressionTree bestTree) {
-      var model = new SymbolicRegressionModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      var model = new SymbolicRegressionModel(ProblemDataParameter.ActualValue.TargetVariable, (ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
       if (ApplyLinearScalingParameter.ActualValue.Value) model.Scale(ProblemDataParameter.ActualValue);
       return new SymbolicRegressionSolution(model, (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone());
Index: branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSolutionsAnalyzer.cs
===================================================================
--- branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSolutionsAnalyzer.cs	(revision 16134)
+++ branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSolutionsAnalyzer.cs	(revision 17687)
@@ -2,5 +2,5 @@
 
 /* HeuristicLab
- * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -22,21 +22,30 @@
 #endregion
 
-using System;
 using System.Linq;
 using HeuristicLab.Analysis;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Operators;
 using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
+  [StorableType("789E0217-6DDC-44E8-85CC-A51A976A8FB8")]
   public class SymbolicRegressionSolutionsAnalyzer : SingleSuccessorOperator, IAnalyzer {
     private const string ResultCollectionParameterName = "Results";
     private const string RegressionSolutionQualitiesResultName = "Regression Solution Qualities";
+    private const string TrainingQualityParameterName = "TrainingRSquared";
+    private const string TestQualityParameterName = "TestRSquared";
 
     public ILookupParameter<ResultCollection> ResultCollectionParameter {
       get { return (ILookupParameter<ResultCollection>)Parameters[ResultCollectionParameterName]; }
+    }
+    public ILookupParameter<DoubleValue> TrainingQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters[TrainingQualityParameterName]; }
+    }
+    public ILookupParameter<DoubleValue> TestQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters[TestQualityParameterName]; }
     }
 
@@ -46,5 +55,5 @@
 
     [StorableConstructor]
-    protected SymbolicRegressionSolutionsAnalyzer(bool deserializing) : base(deserializing) { }
+    protected SymbolicRegressionSolutionsAnalyzer(StorableConstructorFlag _) : base(_) { }
     protected SymbolicRegressionSolutionsAnalyzer(SymbolicRegressionSolutionsAnalyzer original, Cloner cloner)
       : base(original, cloner) { }
@@ -55,4 +64,18 @@
     public SymbolicRegressionSolutionsAnalyzer() {
       Parameters.Add(new LookupParameter<ResultCollection>(ResultCollectionParameterName, "The result collection to store the analysis results."));
+      Parameters.Add(new LookupParameter<DoubleValue>(TrainingQualityParameterName));
+      Parameters.Add(new LookupParameter<DoubleValue>(TestQualityParameterName));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+
+      #region Backwards compatible code, remove with 3.4
+      if (!Parameters.ContainsKey(TrainingQualityParameterName))
+        Parameters.Add(new LookupParameter<DoubleValue>(TrainingQualityParameterName));
+      if (!Parameters.ContainsKey(TestQualityParameterName))
+        Parameters.Add(new LookupParameter<DoubleValue>(TestQualityParameterName));
+      #endregion
     }
 
@@ -66,18 +89,37 @@
 
       var dataTable = (DataTable)results[RegressionSolutionQualitiesResultName].Value;
+
+      // only if the parameters are available (not available in old persisted code)
+      ILookupParameter<DoubleValue> trainingQualityParam = null;
+      ILookupParameter<DoubleValue> testQualityParam = null;
+      // store actual names of parameter because it is changed below
+      trainingQualityParam = TrainingQualityParameter;
+      string prevTrainingQualityParamName = trainingQualityParam.ActualName;
+      testQualityParam = TestQualityParameter;
+      string prevTestQualityParamName = testQualityParam.ActualName;
       foreach (var result in results.Where(r => r.Value is IRegressionSolution)) {
         var solution = (IRegressionSolution)result.Value;
 
-        var trainingR2 = result.Name + Environment.NewLine + "Training R²";
-        if (!dataTable.Rows.ContainsKey(trainingR2))
-          dataTable.Rows.Add(new DataRow(trainingR2));
+        var trainingR2Name = result.Name + " Training R²";
+        if (!dataTable.Rows.ContainsKey(trainingR2Name))
+          dataTable.Rows.Add(new DataRow(trainingR2Name));
 
-        var testR2 = result.Name + Environment.NewLine + " Test R²";
-        if (!dataTable.Rows.ContainsKey(testR2))
-          dataTable.Rows.Add(new DataRow(testR2));
+        var testR2Name = result.Name + " Test R²";
+        if (!dataTable.Rows.ContainsKey(testR2Name))
+          dataTable.Rows.Add(new DataRow(testR2Name));
 
-        dataTable.Rows[trainingR2].Values.Add(solution.TrainingRSquared);
-        dataTable.Rows[testR2].Values.Add(solution.TestRSquared);
+        dataTable.Rows[trainingR2Name].Values.Add(solution.TrainingRSquared);
+        dataTable.Rows[testR2Name].Values.Add(solution.TestRSquared);
+
+        // also add training and test R² to the scope using the parameters
+        // HACK: we change the ActualName of the parameter to write two variables for each solution in the results collection
+        trainingQualityParam.ActualName = trainingR2Name;
+        trainingQualityParam.ActualValue = new DoubleValue(solution.TrainingRSquared);
+        testQualityParam.ActualName = testR2Name;
+        testQualityParam.ActualValue = new DoubleValue(solution.TestRSquared);
       }
+
+      trainingQualityParam.ActualName = prevTrainingQualityParamName;
+      testQualityParam.ActualName = prevTestQualityParamName;
 
       return base.Apply();
