Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessModel.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessModel.cs	(revision 15134)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessModel.cs	(revision 15142)
@@ -165,6 +165,5 @@
       try {
         CalculateModel(ds, rows, scaleInputs);
-      }
-      catch (alglib.alglibexception ae) {
+      } catch (alglib.alglibexception ae) {
         // wrap exception so that calling code doesn't have to know about alglib implementation
         throw new ArgumentException("There was a problem in the calculation of the Gaussian process model", ae);
@@ -260,7 +259,18 @@
     private static double[,] GetData(IDataset ds, IEnumerable<string> allowedInputs, IEnumerable<int> rows, Scaling scaling) {
       if (scaling != null) {
-        return AlglibUtil.PrepareAndScaleInputMatrix(ds, allowedInputs, rows, scaling);
+        // TODO: completely remove Scaling class
+        List<ITransformation<double>> transformations = new List<ITransformation<double>>();
+
+        foreach (var varName in allowedInputs) {
+          double min;
+          double max;
+          scaling.GetScalingParameters(varName, out min, out max);
+          var add = -min / (max - min);
+          var mult = 1.0 / (max - min);
+          transformations.Add(new LinearTransformation(allowedInputs) { Addend = add, Multiplier = mult });
+        }
+        return ds.ToArray(allowedInputs, transformations, rows);
       } else {
-        return AlglibUtil.PrepareInputMatrix(ds, allowedInputs, rows);
+        return ds.ToArray(allowedInputs, rows);
       }
     }
@@ -334,6 +344,5 @@
         return Enumerable.Range(0, newN)
           .Select(i => ms[i] + Util.ScalarProd(Ks[i], alpha));
-      }
-      catch (alglib.alglibexception ae) {
+      } catch (alglib.alglibexception ae) {
         // wrap exception so that calling code doesn't have to know about alglib implementation
         throw new ArgumentException("There was a problem in the calculation of the Gaussian process model", ae);
@@ -381,6 +390,5 @@
         }
         return kss;
-      }
-      catch (alglib.alglibexception ae) {
+      } catch (alglib.alglibexception ae) {
         // wrap exception so that calling code doesn't have to know about alglib implementation
         throw new ArgumentException("There was a problem in the calculation of the Gaussian process model", ae);
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj	(revision 15134)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj	(revision 15142)
@@ -246,6 +246,4 @@
       <SubType>Code</SubType>
     </Compile>
-    <Compile Include="Linear\AlglibUtil.cs" />
-    <Compile Include="Linear\Scaling.cs" />
     <Compile Include="Linear\LinearDiscriminantAnalysis.cs" />
     <Compile Include="Linear\LinearRegression.cs">
@@ -255,4 +253,5 @@
     <Compile Include="Linear\MultinomialLogitClassificationSolution.cs" />
     <Compile Include="Linear\MultinomialLogitModel.cs" />
+    <Compile Include="Linear\Scaling.cs" />
     <Compile Include="Nca\Initialization\INcaInitializer.cs" />
     <Compile Include="Nca\Initialization\LdaInitializer.cs" />
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/AlglibUtil.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/AlglibUtil.cs	(revision 15134)
+++ 	(revision )
@@ -1,132 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Problems.DataAnalysis;
-
-namespace HeuristicLab.Algorithms.DataAnalysis {
-  public static class AlglibUtil {
-    public static double[,] PrepareInputMatrix(IDataset dataset, IEnumerable<string> variables, IEnumerable<int> rows) {
-      // check input variables. Only double variables are allowed.
-      var invalidInputs =
-        variables.Where(name => !dataset.VariableHasType<double>(name));
-      if (invalidInputs.Any())
-        throw new NotSupportedException("Unsupported inputs: " + string.Join(", ", invalidInputs));
-
-      List<int> rowsList = rows.ToList();
-      double[,] matrix = new double[rowsList.Count, variables.Count()];
-
-      int col = 0;
-      foreach (string column in variables) {
-        var values = dataset.GetDoubleValues(column, rows);
-        int row = 0;
-        foreach (var value in values) {
-          matrix[row, col] = value;
-          row++;
-        }
-        col++;
-      }
-
-      return matrix;
-    }
-
-    public static double[,] PrepareAndScaleInputMatrix(IDataset dataset, IEnumerable<string> variables, IEnumerable<int> rows, Scaling scaling) {
-      // check input variables. Only double variables are allowed.
-      var invalidInputs =
-        variables.Where(name => !dataset.VariableHasType<double>(name));
-      if (invalidInputs.Any())
-        throw new NotSupportedException("Unsupported inputs: " + string.Join(", ", invalidInputs));
-
-      List<string> variablesList = variables.ToList();
-      List<int> rowsList = rows.ToList();
-
-      double[,] matrix = new double[rowsList.Count, variablesList.Count];
-
-      int col = 0;
-      foreach (string column in variables) {
-        var values = scaling.GetScaledValues(dataset, column, rows);
-        int row = 0;
-        foreach (var value in values) {
-          matrix[row, col] = value;
-          row++;
-        }
-        col++;
-      }
-
-      return matrix;
-    }
-
-    /// <summary>
-    /// Prepares a binary data matrix from a number of factors and specified factor values
-    /// </summary>
-    /// <param name="dataset">A dataset that contains the variable values</param>
-    /// <param name="factorVariables">An enumerable of categorical variables (factors). For each variable an enumerable of values must be specified.</param>
-    /// <param name="rows">An enumerable of row indices for the dataset</param>
-    /// <returns></returns>
-    /// <remarks>Factor variables (categorical variables) are split up into multiple binary variables one for each specified value.</remarks>
-    public static double[,] PrepareInputMatrix(
-      IDataset dataset,
-      IEnumerable<KeyValuePair<string, IEnumerable<string>>> factorVariables,
-      IEnumerable<int> rows) {
-      // check input variables. Only string variables are allowed.
-      var invalidInputs =
-        factorVariables.Select(kvp => kvp.Key).Where(name => !dataset.VariableHasType<string>(name));
-      if (invalidInputs.Any())
-        throw new NotSupportedException("Unsupported inputs: " + string.Join(", ", invalidInputs));
-
-      int numBinaryColumns = factorVariables.Sum(kvp => kvp.Value.Count());
-
-      List<int> rowsList = rows.ToList();
-      double[,] matrix = new double[rowsList.Count, numBinaryColumns];
-
-      int col = 0;
-      foreach (var kvp in factorVariables) {
-        var varName = kvp.Key;
-        var cats = kvp.Value;
-        if (!cats.Any()) continue;
-        foreach (var cat in cats) {
-          var values = dataset.GetStringValues(varName, rows);
-          int row = 0;
-          foreach (var value in values) {
-            matrix[row, col] = value == cat ? 1 : 0;
-            row++;
-          }
-          col++;
-        }
-      }
-      return matrix;
-    }
-
-    public static IEnumerable<KeyValuePair<string, IEnumerable<string>>> GetFactorVariableValues(IDataset ds, IEnumerable<string> factorVariables, IEnumerable<int> rows) {
-      return from factor in factorVariables
-             let distinctValues = ds.GetStringValues(factor, rows).Distinct().ToArray()
-             // 1 distinct value => skip (constant)
-             // 2 distinct values => only take one of the two values
-             // >=3 distinct values => create a binary value for each value
-             let reducedValues = distinctValues.Length <= 2
-               ? distinctValues.Take(distinctValues.Length - 1)
-               : distinctValues
-             select new KeyValuePair<string, IEnumerable<string>>(factor, reducedValues);
-    }
-  }
-}
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearDiscriminantAnalysis.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearDiscriminantAnalysis.cs	(revision 15134)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearDiscriminantAnalysis.cs	(revision 15142)
@@ -73,8 +73,8 @@
       var doubleVariableNames = allowedInputVariables.Where(dataset.VariableHasType<double>).ToArray();
       var factorVariableNames = allowedInputVariables.Where(dataset.VariableHasType<string>).ToArray();
-      double[,] inputMatrix = AlglibUtil.PrepareInputMatrix(dataset, doubleVariableNames.Concat(new string[] { targetVariable }), rows);
+      double[,] inputMatrix = dataset.ToArray(doubleVariableNames.Concat(new string[] { targetVariable }), rows);
 
-      var factorVariables = AlglibUtil.GetFactorVariableValues(dataset, factorVariableNames, rows);
-      double[,] factorMatrix = AlglibUtil.PrepareInputMatrix(dataset, factorVariables, rows);
+      var factorVariables = dataset.GetFactorVariableValues(factorVariableNames, rows);
+      var factorMatrix = dataset.ToArray(factorVariables, rows);
 
       inputMatrix = factorMatrix.HorzCat(inputMatrix);
@@ -94,30 +94,7 @@
       if (info < 1) throw new ArgumentException("Error in calculation of linear discriminant analysis solution");
 
-      ISymbolicExpressionTree tree = new SymbolicExpressionTree(new ProgramRootSymbol().CreateTreeNode());
-      ISymbolicExpressionTreeNode startNode = new StartSymbol().CreateTreeNode();
-      tree.Root.AddSubtree(startNode);
-      ISymbolicExpressionTreeNode addition = new Addition().CreateTreeNode();
-      startNode.AddSubtree(addition);
-
-      int col = 0;
-      foreach (var kvp in factorVariables) {
-        var varName = kvp.Key;
-        foreach (var cat in kvp.Value) {
-          BinaryFactorVariableTreeNode vNode =
-            (BinaryFactorVariableTreeNode)new HeuristicLab.Problems.DataAnalysis.Symbolic.BinaryFactorVariable().CreateTreeNode();
-          vNode.VariableName = varName;
-          vNode.VariableValue = cat;
-          vNode.Weight = w[col];
-          addition.AddSubtree(vNode);
-          col++;
-        }
-      }
-      foreach (string column in doubleVariableNames) {
-        VariableTreeNode vNode = (VariableTreeNode)new HeuristicLab.Problems.DataAnalysis.Symbolic.Variable().CreateTreeNode();
-        vNode.VariableName = column;
-        vNode.Weight = w[col];
-        addition.AddSubtree(vNode);
-        col++;
-      }
+      var nFactorCoeff = factorMatrix.GetLength(1);
+      var tree = LinearModelToTreeConverter.CreateTree(factorVariables, w.Take(nFactorCoeff).ToArray(),
+        doubleVariableNames, w.Skip(nFactorCoeff).Take(doubleVariableNames.Length).ToArray());
 
       var model = CreateDiscriminantFunctionModel(tree, new SymbolicDataAnalysisExpressionTreeLinearInterpreter(), problemData, rows);
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearRegression.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearRegression.cs	(revision 15134)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearRegression.cs	(revision 15142)
@@ -76,7 +76,7 @@
       var doubleVariables = allowedInputVariables.Where(dataset.VariableHasType<double>);
       var factorVariableNames = allowedInputVariables.Where(dataset.VariableHasType<string>);
-      var factorVariables = AlglibUtil.GetFactorVariableValues(dataset, factorVariableNames, rows);
-      double[,] binaryMatrix = AlglibUtil.PrepareInputMatrix(dataset, factorVariables, rows);
-      double[,] doubleVarMatrix = AlglibUtil.PrepareInputMatrix(dataset, doubleVariables.Concat(new string[] { targetVariable }), rows);
+      var factorVariables = dataset.GetFactorVariableValues(factorVariableNames, rows);
+      double[,] binaryMatrix = dataset.ToArray(factorVariables, rows);
+      double[,] doubleVarMatrix = dataset.ToArray(doubleVariables.Concat(new string[] { targetVariable }), rows);
       var inputMatrix = binaryMatrix.HorzCat(doubleVarMatrix);
 
@@ -98,35 +98,10 @@
       alglib.lrunpack(lm, out coefficients, out nFeatures);
 
-      ISymbolicExpressionTree tree = new SymbolicExpressionTree(new ProgramRootSymbol().CreateTreeNode());
-      ISymbolicExpressionTreeNode startNode = new StartSymbol().CreateTreeNode();
-      tree.Root.AddSubtree(startNode);
-      ISymbolicExpressionTreeNode addition = new Addition().CreateTreeNode();
-      startNode.AddSubtree(addition);
-
-      int col = 0;
-      foreach (var kvp in factorVariables) {
-        var varName = kvp.Key;
-        foreach (var cat in kvp.Value) {
-          BinaryFactorVariableTreeNode vNode =
-            (BinaryFactorVariableTreeNode)new HeuristicLab.Problems.DataAnalysis.Symbolic.BinaryFactorVariable().CreateTreeNode();
-          vNode.VariableName = varName;
-          vNode.VariableValue = cat;
-          vNode.Weight = coefficients[col];
-          addition.AddSubtree(vNode);
-          col++;
-        }
-      }
-      foreach (string column in doubleVariables) {
-        VariableTreeNode vNode = (VariableTreeNode)new HeuristicLab.Problems.DataAnalysis.Symbolic.Variable().CreateTreeNode();
-        vNode.VariableName = column;
-        vNode.Weight = coefficients[col];
-        addition.AddSubtree(vNode);
-        col++;
-      }
-
-      ConstantTreeNode cNode = (ConstantTreeNode)new Constant().CreateTreeNode();
-      cNode.Value = coefficients[coefficients.Length - 1];
-      addition.AddSubtree(cNode);
-
+      int nFactorCoeff = binaryMatrix.GetLength(1);
+      int nVarCoeff = doubleVariables.Count();
+      var tree = LinearModelToTreeConverter.CreateTree(factorVariables, coefficients.Take(nFactorCoeff).ToArray(),
+        doubleVariables.ToArray(), coefficients.Skip(nFactorCoeff).Take(nVarCoeff).ToArray(), 
+        @const: coefficients[nFeatures]);
+      
       SymbolicRegressionSolution solution = new SymbolicRegressionSolution(new SymbolicRegressionModel(problemData.TargetVariable, tree, new SymbolicDataAnalysisExpressionTreeLinearInterpreter()), (IRegressionProblemData)problemData.Clone());
       solution.Model.Name = "Linear Regression Model";
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitClassification.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitClassification.cs	(revision 15134)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitClassification.cs	(revision 15142)
@@ -72,8 +72,8 @@
       var factorVariableNames = problemData.AllowedInputVariables.Where(dataset.VariableHasType<string>);
       IEnumerable<int> rows = problemData.TrainingIndices;
-      double[,] inputMatrix = AlglibUtil.PrepareInputMatrix(dataset, doubleVariableNames.Concat(new string[] { targetVariable }), rows);
+      double[,] inputMatrix = dataset.ToArray(doubleVariableNames.Concat(new string[] { targetVariable }), rows);
 
-      var factorVariableValues = AlglibUtil.GetFactorVariableValues(dataset, factorVariableNames, rows);
-      var factorMatrix = AlglibUtil.PrepareInputMatrix(dataset, factorVariableValues, rows);
+      var factorVariableValues = dataset.GetFactorVariableValues(factorVariableNames, rows);
+      var factorMatrix = dataset.ToArray(factorVariableValues, rows);
       inputMatrix = factorMatrix.HorzCat(inputMatrix);
 
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitModel.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitModel.cs	(revision 15134)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitModel.cs	(revision 15142)
@@ -97,6 +97,6 @@
     public override IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
 
-      double[,] inputData = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables, rows);
-      double[,] factorData = AlglibUtil.PrepareInputMatrix(dataset, factorVariables, rows);
+      double[,] inputData = dataset.ToArray(allowedInputVariables, rows);
+      double[,] factorData = dataset.ToArray(factorVariables, rows);
 
       inputData = factorData.HorzCat(inputData);
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/Scaling.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/Scaling.cs	(revision 15134)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/Scaling.cs	(revision 15142)
@@ -29,4 +29,5 @@
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
+  [Obsolete("Use transformation classes in Problems.DataAnalysis instead")]
   [StorableClass]
   [Item(Name = "Scaling", Description = "Contains information about scaling of variables for data-analysis algorithms.")]
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/Initialization/LdaInitializer.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/Initialization/LdaInitializer.cs	(revision 15134)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/Initialization/LdaInitializer.cs	(revision 15142)
@@ -44,7 +44,7 @@
       var attributes = data.AllowedInputVariables.Count();
 
-      var ldaDs = AlglibUtil.PrepareInputMatrix(data.Dataset,
-                                                data.AllowedInputVariables.Concat(data.TargetVariable.ToEnumerable()),
-                                                data.TrainingIndices);
+      var ldaDs = data.Dataset.ToArray(
+                                       data.AllowedInputVariables.Concat(data.TargetVariable.ToEnumerable()),
+                                       data.TrainingIndices);
 
       // map class values to sequential natural numbers (required by alglib)
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/Initialization/PcaInitializer.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/Initialization/PcaInitializer.cs	(revision 15134)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/Initialization/PcaInitializer.cs	(revision 15142)
@@ -44,5 +44,5 @@
       var attributes = data.AllowedInputVariables.Count();
 
-      var pcaDs = AlglibUtil.PrepareInputMatrix(data.Dataset, data.AllowedInputVariables, data.TrainingIndices);
+      var pcaDs = data.Dataset.ToArray(data.AllowedInputVariables, data.TrainingIndices);
 
       int info;
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaGradientCalculator.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaGradientCalculator.cs	(revision 15134)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaGradientCalculator.cs	(revision 15142)
@@ -99,6 +99,6 @@
       }
 
-      var data = AlglibUtil.PrepareInputMatrix(problemData.Dataset, problemData.AllowedInputVariables,
-                                               problemData.TrainingIndices);
+      var data = problemData.Dataset.ToArray(problemData.AllowedInputVariables,
+                                             problemData.TrainingIndices);
       var classes = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices).ToArray();
 
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaModel.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaModel.cs	(revision 15134)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaModel.cs	(revision 15142)
@@ -86,5 +86,5 @@
 
     public double[,] Reduce(IDataset dataset, IEnumerable<int> rows) {
-      var data = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables, rows);
+      var data = dataset.ToArray(allowedInputVariables, rows);
 
       var targets = dataset.GetDoubleValues(TargetVariable, rows).ToArray();
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourModel.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourModel.cs	(revision 15134)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourModel.cs	(revision 15142)
@@ -119,5 +119,5 @@
       if (IsCompatibilityLoaded) {
         // no scaling
-        inputMatrix = AlglibUtil.PrepareInputMatrix(dataset,
+        inputMatrix = dataset.ToArray(
           this.allowedInputVariables.Concat(new string[] { targetVariable }),
           rows);
@@ -167,15 +167,9 @@
 
     private static double[,] CreateScaledData(IDataset dataset, IEnumerable<string> variables, IEnumerable<int> rows, double[] offsets, double[] factors) {
-      var x = new double[rows.Count(), variables.Count()];
-      var colIdx = 0;
-      foreach (var variableName in variables) {
-        var rowIdx = 0;
-        foreach (var val in dataset.GetDoubleValues(variableName, rows)) {
-          x[rowIdx, colIdx] = (val + offsets[colIdx]) * factors[colIdx];
-          rowIdx++;
-        }
-        colIdx++;
-      }
-      return x;
+      var transforms =
+        variables.Select(
+          (_, colIdx) =>
+            new LinearTransformation(variables) { Addend = offsets[colIdx] * factors[colIdx], Multiplier = factors[colIdx] });
+      return dataset.ToArray(variables, transforms, rows);
     }
 
@@ -187,5 +181,5 @@
       double[,] inputData;
       if (IsCompatibilityLoaded) {
-        inputData = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables, rows);
+        inputData = dataset.ToArray(allowedInputVariables, rows);
       } else {
         inputData = CreateScaledData(dataset, allowedInputVariables, rows, offsets, weights);
@@ -223,5 +217,5 @@
       double[,] inputData;
       if (IsCompatibilityLoaded) {
-        inputData = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables, rows);
+        inputData = dataset.ToArray(allowedInputVariables, rows);
       } else {
         inputData = CreateScaledData(dataset, allowedInputVariables, rows, offsets, weights);
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkClassification.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkClassification.cs	(revision 15134)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkClassification.cs	(revision 15142)
@@ -184,5 +184,5 @@
       IEnumerable<string> allowedInputVariables = problemData.AllowedInputVariables;
       IEnumerable<int> rows = problemData.TrainingIndices;
-      double[,] inputMatrix = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables.Concat(new string[] { targetVariable }), rows);
+      double[,] inputMatrix = dataset.ToArray(allowedInputVariables.Concat(new string[] { targetVariable }), rows);
       if (inputMatrix.Cast<double>().Any(x => double.IsNaN(x) || double.IsInfinity(x)))
         throw new NotSupportedException("Neural network classification does not support NaN or infinity values in the input dataset.");
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleClassification.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleClassification.cs	(revision 15134)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleClassification.cs	(revision 15142)
@@ -125,7 +125,7 @@
     public NeuralNetworkEnsembleClassification()
       : base() {
-      var validHiddenLayerValues = new ItemSet<IntValue>(new IntValue[] { 
-        (IntValue)new IntValue(0).AsReadOnly(), 
-        (IntValue)new IntValue(1).AsReadOnly(), 
+      var validHiddenLayerValues = new ItemSet<IntValue>(new IntValue[] {
+        (IntValue)new IntValue(0).AsReadOnly(),
+        (IntValue)new IntValue(1).AsReadOnly(),
         (IntValue)new IntValue(2).AsReadOnly() });
       var selectedHiddenLayerValue = (from v in validHiddenLayerValues
@@ -170,5 +170,5 @@
       IEnumerable<string> allowedInputVariables = problemData.AllowedInputVariables;
       IEnumerable<int> rows = problemData.TrainingIndices;
-      double[,] inputMatrix = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables.Concat(new string[] { targetVariable }), rows);
+      double[,] inputMatrix = dataset.ToArray(allowedInputVariables.Concat(new string[] { targetVariable }), rows);
       if (inputMatrix.Cast<double>().Any(x => double.IsNaN(x) || double.IsInfinity(x)))
         throw new NotSupportedException("Neural network ensemble classification does not support NaN or infinity values in the input dataset.");
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleModel.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleModel.cs	(revision 15134)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleModel.cs	(revision 15142)
@@ -91,5 +91,5 @@
 
     public IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
-      double[,] inputData = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables, rows);
+      double[,] inputData = dataset.ToArray(allowedInputVariables, rows);
 
       int n = inputData.GetLength(0);
@@ -108,5 +108,5 @@
 
     public override IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
-      double[,] inputData = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables, rows);
+      double[,] inputData = dataset.ToArray(allowedInputVariables, rows);
 
       int n = inputData.GetLength(0);
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleRegression.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleRegression.cs	(revision 15134)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleRegression.cs	(revision 15142)
@@ -169,5 +169,5 @@
       IEnumerable<string> allowedInputVariables = problemData.AllowedInputVariables;
       IEnumerable<int> rows = problemData.TrainingIndices;
-      double[,] inputMatrix = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables.Concat(new string[] { targetVariable }), rows);
+      double[,] inputMatrix = dataset.ToArray(allowedInputVariables.Concat(new string[] { targetVariable }), rows);
       if (inputMatrix.Cast<double>().Any(x => double.IsNaN(x) || double.IsInfinity(x)))
         throw new NotSupportedException("Neural network ensemble regression does not support NaN or infinity values in the input dataset.");
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkModel.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkModel.cs	(revision 15134)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkModel.cs	(revision 15142)
@@ -95,5 +95,5 @@
 
     public IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
-      double[,] inputData = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables, rows);
+      double[,] inputData = dataset.ToArray(allowedInputVariables, rows);
 
       int n = inputData.GetLength(0);
@@ -112,5 +112,5 @@
 
     public override IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
-      double[,] inputData = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables, rows);
+      double[,] inputData = dataset.ToArray( allowedInputVariables, rows);
 
       int n = inputData.GetLength(0);
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkRegression.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkRegression.cs	(revision 15134)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkRegression.cs	(revision 15142)
@@ -185,5 +185,5 @@
       IEnumerable<string> allowedInputVariables = problemData.AllowedInputVariables;
       IEnumerable<int> rows = problemData.TrainingIndices;
-      double[,] inputMatrix = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables.Concat(new string[] { targetVariable }), rows);
+      double[,] inputMatrix = dataset.ToArray(allowedInputVariables.Concat(new string[] { targetVariable }), rows);
       if (inputMatrix.Cast<double>().Any(x => double.IsNaN(x) || double.IsInfinity(x)))
         throw new NotSupportedException("Neural network regression does not support NaN or infinity values in the input dataset.");
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestModel.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestModel.cs	(revision 15134)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestModel.cs	(revision 15142)
@@ -139,5 +139,5 @@
 
     public IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
-      double[,] inputData = AlglibUtil.PrepareInputMatrix(dataset, AllowedInputVariables, rows);
+      double[,] inputData = dataset.ToArray(AllowedInputVariables, rows);
       AssertInputMatrix(inputData);
 
@@ -157,5 +157,5 @@
 
     public IEnumerable<double> GetEstimatedVariances(IDataset dataset, IEnumerable<int> rows) {
-      double[,] inputData = AlglibUtil.PrepareInputMatrix(dataset, AllowedInputVariables, rows);
+      double[,] inputData = dataset.ToArray(AllowedInputVariables, rows);
       AssertInputMatrix(inputData);
 
@@ -175,5 +175,5 @@
 
     public override IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
-      double[,] inputData = AlglibUtil.PrepareInputMatrix(dataset, AllowedInputVariables, rows);
+      double[,] inputData = dataset.ToArray(AllowedInputVariables, rows);
       AssertInputMatrix(inputData);
 
@@ -294,5 +294,5 @@
       out double rmsError, out double outOfBagRmsError, out double avgRelError, out double outOfBagAvgRelError) {
       var variables = problemData.AllowedInputVariables.Concat(new string[] { problemData.TargetVariable });
-      double[,] inputMatrix = AlglibUtil.PrepareInputMatrix(problemData.Dataset, variables, trainingIndices);
+      double[,] inputMatrix = problemData.Dataset.ToArray(variables, trainingIndices);
 
       alglib.dfreport rep;
@@ -316,5 +316,5 @@
 
       var variables = problemData.AllowedInputVariables.Concat(new string[] { problemData.TargetVariable });
-      double[,] inputMatrix = AlglibUtil.PrepareInputMatrix(problemData.Dataset, variables, trainingIndices);
+      double[,] inputMatrix = problemData.Dataset.ToArray(variables, trainingIndices);
 
       var classValues = problemData.ClassValues.ToArray();
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/TimeSeries/AutoregressiveModeling.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/TimeSeries/AutoregressiveModeling.cs	(revision 15134)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/TimeSeries/AutoregressiveModeling.cs	(revision 15142)
@@ -115,22 +115,10 @@
       alglib.lrunpack(lm, out coefficients, out nFeatures);
 
-
-      ISymbolicExpressionTree tree = new SymbolicExpressionTree(new ProgramRootSymbol().CreateTreeNode());
-      ISymbolicExpressionTreeNode startNode = new StartSymbol().CreateTreeNode();
-      tree.Root.AddSubtree(startNode);
-      ISymbolicExpressionTreeNode addition = new Addition().CreateTreeNode();
-      startNode.AddSubtree(addition);
-
-      for (int i = 0; i < timeOffset; i++) {
-        LaggedVariableTreeNode node = (LaggedVariableTreeNode)new LaggedVariable().CreateTreeNode();
-        node.VariableName = targetVariable;
-        node.Weight = coefficients[i];
-        node.Lag = (i + 1) * -1;
-        addition.AddSubtree(node);
-      }
-
-      ConstantTreeNode cNode = (ConstantTreeNode)new Constant().CreateTreeNode();
-      cNode.Value = coefficients[coefficients.Length - 1];
-      addition.AddSubtree(cNode);
+      var tree = LinearModelToTreeConverter.CreateTree(
+        variableNames: Enumerable.Repeat(problemData.TargetVariable, nFeatures).ToArray(),
+        lags: Enumerable.Range(0, timeOffset).Select(i => (i + 1) * -1).ToArray(),
+        coefficients: coefficients.Take(nFeatures).ToArray(),
+        @const: coefficients[nFeatures]
+        );
 
       var interpreter = new SymbolicTimeSeriesPrognosisExpressionTreeInterpreter(problemData.TargetVariable);
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/kMeans/KMeansClustering.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/kMeans/KMeansClustering.cs	(revision 15134)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/kMeans/KMeansClustering.cs	(revision 15142)
@@ -90,5 +90,5 @@
       double[,] centers;
       int[] xyc;
-      double[,] inputMatrix = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables, rows);
+      double[,] inputMatrix = dataset.ToArray(allowedInputVariables, rows);
       if (inputMatrix.Cast<double>().Any(x => double.IsNaN(x) || double.IsInfinity(x)))
         throw new NotSupportedException("k-Means clustering does not support NaN or infinity values in the input dataset.");
