Index: branches/3087_Ceres_Integration/HeuristicLab.ExtLibs/HeuristicLab.NativeInterpreter/0.1/HeuristicLab.NativeInterpreter-0.1/CeresTypes.cs
===================================================================
--- branches/3087_Ceres_Integration/HeuristicLab.ExtLibs/HeuristicLab.NativeInterpreter/0.1/HeuristicLab.NativeInterpreter-0.1/CeresTypes.cs	(revision 18006)
+++ branches/3087_Ceres_Integration/HeuristicLab.ExtLibs/HeuristicLab.NativeInterpreter/0.1/HeuristicLab.NativeInterpreter-0.1/CeresTypes.cs	(revision 18007)
@@ -33,5 +33,5 @@
     // Wrapped for access from C# by Gabriel Kronberger
 
-    public enum LinearSolverType : int {
+    public enum LinearSolver : int {
       // These solvers are for general rectangular systems formed from the
       // normal equations A'A x = A'b. They are direct solvers and do not
@@ -70,5 +70,5 @@
     };
 
-    public enum PreconditionerType {
+    public enum Preconditioner {
       // Trivial preconditioner - the identity matrix.
       IDENTITY,
@@ -116,10 +116,10 @@
     };
 
-    public enum MinimizerType : int {
+    public enum Minimizer : int {
       LINE_SEARCH,
       TRUST_REGION,
     };
 
-    public enum LineSearchDirectionType : int {
+    public enum LineSearchDirection : int {
       // Negative of the gradient.
       STEEPEST_DESCENT,
@@ -201,5 +201,5 @@
     };
 
-    public enum LineSearchType {
+    public enum LineSearch {
       // Backtracking line search with polynomial interpolation or
       // bisection.
@@ -210,5 +210,5 @@
     // Ceres supports different strategies for computing the trust region
     // step.
-    public enum TrustRegionStrategyType : int {
+    public enum TrustRegionStrategy : int {
       // The default trust region strategy is to use the step computation
       // used in the Levenberg-Marquardt algorithm. For more details see
@@ -240,5 +240,5 @@
     //  over two-dimensional subspaces", Mathematical Programming,
     // 40 (1988), pp. 247--263
-    public enum DoglegType {
+    public enum DogLeg {
       // The traditional approach constructs a dogleg path
       // consisting of two line segments and finds the furthest
Index: branches/3087_Ceres_Integration/HeuristicLab.ExtLibs/HeuristicLab.NativeInterpreter/0.1/HeuristicLab.NativeInterpreter-0.1/DllImporter.cs
===================================================================
--- branches/3087_Ceres_Integration/HeuristicLab.ExtLibs/HeuristicLab.NativeInterpreter/0.1/HeuristicLab.NativeInterpreter-0.1/DllImporter.cs	(revision 18006)
+++ branches/3087_Ceres_Integration/HeuristicLab.ExtLibs/HeuristicLab.NativeInterpreter/0.1/HeuristicLab.NativeInterpreter-0.1/DllImporter.cs	(revision 18007)
@@ -24,9 +24,9 @@
     public int Iterations = 10;
     public int UseNonmonotonicSteps = 0; // = false
-    public CeresTypes.MinimizerType Minimizer = CeresTypes.MinimizerType.TRUST_REGION;
-    public CeresTypes.LinearSolverType LinearSolver = CeresTypes.LinearSolverType.DENSE_QR;
-    public CeresTypes.TrustRegionStrategyType TrustRegionStrategy = CeresTypes.TrustRegionStrategyType.LEVENBERG_MARQUARDT;
-    public CeresTypes.DoglegType Dogleg = CeresTypes.DoglegType.TRADITIONAL_DOGLEG;
-    public CeresTypes.LineSearchDirectionType LineSearchDirection = CeresTypes.LineSearchDirectionType.LBFGS;
+    public CeresTypes.Minimizer Minimizer = CeresTypes.Minimizer.TRUST_REGION;
+    public CeresTypes.LinearSolver LinearSolver = CeresTypes.LinearSolver.DENSE_QR;
+    public CeresTypes.TrustRegionStrategy TrustRegionStrategy = CeresTypes.TrustRegionStrategy.LEVENBERG_MARQUARDT;
+    public CeresTypes.DogLeg DogLeg = CeresTypes.DogLeg.TRADITIONAL_DOGLEG;
+    public CeresTypes.LineSearchDirection LineSearchDirection = CeresTypes.LineSearchDirection.LBFGS;
     public Algorithm Algorithm = Algorithm.Krogh;
   }
Index: branches/3087_Ceres_Integration/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/NativeInterpreter.cs
===================================================================
--- branches/3087_Ceres_Integration/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/NativeInterpreter.cs	(revision 18006)
+++ branches/3087_Ceres_Integration/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/NativeInterpreter.cs	(revision 18007)
@@ -38,5 +38,5 @@
   [StorableType("91723319-8F15-4D33-B277-40AC7C7CF9AE")]
   [Item("NativeInterpreter", "Operator calling into native C++ code for tree interpretation.")]
-  public class NativeInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter {
+  public sealed class NativeInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter {
     private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions";
 
@@ -58,13 +58,14 @@
     }
 
+    #region storable ctor and cloning
     [StorableConstructor]
-    protected NativeInterpreter(StorableConstructorFlag _) : base(_) { }
-
-    protected NativeInterpreter(NativeInterpreter original, Cloner cloner) : base(original, cloner) {
-    }
-
+    private NativeInterpreter(StorableConstructorFlag _) : base(_) { }
     public override IDeepCloneable Clone(Cloner cloner) {
       return new NativeInterpreter(this, cloner);
     }
+
+    private NativeInterpreter(NativeInterpreter original, Cloner cloner) : base(original, cloner) { }
+    #endregion
+
     public static NativeInstruction[] Compile(ISymbolicExpressionTree tree, IDataset dataset, Func<ISymbolicExpressionTreeNode, byte> opCodeMapper, out List<ISymbolicExpressionTreeNode> nodes) {
       var root = tree.Root.GetSubtree(0).GetSubtree(0);
@@ -73,23 +74,59 @@
 
     public static NativeInstruction[] Compile(ISymbolicExpressionTreeNode root, IDataset dataset, Func<ISymbolicExpressionTreeNode, byte> opCodeMapper, out List<ISymbolicExpressionTreeNode> nodes) {
-      if (cachedData == null || cachedDataset != dataset) {
+      if (cachedData == null || cachedDataset != dataset || cachedDataset is ModifiableDataset) {
         InitCache(dataset);
       }
-
+      
       nodes = root.IterateNodesPrefix().ToList(); nodes.Reverse();
       var code = new NativeInstruction[nodes.Count];
-
-      for (int i = 0; i < nodes.Count; ++i) {
-        var node = nodes[i];
-        code[i] = new NativeInstruction { Arity = (ushort)node.SubtreeCount, OpCode = opCodeMapper(node), Length = (ushort)node.GetLength(), Optimize = true };
-
-        if (node is VariableTreeNode variable) {
+      if (root.SubtreeCount > ushort.MaxValue) throw new ArgumentException("Number of subtrees is too big (>65.535)");
+      int i = code.Length - 1;
+      foreach (var n in root.IterateNodesPrefix()) {
+        code[i] = new NativeInstruction { Arity = (ushort)n.SubtreeCount, OpCode = opCodeMapper(n), Length = 1, Optimize = false };
+        if (n is VariableTreeNode variable) {
           code[i].Value = variable.Weight;
           code[i].Data = cachedData[variable.VariableName].AddrOfPinnedObject();
-        } else if (node is ConstantTreeNode constant) {
+        } else if (n is ConstantTreeNode constant) {
           code[i].Value = constant.Value;
         }
+        --i;
       }
+      // second pass to calculate lengths
+      for (i = 0; i < code.Length; i++) {
+        var c = i - 1;
+        for (int j = 0; j < code[i].Arity; ++j) {
+          code[i].Length += code[c].Length;
+          c -= code[c].Length;
+        }
+      }
+
       return code;
+    }
+
+    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows) {
+      return GetSymbolicExpressionTreeValues(tree, dataset, rows.ToArray());
+    }
+
+    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, IDataset dataset, int[] rows) {
+      if (!rows.Any()) return Enumerable.Empty<double>();
+
+      byte mapSupportedSymbols(ISymbolicExpressionTreeNode node) {
+        var opCode = OpCodes.MapSymbolToOpCode(node);
+        if (supportedOpCodes.Contains(opCode)) return opCode;
+        else throw new NotSupportedException($"The native interpreter does not support {node.Symbol.Name}");
+      };
+      var code = Compile(tree, dataset, mapSupportedSymbols, out List<ISymbolicExpressionTreeNode> nodes);
+
+      var result = new double[rows.Length];
+      var options = new SolverOptions { Iterations = 0 }; // Evaluate only. Do not optimize.
+
+      NativeWrapper.GetValues(code, rows, options, result, target: null, out var summary);
+
+      // when evaluation took place without any error, we can increment the counter
+      lock (syncRoot) {
+        EvaluatedSolutions++;
+      }
+
+      return result;
     }
 
@@ -102,5 +139,5 @@
     private static IDataset cachedDataset;
 
-    protected static readonly HashSet<byte> supportedOpCodes = new HashSet<byte>() {
+    private static readonly HashSet<byte> supportedOpCodes = new HashSet<byte>() {
       (byte)OpCode.Constant,
       (byte)OpCode.Variable,
@@ -115,6 +152,6 @@
       (byte)OpCode.Tan,
       (byte)OpCode.Tanh,
-      (byte)OpCode.Power,
-      (byte)OpCode.Root,
+      // (byte)OpCode.Power, // these symbols are handled differently in the NativeInterpreter than in HL
+      // (byte)OpCode.Root,
       (byte)OpCode.SquareRoot,
       (byte)OpCode.Square,
@@ -125,8 +162,4 @@
     };
 
-    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows) {
-      return GetSymbolicExpressionTreeValues(tree, dataset, rows.ToArray());
-    }
-    
     private static void InitCache(IDataset dataset) {
       cachedDataset = dataset;
@@ -159,28 +192,4 @@
       ClearState();
     }
-
-    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, IDataset dataset, int[] rows) {
-      if (!rows.Any()) return Enumerable.Empty<double>();
-
-      byte mapSupportedSymbols(ISymbolicExpressionTreeNode node) {
-        var opCode = OpCodes.MapSymbolToOpCode(node);
-        if (supportedOpCodes.Contains(opCode)) return opCode;
-        else throw new NotSupportedException($"The native interpreter does not support {node.Symbol.Name}");
-      };
-      var code = Compile(tree, dataset, mapSupportedSymbols, out List<ISymbolicExpressionTreeNode> nodes);
-
-      var result = new double[rows.Length];
-      var options = new SolverOptions { /* not using any options here */ };
-
-      var summary = new OptimizationSummary(); // also not used
-      NativeWrapper.GetValues(code, rows, options, result, target: null, out summary);
-
-      // when evaluation took place without any error, we can increment the counter
-      lock (syncRoot) {
-        EvaluatedSolutions++;
-      }
-
-      return result;
-    }
   }
 }
Index: branches/3087_Ceres_Integration/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/ParameterOptimizer.cs
===================================================================
--- branches/3087_Ceres_Integration/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/ParameterOptimizer.cs	(revision 18006)
+++ branches/3087_Ceres_Integration/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/ParameterOptimizer.cs	(revision 18007)
@@ -13,42 +13,13 @@
   [StorableType("A624630B-0CEB-4D06-9B26-708987A7AE8F")]
   [Item("ParameterOptimizer", "Operator calling into native C++ code for tree interpretation.")]
-  public class ParameterOptimizer : NativeInterpreter {
+  public sealed class ParameterOptimizer : ParameterizedNamedItem {
     private const string UseNonmonotonicStepsParameterName = "UseNonmonotonicSteps";
     private const string OptimizerIterationsParameterName = "OptimizerIterations";
 
-    private const string MinimizerTypeParameterName = "MinimizerType";
-    private const string LinearSolverTypeParameterName = "LinearSolverType";
-    private const string TrustRegionStrategyTypeParameterName = "TrustRegionStrategyType";
-    private const string DogLegTypeParameterName = "DogLegType";
-    private const string LineSearchDirectionTypeParameterName = "LineSearchDirectionType";
-
-    private static readonly string[] MinimizerType = new[] { "LineSearch", "TrustRegion" };
-    private static readonly string[] LinerSolverType = new[]
-    {
-      "DenseNormalCholesky",
-      "DenseQR",
-      "SparseNormalCholesky",
-      "DenseSchur",
-      "SparseSchur",
-      "IterativeSchur",
-      "ConjugateGradients"
-    };
-    private static readonly string[] TrustRegionStrategyType = new[]
-    {
-      "LevenbergMarquardt",
-      "Dogleg"
-    };
-    private static readonly string[] DoglegType = new[]
-    {
-      "Traditional",
-      "Subspace"
-    };
-    private static readonly string[] LinearSearchDirectionType = new[]
-    {
-      "SteepestDescent",
-      "NonlinearConjugateGradient",
-      "LBFGS",
-      "BFGS"
-    };
+    private const string MinimizerParameterName = "Minimizer";
+    private const string LinearSolverParameterName = "LinearSolver";
+    private const string TrustRegionStrategyParameterName = "TrustRegionStrategy";
+    private const string DogLegParameterName = "DogLeg";
+    private const string LineSearchDirectionParameterName = "LineSearchDirection";
 
     #region parameters
@@ -59,18 +30,18 @@
       get { return (IFixedValueParameter<BoolValue>)Parameters[UseNonmonotonicStepsParameterName]; }
     }
-    public IConstrainedValueParameter<StringValue> MinimizerTypeParameter {
-      get { return (IConstrainedValueParameter<StringValue>)Parameters[MinimizerTypeParameterName]; }
-    }
-    public IConstrainedValueParameter<StringValue> LinearSolverTypeParameter {
-      get { return (IConstrainedValueParameter<StringValue>)Parameters[LinearSolverTypeParameterName]; }
-    }
-    public IConstrainedValueParameter<StringValue> TrustRegionStrategyTypeParameter {
-      get { return (IConstrainedValueParameter<StringValue>)Parameters[TrustRegionStrategyTypeParameterName]; }
-    }
-    public IConstrainedValueParameter<StringValue> DogLegTypeParameter {
-      get { return (IConstrainedValueParameter<StringValue>)Parameters[DogLegTypeParameterName]; }
-    }
-    public IConstrainedValueParameter<StringValue> LineSearchDirectionTypeParameter {
-      get { return (IConstrainedValueParameter<StringValue>)Parameters[LineSearchDirectionTypeParameterName]; }
+    public IFixedValueParameter<EnumValue<CeresTypes.Minimizer>> MinimizerTypeParameter {
+      get { return (IFixedValueParameter<EnumValue<CeresTypes.Minimizer>>)Parameters[MinimizerParameterName]; }
+    }
+    public IFixedValueParameter<EnumValue<CeresTypes.LinearSolver>> LinearSolverTypeParameter {
+      get { return (IFixedValueParameter<EnumValue<CeresTypes.LinearSolver>>)Parameters[LinearSolverParameterName]; }
+    }
+    public IFixedValueParameter<EnumValue<CeresTypes.TrustRegionStrategy>> TrustRegionStrategyTypeParameter {
+      get { return (IFixedValueParameter<EnumValue<CeresTypes.TrustRegionStrategy>>)Parameters[TrustRegionStrategyParameterName]; }
+    }
+    public IFixedValueParameter<EnumValue<CeresTypes.DogLeg>> DogLegTypeParameter {
+      get { return (IFixedValueParameter<EnumValue<CeresTypes.DogLeg>>)Parameters[DogLegParameterName]; }
+    }
+    public IFixedValueParameter<EnumValue<CeresTypes.LineSearchDirection>> LineSearchDirectionTypeParameter {
+      get { return (IFixedValueParameter<EnumValue<CeresTypes.LineSearchDirection>>)Parameters[LineSearchDirectionParameterName]; }
     }
     #endregion
@@ -85,42 +56,29 @@
       set { UseNonmonotonicStepsParameter.Value.Value = value; }
     }
-    private CeresTypes.MinimizerType Minimizer {
-      get { return (CeresTypes.MinimizerType)Enum.Parse(typeof(CeresTypes.MinimizerType), MinimizerTypeParameter.Value.Value); }
-    }
-    private CeresTypes.LinearSolverType LinearSolver {
-      get { return (CeresTypes.LinearSolverType)Enum.Parse(typeof(CeresTypes.LinearSolverType), LinearSolverTypeParameter.Value.Value); }
-    }
-    private CeresTypes.TrustRegionStrategyType TrustRegionStrategy {
-      get { return (CeresTypes.TrustRegionStrategyType)Enum.Parse(typeof(CeresTypes.TrustRegionStrategyType), TrustRegionStrategyTypeParameter.Value.Value); }
-    }
-    private CeresTypes.DoglegType Dogleg {
-      get { return (CeresTypes.DoglegType)Enum.Parse(typeof(CeresTypes.DoglegType), DogLegTypeParameter.Value.Value); }
-    }
-    private CeresTypes.LineSearchDirectionType LineSearchDirection {
-      get { return (CeresTypes.LineSearchDirectionType)Enum.Parse(typeof(CeresTypes.LineSearchDirectionType), LineSearchDirectionTypeParameter.Value.Value); }
+    private CeresTypes.Minimizer Minimizer {
+      get { return MinimizerTypeParameter.Value.Value; }
+      set { MinimizerTypeParameter.Value.Value = value; }
+    }
+    private CeresTypes.LinearSolver LinearSolver {
+      get { return LinearSolverTypeParameter.Value.Value; }
+      set { LinearSolverTypeParameter.Value.Value = value; }
+    }
+    private CeresTypes.TrustRegionStrategy TrustRegionStrategy {
+      get { return TrustRegionStrategyTypeParameter.Value.Value; }
+      set { TrustRegionStrategyTypeParameter.Value.Value = value; }
+    }
+    private CeresTypes.DogLeg DogLeg {
+      get { return DogLegTypeParameter.Value.Value; }
+      set { DogLegTypeParameter.Value.Value = value; }
+    }
+    private CeresTypes.LineSearchDirection LineSearchDirection {
+      get { return LineSearchDirectionTypeParameter.Value.Value; }
+      set { LineSearchDirectionTypeParameter.Value.Value = value; }
     }
     #endregion
 
-    private static IConstrainedValueParameter<StringValue> InitializeParameter(string name, string[] validValues, string value, bool hidden = true) {
-      var parameter = new ConstrainedValueParameter<StringValue>(name, new ItemSet<StringValue>(validValues.Select(x => new StringValue(x))));
-      parameter.Value = parameter.ValidValues.Single(x => x.Value == value);
-      parameter.Hidden = hidden;
-      return parameter;
-    }
-
+    #region storable ctor and cloning
     [StorableConstructor]
-    protected ParameterOptimizer(StorableConstructorFlag _) : base(_) { }
-
-    public ParameterOptimizer() {
-      var minimizerTypeParameter = InitializeParameter(MinimizerTypeParameterName, MinimizerType, "TrustRegion");
-      var linearSolverTypeParameter = InitializeParameter(LinearSolverTypeParameterName, LinerSolverType, "DenseQR");
-      var trustRegionStrategyTypeParameter = InitializeParameter(TrustRegionStrategyTypeParameterName, TrustRegionStrategyType, "LevenbergMarquardt");
-      var dogLegTypeParameter = InitializeParameter(DogLegTypeParameterName, DoglegType, "Traditional");
-      var lineSearchDirectionTypeParameter = InitializeParameter(LineSearchDirectionTypeParameterName, LinearSearchDirectionType, "SteepestDescent");
-
-      Parameters.Add(new FixedValueParameter<IntValue>(OptimizerIterationsParameterName, "The number of iterations for the nonlinear least squares optimizer.", new IntValue(10)));
-      Parameters.Add(new FixedValueParameter<BoolValue>(UseNonmonotonicStepsParameterName, "Allow the non linear least squares optimizer to make steps in parameter space that don't necessarily decrease the error, but might improve overall convergence.", new BoolValue(false)));
-      Parameters.AddRange(new[] { minimizerTypeParameter, linearSolverTypeParameter, trustRegionStrategyTypeParameter, dogLegTypeParameter, lineSearchDirectionTypeParameter });
-    }
+    private ParameterOptimizer(StorableConstructorFlag _) : base(_) { }
 
     public ParameterOptimizer(ParameterOptimizer original, Cloner cloner) : base(original, cloner) { }
@@ -128,4 +86,15 @@
     public override IDeepCloneable Clone(Cloner cloner) {
       return new ParameterOptimizer(this, cloner);
+    }
+    #endregion
+
+    public ParameterOptimizer() {
+      Parameters.Add(new FixedValueParameter<EnumValue<CeresTypes.Minimizer>>(MinimizerParameterName, new EnumValue<CeresTypes.Minimizer>(CeresTypes.Minimizer.TRUST_REGION)));
+      Parameters.Add(new FixedValueParameter<EnumValue<CeresTypes.LinearSolver>>(LinearSolverParameterName, new EnumValue<CeresTypes.LinearSolver>(CeresTypes.LinearSolver.DENSE_QR)));
+      Parameters.Add(new FixedValueParameter<EnumValue<CeresTypes.TrustRegionStrategy>>(TrustRegionStrategyParameterName, new EnumValue<CeresTypes.TrustRegionStrategy>(CeresTypes.TrustRegionStrategy.LEVENBERG_MARQUARDT)));
+      Parameters.Add(new FixedValueParameter<EnumValue<CeresTypes.DogLeg>>(DogLegParameterName, new EnumValue<CeresTypes.DogLeg>(CeresTypes.DogLeg.TRADITIONAL_DOGLEG)));
+      Parameters.Add(new FixedValueParameter<EnumValue<CeresTypes.LineSearchDirection>>(LineSearchDirectionParameterName, new EnumValue<CeresTypes.LineSearchDirection>(CeresTypes.LineSearchDirection.STEEPEST_DESCENT)));
+      Parameters.Add(new FixedValueParameter<IntValue>(OptimizerIterationsParameterName, "The number of iterations for the nonlinear least squares optimizer.", new IntValue(10)));
+      Parameters.Add(new FixedValueParameter<BoolValue>(UseNonmonotonicStepsParameterName, "Allow the non linear least squares optimizer to make steps in parameter space that do not necessarily decrease the error, but might improve overall convergence.", new BoolValue(false)));
     }
 
@@ -136,6 +105,7 @@
     }
 
-    public static Dictionary<ISymbolicExpressionTreeNode, double> OptimizeTree(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows, string targetVariable, HashSet<ISymbolicExpressionTreeNode> nodesToOptimize, SolverOptions options, ref OptimizationSummary summary) {
-      var code = Compile(tree, dataset, MapSupportedSymbols, out List<ISymbolicExpressionTreeNode> nodes);
+    public static Dictionary<ISymbolicExpressionTreeNode, double> OptimizeTree(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows, string targetVariable, 
+      HashSet<ISymbolicExpressionTreeNode> nodesToOptimize, SolverOptions options, ref OptimizationSummary summary) {
+      var code = NativeInterpreter.Compile(tree, dataset, MapSupportedSymbols, out List<ISymbolicExpressionTreeNode> nodes);
 
       for (int i = 0; i < code.Length; ++i) {
@@ -153,5 +123,6 @@
     }
 
-    public Dictionary<ISymbolicExpressionTreeNode, double> OptimizeTree(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows, string targetVariable, HashSet<ISymbolicExpressionTreeNode> nodesToOptimize = null) {
+    public Dictionary<ISymbolicExpressionTreeNode, double> OptimizeTree(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows, string targetVariable, 
+      HashSet<ISymbolicExpressionTreeNode> nodesToOptimize = null) {
       var options = new SolverOptions {
         Iterations = OptimizerIterations,
@@ -159,5 +130,5 @@
         LinearSolver = LinearSolver,
         TrustRegionStrategy = TrustRegionStrategy,
-        Dogleg = Dogleg,
+        DogLeg = DogLeg,
         LineSearchDirection = LineSearchDirection,
         UseNonmonotonicSteps = UseNonmonotonicSteps ? 1 : 0
@@ -187,5 +158,5 @@
       // internally the native wrapper takes a single array of NativeInstructions where the indices point to the individual terms
       for (int i = 0; i < terms.Length; ++i) {
-        var code = Compile(terms[i], dataset, MapSupportedSymbols, out List<ISymbolicExpressionTreeNode> nodes);
+        var code = NativeInterpreter.Compile(terms[i], dataset, MapSupportedSymbols, out List<ISymbolicExpressionTreeNode> nodes);
         for (int j = 0; j < code.Length; ++j) {
           code[j].Optimize = nodesToOptimize.Contains(nodes[j]);
@@ -202,7 +173,30 @@
       var codeArray = totalCode.ToArray();
 
-      NativeWrapper.GetValuesVarPro(codeArray, termIndices,rowsArray, coeff, options, result, target, out summary);
+      NativeWrapper.GetValuesVarPro(codeArray, termIndices, rowsArray, coeff, options, result, target, out summary);
       return Enumerable.Range(0, totalCodeSize).Where(i => codeArray[i].Optimize).ToDictionary(i => totalNodes[i], i => codeArray[i].Value);
     }
+
+    private static readonly HashSet<byte> supportedOpCodes = new HashSet<byte>() {
+      (byte)OpCode.Constant,
+      (byte)OpCode.Variable,
+      (byte)OpCode.Add,
+      (byte)OpCode.Sub,
+      (byte)OpCode.Mul,
+      (byte)OpCode.Div,
+      (byte)OpCode.Exp,
+      (byte)OpCode.Log,
+      (byte)OpCode.Sin,
+      (byte)OpCode.Cos,
+      (byte)OpCode.Tan,
+      (byte)OpCode.Tanh,
+      // (byte)OpCode.Power, // these symbols are handled differently in the NativeInterpreter than in HL
+      // (byte)OpCode.Root,
+      (byte)OpCode.SquareRoot,
+      (byte)OpCode.Square,
+      (byte)OpCode.CubeRoot,
+      (byte)OpCode.Cube,
+      (byte)OpCode.Absolute,
+      (byte)OpCode.AnalyticQuotient
+    };
   }
 }
Index: branches/3087_Ceres_Integration/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeNativeInterpreter.cs
===================================================================
--- branches/3087_Ceres_Integration/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeNativeInterpreter.cs	(revision 18006)
+++ 	(revision )
@@ -1,188 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.NativeInterpreter;
-using HeuristicLab.Parameters;
-using HEAL.Attic;
-
-namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
-  [StorableType("91723319-8F15-4D33-B277-40AC7C7CF9AE")]
-  [Item("SymbolicDataAnalysisExpressionTreeNativeInterpreter", "An interpreter that wraps a native dll")]
-  public class SymbolicDataAnalysisExpressionTreeNativeInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter {
-    private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions";
-
-    #region parameters
-    public IFixedValueParameter<IntValue> EvaluatedSolutionsParameter {
-      get { return (IFixedValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public int EvaluatedSolutions {
-      get { return EvaluatedSolutionsParameter.Value.Value; }
-      set { EvaluatedSolutionsParameter.Value.Value = value; }
-    }
-    #endregion
-
-    public void ClearState() { }
-
-    public SymbolicDataAnalysisExpressionTreeNativeInterpreter() {
-      Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
-    }
-
-    [StorableConstructor]
-    protected SymbolicDataAnalysisExpressionTreeNativeInterpreter(StorableConstructorFlag _) : base(_) { }
-
-    protected SymbolicDataAnalysisExpressionTreeNativeInterpreter(SymbolicDataAnalysisExpressionTreeNativeInterpreter original, Cloner cloner) : base(original, cloner) {
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new SymbolicDataAnalysisExpressionTreeNativeInterpreter(this, cloner);
-    }
-
-    private NativeInstruction[] Compile(ISymbolicExpressionTree tree, Func<ISymbolicExpressionTreeNode, byte> opCodeMapper) {
-      var root = tree.Root.GetSubtree(0).GetSubtree(0);
-      var code = new NativeInstruction[root.GetLength()];
-      if (root.SubtreeCount > ushort.MaxValue) throw new ArgumentException("Number of subtrees is too big (>65.535)");
-      int i = code.Length - 1;
-      foreach (var n in root.IterateNodesPrefix()) {
-        code[i] = new NativeInstruction { Arity = (ushort)n.SubtreeCount, OpCode = opCodeMapper(n), Length = 1, Optimize = false };
-        if (n is VariableTreeNode variable) {
-          code[i].Value = variable.Weight;
-          code[i].Data = cachedData[variable.VariableName].AddrOfPinnedObject();
-        } else if (n is ConstantTreeNode constant) {
-          code[i].Value = constant.Value;
-        }
-        --i;
-      }
-      // second pass to calculate lengths
-      for (i = 0; i < code.Length; i++) {
-        var c = i - 1;
-        for (int j = 0; j < code[i].Arity; ++j) {
-          code[i].Length += code[c].Length;
-          c -= code[c].Length;
-        }
-      }
-
-      return code;
-    }
-
-    private readonly object syncRoot = new object();
-
-    [ThreadStatic]
-    private static Dictionary<string, GCHandle> cachedData;
-
-    [ThreadStatic]
-    private static IDataset cachedDataset;
-
-    private static readonly HashSet<byte> supportedOpCodes = new HashSet<byte>() {
-      (byte)OpCode.Constant,
-      (byte)OpCode.Variable,
-      (byte)OpCode.Add,
-      (byte)OpCode.Sub,
-      (byte)OpCode.Mul,
-      (byte)OpCode.Div,
-      (byte)OpCode.Exp,
-      (byte)OpCode.Log,
-      (byte)OpCode.Sin,
-      (byte)OpCode.Cos,
-      (byte)OpCode.Tan,
-      (byte)OpCode.Tanh,
-      // (byte)OpCode.Power,
-      // (byte)OpCode.Root,
-      (byte)OpCode.SquareRoot,
-      (byte)OpCode.Square,
-      (byte)OpCode.CubeRoot,
-      (byte)OpCode.Cube,
-      (byte)OpCode.Absolute,
-      (byte)OpCode.AnalyticQuotient
-    };
-
-    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows) {
-      if (!rows.Any()) return Enumerable.Empty<double>();
-
-      if (cachedData == null || cachedDataset != dataset || cachedDataset is ModifiableDataset) {
-        InitCache(dataset);
-      }
-
-      byte mapSupportedSymbols(ISymbolicExpressionTreeNode node) {
-        var opCode = OpCodes.MapSymbolToOpCode(node);
-        if (supportedOpCodes.Contains(opCode)) return opCode;
-        else throw new NotSupportedException($"The native interpreter does not support {node.Symbol.Name}");
-      };
-      var code = Compile(tree, mapSupportedSymbols);
-
-      var rowsArray = rows.ToArray();
-      var result = new double[rowsArray.Length];
-      // prevent optimization of parameters
-      var options = new SolverOptions {
-        Iterations = 0
-      };
-      NativeWrapper.GetValues(code, rowsArray, options, result, target: null, optSummary: out var optSummary); // target is only used when optimizing parameters
-
-      // when evaluation took place without any error, we can increment the counter
-      lock (syncRoot) {
-        EvaluatedSolutions++;
-      }
-
-      return result;
-    }
-
-    private void InitCache(IDataset dataset) {
-      cachedDataset = dataset;
-
-      // free handles to old data
-      if (cachedData != null) {
-        foreach (var gch in cachedData.Values) {
-          gch.Free();
-        }
-        cachedData = null;
-      }
-
-      // cache new data
-      cachedData = new Dictionary<string, GCHandle>();
-      foreach (var v in dataset.DoubleVariables) {
-        var values = dataset.GetDoubleValues(v).ToArray();
-        var gch = GCHandle.Alloc(values, GCHandleType.Pinned);
-        cachedData[v] = gch;
-      }
-    }
-
-    public void InitializeState() {
-      if (cachedData != null) {
-        foreach (var gch in cachedData.Values) {
-          gch.Free();
-        }
-        cachedData = null;
-      }
-      cachedDataset = null;
-      EvaluatedSolutions = 0;
-    }
-  }
-}
