Index: HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelRidgeRegressionModel.cs
===================================================================
--- HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelRidgeRegressionModel.cs	(revision 15884)
+++ HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelRidgeRegressionModel.cs	(working copy)
@@ -204,11 +204,11 @@
       var trans = new ITransformation<double>[allowedInputVariables.Count];
       int i = 0;
       foreach (var variable in allowedInputVariables) {
-        var lin = new LinearTransformation(allowedInputVariables);
+        var lin = new LinearTransformation();
         var max = dataset.GetDoubleValues(variable, rows).Max();
         var min = dataset.GetDoubleValues(variable, rows).Min();
-        lin.Multiplier = 1.0 / (max - min);
-        lin.Addend = -min / (max - min);
+        lin.Slope = 1.0 / (max - min);
+        lin.Intercept = -min / (max - min);
         trans[i] = lin;
         i++;
       }
Index: HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourModel.cs
===================================================================
--- HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourModel.cs	(revision 15884)
+++ HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourModel.cs	(working copy)
@@ -169,7 +169,7 @@
       var transforms =
         variables.Select(
           (_, colIdx) =>
-            new LinearTransformation(variables) { Addend = offsets[colIdx] * factors[colIdx], Multiplier = factors[colIdx] });
+            new LinearTransformation() { Intercept = offsets[colIdx] * factors[colIdx], Slope = factors[colIdx] });
       return dataset.ToArray(variables, transforms, rows);
     }
 
Index: HeuristicLab.DataPreprocessing
===================================================================
--- HeuristicLab.DataPreprocessing	(revision 15884)
+++ HeuristicLab.DataPreprocessing	(working copy)

Property changes on: HeuristicLab.DataPreprocessing
___________________________________________________________________
Modified: svn:mergeinfo
## -0,0 +0,1 ##
   Merged /branches/2906_Transformations/HeuristicLab.DataPreprocessing:r15826-15885
Index: HeuristicLab.DataPreprocessing.Views
===================================================================
--- HeuristicLab.DataPreprocessing.Views	(revision 15884)
+++ HeuristicLab.DataPreprocessing.Views	(working copy)

Property changes on: HeuristicLab.DataPreprocessing.Views
___________________________________________________________________
Modified: svn:mergeinfo
## -0,0 +0,1 ##
   Merged /branches/2906_Transformations/HeuristicLab.DataPreprocessing.Views:r15826-15885
Index: HeuristicLab.DataPreprocessing.Views/3.4/CheckedTransformationListView.cs
===================================================================
--- HeuristicLab.DataPreprocessing.Views/3.4/CheckedTransformationListView.cs	(revision 15884)
+++ HeuristicLab.DataPreprocessing.Views/3.4/CheckedTransformationListView.cs	(nonexistent)
@@ -1,71 +0,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Reflection;
-using System.Windows.Forms;
-using HeuristicLab.Core;
-using HeuristicLab.Core.Views;
-using HeuristicLab.MainForm;
-using HeuristicLab.PluginInfrastructure;
-using HeuristicLab.Problems.DataAnalysis;
-
-namespace HeuristicLab.DataPreprocessing.Views {
-  [View("CheckedTransformationList View")]
-  [Content(typeof(ICheckedItemList<ITransformation>), false)]
-  public partial class CheckedTransformationListView : CheckedItemListView<ITransformation> {
-    public CheckedTransformationListView() {
-      InitializeComponent();
-      itemsGroupBox.Text = "Transformations";
-    }
-
-    protected override ITransformation CreateItem() {
-      if (typeSelectorDialog == null) {
-        typeSelectorDialog = new TypeSelectorDialog();
-        typeSelectorDialog.Caption = "Select Transformation";
-        typeSelectorDialog.TypeSelector.Caption = "Available Transformations";
-        typeSelectorDialog.TypeSelector.Configure(typeof(ITransformation), showNotInstantiableTypes: true, showGenericTypes: false, typeCondition: CanInstanciateTransformation);
-      }
-
-      if (typeSelectorDialog.ShowDialog(this) == DialogResult.OK) {
-        try {
-          // TODO: Avoid accessing parent view
-          var transformationView = (TransformationView)Parent;
-          var columnNames = transformationView.Content.PreprocessingData.VariableNames;
-
-          return (ITransformation)typeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType(new[] { columnNames });
-        } catch (Exception ex) {
-          ErrorHandling.ShowErrorDialog(this, ex);
-        }
-      }
-      return null;
-    }
-
-    private bool CanInstanciateTransformation(Type type) {
-      foreach (ConstructorInfo ctor in type.GetConstructors(BindingFlags.Public | BindingFlags.Instance)) {
-        ParameterInfo[] parameters = ctor.GetParameters();
-        if (parameters.Length == 1 && parameters[0].ParameterType == typeof(IEnumerable<string>)) return true;
-      }
-      return false;
-    }
-  }
-}
Index: HeuristicLab.DataPreprocessing.Views/3.4/CheckedTransformationListView.Designer.cs
===================================================================
--- HeuristicLab.DataPreprocessing.Views/3.4/CheckedTransformationListView.Designer.cs	(revision 15884)
+++ HeuristicLab.DataPreprocessing.Views/3.4/CheckedTransformationListView.Designer.cs	(nonexistent)
@@ -1,53 +0,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-namespace HeuristicLab.DataPreprocessing.Views {
-  partial class CheckedTransformationListView {
-    /// <summary> 
-    /// Required designer variable.
-    /// </summary>
-    private System.ComponentModel.IContainer components = null;
-
-    /// <summary> 
-    /// Clean up any resources being used.
-    /// </summary>
-    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
-    protected override void Dispose(bool disposing) {
-      if (disposing && (components != null)) {
-        components.Dispose();
-      }
-      base.Dispose(disposing);
-    }
-
-    #region Component Designer generated code
-
-    /// <summary> 
-    /// Required method for Designer support - do not modify 
-    /// the contents of this method with the code editor.
-    /// </summary>
-    private void InitializeComponent() {
-      components = new System.ComponentModel.Container();
-      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-    }
-
-    #endregion
-  }
-}
Index: HeuristicLab.DataPreprocessing.Views/3.4/HeuristicLab.DataPreprocessing.Views-3.4.csproj
===================================================================
--- HeuristicLab.DataPreprocessing.Views/3.4/HeuristicLab.DataPreprocessing.Views-3.4.csproj	(revision 15884)
+++ HeuristicLab.DataPreprocessing.Views/3.4/HeuristicLab.DataPreprocessing.Views-3.4.csproj	(working copy)
@@ -112,11 +112,11 @@
     <Compile Include="CheckedFilterCollectionView.Designer.cs">
       <DependentUpon>CheckedFilterCollectionView.cs</DependentUpon>
     </Compile>
-    <Compile Include="CheckedTransformationListView.cs">
+    <Compile Include="TransformationListView.cs">
       <SubType>UserControl</SubType>
     </Compile>
-    <Compile Include="CheckedTransformationListView.Designer.cs">
-      <DependentUpon>CheckedTransformationListView.cs</DependentUpon>
+    <Compile Include="TransformationListView.Designer.cs">
+      <DependentUpon>TransformationListView.cs</DependentUpon>
     </Compile>
     <Compile Include="ComparisonFilterView.cs">
       <SubType>UserControl</SubType>
Index: HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingCheckedVariablesView.cs
===================================================================
--- HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingCheckedVariablesView.cs	(revision 15884)
+++ HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingCheckedVariablesView.cs	(working copy)
@@ -41,6 +41,12 @@
 
     protected PreprocessingCheckedVariablesView() {
       InitializeComponent();
+
+      // TODO: fix auto-size of columns
+      //for (int i = 0; i < variablesListView.Columns.Count; i++) {
+      //  variablesListView.Columns[i].Width = -1;
+      //  variablesListView.Columns[i].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
+      //}
     }
 
     protected bool IsVariableChecked(string name) {
Index: HeuristicLab.DataPreprocessing.Views/3.4/TransformationListView.cs
===================================================================
--- HeuristicLab.DataPreprocessing.Views/3.4/TransformationListView.cs	(nonexistent)
+++ HeuristicLab.DataPreprocessing.Views/3.4/TransformationListView.cs	(working copy)
@@ -0,0 +1,114 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Collections;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+  [View("TransformationList View")]
+  [Content(typeof(IItemList<PreprocessingTransformation>), false)]
+  public partial class TransformationListView : ItemListView<PreprocessingTransformation> {
+
+    internal IFilteredPreprocessingData PreprocessingData { get; set; }
+
+    public TransformationListView() {
+      InitializeComponent();
+      itemsGroupBox.Text = "Transformations";
+    }
+
+    protected override PreprocessingTransformation CreateItem() {
+      var variableNames = PreprocessingData.VariableNames.Select(x => new StringValue(x))
+        .Concat(Content.Select(x => new StringValue(x.TransformedVariable))).Distinct();
+
+      var newTransformation = new PreprocessingTransformation(variableNames);
+      newTransformation.TransformedVariableParameter.ValidValues.Add(new StringValue("<New Variable>"));
+      return newTransformation;
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+
+      if (Content == null) return;
+
+      int i = 0;
+      foreach (ListViewItem item in ItemsListView.Items) {
+        var transformation = PreprocessingData.Transformations[i];
+
+        item.ForeColor = transformation.IsApplied ? Color.Black : Color.Gray;
+        i++;
+      }
+      UpdateButtonsState();
+    }
+
+    protected override void Content_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<PreprocessingTransformation>> e) {
+      base.Content_ItemsAdded(sender, e);
+
+      foreach (var transformation in e.Items) {
+        UpdateListViewItemsColor(transformation.Value);
+      }
+    }
+
+    protected override void RegisterItemEvents(PreprocessingTransformation item) {
+      base.RegisterItemEvents(item);
+      item.PropertyChanged += Item_PropertyChanged;
+    }
+    protected override void DeregisterItemEvents(PreprocessingTransformation item) {
+      item.PropertyChanged -= Item_PropertyChanged;
+      base.DeregisterItemEvents(item);
+    }
+
+    private void Item_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) {
+      if (sender is PreprocessingTransformation transformation)
+        UpdateListViewItemsColor(transformation);
+    }
+
+    protected override void itemsListView_SelectedIndexChanged(object sender, EventArgs e) {
+      base.itemsListView_SelectedIndexChanged(sender, e);
+
+      UpdateButtonsState();
+    }
+
+    private void UpdateListViewItemsColor(PreprocessingTransformation transformation) {
+      foreach (ListViewItem item in itemListViewItemMapping[transformation]) {
+        item.ForeColor = transformation.IsApplied ? Color.Black : Color.Gray;
+      }
+    }
+
+    private void UpdateButtonsState() {
+      if (itemsListView.SelectedItems.Count != 1) return;
+      int selectedIndex = itemsListView.SelectedIndices[0];
+
+      // TODO: do not move/remove already applied transformations or disallow of movement generally?
+      if (Content[selectedIndex].IsApplied) {
+        moveUpButton.Enabled = selectedIndex > 0 && Content[selectedIndex - 1].IsApplied;
+        moveDownButton.Enabled = false;
+        removeButton.Enabled = false;
+      }
+    }
+  }
+}
Index: HeuristicLab.DataPreprocessing.Views/3.4/TransformationListView.Designer.cs
===================================================================
--- HeuristicLab.DataPreprocessing.Views/3.4/TransformationListView.Designer.cs	(nonexistent)
+++ HeuristicLab.DataPreprocessing.Views/3.4/TransformationListView.Designer.cs	(working copy)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.DataPreprocessing.Views {
+  partial class TransformationListView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+    }
+
+    #endregion
+  }
+}
Index: HeuristicLab.DataPreprocessing.Views/3.4/TransformationView.cs
===================================================================
--- HeuristicLab.DataPreprocessing.Views/3.4/TransformationView.cs	(revision 15884)
+++ HeuristicLab.DataPreprocessing.Views/3.4/TransformationView.cs	(working copy)
@@ -20,11 +20,10 @@
 #endregion
 
 using System;
-using System.Linq;
+using System.Collections.Generic;
 using System.Windows.Forms;
 using HeuristicLab.MainForm;
 using HeuristicLab.MainForm.WindowsForms;
-using HeuristicLab.Problems.DataAnalysis;
 
 namespace HeuristicLab.DataPreprocessing.Views {
   [View("Transformation View")]
@@ -43,8 +42,10 @@
       base.OnContentChanged();
       if (Content == null) {
         transformationListView.Content = null;
+        transformationListView.PreprocessingData = null;
       } else {
-        transformationListView.Content = Content.CheckedTransformationList;
+        transformationListView.Content = Content.TransformationList;
+        transformationListView.PreprocessingData = Content.PreprocessingData;
         CheckFilters();
       }
     }
@@ -74,24 +75,13 @@
     }
 
     private void applyButton_Click(object sender, EventArgs e) {
-      var transformations = Content.CheckedTransformationList.CheckedItems.Select(x => x.Value);
+      bool success = Content.ApplyTransformations(out IEnumerable<string> errorMessages);
 
-      if (transformations.Any(x => ((Transformation)x).ColumnParameter.Value == null)) {
-        MessageBox.Show(this, "Parameter \"Column\" of a selected Transformation is not set.", "Applying Transformations...", MessageBoxButtons.OK, MessageBoxIcon.Warning);
-        return;
-      }
-
-      var transformator = new PreprocessingTransformator(Content.PreprocessingData);
-      bool preserve = preserveColumnsCheckbox.CheckState == CheckState.Checked;
-      string errorMsg;
-      bool success = transformator.ApplyTransformations(transformations, preserve, out errorMsg);
       if (success) {
-        Content.CheckedTransformationList.Clear();
+        //Content.TransformationList.Clear();
         MessageBox.Show(this, "Transformations applied.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
       } else {
-        MessageBox.Show(this,
-          "Error in Transformation.\nValue is copied when transformion of cell failed.\n" + errorMsg,
-          "Transformation failed", MessageBoxButtons.OK, MessageBoxIcon.Warning);
+        MessageBox.Show(this, string.Join(Environment.NewLine, errorMessages), "Transformation failed", MessageBoxButtons.OK, MessageBoxIcon.Warning);
       }
     }
   }
Index: HeuristicLab.DataPreprocessing.Views/3.4/TransformationView.Designer.cs
===================================================================
--- HeuristicLab.DataPreprocessing.Views/3.4/TransformationView.Designer.cs	(revision 15884)
+++ HeuristicLab.DataPreprocessing.Views/3.4/TransformationView.Designer.cs	(working copy)
@@ -45,9 +45,8 @@
     /// </summary>
     private void InitializeComponent() {
       this.applyButton = new System.Windows.Forms.Button();
-      this.preserveColumnsCheckbox = new System.Windows.Forms.CheckBox();
       this.lblFilterNotice = new System.Windows.Forms.Label();
-      this.transformationListView = new HeuristicLab.DataPreprocessing.Views.CheckedTransformationListView();
+      this.transformationListView = new HeuristicLab.DataPreprocessing.Views.TransformationListView();
       this.SuspendLayout();
       // 
       // applyButton
@@ -61,17 +60,6 @@
       this.applyButton.UseVisualStyleBackColor = true;
       this.applyButton.Click += new System.EventHandler(this.applyButton_Click);
       // 
-      // preserveColumnsCheckbox
-      // 
-      this.preserveColumnsCheckbox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
-      this.preserveColumnsCheckbox.AutoSize = true;
-      this.preserveColumnsCheckbox.Location = new System.Drawing.Point(337, 492);
-      this.preserveColumnsCheckbox.Name = "preserveColumnsCheckbox";
-      this.preserveColumnsCheckbox.Size = new System.Drawing.Size(147, 17);
-      this.preserveColumnsCheckbox.TabIndex = 2;
-      this.preserveColumnsCheckbox.Text = "Preserve original Columns";
-      this.preserveColumnsCheckbox.UseVisualStyleBackColor = true;
-      // 
       // lblFilterNotice
       // 
       this.lblFilterNotice.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
@@ -85,8 +73,8 @@
       // 
       // transformationListView
       // 
-      this.transformationListView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
-            | System.Windows.Forms.AnchorStyles.Left)
+      this.transformationListView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
             | System.Windows.Forms.AnchorStyles.Right)));
       this.transformationListView.Caption = "Transformations";
       this.transformationListView.Content = null;
@@ -101,7 +89,6 @@
       this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
       this.Controls.Add(this.lblFilterNotice);
-      this.Controls.Add(this.preserveColumnsCheckbox);
       this.Controls.Add(this.applyButton);
       this.Controls.Add(this.transformationListView);
       this.Name = "TransformationView";
@@ -112,9 +99,8 @@
     }
 
     #endregion
-    private CheckedTransformationListView transformationListView;
+    private TransformationListView transformationListView;
     private System.Windows.Forms.Button applyButton;
-    private System.Windows.Forms.CheckBox preserveColumnsCheckbox;
     private System.Windows.Forms.Label lblFilterNotice;
   }
 }
Index: HeuristicLab.DataPreprocessing/3.4
===================================================================
--- HeuristicLab.DataPreprocessing/3.4	(revision 15884)
+++ HeuristicLab.DataPreprocessing/3.4	(working copy)

Property changes on: HeuristicLab.DataPreprocessing/3.4
___________________________________________________________________
Modified: svn:mergeinfo
## -0,0 +0,1 ##
   Merged /branches/2906_Transformations/HeuristicLab.DataPreprocessing/3.4:r15826-15885
Index: HeuristicLab.DataPreprocessing/3.4/Content/TransformationContent.cs
===================================================================
--- HeuristicLab.DataPreprocessing/3.4/Content/TransformationContent.cs	(revision 15884)
+++ HeuristicLab.DataPreprocessing/3.4/Content/TransformationContent.cs	(working copy)
@@ -19,7 +19,9 @@
  */
 #endregion
 
+using System.Collections.Generic;
 using System.Drawing;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
@@ -26,6 +28,7 @@
 using HeuristicLab.Problems.DataAnalysis;
 
 namespace HeuristicLab.DataPreprocessing {
+
   [Item("Transformation", "Represents the transformation grid.")]
   [StorableClass]
   public class TransformationContent : PreprocessingContent, IViewShortcut {
@@ -34,17 +37,17 @@
     }
 
     [Storable]
-    public ICheckedItemList<ITransformation> CheckedTransformationList { get; private set; }
+    public IItemList<PreprocessingTransformation> TransformationList { get; private set; }
 
     #region Constructor, Cloning & Persistence
     public TransformationContent(IFilteredPreprocessingData preprocessingData)
       : base(preprocessingData) {
-      CheckedTransformationList = new CheckedItemList<ITransformation>();
+      TransformationList = new ItemList<PreprocessingTransformation>();
     }
 
     public TransformationContent(TransformationContent original, Cloner cloner)
       : base(original, cloner) {
-      CheckedTransformationList = cloner.Clone(original.CheckedTransformationList);
+      TransformationList = cloner.Clone(original.TransformationList);
     }
     public override IDeepCloneable Clone(Cloner cloner) {
       return new TransformationContent(this, cloner);
@@ -54,5 +57,42 @@
     protected TransformationContent(bool deserializing)
       : base(deserializing) { }
     #endregion
+
+    public bool ApplyTransformations(out IEnumerable<string> errorMessages) {
+      bool success = true;
+      var errors = new List<string>();
+      errorMessages = errors;
+
+      foreach (var transformation in TransformationList.Where(x => !x.IsApplied)) {
+        var sourceVariable = transformation.OriginalVariable;
+        var targetVariable = transformation.TransformedVariable ?? sourceVariable + " Transformed";
+        var sourceIdx = PreprocessingData.GetColumnIndex(sourceVariable);
+
+        if (transformation.Transformation is ITransformation<double> trans && PreprocessingData.VariableHasType<double>(sourceIdx)) {
+          if (!PreprocessingData.VariableNames.Contains(targetVariable))
+            PreprocessingData.InsertColumn<double>(targetVariable, PreprocessingData.Columns);
+          var targetIdx = PreprocessingData.GetColumnIndex(targetVariable);
+
+          if (!PreprocessingData.VariableHasType<double>(targetIdx)) { success = false; errors.Add("Target column is not double."); continue; }
+
+          var sourceData = PreprocessingData.GetValues<double>(sourceIdx);
+          if (!trans.Check(sourceData, out string msg)) { success = false; errors.Add(msg); continue; }
+
+          trans.Configure(sourceData);
+          var transformedData = trans.Apply(sourceData).ToList();
+
+          PreprocessingData.SetValues(targetIdx, transformedData);
+
+          PreprocessingData.Transformations.Add(transformation);
+          transformation.IsApplied = true;
+          // TODO: remove unused valid values in constrainedParameters
+        } else {
+          success = false;
+          errors.Add("Transformation datatype is not supported.");
+        }
+      }
+
+      return success;
+    }
   }
 }
Index: HeuristicLab.DataPreprocessing/3.4/Data/FilteredPreprocessingData.cs
===================================================================
--- HeuristicLab.DataPreprocessing/3.4/Data/FilteredPreprocessingData.cs	(revision 15884)
+++ HeuristicLab.DataPreprocessing/3.4/Data/FilteredPreprocessingData.cs	(working copy)
@@ -203,7 +203,7 @@
     #endregion
 
     #region Transformations
-    public IList<ITransformation> Transformations {
+    public IList<PreprocessingTransformation> Transformations {
       get { return originalData.Transformations; }
     }
     #endregion
Index: HeuristicLab.DataPreprocessing/3.4/Data/IPreprocessingData.cs
===================================================================
--- HeuristicLab.DataPreprocessing/3.4/Data/IPreprocessingData.cs	(revision 15884)
+++ HeuristicLab.DataPreprocessing/3.4/Data/IPreprocessingData.cs	(working copy)
@@ -77,7 +77,7 @@
     #endregion
 
     #region Transformations
-    IList<ITransformation> Transformations { get; }
+    IList<PreprocessingTransformation> Transformations { get; }
     #endregion
 
     #region Validation
Index: HeuristicLab.DataPreprocessing/3.4/Data/PreprocessingData.cs
===================================================================
--- HeuristicLab.DataPreprocessing/3.4/Data/PreprocessingData.cs	(revision 15884)
+++ HeuristicLab.DataPreprocessing/3.4/Data/PreprocessingData.cs	(working copy)
@@ -46,7 +46,7 @@
       : base() {
       Name = "Preprocessing Data";
 
-      Transformations = new List<ITransformation>();
+      Transformations = new List<PreprocessingTransformation>();
       selection = new Dictionary<int, IList<int>>();
 
       Import(problemData);
@@ -60,7 +60,7 @@
       variableNames = new List<string>(original.variableNames);
       TrainingPartition = (IntRange)original.TrainingPartition.Clone(cloner);
       TestPartition = (IntRange)original.TestPartition.Clone(cloner);
-      Transformations = new List<ITransformation>(original.Transformations.Select(cloner.Clone));
+      Transformations = new List<PreprocessingTransformation>(original.Transformations.Select(cloner.Clone));
 
       InputVariables = new List<string>(original.InputVariables);
       TargetVariable = original.TargetVariable;
@@ -349,7 +349,7 @@
 
     #region Transformations
     [Storable]
-    public IList<ITransformation> Transformations { get; protected set; }
+    public IList<PreprocessingTransformation> Transformations { get; protected set; }
     #endregion
 
     #region Validation
@@ -413,6 +413,18 @@
         ++columnIndex;
       }
 
+      foreach (var trans in problemData.Transformations) {
+        var newTrans = new PreprocessingTransformation(variableNames.Select(x => new StringValue(x))) {
+          OriginalVariable = trans.OriginalVariable,
+          TransformedVariable = trans.TransformedVariable,
+          IsApplied = true
+        };
+        var cloned = (ITransformation)trans.Transformation.Clone();
+        newTrans.TransformationParameter.ValidValues.Add(cloned);
+        newTrans.Transformation = cloned;
+        Transformations.Add(newTrans);
+      }
+
       TrainingPartition = new IntRange(problemData.TrainingPartition.Start, problemData.TrainingPartition.End);
       TestPartition = new IntRange(problemData.TestPartition.Start, problemData.TestPartition.End);
     }
@@ -458,7 +470,7 @@
 
       public IntRange TrainingPartition { get; set; }
       public IntRange TestPartition { get; set; }
-      public IList<ITransformation> Transformations { get; set; }
+      public IList<PreprocessingTransformation> Transformations { get; set; }
       public DataPreprocessingChangedEventType ChangedType { get; set; }
 
       public int ChangedColumn { get; set; }
@@ -486,7 +498,7 @@
         VariableNames = new List<string>(variableNames),
         TrainingPartition = new IntRange(TrainingPartition.Start, TrainingPartition.End),
         TestPartition = new IntRange(TestPartition.Start, TestPartition.End),
-        Transformations = new List<ITransformation>(Transformations),
+        Transformations = new List<PreprocessingTransformation>(Transformations),
         ChangedType = changedType,
         ChangedColumn = column,
         ChangedRow = row
@@ -681,7 +693,7 @@
       T a;
       l = 0;
       ir = n - 1;
-      for (;;) {
+      for (; ; ) {
         if (ir <= l + 1) {
           // Active partition contains 1 or 2 elements.
           if (ir == l + 1 && arr[ir].CompareTo(arr[l]) < 0) {
@@ -706,7 +718,7 @@
           i = l + 1; // Initialize pointers for partitioning.
           j = ir;
           a = arr[l + 1]; // Partitioning element.
-          for (;;) { // Beginning of innermost loop.
+          for (; ; ) { // Beginning of innermost loop.
             do i++; while (arr[i].CompareTo(a) < 0); // Scan up to find element > a.
             do j--; while (arr[j].CompareTo(a) > 0); // Scan down to find element < a.
             if (j < i) break; // Pointers crossed. Partitioning complete.
Index: HeuristicLab.DataPreprocessing/3.4/Data/PreprocessingTransformation.cs
===================================================================
--- HeuristicLab.DataPreprocessing/3.4/Data/PreprocessingTransformation.cs	(nonexistent)
+++ HeuristicLab.DataPreprocessing/3.4/Data/PreprocessingTransformation.cs	(working copy)
@@ -0,0 +1,157 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.DataPreprocessing {
+  [Item("Preprocessing Transformation", "")]
+  [StorableClass]
+  public class PreprocessingTransformation : ParameterizedNamedItem, INotifyPropertyChanged {
+    #region Parameters
+    public IConstrainedValueParameter<StringValue> OriginalVariableParameter {
+      get { return (IConstrainedValueParameter<StringValue>)Parameters["Original Variable"]; }
+    }
+
+    public IConstrainedValueParameter<StringValue> TransformedVariableParameter {
+      get { return (IConstrainedValueParameter<StringValue>)Parameters["Transformed Variable"]; }
+    }
+
+    public IConstrainedValueParameter<ITransformation> TransformationParameter {
+      get { return (IConstrainedValueParameter<ITransformation>)Parameters["Transformation"]; }
+    }
+    #endregion
+
+    #region Properties
+    public string OriginalVariable {
+      get { return OriginalVariableParameter.Value.Value; }
+      set { SetConstrainedValue(OriginalVariableParameter, value); }
+    }
+
+    public string TransformedVariable {
+      get { return TransformedVariableParameter.Value.Value; }
+      set { SetConstrainedValue(TransformedVariableParameter, value); }
+    }
+
+    public ITransformation Transformation {
+      get { return TransformationParameter.Value; }
+      set { TransformationParameter.Value = value; }
+    }
+
+    public bool IsApplied {
+      get { return isApplied; }
+      set { if (IsApplied != value) { isApplied = value; OnPropertyChanged(); } }
+    }
+    private bool isApplied;
+
+    private static void SetConstrainedValue(IConstrainedValueParameter<StringValue> parameter, string value, [CallerMemberName] string caller = null) {
+      if (value == null) throw new ArgumentNullException(caller);
+      if (value == parameter.Value.Value) return;
+
+      var matchingValue = parameter.ValidValues.SingleOrDefault(v => v.Value == value);
+      if (matchingValue == null) throw new ArgumentException("The provided value is not valid.", caller);
+      parameter.Value = matchingValue;
+    }
+    #endregion
+
+    #region Constructor, Cloning & Persistence
+    public PreprocessingTransformation(IEnumerable<StringValue> variableNames)
+      : base() {
+      var originalVariables = new ItemSet<StringValue>(variableNames.Select(x => x.AsReadOnly()));
+      var transformedVariables = new ItemSet<StringValue>(variableNames.Select(x => x.AsReadOnly()));
+      Parameters.Add(new ConstrainedValueParameter<StringValue>("Original Variable", new ItemSet<StringValue>(originalVariables), originalVariables.FirstOrDefault()));
+      Parameters.Add(new ConstrainedValueParameter<StringValue>("Transformed Variable", new ItemSet<StringValue>(transformedVariables), transformedVariables.FirstOrDefault()));
+      var transformations = new ItemSet<ITransformation>(ApplicationManager.Manager.GetInstances<ITransformation>());
+      Parameters.Add(new ConstrainedValueParameter<ITransformation>("Transformation", transformations, transformations.OfType<IdentityTransformation>().Single()));
+
+      IsApplied = false;
+
+      RegisterEventHandlers();
+    }
+
+    protected PreprocessingTransformation(PreprocessingTransformation original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterEventHandlers();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PreprocessingTransformation(this, cloner);
+    }
+
+    [StorableConstructor]
+    protected PreprocessingTransformation(bool deserializing)
+      : base(deserializing) { }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEventHandlers();
+    }
+    #endregion
+
+    #region Event-Handling
+    private void RegisterEventHandlers() {
+      OriginalVariableParameter.ValueChanged += OriginalVariableParameter_ValueChanged;
+      TransformedVariableParameter.ValueChanged += TransformedVariableParameter_ValueChanged;
+      TransformationParameter.ValueChanged += TransformationParameter_ValueChanged;
+    }
+
+    private void OriginalVariableParameter_ValueChanged(object sender, EventArgs e) {
+      OriginalVariableParameter.Value.ValueChanged += OriginalVariableParameterValue_ValueChanged;
+      OnPropertyChanged(nameof(OriginalVariable));
+    }
+    private void OriginalVariableParameterValue_ValueChanged(object sender, EventArgs e) {
+      OnPropertyChanged(nameof(OriginalVariable));
+    }
+
+    private void TransformedVariableParameter_ValueChanged(object sender, EventArgs e) {
+      TransformedVariableParameter.Value.ValueChanged += TransformedVariableParameterValue_ValueChanged;
+      OnPropertyChanged(nameof(TransformedVariable));
+    }
+    private void TransformedVariableParameterValue_ValueChanged(object sender, EventArgs e) {
+      OnPropertyChanged(nameof(TransformedVariable));
+    }
+
+    private void TransformationParameter_ValueChanged(object sender, EventArgs e) {
+      OnPropertyChanged(nameof(Transformation));
+    }
+    #endregion
+
+    public override string ToString() {
+      return $"{Transformation} ({OriginalVariable} -> {TransformedVariable})";
+    }
+
+    public event PropertyChangedEventHandler PropertyChanged;
+    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) {
+      OnToStringChanged();
+      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+    }
+  }
+}
\ No newline at end of file
Index: HeuristicLab.DataPreprocessing/3.4/HeuristicLab.DataPreprocessing-3.4.csproj
===================================================================
--- HeuristicLab.DataPreprocessing/3.4/HeuristicLab.DataPreprocessing-3.4.csproj	(revision 15884)
+++ HeuristicLab.DataPreprocessing/3.4/HeuristicLab.DataPreprocessing-3.4.csproj	(working copy)
@@ -79,6 +79,7 @@
   <ItemGroup>
     <Compile Include="Content\MultiScatterPlotContent.cs" />
     <Compile Include="Content\PreprocessingContent.cs" />
+    <Compile Include="Data\PreprocessingTransformation.cs" />
     <Compile Include="Content\SingleScatterPlotContent.cs" />
     <Compile Include="Content\ScatterPlotContent.cs" />
     <Compile Include="Content\DataCompletenessChartContent.cs" />
@@ -88,7 +89,6 @@
     <Compile Include="Data\PreprocessingData.cs" />
     <Compile Include="Data\IFilteredPreprocessingData.cs" />
     <Compile Include="Content\CorrelationMatrixContent.cs" />
-    <Compile Include="PreprocessingTransformator.cs" />
     <Compile Include="Data\DataPreprocessingChangedEvent.cs" />
     <Compile Include="Filter\ComparisonFilter.cs" />
     <Compile Include="Filter\IFilter.cs" />
@@ -146,6 +146,11 @@
       <Name>HeuristicLab.Optimization-3.3</Name>
       <Private>False</Private>
     </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Parameters\3.3\HeuristicLab.Parameters-3.3.csproj">
+      <Project>{56f9106a-079f-4c61-92f6-86a84c2d84b7}</Project>
+      <Name>HeuristicLab.Parameters-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Persistence\3.3\HeuristicLab.Persistence-3.3.csproj">
       <Project>{102BC7D3-0EF9-439C-8F6D-96FF0FDB8E1B}</Project>
       <Name>HeuristicLab.Persistence-3.3</Name>
Index: HeuristicLab.DataPreprocessing/3.4/Plugin.cs.frame
===================================================================
--- HeuristicLab.DataPreprocessing/3.4/Plugin.cs.frame	(revision 15884)
+++ HeuristicLab.DataPreprocessing/3.4/Plugin.cs.frame	(working copy)
@@ -34,6 +34,7 @@
   [PluginDependency("HeuristicLab.Collections", "3.3")]
   [PluginDependency("HeuristicLab.Data","3.3")]
   [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
   [PluginDependency("HeuristicLab.Persistence", "3.3")]
   [PluginDependency("HeuristicLab.Problems.DataAnalysis","3.4")]
   [PluginDependency("HeuristicLab.Random", "3.3")]
Index: HeuristicLab.DataPreprocessing/3.4/PreprocessingTransformator.cs
===================================================================
--- HeuristicLab.DataPreprocessing/3.4/PreprocessingTransformator.cs	(revision 15884)
+++ HeuristicLab.DataPreprocessing/3.4/PreprocessingTransformator.cs	(nonexistent)
@@ -1,176 +0,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using HeuristicLab.Data;
-using HeuristicLab.Problems.DataAnalysis;
-
-namespace HeuristicLab.DataPreprocessing {
-  public class PreprocessingTransformator {
-    private readonly IPreprocessingData preprocessingData;
-
-    private readonly IDictionary<string, IList<double>> originalColumns;
-
-    private readonly IDictionary<string, string> renamedColumns;
-
-    public PreprocessingTransformator(IPreprocessingData preprocessingData) {
-      this.preprocessingData = preprocessingData;
-      originalColumns = new Dictionary<string, IList<double>>();
-      renamedColumns = new Dictionary<string, string>();
-    }
-
-    public bool ApplyTransformations(IEnumerable<ITransformation> transformations, bool preserveColumns, out string errorMsg) {
-      bool success = false;
-      errorMsg = string.Empty;
-      preprocessingData.BeginTransaction(DataPreprocessingChangedEventType.Transformation);
-
-      try {
-        var doubleTransformations = transformations.OfType<Transformation<double>>().ToList();
-
-        if (preserveColumns) {
-          PreserveColumns(doubleTransformations);
-        }
-
-        // all transformations are performed inplace. no creation of new columns for transformations
-        ApplyDoubleTranformationsInplace(doubleTransformations, preserveColumns, out success, out errorMsg);
-
-        if (preserveColumns) {
-          RenameTransformedColumsAndRestorePreservedColumns(doubleTransformations);
-          RenameTransformationColumnParameter(doubleTransformations);
-          InsertCopyColumTransformations(doubleTransformations);
-
-          originalColumns.Clear();
-          renamedColumns.Clear();
-        }
-        // only accept changes if everything was successful
-        if (!success) {
-          preprocessingData.Undo();
-        }
-      } catch (Exception e) {
-        preprocessingData.Undo();
-        if (string.IsNullOrEmpty(errorMsg)) errorMsg = e.Message;
-      } finally {
-        preprocessingData.EndTransaction();
-      }
-
-      return success;
-    }
-
-    private void PreserveColumns(IEnumerable<Transformation<double>> transformations) {
-      foreach (var transformation in transformations) {
-        if (!originalColumns.ContainsKey(transformation.Column)) {
-          int colIndex = preprocessingData.GetColumnIndex(transformation.Column);
-          var originalData = preprocessingData.GetValues<double>(colIndex);
-          originalColumns.Add(transformation.Column, originalData);
-        }
-      }
-    }
-
-    private void ApplyDoubleTranformationsInplace(IEnumerable<Transformation<double>> transformations, bool preserveColumns, out bool success, out string errorMsg) {
-      errorMsg = string.Empty;
-      success = true;
-      foreach (var transformation in transformations) {
-        int colIndex = preprocessingData.GetColumnIndex(transformation.Column);
-
-        var originalData = preprocessingData.GetValues<double>(colIndex);
-
-        string errorMsgPart;
-        bool successPart;
-        var transformedData = ApplyDoubleTransformation(transformation, originalData, out successPart, out errorMsgPart);
-        errorMsg += errorMsgPart + Environment.NewLine;
-
-        if (!successPart) success = false;
-        preprocessingData.SetValues(colIndex, transformedData.ToList());
-        preprocessingData.Transformations.Add(transformation);
-      }
-    }
-
-    private IEnumerable<double> ApplyDoubleTransformation(Transformation<double> transformation, IList<double> data, out bool success, out string errorMsg) {
-      success = transformation.Check(data, out errorMsg);
-      // don't apply when the check fails
-      if (success)
-        return transformation.ConfigureAndApply(data);
-      else
-        return data;
-    }
-
-    private void RenameTransformationColumnParameter(List<Transformation<double>> transformations) {
-      foreach (var transformation in transformations) {
-        var newColumnName = new StringValue(renamedColumns[transformation.Column]);
-        transformation.ColumnParameter.ValidValues.Add(newColumnName);
-        transformation.ColumnParameter.Value = newColumnName;
-      }
-    }
-
-    private void InsertCopyColumTransformations(IList<Transformation<double>> transformations) {
-      foreach (var renaming in renamedColumns) {
-        string oldName = renaming.Key;
-        string newName = renaming.Value;
-
-        var copyTransformation = CreateCopyTransformation(oldName, newName);
-        preprocessingData.Transformations.Insert(0, copyTransformation);
-      }
-    }
-
-    private CopyColumnTransformation CreateCopyTransformation(string oldColumn, string newColumn) {
-      var newColumName = new StringValue(newColumn);
-
-      var copyTransformation = new CopyColumnTransformation();
-      copyTransformation.ColumnParameter.ValidValues.Add(newColumName);
-      copyTransformation.ColumnParameter.Value = newColumName;
-
-      copyTransformation.CopiedColumnNameParameter.Value.Value = oldColumn;
-      return copyTransformation;
-    }
-
-    private void RenameTransformedColumsAndRestorePreservedColumns(IList<Transformation<double>> transformations) {
-      foreach (var column in originalColumns) {
-        int originalColumnIndex = preprocessingData.GetColumnIndex(column.Key);
-        int newColumnIndex = originalColumnIndex + 1;
-        string newColumnName = GetTransformatedColumnName(transformations, column.Key);
-        // save renaming mapping
-        renamedColumns[column.Key] = newColumnName;
-        // create new transformed column
-        preprocessingData.InsertColumn<double>(newColumnName, newColumnIndex);
-        preprocessingData.SetValues(newColumnIndex, preprocessingData.GetValues<double>(originalColumnIndex));
-        // restore old values
-        preprocessingData.SetValues(originalColumnIndex, column.Value);
-      }
-    }
-
-    private string GetTransformatedColumnName(IList<Transformation<double>> transformations, string column) {
-      string suffix = GetTransformationSuffix(transformations, column);
-      return column + "_" + suffix;
-    }
-
-    private string GetTransformationSuffix(IList<Transformation<double>> transformations, string column) {
-      var suffixes = transformations.Where(t => t.Column == column).Select(t => t.ShortName);
-      var builder = new StringBuilder();
-      foreach (var suffix in suffixes) {
-        builder.Append(suffix);
-      }
-      return builder.ToString();
-    }
-  }
-}
Index: HeuristicLab.DataPreprocessing/3.4/ProblemDataCreator.cs
===================================================================
--- HeuristicLab.DataPreprocessing/3.4/ProblemDataCreator.cs	(revision 15884)
+++ HeuristicLab.DataPreprocessing/3.4/ProblemDataCreator.cs	(working copy)
@@ -22,7 +22,6 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
-using HeuristicLab.Common;
 using HeuristicLab.Problems.DataAnalysis;
 
 namespace HeuristicLab.DataPreprocessing {
@@ -33,7 +32,7 @@
       get { return context.Data.ExportToDataset(); }
     }
 
-    private IList<ITransformation> Transformations {
+    private IList<PreprocessingTransformation> Transformations {
       get { return context.Data.Transformations; }
     }
 
@@ -45,7 +44,6 @@
       if (context.Data.Rows == 0 || context.Data.Columns == 0) return null;
 
       IDataAnalysisProblemData problemData;
-
       if (oldProblemData is TimeSeriesPrognosisProblemData) {
         problemData = CreateTimeSeriesPrognosisData((TimeSeriesPrognosisProblemData)oldProblemData);
       } else if (oldProblemData is RegressionProblemData) {
@@ -58,13 +56,8 @@
         throw new NotImplementedException("The type of the DataAnalysisProblemData is not supported.");
       }
 
-      SetTrainingAndTestPartition(problemData);
-      // set the input variables to the correct checked state
-      var inputVariables = oldProblemData.InputVariables.ToDictionary(x => x.Value, x => x);
-      foreach (var variable in problemData.InputVariables) {
-        bool isChecked = inputVariables.ContainsKey(variable.Value) && oldProblemData.InputVariables.ItemChecked(inputVariables[variable.Value]);
-        problemData.InputVariables.SetItemCheckedState(variable, isChecked);
-      }
+      SetTrainingAndTestPartition(problemData, context.Data);
+      SetAllowedInputVariables(problemData, oldProblemData);
 
       return problemData;
     }
@@ -73,8 +66,7 @@
       var targetVariable = oldProblemData.TargetVariable;
       if (!context.Data.VariableNames.Contains(targetVariable))
         targetVariable = context.Data.VariableNames.First();
-      var inputVariables = GetDoubleInputVariables(targetVariable);
-      var newProblemData = new TimeSeriesPrognosisProblemData(ExportedDataset, inputVariables, targetVariable, Transformations) {
+      var newProblemData = new TimeSeriesPrognosisProblemData(ExportedDataset, Enumerable.Empty<string>(), targetVariable, CreateDataAnalysisTransformation()) {
         TrainingHorizon = oldProblemData.TrainingHorizon,
         TestHorizon = oldProblemData.TestHorizon
       };
@@ -82,11 +74,10 @@
     }
 
     private IDataAnalysisProblemData CreateRegressionData(RegressionProblemData oldProblemData) {
-      var targetVariable = oldProblemData.TargetVariable;
+      var targetVariable = DataAnalysisTransformation.GetStrictTransitiveVariables(oldProblemData.TargetVariable, CreateDataAnalysisTransformation(), false).Last();
       if (!context.Data.VariableNames.Contains(targetVariable))
         targetVariable = context.Data.VariableNames.First();
-      var inputVariables = GetDoubleInputVariables(targetVariable);
-      var newProblemData = new RegressionProblemData(ExportedDataset, inputVariables, targetVariable, Transformations);
+      var newProblemData = new RegressionProblemData(ExportedDataset, Enumerable.Empty<string>(), targetVariable, CreateDataAnalysisTransformation());
       return newProblemData;
     }
 
@@ -94,8 +85,7 @@
       var targetVariable = oldProblemData.TargetVariable;
       if (!context.Data.VariableNames.Contains(targetVariable))
         targetVariable = context.Data.VariableNames.First();
-      var inputVariables = GetDoubleInputVariables(targetVariable);
-      var newProblemData = new ClassificationProblemData(ExportedDataset, inputVariables, targetVariable, Transformations) {
+      var newProblemData = new ClassificationProblemData(ExportedDataset, Enumerable.Empty<string>(), targetVariable, CreateDataAnalysisTransformation()) {
         PositiveClass = oldProblemData.PositiveClass
       };
       return newProblemData;
@@ -102,12 +92,10 @@
     }
 
     private IDataAnalysisProblemData CreateClusteringData(ClusteringProblemData oldProblemData) {
-      return new ClusteringProblemData(ExportedDataset, GetDoubleInputVariables(String.Empty), Transformations);
+      return new ClusteringProblemData(ExportedDataset, Enumerable.Empty<string>(), CreateDataAnalysisTransformation());
     }
 
-    private void SetTrainingAndTestPartition(IDataAnalysisProblemData problemData) {
-      var ppData = context.Data;
-
+    private static void SetTrainingAndTestPartition(IDataAnalysisProblemData problemData, IPreprocessingData ppData) {
       problemData.TrainingPartition.Start = ppData.TrainingPartition.Start;
       problemData.TrainingPartition.End = ppData.TrainingPartition.End;
       problemData.TestPartition.Start = ppData.TestPartition.Start;
@@ -114,22 +102,24 @@
       problemData.TestPartition.End = ppData.TestPartition.End;
     }
 
-    private IEnumerable<string> GetDoubleInputVariables(string targetVariable) {
-      var variableNames = new List<string>();
-      for (int i = 0; i < context.Data.Columns; ++i) {
-        var variableName = context.Data.GetVariableName(i);
-        if (context.Data.VariableHasType<double>(i)
-          && variableName != targetVariable
-          && IsNotConstantInputVariable(context.Data.GetValues<double>(i))) {
+    private static void SetAllowedInputVariables(IDataAnalysisProblemData problemData, IDataAnalysisProblemData oldProblemData) {
+      // original inputs + extended(transitive) inputs
+      var inputs = DataAnalysisTransformation.ExtendVariables(oldProblemData.AllowedInputVariables, problemData.Transformations).ToList();
+      foreach (var input in problemData.InputVariables) {
+        problemData.InputVariables.SetItemCheckedState(input, inputs.Contains(input.Value));
+      }
 
-          variableNames.Add(variableName);
-        }
+      // new variables that were not created via transformations
+      var originalAndVirtualVariables = DataAnalysisTransformation.ExtendVariables(oldProblemData.Dataset.VariableNames, problemData.Transformations);
+      var newVariables = problemData.Dataset.VariableNames.Except(originalAndVirtualVariables).ToList();
+      foreach (var input in problemData.InputVariables) {
+        if (newVariables.Contains(input.Value))
+          problemData.InputVariables.SetItemCheckedState(input, true);
       }
-      return variableNames;
     }
 
-    private bool IsNotConstantInputVariable(IList<double> list) {
-      return context.Data.TrainingPartition.End - context.Data.TrainingPartition.Start > 1 || list.Range() > 0;
+    private IEnumerable<IDataAnalysisTransformation> CreateDataAnalysisTransformation() {
+      return Transformations.Select(x => new DataAnalysisTransformation(x.OriginalVariable, x.TransformedVariable, (ITransformation)x.Transformation.Clone()));
     }
   }
 }
Index: HeuristicLab.Problems.DataAnalysis
===================================================================
--- HeuristicLab.Problems.DataAnalysis	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis	(working copy)

Property changes on: HeuristicLab.Problems.DataAnalysis
___________________________________________________________________
Modified: svn:mergeinfo
## -0,0 +0,1 ##
   Merged /branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis:r15826-15885
Index: HeuristicLab.Problems.DataAnalysis.Symbolic
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Symbolic	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis.Symbolic	(working copy)

Property changes on: HeuristicLab.Problems.DataAnalysis.Symbolic
___________________________________________________________________
Modified: svn:mergeinfo
## -0,0 +0,1 ##
   Merged /branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis.Symbolic:r15863-15885
Index: HeuristicLab.Problems.DataAnalysis.Symbolic.Regression
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Symbolic.Regression	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis.Symbolic.Regression	(working copy)

Property changes on: HeuristicLab.Problems.DataAnalysis.Symbolic.Regression
___________________________________________________________________
Modified: svn:mergeinfo
## -0,0 +0,1 ##
   Merged /branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression:r15863-15885
Index: HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views	(working copy)

Property changes on: HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views
___________________________________________________________________
Modified: svn:mergeinfo
## -0,0 +0,1 ##
   Merged /branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views:r15863-15885
Index: HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionView.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionView.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionView.cs	(working copy)
@@ -44,8 +44,6 @@
       base.SetEnabledStateOfControls();
       btnSimplify.Enabled = Content != null && !Locked && Content.ProblemData.TrainingIndices.Any(); // simplification is only possible if there are trainings samples
       exportButton.Enabled = Content != null && !Locked;
-      transformModelButton.Visible = Content != null && Content.ProblemData.Transformations.Any();
-      transformModelButton.Enabled = Content != null && !Locked;
     }
 
     private void btn_SimplifyModel_Click(object sender, EventArgs e) {
@@ -67,18 +65,5 @@
         }
       }
     }
-
-    private void transformModelButton_Click(object sender, EventArgs e) {
-      var mapper = new TransformationToSymbolicTreeMapper();
-      var transformator = new SymbolicExpressionTreeBacktransformator(mapper);
-
-      var transformations = Content.ProblemData.Transformations;
-      var targetVar = Content.ProblemData.TargetVariable;
-
-      var transformedModel = (ISymbolicRegressionModel)transformator.Backtransform(Content.Model, transformations, targetVar);
-      var transformedSolution = new SymbolicRegressionSolution(transformedModel, (IRegressionProblemData)Content.ProblemData.Clone());
-
-      MainFormManager.MainForm.ShowContent(transformedSolution);
-    }
   }
 }
Index: HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionView.Designer.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionView.Designer.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionView.Designer.cs	(working copy)
@@ -47,7 +47,6 @@
       this.exportButton = new System.Windows.Forms.Button();
       this.exportFileDialog = new System.Windows.Forms.SaveFileDialog();
       this.btnSimplify = new System.Windows.Forms.Button();
-      this.transformModelButton = new System.Windows.Forms.Button();
       ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
       this.splitContainer.Panel1.SuspendLayout();
       this.splitContainer.Panel2.SuspendLayout();
@@ -60,7 +59,6 @@
       // 
       this.flowLayoutPanel.Controls.Add(this.btnSimplify);
       this.flowLayoutPanel.Controls.Add(this.exportButton);
-      this.flowLayoutPanel.Controls.Add(this.transformModelButton);
       // 
       // btnSimplify
       // 
@@ -90,20 +88,6 @@
       this.exportButton.Click += new System.EventHandler(this.exportButton_Click);
       this.toolTip.SetToolTip(this.exportButton, "Exports the symbolic regression solution to Excel.");
       // 
-      // transformModelButton
-      // 
-      this.transformModelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)));
-      this.transformModelButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Event;
-      this.transformModelButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
-      this.transformModelButton.Name = "transformModelButton";
-      this.transformModelButton.Size = new System.Drawing.Size(135, 24);
-      this.transformModelButton.TabIndex = 9;
-      this.transformModelButton.Text = "Backtransform Model";
-      this.transformModelButton.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
-      this.transformModelButton.UseVisualStyleBackColor = true;
-      this.transformModelButton.Click += new System.EventHandler(this.transformModelButton_Click);
-      this.toolTip.SetToolTip(this.transformModelButton, "Backtransform model based on the stored transformations.");
-      // 
       // SymbolicRegressionSolutionView
       // 
       this.Name = "SymbolicRegressionSolutionView";
@@ -122,6 +106,5 @@
     protected System.Windows.Forms.SaveFileDialog exportFileDialog;
     protected System.Windows.Forms.Button exportButton;
     protected System.Windows.Forms.Button btnSimplify;
-    protected System.Windows.Forms.Button transformModelButton;
   }
 }
Index: HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4	(working copy)

Property changes on: HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4
___________________________________________________________________
Modified: svn:mergeinfo
## -0,0 +0,1 ##
   Merged /branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4:r15863-15885
Index: HeuristicLab.Problems.DataAnalysis.Symbolic.Views
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Symbolic.Views	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis.Symbolic.Views	(working copy)

Property changes on: HeuristicLab.Problems.DataAnalysis.Symbolic.Views
___________________________________________________________________
Modified: svn:mergeinfo
## -0,0 +0,1 ##
   Merged /branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis.Symbolic.Views:r15863-15885
Index: HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs	(working copy)
@@ -486,7 +486,7 @@
     }
 
     private void FormatStartSymbol(StringBuilder strBuilder) {
-      strBuilder.Append(targetVariable ?? "target_" + (targetCount++));
+      strBuilder.Append(EscapeLatexString(targetVariable) ?? "target_{" + (targetCount++) + "}");
       if (containsTimeSeriesSymbol)
         strBuilder.Append("(t)");
       strBuilder.Append(" & = ");
Index: HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(working copy)
@@ -252,8 +252,6 @@
     <Compile Include="Symbols\VariableCondition.cs" />
     <Compile Include="Symbols\VariableConditionTreeNode.cs" />
     <Compile Include="Symbols\VariableTreeNode.cs" />
-    <Compile Include="Transformations\SymbolicExpressionTreeBacktransformator.cs" />
-    <Compile Include="Transformations\TransformationToSymbolicTreeMapper.cs" />
     <Compile Include="TreeMatching\SymbolicExpressionTreeBottomUpSimilarityCalculator.cs" />
     <Compile Include="TreeMatching\SymbolicExpressionTreeCanonicalSorter.cs" />
     <Compile Include="TreeMatching\SymbolicExpressionTreeEqualityComparer.cs" />
Index: HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Transformations/SymbolicExpressionTreeBacktransformator.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Transformations/SymbolicExpressionTreeBacktransformator.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Transformations/SymbolicExpressionTreeBacktransformator.cs	(nonexistent)
@@ -1,97 +0,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-
-namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
-  public class SymbolicExpressionTreeBacktransformator : IModelBacktransformator {
-    private readonly ITransformationMapper<ISymbolicExpressionTreeNode> transformationMapper;
-
-    public SymbolicExpressionTreeBacktransformator(ITransformationMapper<ISymbolicExpressionTreeNode> transformationMapper) {
-      this.transformationMapper = transformationMapper;
-    }
-
-    public ISymbolicDataAnalysisModel Backtransform(ISymbolicDataAnalysisModel model, IEnumerable<ITransformation> transformations, string targetVariable) {
-      var symbolicModel = (ISymbolicDataAnalysisModel)model.Clone();
-
-      foreach (var transformation in transformations.Reverse()) {
-        ApplyBacktransformation(transformation, symbolicModel.SymbolicExpressionTree, targetVariable);
-      }
-
-      return symbolicModel;
-    }
-
-    private void ApplyBacktransformation(ITransformation transformation, ISymbolicExpressionTree symbolicExpressionTree, string targetVariable) {
-      if (transformation.Column != targetVariable) {
-        var variableNodes = symbolicExpressionTree.IterateNodesBreadth()
-          .OfType<VariableTreeNode>()
-          .Where(n => n.VariableName == transformation.Column);
-        ApplyRegularBacktransformation(transformation, variableNodes);
-      } else if (!(transformation is CopyColumnTransformation)) {
-        ApplyInverseBacktransformation(transformation, symbolicExpressionTree);
-      }
-    }
-
-    private void ApplyRegularBacktransformation(ITransformation transformation, IEnumerable<VariableTreeNode> variableNodes) {
-      foreach (var variableNode in variableNodes) {
-        // generate new subtrees because same subtree cannot be added more than once
-        var transformationTree = transformationMapper.GenerateModel(transformation);
-        SwapVariableWithTree(variableNode, transformationTree);
-      }
-    }
-
-    private void ApplyInverseBacktransformation(ITransformation transformation, ISymbolicExpressionTree symbolicExpressionTree) {
-      var startSymbol = symbolicExpressionTree.Root.GetSubtree(0);
-      var modelTree = startSymbol.GetSubtree(0);
-      startSymbol.RemoveSubtree(0);
-
-      var transformationTree = transformationMapper.GenerateInverseModel(transformation);
-      var variableNode = transformationTree.IterateNodesBreadth()
-        .OfType<VariableTreeNode>()
-        .Single(n => n.VariableName == transformation.Column);
-
-      SwapVariableWithTree(variableNode, modelTree);
-
-      startSymbol.AddSubtree(transformationTree);
-    }
-
-    private void SwapVariableWithTree(VariableTreeNode variableNode, ISymbolicExpressionTreeNode treeNode) {
-      var parent = variableNode.Parent;
-      int index = parent.IndexOfSubtree(variableNode);
-      parent.RemoveSubtree(index);
-
-      if (!variableNode.Weight.IsAlmost(1.0))
-        treeNode = CreateNodeFromWeight(treeNode, variableNode);
-
-      parent.InsertSubtree(index, treeNode);
-    }
-
-    private ISymbolicExpressionTreeNode CreateNodeFromWeight(ISymbolicExpressionTreeNode transformationTree, VariableTreeNode variableNode) {
-      var multiplicationNode = new SymbolicExpressionTreeNode(new Multiplication());
-      multiplicationNode.AddSubtree(new ConstantTreeNode(new Constant()) { Value = variableNode.Weight });
-      multiplicationNode.AddSubtree(transformationTree);
-      return multiplicationNode;
-    }
-  }
-}
Index: HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Transformations/TransformationToSymbolicTreeMapper.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Transformations/TransformationToSymbolicTreeMapper.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Transformations/TransformationToSymbolicTreeMapper.cs	(nonexistent)
@@ -1,294 +0,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-
-namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
-  public class TransformationToSymbolicTreeMapper : ITransformationMapper<ISymbolicExpressionTreeNode> {
-    private ITransformation transformation;
-    private string column;
-
-    #region ITransformationMapper<ISymbolicExpressionTree> Members
-
-    public ISymbolicExpressionTreeNode GenerateModel(ITransformation transformation) {
-      InitComponents(transformation);
-
-      if (transformation is LinearTransformation) {
-        return GenerateModelForLinearTransformation();
-      } else if (transformation is ExponentialTransformation) {
-        return GenerateModelForExponentialTransformation();
-      } else if (transformation is LogarithmicTransformation) {
-        return GenerateModelForLogarithmicTransformation();
-      } else if (transformation is PowerTransformation) {
-        return GenerateModelForPowerTransformation();
-      } else if (transformation is ReciprocalTransformation) {
-        return GenerateModelForReciprocalTransformation();
-      } else if (transformation is ShiftStandardDistributionTransformation) {
-        return GenerateModelForShiftStandardDistributionTransformation();
-      } else if (transformation is CopyColumnTransformation) {
-        return GenerateTreeNodeForCopyColumnTransformation();
-      }
-      throw new NotImplementedException();
-    }
-
-    public ISymbolicExpressionTreeNode GenerateInverseModel(ITransformation transformation) {
-      InitComponents(transformation);
-
-      if (transformation is LinearTransformation) {
-        return GenerateInverseModelForLinearTransformation();
-      } else if (transformation is ExponentialTransformation) {
-        return GenerateInverseModelForExponentialTransformation();
-      } else if (transformation is LogarithmicTransformation) {
-        return GenerateInverseModelForLogarithmicTransformation();
-      } else if (transformation is PowerTransformation) {
-        return GenerateInverseModelForPowerTransformation();
-      } else if (transformation is ReciprocalTransformation) {
-        return GenerateInverseModelForReciprocalTransformation();
-      } else if (transformation is ShiftStandardDistributionTransformation) {
-        GenerateInverseModelForShiftStandardDistributionTransformation();
-      } else if (transformation is CopyColumnTransformation) {
-        return GenerateTreeNodeForCopyColumnTransformation();
-      }
-
-      throw new NotImplementedException();
-    }
-
-    #endregion
-
-    // helper
-
-    private ISymbolicExpressionTreeNode GenerateModelForLinearTransformation() {
-      var linearTransformation = (LinearTransformation)transformation;
-      var kValue = linearTransformation.Multiplier;
-      var dValue = linearTransformation.Addend;
-
-      // k * x
-      var multiplicationNode = new Multiplication().CreateTreeNode();
-      var kNode = CreateConstantTreeNode("k", kValue);
-      var xNode = CreateVariableTreeNode(column, "x");
-      multiplicationNode.AddSubtree(kNode);
-      multiplicationNode.AddSubtree(xNode);
-
-      // ( k * x ) + d
-      var additionNode = new Addition().CreateTreeNode();
-      var dNode = CreateConstantTreeNode("d", dValue);
-      additionNode.AddSubtree(multiplicationNode);
-      additionNode.AddSubtree(dNode);
-
-      return additionNode;
-    }
-
-    private ISymbolicExpressionTreeNode GenerateInverseModelForLinearTransformation() {
-      var linearTransformation = (LinearTransformation)transformation;
-      var kValue = linearTransformation.Multiplier;
-      var dValue = linearTransformation.Addend;
-
-      // x - d
-      var substractionNode = new Subtraction().CreateTreeNode();
-      var dNode = CreateConstantTreeNode("d", dValue);
-      var xNode = CreateVariableTreeNode(column, "x");
-      substractionNode.AddSubtree(xNode);
-      substractionNode.AddSubtree(dNode);
-
-      // ( x - d ) / k
-      var divisionNode = new Division().CreateTreeNode();
-      var kNode = CreateConstantTreeNode("k", kValue);
-      divisionNode.AddSubtree(substractionNode);
-      divisionNode.AddSubtree(kNode);
-
-      return divisionNode;
-    }
-
-
-    private ISymbolicExpressionTreeNode GenerateModelForExponentialTransformation() {
-      var exponentialTransformation = (ExponentialTransformation)transformation;
-      var bValue = exponentialTransformation.Base;
-
-      return GenTreePow_b_x(bValue);
-    }
-
-    private ISymbolicExpressionTreeNode GenerateInverseModelForExponentialTransformation() {
-      var exponentialTransformation = (ExponentialTransformation)transformation;
-      var bValue = exponentialTransformation.Base;
-
-      return GenTreeLog_x_b(bValue);
-    }
-
-
-    private ISymbolicExpressionTreeNode GenerateModelForLogarithmicTransformation() {
-      var logarithmicTransformation = (LogarithmicTransformation)transformation;
-      var bValue = logarithmicTransformation.Base;
-
-      return GenTreeLog_x_b(bValue);
-    }
-
-    private ISymbolicExpressionTreeNode GenerateInverseModelForLogarithmicTransformation() {
-      var logarithmicTransformation = (LogarithmicTransformation)transformation;
-      var bValue = logarithmicTransformation.Base;
-
-      return GenTreePow_b_x(bValue);
-    }
-
-
-    private ISymbolicExpressionTreeNode GenerateModelForPowerTransformation() {
-      var powerTransformation = (PowerTransformation)transformation;
-      var expValue = powerTransformation.Exponent;
-
-      // x ^ exp
-      var powerNode = new Power().CreateTreeNode();
-      var xNode = CreateVariableTreeNode(column, "x");
-      var expNode = CreateConstantTreeNode("exp", expValue);
-      powerNode.AddSubtree(xNode);
-      powerNode.AddSubtree(expNode);
-
-      return powerNode;
-    }
-
-    private ISymbolicExpressionTreeNode GenerateInverseModelForPowerTransformation() {
-      var powerTransformation = (PowerTransformation)transformation;
-      var expValue = powerTransformation.Exponent;
-
-      // rt(x, b)
-      var rootNode = new Root().CreateTreeNode();
-      var xNode = CreateVariableTreeNode(column, "x");
-      var bNode = CreateConstantTreeNode("b", expValue);
-      rootNode.AddSubtree(xNode);
-      rootNode.AddSubtree(bNode);
-
-      return rootNode;
-    }
-
-
-    private ISymbolicExpressionTreeNode GenerateModelForReciprocalTransformation() {
-      return GenTreeDiv_1_x();
-    }
-
-    private ISymbolicExpressionTreeNode GenerateInverseModelForReciprocalTransformation() {
-      return GenTreeDiv_1_x();
-    }
-
-
-    private ISymbolicExpressionTreeNode GenerateModelForShiftStandardDistributionTransformation() {
-      var shiftStandardDistributionTransformation = (ShiftStandardDistributionTransformation)transformation;
-      var m_orgValue = shiftStandardDistributionTransformation.OriginalMean;
-      var s_orgValue = shiftStandardDistributionTransformation.OriginalStandardDeviation;
-      var m_tarValue = shiftStandardDistributionTransformation.Mean;
-      var s_tarValue = shiftStandardDistributionTransformation.StandardDeviation;
-
-      return GenTreeShiftStdDist(column, m_orgValue, s_orgValue, m_tarValue, s_tarValue);
-    }
-
-    private ISymbolicExpressionTreeNode GenerateInverseModelForShiftStandardDistributionTransformation() {
-      var shiftStandardDistributionTransformation = (ShiftStandardDistributionTransformation)transformation;
-      var m_orgValue = shiftStandardDistributionTransformation.OriginalMean;
-      var s_orgValue = shiftStandardDistributionTransformation.OriginalStandardDeviation;
-      var m_tarValue = shiftStandardDistributionTransformation.Mean;
-      var s_tarValue = shiftStandardDistributionTransformation.StandardDeviation;
-
-      return GenTreeShiftStdDist(column, m_tarValue, s_tarValue, m_orgValue, s_orgValue);
-    }
-
-    private ISymbolicExpressionTreeNode GenerateTreeNodeForCopyColumnTransformation() {
-      var copyColumnTransformation = (CopyColumnTransformation)transformation;
-      var copiedColumnName = copyColumnTransformation.CopiedColumnName;
-
-      return CreateVariableTreeNode(copiedColumnName, copiedColumnName + "(original)");
-    }
-
-    // helper's helper:
-
-    private ISymbolicExpressionTreeNode GenTreeLog_x_b(double b) {
-      // log(x, b)
-      var logNode = new Logarithm().CreateTreeNode();
-      var bNode = CreateConstantTreeNode("b", b);
-      var xNode = CreateVariableTreeNode(column, "x");
-      logNode.AddSubtree(xNode);
-      logNode.AddSubtree(bNode);
-
-      return logNode;
-    }
-
-    private ISymbolicExpressionTreeNode GenTreePow_b_x(double b) {
-      // b ^ x
-      var powerNode = new Power().CreateTreeNode();
-      var bNode = CreateConstantTreeNode("b", b);
-      var xNode = CreateVariableTreeNode(column, "x");
-      powerNode.AddSubtree(bNode);
-      powerNode.AddSubtree(xNode);
-
-      return powerNode;
-    }
-
-    private ISymbolicExpressionTreeNode GenTreeDiv_1_x() {
-      // 1 / x
-      var divNode = new Division().CreateTreeNode();
-      var oneNode = CreateConstantTreeNode("1", 1.0);
-      var xNode = CreateVariableTreeNode(column, "x");
-      divNode.AddSubtree(oneNode);
-      divNode.AddSubtree(xNode);
-
-      return divNode;
-    }
-
-    private ISymbolicExpressionTreeNode GenTreeShiftStdDist(string variable, double m_org, double s_org, double m_tar, double s_tar) {
-      // x - m_org
-      var substractionNode = new Subtraction().CreateTreeNode();
-      var xNode = CreateVariableTreeNode(variable, "x");
-      var m_orgNode = CreateConstantTreeNode("m_org", m_org);
-      substractionNode.AddSubtree(xNode);
-      substractionNode.AddSubtree(m_orgNode);
-
-      // (x - m_org) / s_org
-      var divisionNode = new Division().CreateTreeNode();
-      var s_orgNode = CreateConstantTreeNode("s_org", s_org);
-      divisionNode.AddSubtree(substractionNode);
-      divisionNode.AddSubtree(s_orgNode);
-
-      // ((x - m_org) / s_org ) * s_tar
-      var multiplicationNode = new Multiplication().CreateTreeNode();
-      var s_tarNode = CreateConstantTreeNode("s_tar", s_tar);
-      multiplicationNode.AddSubtree(divisionNode);
-      multiplicationNode.AddSubtree(s_tarNode);
-
-      // ((x - m_org) / s_org ) * s_tar + m_tar
-      var additionNode = new Addition().CreateTreeNode();
-      var m_tarNode = CreateConstantTreeNode("m_tar", m_tar);
-      additionNode.AddSubtree(multiplicationNode);
-      additionNode.AddSubtree(m_tarNode);
-
-      return additionNode;
-    }
-
-    private ConstantTreeNode CreateConstantTreeNode(string description, double value) {
-      return new ConstantTreeNode(new Constant()) { Value = value };
-    }
-
-    private VariableTreeNode CreateVariableTreeNode(string name, string description) {
-      return new VariableTreeNode(new Variable(name, description)) { VariableName = name, Weight = 1.0 };
-    }
-
-    private void InitComponents(ITransformation transformation) {
-      this.transformation = transformation;
-      column = transformation.Column;
-    }
-  }
-}
Index: HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Transformations/SymbolicExpressionTreeBacktransformator.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Transformations/SymbolicExpressionTreeBacktransformator.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Transformations/SymbolicExpressionTreeBacktransformator.cs	(nonexistent)
@@ -1,97 +0,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-
-namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
-  public class SymbolicExpressionTreeBacktransformator : IModelBacktransformator {
-    private readonly ITransformationMapper<ISymbolicExpressionTreeNode> transformationMapper;
-
-    public SymbolicExpressionTreeBacktransformator(ITransformationMapper<ISymbolicExpressionTreeNode> transformationMapper) {
-      this.transformationMapper = transformationMapper;
-    }
-
-    public ISymbolicDataAnalysisModel Backtransform(ISymbolicDataAnalysisModel model, IEnumerable<ITransformation> transformations, string targetVariable) {
-      var symbolicModel = (ISymbolicDataAnalysisModel)model.Clone();
-
-      foreach (var transformation in transformations.Reverse()) {
-        ApplyBacktransformation(transformation, symbolicModel.SymbolicExpressionTree, targetVariable);
-      }
-
-      return symbolicModel;
-    }
-
-    private void ApplyBacktransformation(ITransformation transformation, ISymbolicExpressionTree symbolicExpressionTree, string targetVariable) {
-      if (transformation.Column != targetVariable) {
-        var variableNodes = symbolicExpressionTree.IterateNodesBreadth()
-          .OfType<VariableTreeNode>()
-          .Where(n => n.VariableName == transformation.Column);
-        ApplyRegularBacktransformation(transformation, variableNodes);
-      } else if (!(transformation is CopyColumnTransformation)) {
-        ApplyInverseBacktransformation(transformation, symbolicExpressionTree);
-      }
-    }
-
-    private void ApplyRegularBacktransformation(ITransformation transformation, IEnumerable<VariableTreeNode> variableNodes) {
-      foreach (var variableNode in variableNodes) {
-        // generate new subtrees because same subtree cannot be added more than once
-        var transformationTree = transformationMapper.GenerateModel(transformation);
-        SwapVariableWithTree(variableNode, transformationTree);
-      }
-    }
-
-    private void ApplyInverseBacktransformation(ITransformation transformation, ISymbolicExpressionTree symbolicExpressionTree) {
-      var startSymbol = symbolicExpressionTree.Root.GetSubtree(0);
-      var modelTree = startSymbol.GetSubtree(0);
-      startSymbol.RemoveSubtree(0);
-
-      var transformationTree = transformationMapper.GenerateInverseModel(transformation);
-      var variableNode = transformationTree.IterateNodesBreadth()
-        .OfType<VariableTreeNode>()
-        .Single(n => n.VariableName == transformation.Column);
-
-      SwapVariableWithTree(variableNode, modelTree);
-
-      startSymbol.AddSubtree(transformationTree);
-    }
-
-    private void SwapVariableWithTree(VariableTreeNode variableNode, ISymbolicExpressionTreeNode treeNode) {
-      var parent = variableNode.Parent;
-      int index = parent.IndexOfSubtree(variableNode);
-      parent.RemoveSubtree(index);
-
-      if (!variableNode.Weight.IsAlmost(1.0))
-        treeNode = CreateNodeFromWeight(treeNode, variableNode);
-
-      parent.InsertSubtree(index, treeNode);
-    }
-
-    private ISymbolicExpressionTreeNode CreateNodeFromWeight(ISymbolicExpressionTreeNode transformationTree, VariableTreeNode variableNode) {
-      var multiplicationNode = new SymbolicExpressionTreeNode(new Multiplication());
-      multiplicationNode.AddSubtree(new ConstantTreeNode(new Constant()) { Value = variableNode.Weight });
-      multiplicationNode.AddSubtree(transformationTree);
-      return multiplicationNode;
-    }
-  }
-}
Index: HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Transformations/TransformationToSymbolicTreeMapper.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Transformations/TransformationToSymbolicTreeMapper.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Transformations/TransformationToSymbolicTreeMapper.cs	(nonexistent)
@@ -1,294 +0,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-
-namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
-  public class TransformationToSymbolicTreeMapper : ITransformationMapper<ISymbolicExpressionTreeNode> {
-    private ITransformation transformation;
-    private string column;
-
-    #region ITransformationMapper<ISymbolicExpressionTree> Members
-
-    public ISymbolicExpressionTreeNode GenerateModel(ITransformation transformation) {
-      InitComponents(transformation);
-
-      if (transformation is LinearTransformation) {
-        return GenerateModelForLinearTransformation();
-      } else if (transformation is ExponentialTransformation) {
-        return GenerateModelForExponentialTransformation();
-      } else if (transformation is LogarithmicTransformation) {
-        return GenerateModelForLogarithmicTransformation();
-      } else if (transformation is PowerTransformation) {
-        return GenerateModelForPowerTransformation();
-      } else if (transformation is ReciprocalTransformation) {
-        return GenerateModelForReciprocalTransformation();
-      } else if (transformation is ShiftStandardDistributionTransformation) {
-        return GenerateModelForShiftStandardDistributionTransformation();
-      } else if (transformation is CopyColumnTransformation) {
-        return GenerateTreeNodeForCopyColumnTransformation();
-      }
-      throw new NotImplementedException();
-    }
-
-    public ISymbolicExpressionTreeNode GenerateInverseModel(ITransformation transformation) {
-      InitComponents(transformation);
-
-      if (transformation is LinearTransformation) {
-        return GenerateInverseModelForLinearTransformation();
-      } else if (transformation is ExponentialTransformation) {
-        return GenerateInverseModelForExponentialTransformation();
-      } else if (transformation is LogarithmicTransformation) {
-        return GenerateInverseModelForLogarithmicTransformation();
-      } else if (transformation is PowerTransformation) {
-        return GenerateInverseModelForPowerTransformation();
-      } else if (transformation is ReciprocalTransformation) {
-        return GenerateInverseModelForReciprocalTransformation();
-      } else if (transformation is ShiftStandardDistributionTransformation) {
-        GenerateInverseModelForShiftStandardDistributionTransformation();
-      } else if (transformation is CopyColumnTransformation) {
-        return GenerateTreeNodeForCopyColumnTransformation();
-      }
-
-      throw new NotImplementedException();
-    }
-
-    #endregion
-
-    // helper
-
-    private ISymbolicExpressionTreeNode GenerateModelForLinearTransformation() {
-      var linearTransformation = (LinearTransformation)transformation;
-      var kValue = linearTransformation.Multiplier;
-      var dValue = linearTransformation.Addend;
-
-      // k * x
-      var multiplicationNode = new Multiplication().CreateTreeNode();
-      var kNode = CreateConstantTreeNode("k", kValue);
-      var xNode = CreateVariableTreeNode(column, "x");
-      multiplicationNode.AddSubtree(kNode);
-      multiplicationNode.AddSubtree(xNode);
-
-      // ( k * x ) + d
-      var additionNode = new Addition().CreateTreeNode();
-      var dNode = CreateConstantTreeNode("d", dValue);
-      additionNode.AddSubtree(multiplicationNode);
-      additionNode.AddSubtree(dNode);
-
-      return additionNode;
-    }
-
-    private ISymbolicExpressionTreeNode GenerateInverseModelForLinearTransformation() {
-      var linearTransformation = (LinearTransformation)transformation;
-      var kValue = linearTransformation.Multiplier;
-      var dValue = linearTransformation.Addend;
-
-      // x - d
-      var substractionNode = new Subtraction().CreateTreeNode();
-      var dNode = CreateConstantTreeNode("d", dValue);
-      var xNode = CreateVariableTreeNode(column, "x");
-      substractionNode.AddSubtree(xNode);
-      substractionNode.AddSubtree(dNode);
-
-      // ( x - d ) / k
-      var divisionNode = new Division().CreateTreeNode();
-      var kNode = CreateConstantTreeNode("k", kValue);
-      divisionNode.AddSubtree(substractionNode);
-      divisionNode.AddSubtree(kNode);
-
-      return divisionNode;
-    }
-
-
-    private ISymbolicExpressionTreeNode GenerateModelForExponentialTransformation() {
-      var exponentialTransformation = (ExponentialTransformation)transformation;
-      var bValue = exponentialTransformation.Base;
-
-      return GenTreePow_b_x(bValue);
-    }
-
-    private ISymbolicExpressionTreeNode GenerateInverseModelForExponentialTransformation() {
-      var exponentialTransformation = (ExponentialTransformation)transformation;
-      var bValue = exponentialTransformation.Base;
-
-      return GenTreeLog_x_b(bValue);
-    }
-
-
-    private ISymbolicExpressionTreeNode GenerateModelForLogarithmicTransformation() {
-      var logarithmicTransformation = (LogarithmicTransformation)transformation;
-      var bValue = logarithmicTransformation.Base;
-
-      return GenTreeLog_x_b(bValue);
-    }
-
-    private ISymbolicExpressionTreeNode GenerateInverseModelForLogarithmicTransformation() {
-      var logarithmicTransformation = (LogarithmicTransformation)transformation;
-      var bValue = logarithmicTransformation.Base;
-
-      return GenTreePow_b_x(bValue);
-    }
-
-
-    private ISymbolicExpressionTreeNode GenerateModelForPowerTransformation() {
-      var powerTransformation = (PowerTransformation)transformation;
-      var expValue = powerTransformation.Exponent;
-
-      // x ^ exp
-      var powerNode = new Power().CreateTreeNode();
-      var xNode = CreateVariableTreeNode(column, "x");
-      var expNode = CreateConstantTreeNode("exp", expValue);
-      powerNode.AddSubtree(xNode);
-      powerNode.AddSubtree(expNode);
-
-      return powerNode;
-    }
-
-    private ISymbolicExpressionTreeNode GenerateInverseModelForPowerTransformation() {
-      var powerTransformation = (PowerTransformation)transformation;
-      var expValue = powerTransformation.Exponent;
-
-      // rt(x, b)
-      var rootNode = new Root().CreateTreeNode();
-      var xNode = CreateVariableTreeNode(column, "x");
-      var bNode = CreateConstantTreeNode("b", expValue);
-      rootNode.AddSubtree(xNode);
-      rootNode.AddSubtree(bNode);
-
-      return rootNode;
-    }
-
-
-    private ISymbolicExpressionTreeNode GenerateModelForReciprocalTransformation() {
-      return GenTreeDiv_1_x();
-    }
-
-    private ISymbolicExpressionTreeNode GenerateInverseModelForReciprocalTransformation() {
-      return GenTreeDiv_1_x();
-    }
-
-
-    private ISymbolicExpressionTreeNode GenerateModelForShiftStandardDistributionTransformation() {
-      var shiftStandardDistributionTransformation = (ShiftStandardDistributionTransformation)transformation;
-      var m_orgValue = shiftStandardDistributionTransformation.OriginalMean;
-      var s_orgValue = shiftStandardDistributionTransformation.OriginalStandardDeviation;
-      var m_tarValue = shiftStandardDistributionTransformation.Mean;
-      var s_tarValue = shiftStandardDistributionTransformation.StandardDeviation;
-
-      return GenTreeShiftStdDist(column, m_orgValue, s_orgValue, m_tarValue, s_tarValue);
-    }
-
-    private ISymbolicExpressionTreeNode GenerateInverseModelForShiftStandardDistributionTransformation() {
-      var shiftStandardDistributionTransformation = (ShiftStandardDistributionTransformation)transformation;
-      var m_orgValue = shiftStandardDistributionTransformation.OriginalMean;
-      var s_orgValue = shiftStandardDistributionTransformation.OriginalStandardDeviation;
-      var m_tarValue = shiftStandardDistributionTransformation.Mean;
-      var s_tarValue = shiftStandardDistributionTransformation.StandardDeviation;
-
-      return GenTreeShiftStdDist(column, m_tarValue, s_tarValue, m_orgValue, s_orgValue);
-    }
-
-    private ISymbolicExpressionTreeNode GenerateTreeNodeForCopyColumnTransformation() {
-      var copyColumnTransformation = (CopyColumnTransformation)transformation;
-      var copiedColumnName = copyColumnTransformation.CopiedColumnName;
-
-      return CreateVariableTreeNode(copiedColumnName, copiedColumnName + "(original)");
-    }
-
-    // helper's helper:
-
-    private ISymbolicExpressionTreeNode GenTreeLog_x_b(double b) {
-      // log(x, b)
-      var logNode = new Logarithm().CreateTreeNode();
-      var bNode = CreateConstantTreeNode("b", b);
-      var xNode = CreateVariableTreeNode(column, "x");
-      logNode.AddSubtree(xNode);
-      logNode.AddSubtree(bNode);
-
-      return logNode;
-    }
-
-    private ISymbolicExpressionTreeNode GenTreePow_b_x(double b) {
-      // b ^ x
-      var powerNode = new Power().CreateTreeNode();
-      var bNode = CreateConstantTreeNode("b", b);
-      var xNode = CreateVariableTreeNode(column, "x");
-      powerNode.AddSubtree(bNode);
-      powerNode.AddSubtree(xNode);
-
-      return powerNode;
-    }
-
-    private ISymbolicExpressionTreeNode GenTreeDiv_1_x() {
-      // 1 / x
-      var divNode = new Division().CreateTreeNode();
-      var oneNode = CreateConstantTreeNode("1", 1.0);
-      var xNode = CreateVariableTreeNode(column, "x");
-      divNode.AddSubtree(oneNode);
-      divNode.AddSubtree(xNode);
-
-      return divNode;
-    }
-
-    private ISymbolicExpressionTreeNode GenTreeShiftStdDist(string variable, double m_org, double s_org, double m_tar, double s_tar) {
-      // x - m_org
-      var substractionNode = new Subtraction().CreateTreeNode();
-      var xNode = CreateVariableTreeNode(variable, "x");
-      var m_orgNode = CreateConstantTreeNode("m_org", m_org);
-      substractionNode.AddSubtree(xNode);
-      substractionNode.AddSubtree(m_orgNode);
-
-      // (x - m_org) / s_org
-      var divisionNode = new Division().CreateTreeNode();
-      var s_orgNode = CreateConstantTreeNode("s_org", s_org);
-      divisionNode.AddSubtree(substractionNode);
-      divisionNode.AddSubtree(s_orgNode);
-
-      // ((x - m_org) / s_org ) * s_tar
-      var multiplicationNode = new Multiplication().CreateTreeNode();
-      var s_tarNode = CreateConstantTreeNode("s_tar", s_tar);
-      multiplicationNode.AddSubtree(divisionNode);
-      multiplicationNode.AddSubtree(s_tarNode);
-
-      // ((x - m_org) / s_org ) * s_tar + m_tar
-      var additionNode = new Addition().CreateTreeNode();
-      var m_tarNode = CreateConstantTreeNode("m_tar", m_tar);
-      additionNode.AddSubtree(multiplicationNode);
-      additionNode.AddSubtree(m_tarNode);
-
-      return additionNode;
-    }
-
-    private ConstantTreeNode CreateConstantTreeNode(string description, double value) {
-      return new ConstantTreeNode(new Constant()) { Value = value };
-    }
-
-    private VariableTreeNode CreateVariableTreeNode(string name, string description) {
-      return new VariableTreeNode(new Variable(name, description)) { VariableName = name, Weight = 1.0 };
-    }
-
-    private void InitComponents(ITransformation transformation) {
-      this.transformation = transformation;
-      column = transformation.Column;
-    }
-  }
-}
Index: HeuristicLab.Problems.DataAnalysis.Trading/3.4/ProblemData.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Trading/3.4/ProblemData.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis.Trading/3.4/ProblemData.cs	(working copy)
@@ -1626,8 +1626,8 @@
       : this(defaultDataset, defaultAllowedInputVariables, defaultPriceVariable) {
     }
 
-    public ProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable, IEnumerable<ITransformation> transformations = null)
-      : base(dataset, allowedInputVariables, transformations ?? Enumerable.Empty<ITransformation>()) {
+    public ProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable, IEnumerable<IDataAnalysisTransformation> transformations = null)
+      : base(dataset, allowedInputVariables, transformations ?? Enumerable.Empty<IDataAnalysisTransformation>()) {
       var variables = InputVariables.Select(x => x.AsReadOnly()).ToList();
       Parameters.Add(new ConstrainedValueParameter<StringValue>(PriceChangeVariableParameterName, new ItemSet<StringValue>(variables), variables.First(x => x.Value == targetVariable)));
       Parameters.Add(new FixedValueParameter<DoubleValue>(TransactionCostsParameterName, "The absolute cost of on buy/sell transaction (assumed to be constant and independent of transaction volume)", new DoubleValue(0.0002)));
Index: HeuristicLab.Problems.DataAnalysis.Views
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Views	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis.Views	(working copy)

Property changes on: HeuristicLab.Problems.DataAnalysis.Views
___________________________________________________________________
Modified: svn:mergeinfo
## -0,0 +0,1 ##
   Merged /branches/2906_Transformations/HeuristicLab.Problems.DataAnalysis.Views:r15826-15885
Index: HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisTransformationModelView.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisTransformationModelView.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisTransformationModelView.cs	(working copy)
@@ -0,0 +1,52 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Transformation Model View")]
+  [Content(typeof(DataAnalysisTransformationModel), true)]
+  public partial class DataAnalysisTransformationModelView : ItemView {
+
+    public new DataAnalysisTransformationModel Content {
+      get { return (DataAnalysisTransformationModel)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public DataAnalysisTransformationModelView() {
+      InitializeComponent();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      modelViewHost.Content = Content?.OriginalModel;
+      inputTransformationsViewHost.Content = Content?.InputTransformations;
+      targetTransformationsTabPage.Visible = Content is IRegressionTransformationModel;
+      targetTransformationsViewHost.Content = Content?.TargetTransformations;
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      tabControl.Enabled = Content != null && !Locked;
+    }
+  }
+}
Index: HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisTransformationModelView.Designer.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisTransformationModelView.Designer.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisTransformationModelView.Designer.cs	(working copy)
@@ -0,0 +1,174 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class DataAnalysisTransformationModelView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.trainedModelTabPage = new System.Windows.Forms.TabPage();
+      this.modelViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.tabControl = new System.Windows.Forms.TabControl();
+      this.inputTransformationsTabPage = new System.Windows.Forms.TabPage();
+      this.inputTransformationsViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.targetTransformationsTabPage = new System.Windows.Forms.TabPage();
+      this.targetTransformationsViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.trainedModelTabPage.SuspendLayout();
+      this.tabControl.SuspendLayout();
+      this.inputTransformationsTabPage.SuspendLayout();
+      this.targetTransformationsTabPage.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // trainedModelTabPage
+      // 
+      this.trainedModelTabPage.Controls.Add(this.modelViewHost);
+      this.trainedModelTabPage.Location = new System.Drawing.Point(4, 22);
+      this.trainedModelTabPage.Name = "trainedModelTabPage";
+      this.trainedModelTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.trainedModelTabPage.Size = new System.Drawing.Size(486, 392);
+      this.trainedModelTabPage.TabIndex = 0;
+      this.trainedModelTabPage.Text = "Trained Model";
+      this.trainedModelTabPage.UseVisualStyleBackColor = true;
+      // 
+      // modelViewHost
+      // 
+      this.modelViewHost.Caption = "View";
+      this.modelViewHost.Content = null;
+      this.modelViewHost.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.modelViewHost.Enabled = false;
+      this.modelViewHost.Location = new System.Drawing.Point(3, 3);
+      this.modelViewHost.Name = "modelViewHost";
+      this.modelViewHost.ReadOnly = false;
+      this.modelViewHost.Size = new System.Drawing.Size(480, 386);
+      this.modelViewHost.TabIndex = 0;
+      this.modelViewHost.ViewsLabelVisible = true;
+      this.modelViewHost.ViewType = null;
+      // 
+      // tabControl
+      // 
+      this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.tabControl.Controls.Add(this.trainedModelTabPage);
+      this.tabControl.Controls.Add(this.inputTransformationsTabPage);
+      this.tabControl.Controls.Add(this.targetTransformationsTabPage);
+      this.tabControl.Location = new System.Drawing.Point(3, 3);
+      this.tabControl.Name = "tabControl";
+      this.tabControl.SelectedIndex = 0;
+      this.tabControl.Size = new System.Drawing.Size(494, 418);
+      this.tabControl.TabIndex = 0;
+      // 
+      // inputTransformationsTabPage
+      // 
+      this.inputTransformationsTabPage.Controls.Add(this.inputTransformationsViewHost);
+      this.inputTransformationsTabPage.Location = new System.Drawing.Point(4, 22);
+      this.inputTransformationsTabPage.Name = "inputTransformationsTabPage";
+      this.inputTransformationsTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.inputTransformationsTabPage.Size = new System.Drawing.Size(486, 392);
+      this.inputTransformationsTabPage.TabIndex = 1;
+      this.inputTransformationsTabPage.Text = "Input Transformations";
+      this.inputTransformationsTabPage.UseVisualStyleBackColor = true;
+      // 
+      // inputTransformationsViewHost
+      // 
+      this.inputTransformationsViewHost.Caption = "View";
+      this.inputTransformationsViewHost.Content = null;
+      this.inputTransformationsViewHost.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.inputTransformationsViewHost.Enabled = false;
+      this.inputTransformationsViewHost.Location = new System.Drawing.Point(3, 3);
+      this.inputTransformationsViewHost.Name = "inputTransformationsViewHost";
+      this.inputTransformationsViewHost.ReadOnly = false;
+      this.inputTransformationsViewHost.Size = new System.Drawing.Size(480, 386);
+      this.inputTransformationsViewHost.TabIndex = 1;
+      this.inputTransformationsViewHost.ViewsLabelVisible = false;
+      this.inputTransformationsViewHost.ViewType = null;
+      // 
+      // targetTransformationsTabPage
+      // 
+      this.targetTransformationsTabPage.Controls.Add(this.targetTransformationsViewHost);
+      this.targetTransformationsTabPage.Location = new System.Drawing.Point(4, 22);
+      this.targetTransformationsTabPage.Name = "targetTransformationsTabPage";
+      this.targetTransformationsTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.targetTransformationsTabPage.Size = new System.Drawing.Size(486, 392);
+      this.targetTransformationsTabPage.TabIndex = 2;
+      this.targetTransformationsTabPage.Text = "Target Transformations";
+      this.targetTransformationsTabPage.UseVisualStyleBackColor = true;
+      // 
+      // targetTransformationsViewHost
+      // 
+      this.targetTransformationsViewHost.Caption = "View";
+      this.targetTransformationsViewHost.Content = null;
+      this.targetTransformationsViewHost.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.targetTransformationsViewHost.Enabled = false;
+      this.targetTransformationsViewHost.Location = new System.Drawing.Point(3, 3);
+      this.targetTransformationsViewHost.Name = "targetTransformationsViewHost";
+      this.targetTransformationsViewHost.ReadOnly = false;
+      this.targetTransformationsViewHost.Size = new System.Drawing.Size(480, 386);
+      this.targetTransformationsViewHost.TabIndex = 1;
+      this.targetTransformationsViewHost.ViewsLabelVisible = false;
+      this.targetTransformationsViewHost.ViewType = null;
+      // 
+      // DataAnalysisTransformationModelView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.tabControl);
+      this.Name = "DataAnalysisTransformationModelView";
+      this.Size = new System.Drawing.Size(500, 424);
+      this.trainedModelTabPage.ResumeLayout(false);
+      this.tabControl.ResumeLayout(false);
+      this.inputTransformationsTabPage.ResumeLayout(false);
+      this.targetTransformationsTabPage.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.TabPage trainedModelTabPage;
+    private MainForm.WindowsForms.ViewHost modelViewHost;
+    private System.Windows.Forms.TabControl tabControl;
+    private System.Windows.Forms.TabPage inputTransformationsTabPage;
+    private System.Windows.Forms.TabPage targetTransformationsTabPage;
+    private MainForm.WindowsForms.ViewHost inputTransformationsViewHost;
+    private MainForm.WindowsForms.ViewHost targetTransformationsViewHost;
+  }
+}
Index: HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(working copy)
@@ -337,6 +337,12 @@
     <Compile Include="Regression\RegressionSolutionScatterPlotView.Designer.cs">
       <DependentUpon>RegressionSolutionScatterPlotView.cs</DependentUpon>
     </Compile>
+    <Compile Include="DataAnalysisTransformationModelView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="DataAnalysisTransformationModelView.Designer.cs">
+      <DependentUpon>DataAnalysisTransformationModelView.cs</DependentUpon>
+    </Compile>
     <Compile Include="Solution Views\ClassificationSolutionView.cs">
       <SubType>UserControl</SubType>
     </Compile>
Index: HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.cs	(working copy)
@@ -24,6 +24,7 @@
 using System.Drawing;
 using System.Linq;
 using System.Windows.Forms;
+using HeuristicLab.Common.Resources;
 using HeuristicLab.Core;
 using HeuristicLab.Core.Views;
 using HeuristicLab.MainForm;
@@ -36,9 +37,14 @@
   [View("DataAnalysisSolution View")]
   [Content(typeof(DataAnalysisSolution), false)]
   public partial class DataAnalysisSolutionView : NamedItemCollectionView<IResult> {
+
+    private const string BacktransformButtonText = "Integrate Transformations";
+    private const string ReapplyTransformationsButtonText = "Restore Trained Model";
+
     public DataAnalysisSolutionView() {
       InitializeComponent();
       viewHost.ViewsLabelVisible = false;
+      transformButton.Image = VSImageLibrary.Event;
     }
 
     public new DataAnalysisSolution Content {
@@ -51,6 +57,8 @@
       addButton.Enabled = false;
       removeButton.Enabled = false;
       loadProblemDataButton.Enabled = Content != null && !Locked;
+      transformButton.Enabled = Content != null && !Locked;
+      transformButton.Visible = Content != null && Content.ProblemData.Transformations.Any();
     }
 
     protected override void RegisterContentEvents() {
@@ -80,6 +88,12 @@
             item.Selected = true;
         }
       }
+
+      if (Content == null) return;
+
+      transformButton.Text = Content.Model is IDataAnalysisTransformationModel
+        ? ReapplyTransformationsButtonText
+        : BacktransformButtonText;
     }
 
     protected override IResult CreateItem() {
@@ -146,11 +160,9 @@
         if (!solution.Name.EndsWith(" with loaded problemData"))
           solution.Name += " with loaded problemData";
         MainFormManager.MainForm.ShowContent(solution);
-      }
-      catch (InvalidOperationException invalidOperationException) {
+      } catch (InvalidOperationException invalidOperationException) {
         ErrorHandling.ShowErrorDialog(this, invalidOperationException);
-      }
-      catch (ArgumentException argumentException) {
+      } catch (ArgumentException argumentException) {
         ErrorHandling.ShowErrorDialog(this, argumentException);
       }
     }
@@ -225,6 +237,7 @@
         var param = (IValueParameter)dropData;
         problemData = param.Value as DataAnalysisProblemData;
       }
+
       if (problemData == null) return;
 
       problemData = (IDataAnalysisProblemData)problemData.Clone();
@@ -237,15 +250,17 @@
           Content.Name += " with changed problemData";
         Content.Filename = string.Empty;
         MainFormManager.GetMainForm<HeuristicLab.MainForm.WindowsForms.MainForm>().UpdateTitle();
-      }
-      catch (InvalidOperationException invalidOperationException) {
+      } catch (InvalidOperationException invalidOperationException) {
         ErrorHandling.ShowErrorDialog(this, invalidOperationException);
-      }
-      catch (ArgumentException argumentException) {
+      } catch (ArgumentException argumentException) {
         ErrorHandling.ShowErrorDialog(this, argumentException);
       }
     }
     #endregion
 
+    private void transformButton_Click(object sender, EventArgs e) {
+      var transformedSolution = DataAnalysisTransformation.TransformSolution(Content);
+      MainFormManager.MainForm.ShowContent(transformedSolution);
+    }
   }
-}
+}
\ No newline at end of file
Index: HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.Designer.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.Designer.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.Designer.cs	(working copy)
@@ -46,6 +46,7 @@
     private void InitializeComponent() {
       this.flowLayoutPanel = new System.Windows.Forms.FlowLayoutPanel();
       this.loadProblemDataButton = new System.Windows.Forms.Button();
+      this.transformButton = new System.Windows.Forms.Button();
       this.loadProblemDataFileDialog = new System.Windows.Forms.OpenFileDialog();
       ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
       this.splitContainer.Panel1.SuspendLayout();
@@ -53,6 +54,7 @@
       this.splitContainer.SuspendLayout();
       this.itemsGroupBox.SuspendLayout();
       this.detailsGroupBox.SuspendLayout();
+      this.flowLayoutPanel.SuspendLayout();
       this.SuspendLayout();
       //
       // itemslistView
@@ -76,16 +78,19 @@
       this.itemsGroupBox.Text = "Data Analysis Solution";
       //
       // flowLayoutPanel
-      //
-      this.flowLayoutPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
-      this.flowLayoutPanel.FlowDirection = System.Windows.Forms.FlowDirection.LeftToRight;
+      // 
+      this.flowLayoutPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.flowLayoutPanel.Controls.Add(this.loadProblemDataButton);
+      this.flowLayoutPanel.Controls.Add(this.transformButton);
       this.flowLayoutPanel.Location = new System.Drawing.Point(0, 0);
+      this.flowLayoutPanel.Name = "flowLayoutPanel";
       this.flowLayoutPanel.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
       this.flowLayoutPanel.Size = new System.Drawing.Size(266, 30);
-      this.flowLayoutPanel.Controls.Add(this.loadProblemDataButton);
-      //
+      this.flowLayoutPanel.TabIndex = 1;
+      // 
       // loadProblemDataButton
-      //
+      // 
       this.loadProblemDataButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)));
       this.loadProblemDataButton.AutoSize = true;
       this.loadProblemDataButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Open;
@@ -97,10 +102,21 @@
       this.loadProblemDataButton.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
       this.loadProblemDataButton.UseVisualStyleBackColor = true;
       this.loadProblemDataButton.Click += new System.EventHandler(this.loadProblemDataButton_Click);
-      this.toolTip.SetToolTip(this.loadProblemDataButton, "Creates a new data analysis solution with the same model and the loaded problem data.");
       // 
-      // openFileDialog
+      // transformButton
       // 
+      this.transformButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+      this.transformButton.Location = new System.Drawing.Point(6, 33);
+      this.transformButton.Name = "transformButton";
+      this.transformButton.Size = new System.Drawing.Size(152, 23);
+      this.transformButton.TabIndex = 7;
+      this.transformButton.Text = "Integrate Transformations";
+      this.transformButton.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+      this.transformButton.UseVisualStyleBackColor = true;
+      this.transformButton.Click += new System.EventHandler(this.transformButton_Click);
+      // 
+      // loadProblemDataFileDialog
+      // 
       this.loadProblemDataFileDialog.Filter = "HL files|*.hl";
       this.loadProblemDataFileDialog.Title = "Load new ProblemData or Problem...";
       // 
@@ -114,6 +130,8 @@
       this.splitContainer.ResumeLayout(false);
       this.itemsGroupBox.ResumeLayout(false);
       this.detailsGroupBox.ResumeLayout(false);
+      this.flowLayoutPanel.ResumeLayout(false);
+      this.flowLayoutPanel.PerformLayout();
       this.ResumeLayout(false);
 
     }
@@ -123,6 +141,6 @@
     protected System.Windows.Forms.Button loadProblemDataButton;
     protected System.Windows.Forms.OpenFileDialog loadProblemDataFileDialog;
     protected System.Windows.Forms.FlowLayoutPanel flowLayoutPanel;
-
+    protected System.Windows.Forms.Button transformButton;
   }
 }
Index: HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.cs	(working copy)
@@ -36,6 +36,10 @@
       set { base.Content = value; }
     }
 
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+    }
+
     #region drag and drop
     protected override void itemsListView_DragEnter(object sender, DragEventArgs e) {
       validDragOperation = false;
Index: HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.Designer.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.Designer.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.Designer.cs	(working copy)
@@ -20,6 +20,7 @@
 #endregion
 
 
+
 namespace HeuristicLab.Problems.DataAnalysis.Views {
   partial class RegressionSolutionView {
     /// <summary> 
@@ -45,6 +46,7 @@
     /// the contents of this method with the code editor.
     /// </summary>
     private void InitializeComponent() {
+      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RegressionSolutionView));
       ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
       this.splitContainer.Panel1.SuspendLayout();
       this.splitContainer.Panel2.SuspendLayout();
@@ -52,6 +54,10 @@
       this.itemsGroupBox.SuspendLayout();
       this.detailsGroupBox.SuspendLayout();
       this.SuspendLayout();
+      // 
+      // splitContainer
+      // 
+      // 
       // itemsGroupBox
       // 
       this.itemsGroupBox.Text = "Regression Solution";
@@ -66,7 +72,6 @@
       // 
       // RegressionSolutionView
       // 
-      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
       this.Name = "RegressionSolutionView";
       this.splitContainer.Panel1.ResumeLayout(false);
Index: HeuristicLab.Problems.DataAnalysis/3.4
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4	(working copy)

Property changes on: HeuristicLab.Problems.DataAnalysis/3.4
___________________________________________________________________
Modified: svn:ignore
## -4,3 +4,4 ##
 obj
 *.vs10x
 Plugin.cs
+*.DotSettings
Index: HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs	(working copy)
@@ -140,7 +140,7 @@
       return new Dataset(variableNames, values.ShuffleLists(random));
     }
 
-    protected Dataset(Dataset dataset) : this(dataset.variableNames, dataset.variableValues.Values) { }
+    public Dataset(Dataset dataset) : this(dataset.variableNames, dataset.variableValues.Values) { }
 
     #region Backwards compatible code, remove with 3.5
     private double[,] storableData;
Index: HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(working copy)
@@ -131,6 +131,7 @@
     <Compile Include="Implementation\Classification\ClassificationEnsembleProblemData.cs" />
     <Compile Include="Implementation\Classification\ClassificationSolutionBase.cs" />
     <Compile Include="Implementation\Classification\ClassificationSolutionVariableImpactsCalculator.cs" />
+    <Compile Include="Implementation\Classification\ClassificationTransformationModel.cs" />
     <Compile Include="Implementation\Classification\ConstantClassificationSolution.cs" />
     <Compile Include="Implementation\Classification\DiscriminantFunctionClassificationSolutionBase.cs" />
     <Compile Include="Implementation\Classification\ClassificationModel.cs" />
@@ -137,8 +138,10 @@
     <Compile Include="Implementation\Clustering\ClusteringProblem.cs" />
     <Compile Include="Implementation\Clustering\ClusteringProblemData.cs" />
     <Compile Include="Implementation\Clustering\ClusteringSolution.cs" />
+    <Compile Include="Implementation\Clustering\ClusteringTransformationModel.cs" />
     <Compile Include="Implementation\ConstantModel.cs" />
     <Compile Include="Implementation\DataAnalysisModel.cs" />
+    <Compile Include="Implementation\DataAnalysisTransformation.cs" />
     <Compile Include="Implementation\Regression\ConfidenceBoundRegressionSolution.cs" />
     <Compile Include="Implementation\Regression\ConstantRegressionModel.cs" />
     <Compile Include="Implementation\Regression\ConstantRegressionSolution.cs" />
@@ -149,22 +152,31 @@
     <Compile Include="Implementation\Regression\RegressionEnsembleSolution.cs" />
     <Compile Include="Implementation\Regression\RegressionModel.cs" />
     <Compile Include="Implementation\Regression\RegressionSolutionVariableImpactsCalculator.cs" />
+    <Compile Include="Implementation\DataAnalysisTransformationModel.cs" />
+    <Compile Include="Implementation\Regression\RegressionTransformationModel.cs" />
     <Compile Include="Implementation\TimeSeriesPrognosis\Models\ConstantTimeSeriesPrognosisModel.cs" />
     <Compile Include="Implementation\TimeSeriesPrognosis\Models\TimeSeriesPrognosisAutoRegressiveModel.cs" />
+    <Compile Include="Implementation\TimeSeriesPrognosis\Models\TimeSeriesPrognosisTransformationModel.cs" />
     <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisProblem.cs" />
     <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisProblemData.cs" />
     <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisResults.cs" />
     <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisSolution.cs" />
     <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisSolutionBase.cs" />
-    <Compile Include="Implementation\Transformations\CopyColumnTransformation.cs" />
+    <None Include="Implementation\Transformations %28old%29\CopyColumnTransformation.cs" />
+    <None Include="Implementation\Transformations %28old%29\ExponentialTransformation.cs" />
+    <None Include="Implementation\Transformations %28old%29\LinearTransformation.cs" />
+    <None Include="Implementation\Transformations %28old%29\LogarithmicTransformation.cs" />
+    <None Include="Implementation\Transformations %28old%29\PowerTransformation.cs" />
+    <None Include="Implementation\Transformations %28old%29\ReciprocalTransformation.cs" />
+    <None Include="Implementation\Transformations %28old%29\ShiftStandardDistributionTransformation.cs" />
+    <None Include="Implementation\Transformations %28old%29\ShiftToRangeTransformation.cs" />
+    <None Include="Implementation\Transformations %28old%29\Transformation.cs" />
     <Compile Include="Implementation\Transformations\ExponentialTransformation.cs" />
+    <Compile Include="Implementation\Transformations\IdentityTransformation.cs" />
     <Compile Include="Implementation\Transformations\LinearTransformation.cs" />
-    <Compile Include="Implementation\Transformations\LogarithmicTransformation.cs" />
-    <Compile Include="Implementation\Transformations\PowerTransformation.cs" />
-    <Compile Include="Implementation\Transformations\ReciprocalTransformation.cs" />
-    <Compile Include="Implementation\Transformations\ShiftStandardDistributionTransformation.cs" />
-    <Compile Include="Implementation\Transformations\ShiftToRangeTransformation.cs" />
+    <Compile Include="Implementation\Transformations\LogarithmTransformation.cs" />
     <Compile Include="Implementation\Transformations\Transformation.cs" />
+    <Compile Include="Implementation\Transformations\ZNormalizationTransformation.cs" />
     <Compile Include="Interfaces\Classification\IClassificationEnsembleModel.cs">
       <SubType>Code</SubType>
     </Compile>
@@ -171,12 +183,16 @@
     <Compile Include="Interfaces\Classification\IClassificationEnsembleSolution.cs">
       <SubType>Code</SubType>
     </Compile>
+    <Compile Include="Interfaces\Classification\IClassificationTransformationModel.cs" />
     <Compile Include="Interfaces\Classification\IDiscriminantFunctionThresholdCalculator.cs" />
+    <Compile Include="Interfaces\Clustering\IClusteringTransformationModel.cs" />
     <Compile Include="Interfaces\IDataAnalysisSolutionExporter.cs" />
+    <Compile Include="Interfaces\IDataAnalysisTransformation.cs" />
+    <Compile Include="Interfaces\IDataAnalysisTransformationModel.cs" />
     <Compile Include="Interfaces\IDataset.cs" />
     <Compile Include="Interfaces\IDependencyCalculator.cs" />
     <Compile Include="Interfaces\ITransformation.cs" />
-    <Compile Include="Interfaces\ITransformationMapper.cs" />
+    <Compile Include="Interfaces\Regression\IRegressionTransformationModel.cs" />
     <Compile Include="Interfaces\Regression\IConfidenceRegressionModel.cs" />
     <Compile Include="Interfaces\Regression\IConfidenceRegressionSolution.cs" />
     <Compile Include="Interfaces\Regression\IRegressionEnsembleModel.cs">
@@ -189,6 +205,7 @@
     <Compile Include="Interfaces\TimeSeriesPrognosis\ITimeSeriesPrognosisProblem.cs" />
     <Compile Include="Interfaces\TimeSeriesPrognosis\ITimeSeriesPrognosisProblemData.cs" />
     <Compile Include="Interfaces\TimeSeriesPrognosis\ITimeSeriesPrognosisSolution.cs" />
+    <Compile Include="Interfaces\TimeSeriesPrognosis\ITimeSeriesPrognosisTransformationModel.cs" />
     <Compile Include="ModifiableDataset.cs" />
     <Compile Include="OnlineCalculators\AutoCorrelationCalculator.cs" />
     <Compile Include="OnlineCalculators\ClassificationPerformanceMeasuresCalculator.cs" />
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs	(working copy)
@@ -313,7 +313,7 @@
     public ClassificationProblemData() : this(defaultDataset, defaultAllowedInputVariables, defaultTargetVariable) { }
 
     public ClassificationProblemData(IClassificationProblemData classificationProblemData)
-      : this(classificationProblemData.Dataset, classificationProblemData.AllowedInputVariables, classificationProblemData.TargetVariable) {
+      : this(classificationProblemData.Dataset, classificationProblemData.AllowedInputVariables, classificationProblemData.TargetVariable, classificationProblemData.Transformations) {
       TrainingPartition.Start = classificationProblemData.TrainingPartition.Start;
       TrainingPartition.End = classificationProblemData.TrainingPartition.End;
       TestPartition.Start = classificationProblemData.TestPartition.Start;
@@ -332,8 +332,8 @@
       }
     }
 
-    public ClassificationProblemData(IDataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable, IEnumerable<ITransformation> transformations = null)
-      : base(dataset, allowedInputVariables, transformations ?? Enumerable.Empty<ITransformation>()) {
+    public ClassificationProblemData(IDataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable, IEnumerable<IDataAnalysisTransformation> transformations = null)
+      : base(dataset, allowedInputVariables, transformations ?? Enumerable.Empty<IDataAnalysisTransformation>()) {
       var validTargetVariableValues = CheckVariablesForPossibleTargetVariables(dataset).Select(x => new StringValue(x).AsReadOnly()).ToList();
       var target = validTargetVariableValues.Where(x => x.Value == targetVariable).DefaultIfEmpty(validTargetVariableValues.First()).First();
 
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationTransformationModel.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationTransformationModel.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationTransformationModel.cs	(working copy)
@@ -0,0 +1,66 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [Item("Classification Transformation Model", "A classification model that was transformed back to match the original variables after the training was performed on transformed variables.")]
+  [StorableClass]
+  public class ClassificationTransformationModel : DataAnalysisTransformationModel, IClassificationTransformationModel {
+    public new IClassificationModel OriginalModel {
+      get { return (IClassificationModel)base.OriginalModel; }
+    }
+
+    #region Constructor, Cloning & Persistence
+    public ClassificationTransformationModel(IClassificationModel originalModel, IEnumerable<IDataAnalysisTransformation> transformations)
+      : base(originalModel, transformations) {
+      if (transformations.Any(t => t.TransformedVariable == originalModel.TargetVariable))
+        throw new NotSupportedException("Classification with a transformed target variable is not allowed");
+    }
+
+    protected ClassificationTransformationModel(ClassificationTransformationModel original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ClassificationTransformationModel(this, cloner);
+    }
+
+    [StorableConstructor]
+    protected ClassificationTransformationModel(bool deserializing)
+      : base(deserializing) { }
+    #endregion
+
+    public virtual IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
+      var transformedInput = DataAnalysisTransformation.Transform(dataset, InputTransformations);
+      return OriginalModel.GetEstimatedClassValues(transformedInput, rows);
+    }
+
+    public virtual IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
+      return new ClassificationSolution(this, problemData);
+    }
+  }
+}
\ No newline at end of file
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblemData.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblemData.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblemData.cs	(working copy)
@@ -86,8 +86,8 @@
       : this(defaultDataset, defaultAllowedInputVariables) {
     }
 
-    public ClusteringProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, IEnumerable<ITransformation> transformations = null)
-      : base(dataset, allowedInputVariables, transformations ?? Enumerable.Empty<ITransformation>()) {
+    public ClusteringProblemData(IDataset dataset, IEnumerable<string> allowedInputVariables, IEnumerable<IDataAnalysisTransformation> transformations = null)
+      : base(dataset, allowedInputVariables, transformations ?? Enumerable.Empty<IDataAnalysisTransformation>()) {
     }
   }
 }
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringTransformationModel.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringTransformationModel.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringTransformationModel.cs	(working copy)
@@ -0,0 +1,59 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [Item("Clustering Transformation Model", "A clustering model that was transformed back to match the original variables after the training was performed on transformed variables.")]
+  [StorableClass]
+  public class ClusteringTransformationModel : DataAnalysisTransformationModel, IClusteringTransformationModel {
+
+    public new IClusteringModel OriginalModel {
+      get { return (IClusteringModel)base.OriginalModel; }
+    }
+
+    #region Constructor, Cloning & Persistence
+    public ClusteringTransformationModel(IClusteringModel originalModel, IEnumerable<IDataAnalysisTransformation> transformations)
+      : base(originalModel, transformations) {
+    }
+
+    protected ClusteringTransformationModel(ClusteringTransformationModel original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ClusteringTransformationModel(this, cloner);
+    }
+
+    [StorableConstructor]
+    protected ClusteringTransformationModel(bool deserializing)
+      : base(deserializing) { }
+    #endregion
+
+    public IEnumerable<int> GetClusterValues(IDataset dataset, IEnumerable<int> rows) {
+      var transformedInputs = DataAnalysisTransformation.Transform(dataset, InputTransformations);
+      return OriginalModel.GetClusterValues(transformedInputs, rows);
+    }
+  }
+}
\ No newline at end of file
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs	(working copy)
@@ -73,8 +73,8 @@
       }
     }
 
-    public IFixedValueParameter<ReadOnlyItemList<ITransformation>> TransformationsParameter {
-      get { return (IFixedValueParameter<ReadOnlyItemList<ITransformation>>)Parameters[TransformationsParameterName]; }
+    public IFixedValueParameter<ReadOnlyItemList<IDataAnalysisTransformation>> TransformationsParameter {
+      get { return (IFixedValueParameter<ReadOnlyItemList<IDataAnalysisTransformation>>)Parameters[TransformationsParameterName]; }
     }
     #endregion
 
@@ -121,7 +121,7 @@
       }
     }
 
-    public IEnumerable<ITransformation> Transformations {
+    public IEnumerable<IDataAnalysisTransformation> Transformations {
       get { return TransformationsParameter.Value; }
     }
 
@@ -147,14 +147,15 @@
 
     [StorableHook(HookType.AfterDeserialization)]
     private void AfterDeserialization() {
-      if (!Parameters.ContainsKey(TransformationsParameterName)) {
-        Parameters.Add(new FixedValueParameter<ReadOnlyItemList<ITransformation>>(TransformationsParameterName, "", new ItemList<ITransformation>().AsReadOnly()));
-        TransformationsParameter.Hidden = true;
-      }
+      if (Parameters[TransformationsParameterName] is FixedValueParameter<ReadOnlyItemList<ITransformation>>)
+        Parameters.Remove(TransformationsParameterName);
+      if (!Parameters.ContainsKey(TransformationsParameterName))
+        Parameters.Add(new FixedValueParameter<ReadOnlyItemList<IDataAnalysisTransformation>>(TransformationsParameterName, new ItemList<IDataAnalysisTransformation>().AsReadOnly()) { Hidden = true });
+
       RegisterEventHandlers();
     }
 
-    protected DataAnalysisProblemData(IDataset dataset, IEnumerable<string> allowedInputVariables, IEnumerable<ITransformation> transformations = null) {
+    protected DataAnalysisProblemData(IDataset dataset, IEnumerable<string> allowedInputVariables, IEnumerable<IDataAnalysisTransformation> transformations = null) {
       if (dataset == null) throw new ArgumentNullException("The dataset must not be null.");
       if (allowedInputVariables == null) throw new ArgumentNullException("The allowed input variables must not be null.");
 
@@ -171,16 +172,14 @@
       int testPartitionStart = dataset.Rows / 2;
       int testPartitionEnd = dataset.Rows;
 
-      var transformationsList = new ItemList<ITransformation>(transformations ?? Enumerable.Empty<ITransformation>());
+      var transformationsList = new ItemList<IDataAnalysisTransformation>(transformations ?? Enumerable.Empty<IDataAnalysisTransformation>());
 
       Parameters.Add(new FixedValueParameter<Dataset>(DatasetParameterName, "", (Dataset)dataset));
       Parameters.Add(new FixedValueParameter<ReadOnlyCheckedItemList<StringValue>>(InputVariablesParameterName, "", inputVariables.AsReadOnly()));
       Parameters.Add(new FixedValueParameter<IntRange>(TrainingPartitionParameterName, "", new IntRange(trainingPartitionStart, trainingPartitionEnd)));
       Parameters.Add(new FixedValueParameter<IntRange>(TestPartitionParameterName, "", new IntRange(testPartitionStart, testPartitionEnd)));
-      Parameters.Add(new FixedValueParameter<ReadOnlyItemList<ITransformation>>(TransformationsParameterName, "", transformationsList.AsReadOnly()));
+      Parameters.Add(new FixedValueParameter<ReadOnlyItemList<IDataAnalysisTransformation>>(TransformationsParameterName, "", transformationsList.AsReadOnly()) { Hidden = transformationsList.Count == 0 });
 
-      TransformationsParameter.Hidden = true;
-
       ((ValueParameter<Dataset>)DatasetParameter).ReactOnValueToStringChangedAndValueItemImageChanged = false;
       RegisterEventHandlers();
     }
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisTransformation.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisTransformation.cs	(working copy)
@@ -0,0 +1,282 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [Item("Transformation", "A transformation applied to a DataAnalysisProblemData")]
+  [StorableClass]
+  public sealed class DataAnalysisTransformation : ParameterizedNamedItem, IDataAnalysisTransformation {
+    #region Parameter Properties
+    private IFixedValueParameter<StringValue> OriginalVariableParameter {
+      get { return (IFixedValueParameter<StringValue>)Parameters["Original Variable"]; }
+    }
+
+    private IFixedValueParameter<StringValue> TransformedVariableParameter {
+      get { return (IFixedValueParameter<StringValue>)Parameters["Transformed Variable"]; }
+    }
+
+    private ValueParameter<ITransformation> TransformationParameter {
+      get { return (ValueParameter<ITransformation>)Parameters["Transformation"]; }
+    }
+    #endregion
+
+    #region Properties
+    public string OriginalVariable {
+      get { return OriginalVariableParameter.Value.Value; }
+    }
+
+    public string TransformedVariable {
+      get { return TransformedVariableParameter.Value.Value; }
+    }
+
+    public ITransformation Transformation {
+      get { return TransformationParameter.Value; }
+    }
+    #endregion
+
+    #region Constructor, Cloning & Persistence
+    public DataAnalysisTransformation(string originalVariable, string transformedVariable, ITransformation transformation)
+      : base() {
+      Parameters.Add(new FixedValueParameter<StringValue>("Original Variable", new StringValue(originalVariable).AsReadOnly()));
+      Parameters.Add(new FixedValueParameter<StringValue>("Transformed Variable", new StringValue(transformedVariable).AsReadOnly()));
+      Parameters.Add(new ValueParameter<ITransformation>("Transformation", transformation)); // TODO: should be readonly/fixed; alternatively lock in view
+    }
+
+    private DataAnalysisTransformation(DataAnalysisTransformation original, Cloner cloner)
+      : base(original, cloner) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DataAnalysisTransformation(this, cloner);
+    }
+
+    [StorableConstructor]
+    private DataAnalysisTransformation(bool deserializing)
+      : base(deserializing) { }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    #endregion
+
+    public override string ToString() {
+      return $"{Transformation} ({OriginalVariable} -> {TransformedVariable})";
+    }
+
+    #region Transformation
+
+    #region Variable Extension & Reduction
+    // originals => include extended
+    public static IEnumerable<string> ExtendVariables(IEnumerable<string> variables, IEnumerable<IDataAnalysisTransformation> transformations) {
+      return GetTransitiveVariables(variables, transformations, inverse: false);
+    }
+
+    // extended => originals
+    public static IEnumerable<string> ReduceVariables(IEnumerable<string> variables, IEnumerable<IDataAnalysisTransformation> transformations) {
+      var originalVariables = new HashSet<string>();
+      foreach (var variable in variables) {
+        var originalVariable = GetStrictTransitiveVariables(variable, transformations, inverse: true).Last();
+        originalVariables.Add(originalVariable);
+      }
+
+      return originalVariables;
+    }
+
+    // return all reachable variables
+    public static IEnumerable<string> GetTransitiveVariables(IEnumerable<string> variables, IEnumerable<IDataAnalysisTransformation> transformations, bool inverse = false) {
+      var reachableVariables = new HashSet<string>(variables);
+      if (inverse) transformations = transformations.Reverse();
+      foreach (var transformation in transformations) {
+        var source = inverse ? transformation.TransformedVariable : transformation.OriginalVariable;
+        var target = inverse ? transformation.OriginalVariable : transformation.TransformedVariable;
+        if (reachableVariables.Contains(source))
+          reachableVariables.Add(target);
+      }
+
+      return reachableVariables;
+    }
+
+    // return the (unique) chain of transformations for a given variable
+    public static IEnumerable<string> GetStrictTransitiveVariables(string variable, IEnumerable<IDataAnalysisTransformation> transformations, bool inverse = false) {
+      yield return variable;
+      if (inverse) transformations = transformations.Reverse();
+      foreach (var transformation in transformations) {
+        var source = inverse ? transformation.TransformedVariable : transformation.OriginalVariable;
+        var target = inverse ? transformation.OriginalVariable : transformation.TransformedVariable;
+        if (variable == source) {
+          variable = target;
+          yield return variable;
+        }
+      }
+    }
+    #endregion
+
+    #region Transform Dataset
+    public static IDataset Transform(IDataset dataset, IEnumerable<IDataAnalysisTransformation> transformations) {
+      var modifiableDataset = ((Dataset)dataset).ToModifiable();
+
+      foreach (var transformation in transformations) {
+        var trans = (ITransformation<double>)transformation.Transformation;
+
+        var originalData = modifiableDataset.GetDoubleValues(transformation.OriginalVariable);
+        var transformedData = trans.Apply(originalData).ToList();
+        if (modifiableDataset.VariableNames.Contains(transformation.TransformedVariable))
+          modifiableDataset.ReplaceVariable(transformation.TransformedVariable, transformedData);
+        else
+          modifiableDataset.AddVariable(transformation.TransformedVariable, transformedData);
+      }
+
+      return new Dataset(modifiableDataset);
+    }
+
+    public static IDataset InverseTransform(IDataset dataset, IEnumerable<IDataAnalysisTransformation> transformations, bool removeVirtualVariables = true) {
+      var modifiableDataset = ((Dataset)dataset).ToModifiable();
+
+      var transformationsStack = new Stack<IDataAnalysisTransformation>(transformations);
+      while (transformationsStack.Any()) {
+        var transformation = transformationsStack.Pop();
+        var trans = (ITransformation<double>)transformation.Transformation;
+
+        var prevTransformations = transformations.Except(transformationsStack);
+        bool originalWasChanged = prevTransformations.Any(x => x.TransformedVariable == transformation.OriginalVariable);
+        if (originalWasChanged) {
+          var transformedData = modifiableDataset.GetDoubleValues(transformation.TransformedVariable);
+
+          var originalData = trans.InverseApply(transformedData).ToList();
+          modifiableDataset.ReplaceVariable(transformation.OriginalVariable, originalData);
+        }
+      }
+
+      if (removeVirtualVariables) {
+        var originalVariables = ReduceVariables(dataset.VariableNames, transformations);
+        var virtualVariables = dataset.VariableNames.Except(originalVariables);
+        foreach (var virtualVariable in virtualVariables)
+          modifiableDataset.RemoveVariable(virtualVariable);
+      }
+
+      return new Dataset(modifiableDataset);
+    }
+    #endregion
+
+    #region Transform ProblemData
+    public static IDataAnalysisProblemData ApplyTransformations(IDataAnalysisProblemData problemData) {
+      var newDataset = Transform(problemData.Dataset, problemData.Transformations);
+      var extendedInputs = ExtendVariables(problemData.AllowedInputVariables, problemData.Transformations);
+
+      return CreateNewProblemData(problemData, newDataset, extendedInputs, inverse: false);
+    }
+
+    public static IDataAnalysisProblemData InverseApplyTransformations(IDataAnalysisProblemData problemData) {
+      var newDataset = InverseTransform(problemData.Dataset, problemData.Transformations);
+      var reducedInputs = ReduceVariables(problemData.AllowedInputVariables, problemData.Transformations);
+
+      return CreateNewProblemData(problemData, newDataset, reducedInputs, inverse: true);
+    }
+
+    private static IDataAnalysisProblemData CreateNewProblemData(IDataAnalysisProblemData problemData, IDataset dataset, IEnumerable<string> inputs, bool inverse = false) {
+      IDataAnalysisProblemData newProblemData;
+      if (problemData is IRegressionProblemData regressionProblemData) {
+        var newTargetVariable = GetStrictTransitiveVariables(regressionProblemData.TargetVariable, problemData.Transformations, inverse).Last();
+        if (problemData is ITimeSeriesPrognosisProblemData timeSeriesPrognosisProblemData) {
+          newProblemData = new TimeSeriesPrognosisProblemData(dataset, inputs, newTargetVariable, problemData.Transformations) {
+            TrainingHorizon = timeSeriesPrognosisProblemData.TrainingHorizon,
+            TestHorizon = timeSeriesPrognosisProblemData.TestHorizon,
+          };
+
+        } else
+          newProblemData = new RegressionProblemData(dataset, inputs, newTargetVariable, problemData.Transformations);
+      } else if (problemData is IClassificationProblemData classificationProblemData) {
+        newProblemData = new ClassificationProblemData(dataset, inputs, classificationProblemData.TargetVariable, problemData.Transformations);
+      } else if (problemData is IClusteringProblemData) {
+        newProblemData = new ClusteringProblemData(dataset, inputs, problemData.Transformations);
+      } else throw new NotSupportedException("Type of ProblemData not supported");
+
+      newProblemData.TrainingPartition.Start = problemData.TrainingPartition.Start;
+      newProblemData.TrainingPartition.End = problemData.TrainingPartition.End;
+      newProblemData.TestPartition.Start = problemData.TestPartition.Start;
+      newProblemData.TestPartition.End = problemData.TestPartition.End;
+
+      return newProblemData;
+    }
+    #endregion
+
+    #region Transform Model
+    // problemdata required for type-switch. cannot differ based on model type (e.g. RF model is both regression and classification)
+    public static IDataAnalysisTransformationModel CreateTransformationIntegratedModel(IDataAnalysisModel model, IEnumerable<IDataAnalysisTransformation> transformations, IDataAnalysisProblemData problemData) {
+      if (model is IDataAnalysisTransformationModel)
+        throw new InvalidOperationException("Model already is a transformation model.");
+
+      if (problemData is ITimeSeriesPrognosisProblemData)
+        return new TimeSeriesPrognosisTransformationModel((ITimeSeriesPrognosisModel)model, transformations);
+      if (problemData is IRegressionProblemData)
+        return new RegressionTransformationModel((IRegressionModel)model, transformations);
+      if (problemData is IClassificationProblemData)
+        return new ClassificationTransformationModel((IClassificationModel)model, transformations);
+      if (problemData is IClusteringProblemData)
+        return new ClusteringTransformationModel((IClusteringModel)model, transformations);
+
+      throw new NotSupportedException("Type of the model is not supported;");
+    }
+
+    public static IDataAnalysisModel RestoreTrainedModel(IDataAnalysisModel transformationModel, IEnumerable<IDataAnalysisTransformation> transformations) {
+      if (!(transformationModel is IDataAnalysisTransformationModel model))
+        throw new InvalidOperationException("Cannot restore because model is not a TransformationModel");
+      return model.OriginalModel;
+    }
+    #endregion
+
+    #region Transform Solution
+    public static IDataAnalysisSolution TransformSolution(IDataAnalysisSolution solution) {
+      var transformations = solution.ProblemData.Transformations;
+
+      var model = solution.Model is IDataAnalysisTransformationModel // TODO: what if model is a integrated sym-reg model?
+        ? RestoreTrainedModel(solution.Model, transformations)
+        : CreateTransformationIntegratedModel(solution.Model, transformations, solution.ProblemData);
+
+      var data = solution.Model is IDataAnalysisTransformationModel
+        ? ApplyTransformations(solution.ProblemData) // original -> transformed
+        : InverseApplyTransformations(solution.ProblemData); // transformed -> original
+
+      return CreateSolution(model, data);
+    }
+
+    private static IDataAnalysisSolution CreateSolution(IDataAnalysisModel model, IDataAnalysisProblemData problemData) {
+      if (problemData is ITimeSeriesPrognosisProblemData)
+        return ((ITimeSeriesPrognosisModel)model).CreateTimeSeriesPrognosisSolution((ITimeSeriesPrognosisProblemData)problemData);
+      if (problemData is IRegressionProblemData)
+        return ((IRegressionModel)model).CreateRegressionSolution((IRegressionProblemData)problemData);
+      if (problemData is IClassificationProblemData)
+        return ((IClassificationModel)model).CreateClassificationSolution((IClassificationProblemData)problemData);
+      //if (problemData is IClusteringProblemData)
+      //  return ((IClusteringModel)model).CreateClusteringSolution((IClusteringProblemData)problemData);
+
+      throw new NotSupportedException("Cannot create Solution of the model type.");
+    }
+    #endregion
+
+    #endregion
+  }
+}
\ No newline at end of file
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisTransformationModel.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisTransformationModel.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisTransformationModel.cs	(working copy)
@@ -0,0 +1,95 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [Item("Data Analysis Transformation Model", "A model that was transformed back to match the original variables after the training was performed on transformed variables.")]
+  [StorableClass]
+  public abstract class DataAnalysisTransformationModel : DataAnalysisModel, IDataAnalysisTransformationModel {
+
+    [Storable]
+    public IDataAnalysisModel OriginalModel { get; protected set; }
+
+    IEnumerable<IDataAnalysisTransformation> IDataAnalysisTransformationModel.InputTransformations {
+      get { return InputTransformations; }
+    }
+
+    [Storable]
+    public ReadOnlyItemList<IDataAnalysisTransformation> InputTransformations { get; protected set; }
+
+    [Storable]
+    public ReadOnlyItemList<IDataAnalysisTransformation> TargetTransformations { get; protected set; }
+
+    // Usually, the TargetVariable is usually only implemented for Regression and Classification.
+    // However, we implement it in the base class for reducing code duplication and to avoid quasi-identical views.
+    [Storable]
+    private string targetVariable;
+    public string TargetVariable {
+      get { return targetVariable; }
+      set {
+        if (string.IsNullOrEmpty(value) || targetVariable == value) return;
+        targetVariable = value;
+        OnTargetVariableChanged(this, EventArgs.Empty);
+      }
+    }
+
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return DataAnalysisTransformation.ReduceVariables(OriginalModel.VariablesUsedForPrediction, InputTransformations); }
+    }
+
+    #region Constructor, Cloning & Persistence
+    protected DataAnalysisTransformationModel(IDataAnalysisModel originalModel, IEnumerable<IDataAnalysisTransformation> transformations)
+      : base("Transformation Model " + originalModel.Name) {
+      OriginalModel = originalModel;
+      var transitiveInputs = DataAnalysisTransformation.GetTransitiveVariables(originalModel.VariablesUsedForPrediction, transformations, inverse: true);
+      InputTransformations = new ItemList<IDataAnalysisTransformation>(transformations.Where(t => transitiveInputs.Contains(t.OriginalVariable))).AsReadOnly();
+      TargetTransformations = new ReadOnlyItemList<IDataAnalysisTransformation>();
+    }
+
+    protected DataAnalysisTransformationModel(DataAnalysisTransformationModel original, Cloner cloner)
+      : base(original, cloner) {
+      OriginalModel = cloner.Clone(original.OriginalModel);
+      InputTransformations = cloner.Clone(original.InputTransformations);
+      TargetTransformations = cloner.Clone(original.TargetTransformations);
+      targetVariable = original.targetVariable;
+    }
+
+    [StorableConstructor]
+    protected DataAnalysisTransformationModel(bool deserializing)
+      : base(deserializing) { }
+    #endregion
+
+    #region Events
+    public event EventHandler TargetVariableChanged;
+    private void OnTargetVariableChanged(object sender, EventArgs args) {
+      var changed = TargetVariableChanged;
+      if (changed != null)
+        changed(sender, args);
+    }
+    #endregion
+  }
+}
\ No newline at end of file
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs	(working copy)
@@ -140,7 +140,7 @@
       : this(defaultDataset, defaultAllowedInputVariables, defaultTargetVariable) {
     }
     public RegressionProblemData(IRegressionProblemData regressionProblemData)
-      : this(regressionProblemData.Dataset, regressionProblemData.AllowedInputVariables, regressionProblemData.TargetVariable) {
+      : this(regressionProblemData.Dataset, regressionProblemData.AllowedInputVariables, regressionProblemData.TargetVariable, regressionProblemData.Transformations) {
       TrainingPartition.Start = regressionProblemData.TrainingPartition.Start;
       TrainingPartition.End = regressionProblemData.TrainingPartition.End;
       TestPartition.Start = regressionProblemData.TestPartition.Start;
@@ -147,8 +147,8 @@
       TestPartition.End = regressionProblemData.TestPartition.End;
     }
 
-    public RegressionProblemData(IDataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable, IEnumerable<ITransformation> transformations = null)
-      : base(dataset, allowedInputVariables, transformations ?? Enumerable.Empty<ITransformation>()) {
+    public RegressionProblemData(IDataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable, IEnumerable<IDataAnalysisTransformation> transformations = null)
+      : base(dataset, allowedInputVariables, transformations ?? Enumerable.Empty<IDataAnalysisTransformation>()) {
       var variables = InputVariables.Select(x => x.AsReadOnly()).ToList();
       Parameters.Add(new ConstrainedValueParameter<StringValue>(TargetVariableParameterName, new ItemSet<StringValue>(variables), variables.Where(x => x.Value == targetVariable).First()));
       RegisterParameterEvents();
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionTransformationModel.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionTransformationModel.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionTransformationModel.cs	(working copy)
@@ -0,0 +1,82 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [Item("Regression Transformation Model", "A regression model that was transformed back to match the original variables after the training was performed on transformed variables.")]
+  [StorableClass]
+  public class RegressionTransformationModel : DataAnalysisTransformationModel, IRegressionTransformationModel {
+
+    public new IRegressionModel OriginalModel {
+      get { return (IRegressionModel)base.OriginalModel; }
+    }
+
+    IEnumerable<IDataAnalysisTransformation> IRegressionTransformationModel.TargetTransformations {
+      get { return TargetTransformations; }
+    }
+
+    #region Constructor, Cloning & Persistence
+    public RegressionTransformationModel(IRegressionModel originalModel, IEnumerable<IDataAnalysisTransformation> transformations)
+      : base(originalModel, transformations) {
+      var learnedTarget = DataAnalysisTransformation.GetStrictTransitiveVariables(originalModel.TargetVariable, transformations, true).Last();
+      var transitiveTargets = DataAnalysisTransformation.GetStrictTransitiveVariables(learnedTarget, transformations, inverse: false).ToList();
+      TargetTransformations = new ItemList<IDataAnalysisTransformation>(transformations.Where(t => transitiveTargets.Contains(t.TransformedVariable))).AsReadOnly();
+
+      TargetVariable = DataAnalysisTransformation.GetStrictTransitiveVariables(originalModel.TargetVariable, TargetTransformations, true).Last();
+    }
+
+    protected RegressionTransformationModel(RegressionTransformationModel original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RegressionTransformationModel(this, cloner);
+    }
+
+    [StorableConstructor]
+    protected RegressionTransformationModel(bool deserializing)
+      : base(deserializing) { }
+    #endregion
+
+    public virtual IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
+      var transformedInput = DataAnalysisTransformation.Transform(dataset, InputTransformations);
+      var estimates = OriginalModel.GetEstimatedValues(transformedInput, rows);
+      return InverseTransform(estimates, TargetTransformations);
+    }
+
+    public virtual IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+      return new RegressionSolution(this, new RegressionProblemData(problemData));
+    }
+
+    protected static IEnumerable<double> InverseTransform(IEnumerable<double> data, IEnumerable<IDataAnalysisTransformation> transformations) {
+      foreach (var transformation in transformations.Reverse()) { // TargetTransformations only contains only relevant transformations
+        var trans = (ITransformation<double>)transformation.Transformation;
+        data = trans.InverseApply(data).ToList();
+      }
+      return data;
+    }
+  }
+}
\ No newline at end of file
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisTransformationModel.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisTransformationModel.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisTransformationModel.cs	(working copy)
@@ -0,0 +1,66 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [Item("Time Series Prognosis Transformation Model", "A time series prognosis model that was transformed back to match the original variables after the training was performed on transformed variables.")]
+  [StorableClass]
+  public class TimeSeriesPrognosisTransformationModel : RegressionTransformationModel, ITimeSeriesPrognosisTransformationModel {
+
+    public new ITimeSeriesPrognosisModel OriginalModel {
+      get { return (ITimeSeriesPrognosisModel)base.OriginalModel; }
+    }
+
+    #region Constructor, Cloning & Persistence
+    public TimeSeriesPrognosisTransformationModel(ITimeSeriesPrognosisModel originalModel, IEnumerable<IDataAnalysisTransformation> transformations)
+      : base(originalModel, transformations) {
+    }
+
+    protected TimeSeriesPrognosisTransformationModel(TimeSeriesPrognosisTransformationModel original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TimeSeriesPrognosisTransformationModel(this, cloner);
+    }
+
+    [StorableConstructor]
+    protected TimeSeriesPrognosisTransformationModel(bool deserializing)
+      : base(deserializing) { }
+    #endregion
+
+
+    public IEnumerable<IEnumerable<double>> GetPrognosedValues(IDataset dataset, IEnumerable<int> rows, IEnumerable<int> horizons) {
+      var transformedInput = DataAnalysisTransformation.Transform(dataset, InputTransformations);
+      var estimates = OriginalModel.GetPrognosedValues(transformedInput, rows, horizons);
+      return estimates.Select(x => InverseTransform(x, TargetTransformations));
+    }
+
+    public ITimeSeriesPrognosisSolution CreateTimeSeriesPrognosisSolution(ITimeSeriesPrognosisProblemData problemData) {
+      return new TimeSeriesPrognosisSolution(this, problemData);
+    }
+  }
+}
\ No newline at end of file
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblemData.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblemData.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblemData.cs	(working copy)
@@ -1581,8 +1581,8 @@
       : this(defaultDataset, defaultAllowedInputVariables, defaultTargetVariable) {
       TrainingPartition.Start = 50;
     }
-    public TimeSeriesPrognosisProblemData(IDataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable, IEnumerable<ITransformation> transformations = null)
-      : base(dataset, allowedInputVariables, targetVariable, transformations ?? Enumerable.Empty<ITransformation>()) {
+    public TimeSeriesPrognosisProblemData(IDataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable, IEnumerable<IDataAnalysisTransformation> transformations = null)
+      : base(dataset, allowedInputVariables, targetVariable, transformations ?? Enumerable.Empty<IDataAnalysisTransformation>()) {
       Parameters.Add(new FixedValueParameter<IntValue>(TrainingHorizonParameterName, "Specifies the horizon (how far the prognosis reaches in the future) for each training sample.", new IntValue(1)));
       Parameters.Add(new FixedValueParameter<IntValue>(TestHorizonParameterName, "Specifies the horizon (how far the prognosis reaches in the future) for each test sample.", new IntValue(1)));
 
@@ -1595,7 +1595,7 @@
     }
 
     public TimeSeriesPrognosisProblemData(ITimeSeriesPrognosisProblemData timeseriesProblemData)
-      : this(timeseriesProblemData.Dataset, timeseriesProblemData.AllowedInputVariables, timeseriesProblemData.TargetVariable) {
+      : this(timeseriesProblemData.Dataset, timeseriesProblemData.AllowedInputVariables, timeseriesProblemData.TargetVariable, timeseriesProblemData.Transformations) {
 
       TrainingPartition.Start = timeseriesProblemData.TrainingPartition.Start;
       TrainingPartition.End = timeseriesProblemData.TrainingPartition.End;
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/CopyColumnTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/CopyColumnTransformation.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/CopyColumnTransformation.cs	(nonexistent)
@@ -1,65 +0,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  [Item("CopyColumnTransformation", "Represents a transformation which represents a copied Column.")]
-  public class CopyColumnTransformation : Transformation {
-    protected const string CopiedColumnNameParameterName = "CopiedColumnName";
-
-    #region Parameters
-    public IValueParameter<StringValue> CopiedColumnNameParameter {
-      get { return (IValueParameter<StringValue>)Parameters[CopiedColumnNameParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public override string ShortName {
-      get { return "Cpy"; }
-    }
-    public string CopiedColumnName {
-      get { return CopiedColumnNameParameter.Value.Value; }
-    }
-    #endregion
-
-    [StorableConstructor]
-    protected CopyColumnTransformation(bool deserializing) : base(deserializing) { }
-    protected CopyColumnTransformation(CopyColumnTransformation original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public CopyColumnTransformation()
-      : base(Enumerable.Empty<string>()) {
-      Parameters.Add(new ValueParameter<StringValue>(CopiedColumnNameParameterName, "Name for the copied column", new StringValue()));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new CopyColumnTransformation(this, cloner);
-    }
-  }
-}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ExponentialTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ExponentialTransformation.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ExponentialTransformation.cs	(nonexistent)
@@ -1,56 +0,0 @@
-﻿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;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  [Item("Exponential Transformation", "f(x) = b ^ x | Represents a exponential transformation.")]
-  public class ExponentialTransformation : Transformation<double> {
-    protected const string BaseParameterName = "Base";
-
-    #region Parameters
-    public IValueParameter<DoubleValue> BaseParameter {
-      get { return (IValueParameter<DoubleValue>)Parameters[BaseParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public override string ShortName {
-      get { return "Exp"; }
-    }
-    public double Base {
-      get { return BaseParameter.Value.Value; }
-    }
-    #endregion
-
-    [StorableConstructor]
-    protected ExponentialTransformation(bool deserializing) : base(deserializing) { }
-
-    protected ExponentialTransformation(ExponentialTransformation original, Cloner cloner)
-      : base(original, cloner) {
-    }
-
-    public ExponentialTransformation(IEnumerable<string> allowedColumns)
-      : base(allowedColumns) {
-      Parameters.Add(new ValueParameter<DoubleValue>(BaseParameterName, "b | Base of exp-function", new DoubleValue(Math.E)));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new ExponentialTransformation(this, cloner);
-    }
-
-    public override IEnumerable<double> Apply(IEnumerable<double> data) {
-      return data.Select(d => Math.Pow(Base, d));
-    }
-
-    public override bool Check(IEnumerable<double> data, out string errorMsg) {
-      errorMsg = "";
-      return true;
-    }
-  }
-}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LinearTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LinearTransformation.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LinearTransformation.cs	(nonexistent)
@@ -1,97 +0,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  [Item("Linear Transformation", "f(x) = k * x + d | Represents a linear transformation with multiplication and addition.")]
-  public class LinearTransformation : Transformation<double> {
-    protected const string MultiplierParameterName = "Multiplier";
-    protected const string AddendParameterName = "Addend";
-
-    #region Parameters
-    public IValueParameter<DoubleValue> MultiplierParameter {
-      get { return (IValueParameter<DoubleValue>)Parameters[MultiplierParameterName]; }
-    }
-    public IValueParameter<DoubleValue> AddendParameter {
-      get { return (IValueParameter<DoubleValue>)Parameters[AddendParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public override string ShortName {
-      get { return "Lin"; }
-    }
-    public double Multiplier {
-      get { return MultiplierParameter.Value.Value; }
-      set {
-        MultiplierParameter.Value.Value = value;
-      }
-    }
-
-    public double Addend {
-      get { return AddendParameter.Value.Value; }
-      set {
-        AddendParameter.Value.Value = value;
-      }
-    }
-    #endregion
-
-    [StorableConstructor]
-    protected LinearTransformation(bool deserializing) : base(deserializing) { }
-    protected LinearTransformation(LinearTransformation original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public LinearTransformation(IEnumerable<string> allowedColumns)
-      : base(allowedColumns) {
-      Parameters.Add(new ValueParameter<DoubleValue>(MultiplierParameterName, "k | Multiplier for linear transformation", new DoubleValue(1.0)));
-      Parameters.Add(new ValueParameter<DoubleValue>(AddendParameterName, "d | Addend for linear transformation", new DoubleValue(0.0)));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new LinearTransformation(this, cloner);
-    }
-
-    public override IEnumerable<double> Apply(IEnumerable<double> data) {
-      var m = Multiplier;
-      var a = Addend;
-      return data.Select(e => e * m + a);
-    }
-
-    public override bool Check(IEnumerable<double> data, out string errorMsg) {
-      errorMsg = null;
-      if (Multiplier.IsAlmost(0.0)) {
-        errorMsg = String.Format("Multiplicand is 0, all {0} entries will be set to {1}. Inverse apply will not be possible (division by 0).", data.Count(), Addend);
-        return false;
-      }
-      return true;
-    }
-  }
-}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LogarithmicTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LogarithmicTransformation.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LogarithmicTransformation.cs	(nonexistent)
@@ -1,61 +0,0 @@
-﻿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;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  [Item("Logarithmic Transformation", "f(x) = log(x, b) | Represents a logarithmic transformation.")]
-  public class LogarithmicTransformation : Transformation<double> {
-    protected const string BaseParameterName = "Base";
-
-    #region Parameters
-    public IValueParameter<DoubleValue> BaseParameter {
-      get { return (IValueParameter<DoubleValue>)Parameters[BaseParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public override string ShortName {
-      get { return "Log"; }
-    }
-    public double Base {
-      get { return BaseParameter.Value.Value; }
-    }
-    #endregion
-
-    [StorableConstructor]
-    protected LogarithmicTransformation(bool deserializing) : base(deserializing) { }
-    protected LogarithmicTransformation(LogarithmicTransformation original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public LogarithmicTransformation(IEnumerable<string> allowedColumns)
-      : base(allowedColumns) {
-      Parameters.Add(new ValueParameter<DoubleValue>(BaseParameterName, "b | Base of log-function", new DoubleValue(Math.E)));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new LogarithmicTransformation(this, cloner);
-    }
-
-    public override IEnumerable<double> Apply(IEnumerable<double> data) {
-      var b = Base;
-      return data.Select(d => d > 0.0 ? Math.Log(d, b) : d);
-    }
-
-    public override bool Check(IEnumerable<double> data, out string errorMsg) {
-      errorMsg = null;
-      int errorCounter = data.Count(i => i <= 0.0);
-      if (errorCounter > 0) {
-        errorMsg = String.Format("{0} values are zero or below zero. Logarithm can not be applied onto these values", errorCounter);
-        return false;
-      }
-      return true;
-    }
-
-  }
-}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/PowerTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/PowerTransformation.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/PowerTransformation.cs	(nonexistent)
@@ -1,55 +0,0 @@
-﻿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;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  [Item("Power Transformation", "f(x) = x ^ exp | Represents a power transformation.")]
-  public class PowerTransformation : Transformation<double> {
-    protected const string ExponentParameterName = "Exponent";
-
-    #region Parameters
-    public IValueParameter<DoubleValue> ExponentParameter {
-      get { return (IValueParameter<DoubleValue>)Parameters[ExponentParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public override string ShortName {
-      get { return "Pow"; }
-    }
-    public double Exponent {
-      get { return ExponentParameter.Value.Value; }
-    }
-    #endregion
-
-    [StorableConstructor]
-    protected PowerTransformation(bool deserializing) : base(deserializing) { }
-    protected PowerTransformation(PowerTransformation original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public PowerTransformation(IEnumerable<string> allowedColumns)
-      : base(allowedColumns) {
-      Parameters.Add(new ValueParameter<DoubleValue>(ExponentParameterName, "exp | Exponent for Exponentation", new DoubleValue(2.0)));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new PowerTransformation(this, cloner);
-    }
-
-    public override IEnumerable<double> Apply(IEnumerable<double> data) {
-      return data.Select(i => Math.Pow(i, Exponent));
-    }
-
-    public override bool Check(IEnumerable<double> data, out string errorMsg) {
-      errorMsg = "";
-      return true;
-    }
-
-  }
-}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ReciprocalTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ReciprocalTransformation.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ReciprocalTransformation.cs	(nonexistent)
@@ -1,46 +0,0 @@
-﻿
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  [Item("Reciprocal Transformation", "f(x) = 1 / x | Represents a reciprocal transformation.")]
-  public class ReciprocalTransformation : Transformation<double> {
-
-    #region properties
-    public override string ShortName {
-      get { return "Inv"; }
-    }
-    #endregion
-
-    [StorableConstructor]
-    protected ReciprocalTransformation(bool deserializing) : base(deserializing) { }
-    protected ReciprocalTransformation(ReciprocalTransformation original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public ReciprocalTransformation(IEnumerable<string> allowedColumns)
-      : base(allowedColumns) {
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new ReciprocalTransformation(this, cloner);
-    }
-
-    public override IEnumerable<double> Apply(IEnumerable<double> data) {
-      return data.Select(d => d > 0 ? 1.0 / d : d);
-    }
-
-    public override bool Check(IEnumerable<double> data, out string errorMsg) {
-      errorMsg = null;
-      int errorCounter = data.Count(i => i <= 0.0);
-      if (errorCounter > 0) {
-        errorMsg = String.Format("{0} values are zero or below zero. 1/x can not be applied onto these values", errorCounter);
-        return false;
-      }
-      return true;
-    }
-  }
-}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftStandardDistributionTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftStandardDistributionTransformation.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftStandardDistributionTransformation.cs	(nonexistent)
@@ -1,100 +0,0 @@
-﻿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;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  [Item("Shift Standard Distribution Transformation", "f(x) = ((x - m_org) / s_org ) * s_tar + m_tar | Represents Transformation to unit standard deviation and additional linear transformation to a target Mean and Standard deviation")]
-  public class ShiftStandardDistributionTransformation : Transformation<double> {
-    protected const string OriginalMeanParameterName = "Original Mean";
-    protected const string OriginalStandardDeviationParameterName = "Original Standard Deviation";
-    protected const string MeanParameterName = "Mean";
-    protected const string StandardDeviationParameterName = "Standard Deviation";
-
-    #region Parameters
-    public IValueParameter<DoubleValue> OriginalMeanParameter {
-      get { return (IValueParameter<DoubleValue>)Parameters[OriginalMeanParameterName]; }
-    }
-    public IValueParameter<DoubleValue> OriginalStandardDeviationParameter {
-      get { return (IValueParameter<DoubleValue>)Parameters[OriginalStandardDeviationParameterName]; }
-    }
-    public IValueParameter<DoubleValue> MeanParameter {
-      get { return (IValueParameter<DoubleValue>)Parameters[MeanParameterName]; }
-    }
-    public IValueParameter<DoubleValue> StandardDeviationParameter {
-      get { return (IValueParameter<DoubleValue>)Parameters[StandardDeviationParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public override string ShortName {
-      get { return "Std"; }
-    }
-    public double OriginalMean {
-      get { return OriginalMeanParameter.Value.Value; }
-      set { OriginalMeanParameter.Value.Value = value; }
-    }
-    public double OriginalStandardDeviation {
-      get { return OriginalStandardDeviationParameter.Value.Value; }
-      set { OriginalStandardDeviationParameter.Value.Value = value; }
-    }
-    public double Mean {
-      get { return MeanParameter.Value.Value; }
-    }
-    public double StandardDeviation {
-      get { return StandardDeviationParameter.Value.Value; }
-    }
-    #endregion
-
-    [StorableConstructor]
-    protected ShiftStandardDistributionTransformation(bool deserializing) : base(deserializing) { }
-    protected ShiftStandardDistributionTransformation(ShiftStandardDistributionTransformation original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public ShiftStandardDistributionTransformation(IEnumerable<string> allowedColumns)
-      : base(allowedColumns) {
-      Parameters.Add(new ValueParameter<DoubleValue>(OriginalMeanParameterName, "m_org | Mean value of the original data's deviation.", new DoubleValue()));
-      Parameters.Add(new ValueParameter<DoubleValue>(OriginalStandardDeviationParameterName, "s_org | Standard deviation of the original data.", new DoubleValue()));
-      OriginalMeanParameter.Hidden = true;
-      OriginalStandardDeviationParameter.Hidden = true;
-      Parameters.Add(new ValueParameter<DoubleValue>(MeanParameterName, "m_tar | Mean value for the target deviation.", new DoubleValue(0.0)));
-      Parameters.Add(new ValueParameter<DoubleValue>(StandardDeviationParameterName, "s_tar | Standard deviation for the target data.", new DoubleValue(1.0)));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new ShiftStandardDistributionTransformation(this, cloner);
-    }
-
-    public override IEnumerable<double> Apply(IEnumerable<double> data) {
-      if (OriginalStandardDeviation.IsAlmost(0.0)) {
-        return data;
-      }
-      var old_m = OriginalMean;
-      var old_s = OriginalStandardDeviation;
-      var m = Mean;
-      var s = StandardDeviation;
-      return data
-        .Select(d => (d - old_m) / old_s) // standardized
-        .Select(d => d * s + m);
-    }
-
-    public override bool Check(IEnumerable<double> data, out string errorMsg) {
-      ConfigureParameters(data);
-      errorMsg = "";
-      if (OriginalStandardDeviation.IsAlmost(0.0)) {
-        errorMsg = "Standard deviaton for the original data is 0.0, Transformation cannot be applied onto these values.";
-        return false;
-      }
-      return true;
-    }
-
-    public override void ConfigureParameters(IEnumerable<double> data) {
-      OriginalStandardDeviation = data.StandardDeviation();
-      OriginalMean = data.Average();
-    }
-  }
-}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftToRangeTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftToRangeTransformation.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftToRangeTransformation.cs	(nonexistent)
@@ -1,62 +0,0 @@
-﻿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;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  [Item("Shift to Range Transformation", "f(x) = k * x + d, start <= f(x) <= end | Represents a linear Transformation using Parameters defining a target range")]
-  public class ShiftToRangeTransformation : LinearTransformation {
-    protected const string RangeParameterName = "Range";
-
-    #region Parameters
-    public IValueParameter<DoubleRange> RangeParameter {
-      get { return (IValueParameter<DoubleRange>)Parameters[RangeParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public override string ShortName {
-      get { return "Sft"; }
-    }
-    public DoubleRange Range {
-      get { return RangeParameter.Value; }
-    }
-    #endregion
-
-    [StorableConstructor]
-    protected ShiftToRangeTransformation(bool deserializing) : base(deserializing) { }
-    protected ShiftToRangeTransformation(ShiftToRangeTransformation original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public ShiftToRangeTransformation(IEnumerable<string> allowedColumns)
-      : base(allowedColumns) {
-      MultiplierParameter.Hidden = true;
-      AddendParameter.Hidden = true;
-      Parameters.Add(new ValueParameter<DoubleRange>(RangeParameterName, "start, end | Range for the target window of the linear transformation", new DoubleRange(0.0, 1.0)));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new ShiftToRangeTransformation(this, cloner);
-    }
-
-    public override bool Check(IEnumerable<double> data, out string errorMsg) {
-      ConfigureParameters(data);
-      return base.Check(data, out errorMsg);
-    }
-
-    public override void ConfigureParameters(IEnumerable<double> data) {
-      double originalRangeStart = data.Min();
-      double originalRangeEnd = data.Max();
-
-      double originalRangeWidth = originalRangeEnd - originalRangeStart;
-      double targetRangeWidth = Range.End - Range.Start;
-
-      Multiplier = targetRangeWidth / originalRangeWidth;
-      Addend = Range.Start - originalRangeStart * Multiplier;
-    }
-  }
-}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/Transformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/Transformation.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/Transformation.cs	(nonexistent)
@@ -1,80 +0,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-
-  [Item("Transformation", "Represents the base class for a transformation.")]
-  [StorableClass]
-  public abstract class Transformation : ParameterizedNamedItem, ITransformation {
-    protected const string ColumnParameterName = "Column";
-    #region parameter properties
-    public IConstrainedValueParameter<StringValue> ColumnParameter {
-      get { return (IConstrainedValueParameter<StringValue>)Parameters[ColumnParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public abstract string ShortName { get; }
-
-    public string Column {
-      get { return ColumnParameter.Value.Value; }
-    }
-    #endregion
-
-    [StorableConstructor]
-    protected Transformation(bool deserializing) : base(deserializing) { }
-    protected Transformation(Transformation original, Cloner cloner) : base(original, cloner) { }
-    protected Transformation(IEnumerable<string> allowedColumns) {
-      var allowed = new ItemSet<StringValue>(allowedColumns.Select(e => new StringValue(e)));
-      Parameters.Add(new ConstrainedValueParameter<StringValue>(ColumnParameterName, "Column used for the Transformation", allowed));
-    }
-  }
-
-  [Item("Transformation", "Represents the base class for a transformation.")]
-  [StorableClass]
-  public abstract class Transformation<T> : Transformation, ITransformation<T> {
-
-    [StorableConstructor]
-    protected Transformation(bool deserializing) : base(deserializing) { }
-    protected Transformation(Transformation<T> original, Cloner cloner) : base(original, cloner) { }
-    protected Transformation(IEnumerable<string> allowedColumns) : base(allowedColumns) { }
-
-    public virtual void ConfigureParameters(IEnumerable<T> data) {
-      // override in transformations with parameters
-    }
-
-    public abstract IEnumerable<T> Apply(IEnumerable<T> data);
-    public IEnumerable<T> ConfigureAndApply(IEnumerable<T> data) {
-      ConfigureParameters(data);
-      return Apply(data);
-    }
-
-    public abstract bool Check(IEnumerable<T> data, out string errorMsg);
-  }
-}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ExponentialTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ExponentialTransformation.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ExponentialTransformation.cs	(working copy)
@@ -0,0 +1,84 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [Item("Exponential", "Exponential transformation x' = Base ^ x")]
+  [StorableClass]
+  public class ExponentialTransformation : Transformation<double> {
+    #region Parameters
+    private FixedValueParameter<DoubleValue> BaseParameter {
+      get { return (FixedValueParameter<DoubleValue>)Parameters["Base"]; }
+    }
+    #endregion
+
+    #region Properties
+    public double Base {
+      get { return BaseParameter.Value.Value; }
+      set { BaseParameter.Value.Value = value; }
+    }
+    #endregion
+
+    #region Constructor, Cloning & Persistence
+    public ExponentialTransformation()
+      : base() {
+      Parameters.Add(new FixedValueParameter<DoubleValue>("Base", "", new DoubleValue(Math.E)));
+    }
+
+    protected ExponentialTransformation(ExponentialTransformation original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ExponentialTransformation(this, cloner);
+    }
+
+    [StorableConstructor]
+    protected ExponentialTransformation(bool deserializing)
+      : base(deserializing) {
+    }
+    #endregion
+
+    public override IEnumerable<double> Apply(IEnumerable<double> data) {
+      return Apply(data, Base);
+    }
+
+    public override IEnumerable<double> InverseApply(IEnumerable<double> data) {
+      return InverseApply(data, Base);
+    }
+
+
+    public static IEnumerable<double> Apply(IEnumerable<double> data, double @base = Math.E) {
+      return data.Select(x => Math.Pow(@base, x));
+    }
+
+    public static IEnumerable<double> InverseApply(IEnumerable<double> data, double @base = Math.E) {
+      return LogarithmTransformation.Apply(data, @base);
+    }
+  }
+}
\ No newline at end of file
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/IdentityTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/IdentityTransformation.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/IdentityTransformation.cs	(working copy)
@@ -0,0 +1,57 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [Item("Identity", "Identity transformation x' = x")]
+  [StorableClass]
+  public class IdentityTransformation : Transformation<double> {
+    #region Constructor, Cloning & Persistence
+    public IdentityTransformation()
+      : base() {
+    }
+
+    protected IdentityTransformation(IdentityTransformation original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new IdentityTransformation(this, cloner);
+    }
+
+    [StorableConstructor]
+    protected IdentityTransformation(bool deserializing)
+      : base(deserializing) {
+    }
+    #endregion
+
+    public override IEnumerable<double> Apply(IEnumerable<double> data) {
+      return data;
+    }
+
+    public override IEnumerable<double> InverseApply(IEnumerable<double> data) {
+      return data;
+    }
+  }
+}
\ No newline at end of file
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LinearTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LinearTransformation.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LinearTransformation.cs	(working copy)
@@ -0,0 +1,101 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [Item("Linear", "Linear transformation x' = slope * x + intercept")]
+  [StorableClass]
+  public class LinearTransformation : Transformation<double> {
+
+    #region Parameters
+    private FixedValueParameter<DoubleValue> SlopeParameter {
+      get { return (FixedValueParameter<DoubleValue>)Parameters["Slope"]; }
+    }
+
+    private FixedValueParameter<DoubleValue> InterceptParameter {
+      get { return (FixedValueParameter<DoubleValue>)Parameters["Intercept"]; }
+    }
+    #endregion
+
+    #region Properties
+    public double Slope {
+      get { return SlopeParameter.Value.Value; }
+      set { SlopeParameter.Value.Value = value; }
+    }
+
+    public double Intercept {
+      get { return InterceptParameter.Value.Value; }
+      set { InterceptParameter.Value.Value = value; }
+    }
+    #endregion
+
+    #region Constructor, Cloning & Persistence
+    public LinearTransformation()
+      : base() {
+      Parameters.Add(new FixedValueParameter<DoubleValue>("Slope", "Slope (multiplicative factor)", new DoubleValue(1.0)));
+      Parameters.Add(new FixedValueParameter<DoubleValue>("Intercept", "Intercept (additive factor)", new DoubleValue(0.0)));
+    }
+
+    protected LinearTransformation(LinearTransformation original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LinearTransformation(this, cloner);
+    }
+
+    [StorableConstructor]
+    protected LinearTransformation(bool deserializing)
+      : base(deserializing) {
+    }
+    #endregion
+
+    public override IEnumerable<double> Apply(IEnumerable<double> data) {
+      return Apply(data, Slope, Intercept);
+    }
+
+    public override IEnumerable<double> InverseApply(IEnumerable<double> data) {
+      return InverseApply(data, Slope, Intercept);
+    }
+
+
+    public static IEnumerable<double> Apply(IEnumerable<double> data, double slope = 1.0, double intercept = 0.0) {
+      if (slope.IsAlmost(0.0))
+        throw new InvalidOperationException($"Cannot transform with a {nameof(slope)} of zero because inverse transformation would be invalid.");
+
+      return data.Select(x => slope * x + intercept);
+    }
+
+    public static IEnumerable<double> InverseApply(IEnumerable<double> data, double slope = 1.0, double intercept = 0.0) {
+      if (slope.IsAlmost(0.0))
+        throw new InvalidOperationException($"Cannot inverse transform with a {nameof(slope)} of zero.");
+
+      return data.Select(x => (x - intercept) / slope);
+    }
+  }
+}
\ No newline at end of file
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LogarithmTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LogarithmTransformation.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LogarithmTransformation.cs	(working copy)
@@ -0,0 +1,92 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [Item("Logarithm", "Logarithm transformation x' = log(x, Base)")]
+  [StorableClass]
+  public class LogarithmTransformation : Transformation<double> {
+    #region Parameters
+    private FixedValueParameter<DoubleValue> BaseParameter {
+      get { return (FixedValueParameter<DoubleValue>)Parameters["Base"]; }
+    }
+    #endregion
+
+    #region Properties
+    public double Base {
+      get { return BaseParameter.Value.Value; }
+      set { BaseParameter.Value.Value = value; }
+    }
+    #endregion
+
+    #region Constructor, Cloning & Persistence
+    public LogarithmTransformation()
+      : base() {
+      Parameters.Add(new FixedValueParameter<DoubleValue>("Base", "Base the logarithm", new DoubleValue(Math.E)));
+    }
+
+    protected LogarithmTransformation(LogarithmTransformation original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LogarithmTransformation(this, cloner);
+    }
+
+    [StorableConstructor]
+    protected LogarithmTransformation(bool deserializing)
+      : base(deserializing) {
+    }
+    #endregion
+
+    public override bool Check(IEnumerable<double> data, out string errorMessage) {
+      if (data.Any(x => x <= 0)) {
+        errorMessage = "Log is not available for zero or negative values";
+        return false;
+      }
+      return base.Check(data, out errorMessage);
+    }
+
+    public override IEnumerable<double> Apply(IEnumerable<double> data) {
+      return Apply(data, Base);
+    }
+
+    public override IEnumerable<double> InverseApply(IEnumerable<double> data) {
+      return InverseApply(data, Base);
+    }
+
+
+    public static IEnumerable<double> Apply(IEnumerable<double> data, double @base = Math.E) {
+      return data.Select(x => Math.Log(x, @base));
+    }
+
+    public static IEnumerable<double> InverseApply(IEnumerable<double> data, double @base = Math.E) {
+      return ExponentialTransformation.Apply(data, @base);
+    }
+  }
+}
\ No newline at end of file
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/Transformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/Transformation.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/Transformation.cs	(working copy)
@@ -0,0 +1,58 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [Item("Transformation", "Represents the base class for transformations.")]
+  [StorableClass]
+  public abstract class Transformation<T> : ParameterizedNamedItem, ITransformation<T> {
+    #region Constructor, Cloning & Persistence
+    protected Transformation()
+      : base() {
+    }
+
+    protected Transformation(Transformation<T> original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    [StorableConstructor]
+    protected Transformation(bool deserializing)
+      : base(deserializing) {
+    }
+    #endregion
+
+    public virtual bool Check(IEnumerable<T> data, out string errorMessage) {
+      errorMessage = string.Empty;
+      return true;
+    }
+
+    public virtual void Configure(IEnumerable<T> data) {
+    }
+
+    public abstract IEnumerable<T> Apply(IEnumerable<T> data);
+
+    public abstract IEnumerable<T> InverseApply(IEnumerable<T> data);
+  }
+}
\ No newline at end of file
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ZNormalizationTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ZNormalizationTransformation.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ZNormalizationTransformation.cs	(working copy)
@@ -0,0 +1,139 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [Item("Z-Score Normalization", "Z-Score normalization transformation to standardize the values to a Target Mean and Target Standard Deviation.")]
+  [StorableClass]
+  public class ZNormalizationTransformation : Transformation<double> {
+    #region Parameters
+    private IFixedValueParameter<DoubleValue> TargetMeanParameter {
+      get { return (IFixedValueParameter<DoubleValue>)Parameters["Target Mean"]; }
+    }
+    private IFixedValueParameter<DoubleValue> TargetStandardDeviationParameter {
+      get { return (IFixedValueParameter<DoubleValue>)Parameters["Target Standard Deviation"]; }
+    }
+    private IFixedValueParameter<DoubleValue> OriginalMeanParameter {
+      get { return (IFixedValueParameter<DoubleValue>)Parameters["Original Mean"]; }
+    }
+    private IFixedValueParameter<DoubleValue> OriginalStandardDeviationParameter {
+      get { return (IFixedValueParameter<DoubleValue>)Parameters["Original Standard Deviation"]; }
+    }
+    #endregion
+
+    #region Properties
+    public double TargetMean {
+      get { return TargetMeanParameter.Value.Value; }
+      set { TargetMeanParameter.Value.Value = value; }
+    }
+    public double TargetStandardDeviation {
+      get { return TargetStandardDeviationParameter.Value.Value; }
+      set { TargetStandardDeviationParameter.Value.Value = value; }
+    }
+    public double OriginalMean {
+      get { return OriginalMeanParameter.Value.Value; }
+      private set { OriginalMeanParameter.Value.Value = value; }
+    }
+    public double OriginalStandardDeviation {
+      get { return OriginalStandardDeviationParameter.Value.Value; }
+      private set { OriginalStandardDeviationParameter.Value.Value = value; }
+    }
+    #endregion
+
+    #region Constructor, Cloning & Persistence
+    public ZNormalizationTransformation()
+      : base() {
+      Parameters.Add(new FixedValueParameter<DoubleValue>("Target Mean", new DoubleValue(0)));
+      Parameters.Add(new FixedValueParameter<DoubleValue>("Target Standard Deviation", new DoubleValue(1)));
+      Parameters.Add(new FixedValueParameter<DoubleValue>("Original Mean", new DoubleValue(double.NaN)) { Hidden = true });
+      Parameters.Add(new FixedValueParameter<DoubleValue>("Original Standard Deviation", new DoubleValue(double.NaN)) { Hidden = true });
+    }
+
+    protected ZNormalizationTransformation(ZNormalizationTransformation original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ZNormalizationTransformation(this, cloner);
+    }
+
+    [StorableConstructor]
+    protected ZNormalizationTransformation(bool deserializing)
+      : base(deserializing) {
+    }
+    #endregion
+
+    public override bool Check(IEnumerable<double> data, out string errorMessage) {
+      if (data.StandardDeviationPop().IsAlmost(0.0)) {
+        errorMessage = "Z-Score Normalization cannot be applied for data with a standard deviation of zero.";
+        return false;
+      }
+      return base.Check(data, out errorMessage);
+    }
+
+    public override void Configure(IEnumerable<double> data) {
+      Configure(data, out double originalMean, out double originalStandardDeviation);
+      OriginalMean = originalMean;
+      OriginalStandardDeviation = originalStandardDeviation;
+      base.Configure(data);
+    }
+
+    public override IEnumerable<double> Apply(IEnumerable<double> data) {
+      if (double.IsNaN(OriginalMean) || double.IsNaN(OriginalStandardDeviation))
+        throw new InvalidOperationException("Transformation is not configured");
+
+      return Apply(data, TargetMean, TargetStandardDeviation, OriginalMean, OriginalStandardDeviation);
+    }
+
+    public override IEnumerable<double> InverseApply(IEnumerable<double> data) {
+      if (double.IsNaN(OriginalMean) || double.IsNaN(OriginalStandardDeviation))
+        throw new InvalidOperationException("Transformation is not configured");
+
+      return InverseApply(data, TargetMean, TargetStandardDeviation, OriginalMean, OriginalStandardDeviation);
+    }
+
+
+    public static void Configure(IEnumerable<double> data, out double originalMean, out double originalStandardDeviation) {
+      originalMean = data.Average();
+      originalStandardDeviation = data.StandardDeviationPop();
+    }
+
+    public static IEnumerable<double> Apply(IEnumerable<double> data, double targetMean, double targetStandardDeviation, double originalMean = double.NaN, double originalStandardDeviation = double.NaN) {
+      if (double.IsNaN(originalMean)) originalMean = data.Average();
+      if (double.IsNaN(originalStandardDeviation)) originalStandardDeviation = data.StandardDeviationPop();
+
+      return data
+        .Select(x => (x - originalMean) / originalStandardDeviation) // standardize (0, 1)
+        .Select(x => x * targetStandardDeviation + targetMean);
+    }
+
+    public static IEnumerable<double> InverseApply(IEnumerable<double> data, double targetMean, double targetStandardDeviation, double originalMean, double originalStandardDeviation) {
+      return Apply(data, originalMean, originalStandardDeviation, targetMean, targetStandardDeviation);
+    }
+  }
+}
\ No newline at end of file
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/CopyColumnTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/CopyColumnTransformation.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/CopyColumnTransformation.cs	(working copy)
@@ -0,0 +1,65 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("CopyColumnTransformation", "Represents a transformation which represents a copied Column.")]
+  public class CopyColumnTransformation : Transformation {
+    protected const string CopiedColumnNameParameterName = "CopiedColumnName";
+
+    #region Parameters
+    public IValueParameter<StringValue> CopiedColumnNameParameter {
+      get { return (IValueParameter<StringValue>)Parameters[CopiedColumnNameParameterName]; }
+    }
+    #endregion
+
+    #region properties
+    public override string ShortName {
+      get { return "Cpy"; }
+    }
+    public string CopiedColumnName {
+      get { return CopiedColumnNameParameter.Value.Value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected CopyColumnTransformation(bool deserializing) : base(deserializing) { }
+    protected CopyColumnTransformation(CopyColumnTransformation original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public CopyColumnTransformation()
+      : base(Enumerable.Empty<string>()) {
+      Parameters.Add(new ValueParameter<StringValue>(CopiedColumnNameParameterName, "Name for the copied column", new StringValue()));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CopyColumnTransformation(this, cloner);
+    }
+  }
+}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/ExponentialTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/ExponentialTransformation.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/ExponentialTransformation.cs	(working copy)
@@ -0,0 +1,56 @@
+﻿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;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Exponential Transformation", "f(x) = b ^ x | Represents a exponential transformation.")]
+  public class ExponentialTransformation : Transformation<double> {
+    protected const string BaseParameterName = "Base";
+
+    #region Parameters
+    public IValueParameter<DoubleValue> BaseParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters[BaseParameterName]; }
+    }
+    #endregion
+
+    #region properties
+    public override string ShortName {
+      get { return "Exp"; }
+    }
+    public double Base {
+      get { return BaseParameter.Value.Value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected ExponentialTransformation(bool deserializing) : base(deserializing) { }
+
+    protected ExponentialTransformation(ExponentialTransformation original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    public ExponentialTransformation(IEnumerable<string> allowedColumns)
+      : base(allowedColumns) {
+      Parameters.Add(new ValueParameter<DoubleValue>(BaseParameterName, "b | Base of exp-function", new DoubleValue(Math.E)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ExponentialTransformation(this, cloner);
+    }
+
+    public override IEnumerable<double> Apply(IEnumerable<double> data) {
+      return data.Select(d => Math.Pow(Base, d));
+    }
+
+    public override bool Check(IEnumerable<double> data, out string errorMsg) {
+      errorMsg = "";
+      return true;
+    }
+  }
+}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/LinearTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/LinearTransformation.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/LinearTransformation.cs	(working copy)
@@ -0,0 +1,97 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Linear Transformation", "f(x) = k * x + d | Represents a linear transformation with multiplication and addition.")]
+  public class LinearTransformation : Transformation<double> {
+    protected const string MultiplierParameterName = "Multiplier";
+    protected const string AddendParameterName = "Addend";
+
+    #region Parameters
+    public IValueParameter<DoubleValue> MultiplierParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters[MultiplierParameterName]; }
+    }
+    public IValueParameter<DoubleValue> AddendParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters[AddendParameterName]; }
+    }
+    #endregion
+
+    #region properties
+    public override string ShortName {
+      get { return "Lin"; }
+    }
+    public double Multiplier {
+      get { return MultiplierParameter.Value.Value; }
+      set {
+        MultiplierParameter.Value.Value = value;
+      }
+    }
+
+    public double Addend {
+      get { return AddendParameter.Value.Value; }
+      set {
+        AddendParameter.Value.Value = value;
+      }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected LinearTransformation(bool deserializing) : base(deserializing) { }
+    protected LinearTransformation(LinearTransformation original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public LinearTransformation(IEnumerable<string> allowedColumns)
+      : base(allowedColumns) {
+      Parameters.Add(new ValueParameter<DoubleValue>(MultiplierParameterName, "k | Multiplier for linear transformation", new DoubleValue(1.0)));
+      Parameters.Add(new ValueParameter<DoubleValue>(AddendParameterName, "d | Addend for linear transformation", new DoubleValue(0.0)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LinearTransformation(this, cloner);
+    }
+
+    public override IEnumerable<double> Apply(IEnumerable<double> data) {
+      var m = Multiplier;
+      var a = Addend;
+      return data.Select(e => e * m + a);
+    }
+
+    public override bool Check(IEnumerable<double> data, out string errorMsg) {
+      errorMsg = null;
+      if (Multiplier.IsAlmost(0.0)) {
+        errorMsg = String.Format("Multiplicand is 0, all {0} entries will be set to {1}. Inverse apply will not be possible (division by 0).", data.Count(), Addend);
+        return false;
+      }
+      return true;
+    }
+  }
+}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/LogarithmicTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/LogarithmicTransformation.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/LogarithmicTransformation.cs	(working copy)
@@ -0,0 +1,61 @@
+﻿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;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Logarithmic Transformation", "f(x) = log(x, b) | Represents a logarithmic transformation.")]
+  public class LogarithmicTransformation : Transformation<double> {
+    protected const string BaseParameterName = "Base";
+
+    #region Parameters
+    public IValueParameter<DoubleValue> BaseParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters[BaseParameterName]; }
+    }
+    #endregion
+
+    #region properties
+    public override string ShortName {
+      get { return "Log"; }
+    }
+    public double Base {
+      get { return BaseParameter.Value.Value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected LogarithmicTransformation(bool deserializing) : base(deserializing) { }
+    protected LogarithmicTransformation(LogarithmicTransformation original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public LogarithmicTransformation(IEnumerable<string> allowedColumns)
+      : base(allowedColumns) {
+      Parameters.Add(new ValueParameter<DoubleValue>(BaseParameterName, "b | Base of log-function", new DoubleValue(Math.E)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LogarithmicTransformation(this, cloner);
+    }
+
+    public override IEnumerable<double> Apply(IEnumerable<double> data) {
+      var b = Base;
+      return data.Select(d => d > 0.0 ? Math.Log(d, b) : d);
+    }
+
+    public override bool Check(IEnumerable<double> data, out string errorMsg) {
+      errorMsg = null;
+      int errorCounter = data.Count(i => i <= 0.0);
+      if (errorCounter > 0) {
+        errorMsg = String.Format("{0} values are zero or below zero. Logarithm can not be applied onto these values", errorCounter);
+        return false;
+      }
+      return true;
+    }
+
+  }
+}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/PowerTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/PowerTransformation.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/PowerTransformation.cs	(working copy)
@@ -0,0 +1,55 @@
+﻿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;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Power Transformation", "f(x) = x ^ exp | Represents a power transformation.")]
+  public class PowerTransformation : Transformation<double> {
+    protected const string ExponentParameterName = "Exponent";
+
+    #region Parameters
+    public IValueParameter<DoubleValue> ExponentParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters[ExponentParameterName]; }
+    }
+    #endregion
+
+    #region properties
+    public override string ShortName {
+      get { return "Pow"; }
+    }
+    public double Exponent {
+      get { return ExponentParameter.Value.Value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected PowerTransformation(bool deserializing) : base(deserializing) { }
+    protected PowerTransformation(PowerTransformation original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public PowerTransformation(IEnumerable<string> allowedColumns)
+      : base(allowedColumns) {
+      Parameters.Add(new ValueParameter<DoubleValue>(ExponentParameterName, "exp | Exponent for Exponentation", new DoubleValue(2.0)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PowerTransformation(this, cloner);
+    }
+
+    public override IEnumerable<double> Apply(IEnumerable<double> data) {
+      return data.Select(i => Math.Pow(i, Exponent));
+    }
+
+    public override bool Check(IEnumerable<double> data, out string errorMsg) {
+      errorMsg = "";
+      return true;
+    }
+
+  }
+}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/ReciprocalTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/ReciprocalTransformation.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/ReciprocalTransformation.cs	(working copy)
@@ -0,0 +1,46 @@
+﻿
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Reciprocal Transformation", "f(x) = 1 / x | Represents a reciprocal transformation.")]
+  public class ReciprocalTransformation : Transformation<double> {
+
+    #region properties
+    public override string ShortName {
+      get { return "Inv"; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected ReciprocalTransformation(bool deserializing) : base(deserializing) { }
+    protected ReciprocalTransformation(ReciprocalTransformation original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public ReciprocalTransformation(IEnumerable<string> allowedColumns)
+      : base(allowedColumns) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ReciprocalTransformation(this, cloner);
+    }
+
+    public override IEnumerable<double> Apply(IEnumerable<double> data) {
+      return data.Select(d => d > 0 ? 1.0 / d : d);
+    }
+
+    public override bool Check(IEnumerable<double> data, out string errorMsg) {
+      errorMsg = null;
+      int errorCounter = data.Count(i => i <= 0.0);
+      if (errorCounter > 0) {
+        errorMsg = String.Format("{0} values are zero or below zero. 1/x can not be applied onto these values", errorCounter);
+        return false;
+      }
+      return true;
+    }
+  }
+}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/ShiftStandardDistributionTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/ShiftStandardDistributionTransformation.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/ShiftStandardDistributionTransformation.cs	(working copy)
@@ -0,0 +1,100 @@
+﻿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;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Shift Standard Distribution Transformation", "f(x) = ((x - m_org) / s_org ) * s_tar + m_tar | Represents Transformation to unit standard deviation and additional linear transformation to a target Mean and Standard deviation")]
+  public class ShiftStandardDistributionTransformation : Transformation<double> {
+    protected const string OriginalMeanParameterName = "Original Mean";
+    protected const string OriginalStandardDeviationParameterName = "Original Standard Deviation";
+    protected const string MeanParameterName = "Mean";
+    protected const string StandardDeviationParameterName = "Standard Deviation";
+
+    #region Parameters
+    public IValueParameter<DoubleValue> OriginalMeanParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters[OriginalMeanParameterName]; }
+    }
+    public IValueParameter<DoubleValue> OriginalStandardDeviationParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters[OriginalStandardDeviationParameterName]; }
+    }
+    public IValueParameter<DoubleValue> MeanParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters[MeanParameterName]; }
+    }
+    public IValueParameter<DoubleValue> StandardDeviationParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters[StandardDeviationParameterName]; }
+    }
+    #endregion
+
+    #region properties
+    public override string ShortName {
+      get { return "Std"; }
+    }
+    public double OriginalMean {
+      get { return OriginalMeanParameter.Value.Value; }
+      set { OriginalMeanParameter.Value.Value = value; }
+    }
+    public double OriginalStandardDeviation {
+      get { return OriginalStandardDeviationParameter.Value.Value; }
+      set { OriginalStandardDeviationParameter.Value.Value = value; }
+    }
+    public double Mean {
+      get { return MeanParameter.Value.Value; }
+    }
+    public double StandardDeviation {
+      get { return StandardDeviationParameter.Value.Value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected ShiftStandardDistributionTransformation(bool deserializing) : base(deserializing) { }
+    protected ShiftStandardDistributionTransformation(ShiftStandardDistributionTransformation original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public ShiftStandardDistributionTransformation(IEnumerable<string> allowedColumns)
+      : base(allowedColumns) {
+      Parameters.Add(new ValueParameter<DoubleValue>(OriginalMeanParameterName, "m_org | Mean value of the original data's deviation.", new DoubleValue()));
+      Parameters.Add(new ValueParameter<DoubleValue>(OriginalStandardDeviationParameterName, "s_org | Standard deviation of the original data.", new DoubleValue()));
+      OriginalMeanParameter.Hidden = true;
+      OriginalStandardDeviationParameter.Hidden = true;
+      Parameters.Add(new ValueParameter<DoubleValue>(MeanParameterName, "m_tar | Mean value for the target deviation.", new DoubleValue(0.0)));
+      Parameters.Add(new ValueParameter<DoubleValue>(StandardDeviationParameterName, "s_tar | Standard deviation for the target data.", new DoubleValue(1.0)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ShiftStandardDistributionTransformation(this, cloner);
+    }
+
+    public override IEnumerable<double> Apply(IEnumerable<double> data) {
+      if (OriginalStandardDeviation.IsAlmost(0.0)) {
+        return data;
+      }
+      var old_m = OriginalMean;
+      var old_s = OriginalStandardDeviation;
+      var m = Mean;
+      var s = StandardDeviation;
+      return data
+        .Select(d => (d - old_m) / old_s) // standardized
+        .Select(d => d * s + m);
+    }
+
+    public override bool Check(IEnumerable<double> data, out string errorMsg) {
+      ConfigureParameters(data);
+      errorMsg = "";
+      if (OriginalStandardDeviation.IsAlmost(0.0)) {
+        errorMsg = "Standard deviaton for the original data is 0.0, Transformation cannot be applied onto these values.";
+        return false;
+      }
+      return true;
+    }
+
+    public override void ConfigureParameters(IEnumerable<double> data) {
+      OriginalStandardDeviation = data.StandardDeviation();
+      OriginalMean = data.Average();
+    }
+  }
+}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/ShiftToRangeTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/ShiftToRangeTransformation.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/ShiftToRangeTransformation.cs	(working copy)
@@ -0,0 +1,62 @@
+﻿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;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Shift to Range Transformation", "f(x) = k * x + d, start <= f(x) <= end | Represents a linear Transformation using Parameters defining a target range")]
+  public class ShiftToRangeTransformation : LinearTransformation {
+    protected const string RangeParameterName = "Range";
+
+    #region Parameters
+    public IValueParameter<DoubleRange> RangeParameter {
+      get { return (IValueParameter<DoubleRange>)Parameters[RangeParameterName]; }
+    }
+    #endregion
+
+    #region properties
+    public override string ShortName {
+      get { return "Sft"; }
+    }
+    public DoubleRange Range {
+      get { return RangeParameter.Value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected ShiftToRangeTransformation(bool deserializing) : base(deserializing) { }
+    protected ShiftToRangeTransformation(ShiftToRangeTransformation original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public ShiftToRangeTransformation(IEnumerable<string> allowedColumns)
+      : base(allowedColumns) {
+      MultiplierParameter.Hidden = true;
+      AddendParameter.Hidden = true;
+      Parameters.Add(new ValueParameter<DoubleRange>(RangeParameterName, "start, end | Range for the target window of the linear transformation", new DoubleRange(0.0, 1.0)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ShiftToRangeTransformation(this, cloner);
+    }
+
+    public override bool Check(IEnumerable<double> data, out string errorMsg) {
+      ConfigureParameters(data);
+      return base.Check(data, out errorMsg);
+    }
+
+    public override void ConfigureParameters(IEnumerable<double> data) {
+      double originalRangeStart = data.Min();
+      double originalRangeEnd = data.Max();
+
+      double originalRangeWidth = originalRangeEnd - originalRangeStart;
+      double targetRangeWidth = Range.End - Range.Start;
+
+      Multiplier = targetRangeWidth / originalRangeWidth;
+      Addend = Range.Start - originalRangeStart * Multiplier;
+    }
+  }
+}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/Transformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/Transformation.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations (old)/Transformation.cs	(working copy)
@@ -0,0 +1,80 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+
+  [Item("Transformation", "Represents the base class for a transformation.")]
+  [StorableClass]
+  public abstract class Transformation : ParameterizedNamedItem, ITransformation {
+    protected const string ColumnParameterName = "Column";
+    #region parameter properties
+    public IConstrainedValueParameter<StringValue> ColumnParameter {
+      get { return (IConstrainedValueParameter<StringValue>)Parameters[ColumnParameterName]; }
+    }
+    #endregion
+
+    #region properties
+    public abstract string ShortName { get; }
+
+    public string Column {
+      get { return ColumnParameter.Value.Value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected Transformation(bool deserializing) : base(deserializing) { }
+    protected Transformation(Transformation original, Cloner cloner) : base(original, cloner) { }
+    protected Transformation(IEnumerable<string> allowedColumns) {
+      var allowed = new ItemSet<StringValue>(allowedColumns.Select(e => new StringValue(e)));
+      Parameters.Add(new ConstrainedValueParameter<StringValue>(ColumnParameterName, "Column used for the Transformation", allowed));
+    }
+  }
+
+  [Item("Transformation", "Represents the base class for a transformation.")]
+  [StorableClass]
+  public abstract class Transformation<T> : Transformation, ITransformation<T> {
+
+    [StorableConstructor]
+    protected Transformation(bool deserializing) : base(deserializing) { }
+    protected Transformation(Transformation<T> original, Cloner cloner) : base(original, cloner) { }
+    protected Transformation(IEnumerable<string> allowedColumns) : base(allowedColumns) { }
+
+    public virtual void ConfigureParameters(IEnumerable<T> data) {
+      // override in transformations with parameters
+    }
+
+    public abstract IEnumerable<T> Apply(IEnumerable<T> data);
+    public IEnumerable<T> ConfigureAndApply(IEnumerable<T> data) {
+      ConfigureParameters(data);
+      return Apply(data);
+    }
+
+    public abstract bool Check(IEnumerable<T> data, out string errorMsg);
+  }
+}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/CopyColumnTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/CopyColumnTransformation.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/CopyColumnTransformation.cs	(nonexistent)
@@ -1,65 +0,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  [Item("CopyColumnTransformation", "Represents a transformation which represents a copied Column.")]
-  public class CopyColumnTransformation : Transformation {
-    protected const string CopiedColumnNameParameterName = "CopiedColumnName";
-
-    #region Parameters
-    public IValueParameter<StringValue> CopiedColumnNameParameter {
-      get { return (IValueParameter<StringValue>)Parameters[CopiedColumnNameParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public override string ShortName {
-      get { return "Cpy"; }
-    }
-    public string CopiedColumnName {
-      get { return CopiedColumnNameParameter.Value.Value; }
-    }
-    #endregion
-
-    [StorableConstructor]
-    protected CopyColumnTransformation(bool deserializing) : base(deserializing) { }
-    protected CopyColumnTransformation(CopyColumnTransformation original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public CopyColumnTransformation()
-      : base(Enumerable.Empty<string>()) {
-      Parameters.Add(new ValueParameter<StringValue>(CopiedColumnNameParameterName, "Name for the copied column", new StringValue()));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new CopyColumnTransformation(this, cloner);
-    }
-  }
-}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LogarithmicTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LogarithmicTransformation.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LogarithmicTransformation.cs	(nonexistent)
@@ -1,61 +0,0 @@
-﻿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;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  [Item("Logarithmic Transformation", "f(x) = log(x, b) | Represents a logarithmic transformation.")]
-  public class LogarithmicTransformation : Transformation<double> {
-    protected const string BaseParameterName = "Base";
-
-    #region Parameters
-    public IValueParameter<DoubleValue> BaseParameter {
-      get { return (IValueParameter<DoubleValue>)Parameters[BaseParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public override string ShortName {
-      get { return "Log"; }
-    }
-    public double Base {
-      get { return BaseParameter.Value.Value; }
-    }
-    #endregion
-
-    [StorableConstructor]
-    protected LogarithmicTransformation(bool deserializing) : base(deserializing) { }
-    protected LogarithmicTransformation(LogarithmicTransformation original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public LogarithmicTransformation(IEnumerable<string> allowedColumns)
-      : base(allowedColumns) {
-      Parameters.Add(new ValueParameter<DoubleValue>(BaseParameterName, "b | Base of log-function", new DoubleValue(Math.E)));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new LogarithmicTransformation(this, cloner);
-    }
-
-    public override IEnumerable<double> Apply(IEnumerable<double> data) {
-      var b = Base;
-      return data.Select(d => d > 0.0 ? Math.Log(d, b) : d);
-    }
-
-    public override bool Check(IEnumerable<double> data, out string errorMsg) {
-      errorMsg = null;
-      int errorCounter = data.Count(i => i <= 0.0);
-      if (errorCounter > 0) {
-        errorMsg = String.Format("{0} values are zero or below zero. Logarithm can not be applied onto these values", errorCounter);
-        return false;
-      }
-      return true;
-    }
-
-  }
-}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/PowerTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/PowerTransformation.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/PowerTransformation.cs	(nonexistent)
@@ -1,55 +0,0 @@
-﻿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;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  [Item("Power Transformation", "f(x) = x ^ exp | Represents a power transformation.")]
-  public class PowerTransformation : Transformation<double> {
-    protected const string ExponentParameterName = "Exponent";
-
-    #region Parameters
-    public IValueParameter<DoubleValue> ExponentParameter {
-      get { return (IValueParameter<DoubleValue>)Parameters[ExponentParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public override string ShortName {
-      get { return "Pow"; }
-    }
-    public double Exponent {
-      get { return ExponentParameter.Value.Value; }
-    }
-    #endregion
-
-    [StorableConstructor]
-    protected PowerTransformation(bool deserializing) : base(deserializing) { }
-    protected PowerTransformation(PowerTransformation original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public PowerTransformation(IEnumerable<string> allowedColumns)
-      : base(allowedColumns) {
-      Parameters.Add(new ValueParameter<DoubleValue>(ExponentParameterName, "exp | Exponent for Exponentation", new DoubleValue(2.0)));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new PowerTransformation(this, cloner);
-    }
-
-    public override IEnumerable<double> Apply(IEnumerable<double> data) {
-      return data.Select(i => Math.Pow(i, Exponent));
-    }
-
-    public override bool Check(IEnumerable<double> data, out string errorMsg) {
-      errorMsg = "";
-      return true;
-    }
-
-  }
-}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ReciprocalTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ReciprocalTransformation.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ReciprocalTransformation.cs	(nonexistent)
@@ -1,46 +0,0 @@
-﻿
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  [Item("Reciprocal Transformation", "f(x) = 1 / x | Represents a reciprocal transformation.")]
-  public class ReciprocalTransformation : Transformation<double> {
-
-    #region properties
-    public override string ShortName {
-      get { return "Inv"; }
-    }
-    #endregion
-
-    [StorableConstructor]
-    protected ReciprocalTransformation(bool deserializing) : base(deserializing) { }
-    protected ReciprocalTransformation(ReciprocalTransformation original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public ReciprocalTransformation(IEnumerable<string> allowedColumns)
-      : base(allowedColumns) {
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new ReciprocalTransformation(this, cloner);
-    }
-
-    public override IEnumerable<double> Apply(IEnumerable<double> data) {
-      return data.Select(d => d > 0 ? 1.0 / d : d);
-    }
-
-    public override bool Check(IEnumerable<double> data, out string errorMsg) {
-      errorMsg = null;
-      int errorCounter = data.Count(i => i <= 0.0);
-      if (errorCounter > 0) {
-        errorMsg = String.Format("{0} values are zero or below zero. 1/x can not be applied onto these values", errorCounter);
-        return false;
-      }
-      return true;
-    }
-  }
-}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftStandardDistributionTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftStandardDistributionTransformation.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftStandardDistributionTransformation.cs	(nonexistent)
@@ -1,100 +0,0 @@
-﻿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;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  [Item("Shift Standard Distribution Transformation", "f(x) = ((x - m_org) / s_org ) * s_tar + m_tar | Represents Transformation to unit standard deviation and additional linear transformation to a target Mean and Standard deviation")]
-  public class ShiftStandardDistributionTransformation : Transformation<double> {
-    protected const string OriginalMeanParameterName = "Original Mean";
-    protected const string OriginalStandardDeviationParameterName = "Original Standard Deviation";
-    protected const string MeanParameterName = "Mean";
-    protected const string StandardDeviationParameterName = "Standard Deviation";
-
-    #region Parameters
-    public IValueParameter<DoubleValue> OriginalMeanParameter {
-      get { return (IValueParameter<DoubleValue>)Parameters[OriginalMeanParameterName]; }
-    }
-    public IValueParameter<DoubleValue> OriginalStandardDeviationParameter {
-      get { return (IValueParameter<DoubleValue>)Parameters[OriginalStandardDeviationParameterName]; }
-    }
-    public IValueParameter<DoubleValue> MeanParameter {
-      get { return (IValueParameter<DoubleValue>)Parameters[MeanParameterName]; }
-    }
-    public IValueParameter<DoubleValue> StandardDeviationParameter {
-      get { return (IValueParameter<DoubleValue>)Parameters[StandardDeviationParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public override string ShortName {
-      get { return "Std"; }
-    }
-    public double OriginalMean {
-      get { return OriginalMeanParameter.Value.Value; }
-      set { OriginalMeanParameter.Value.Value = value; }
-    }
-    public double OriginalStandardDeviation {
-      get { return OriginalStandardDeviationParameter.Value.Value; }
-      set { OriginalStandardDeviationParameter.Value.Value = value; }
-    }
-    public double Mean {
-      get { return MeanParameter.Value.Value; }
-    }
-    public double StandardDeviation {
-      get { return StandardDeviationParameter.Value.Value; }
-    }
-    #endregion
-
-    [StorableConstructor]
-    protected ShiftStandardDistributionTransformation(bool deserializing) : base(deserializing) { }
-    protected ShiftStandardDistributionTransformation(ShiftStandardDistributionTransformation original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public ShiftStandardDistributionTransformation(IEnumerable<string> allowedColumns)
-      : base(allowedColumns) {
-      Parameters.Add(new ValueParameter<DoubleValue>(OriginalMeanParameterName, "m_org | Mean value of the original data's deviation.", new DoubleValue()));
-      Parameters.Add(new ValueParameter<DoubleValue>(OriginalStandardDeviationParameterName, "s_org | Standard deviation of the original data.", new DoubleValue()));
-      OriginalMeanParameter.Hidden = true;
-      OriginalStandardDeviationParameter.Hidden = true;
-      Parameters.Add(new ValueParameter<DoubleValue>(MeanParameterName, "m_tar | Mean value for the target deviation.", new DoubleValue(0.0)));
-      Parameters.Add(new ValueParameter<DoubleValue>(StandardDeviationParameterName, "s_tar | Standard deviation for the target data.", new DoubleValue(1.0)));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new ShiftStandardDistributionTransformation(this, cloner);
-    }
-
-    public override IEnumerable<double> Apply(IEnumerable<double> data) {
-      if (OriginalStandardDeviation.IsAlmost(0.0)) {
-        return data;
-      }
-      var old_m = OriginalMean;
-      var old_s = OriginalStandardDeviation;
-      var m = Mean;
-      var s = StandardDeviation;
-      return data
-        .Select(d => (d - old_m) / old_s) // standardized
-        .Select(d => d * s + m);
-    }
-
-    public override bool Check(IEnumerable<double> data, out string errorMsg) {
-      ConfigureParameters(data);
-      errorMsg = "";
-      if (OriginalStandardDeviation.IsAlmost(0.0)) {
-        errorMsg = "Standard deviaton for the original data is 0.0, Transformation cannot be applied onto these values.";
-        return false;
-      }
-      return true;
-    }
-
-    public override void ConfigureParameters(IEnumerable<double> data) {
-      OriginalStandardDeviation = data.StandardDeviation();
-      OriginalMean = data.Average();
-    }
-  }
-}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftToRangeTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftToRangeTransformation.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftToRangeTransformation.cs	(nonexistent)
@@ -1,62 +0,0 @@
-﻿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;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
-  [Item("Shift to Range Transformation", "f(x) = k * x + d, start <= f(x) <= end | Represents a linear Transformation using Parameters defining a target range")]
-  public class ShiftToRangeTransformation : LinearTransformation {
-    protected const string RangeParameterName = "Range";
-
-    #region Parameters
-    public IValueParameter<DoubleRange> RangeParameter {
-      get { return (IValueParameter<DoubleRange>)Parameters[RangeParameterName]; }
-    }
-    #endregion
-
-    #region properties
-    public override string ShortName {
-      get { return "Sft"; }
-    }
-    public DoubleRange Range {
-      get { return RangeParameter.Value; }
-    }
-    #endregion
-
-    [StorableConstructor]
-    protected ShiftToRangeTransformation(bool deserializing) : base(deserializing) { }
-    protected ShiftToRangeTransformation(ShiftToRangeTransformation original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public ShiftToRangeTransformation(IEnumerable<string> allowedColumns)
-      : base(allowedColumns) {
-      MultiplierParameter.Hidden = true;
-      AddendParameter.Hidden = true;
-      Parameters.Add(new ValueParameter<DoubleRange>(RangeParameterName, "start, end | Range for the target window of the linear transformation", new DoubleRange(0.0, 1.0)));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new ShiftToRangeTransformation(this, cloner);
-    }
-
-    public override bool Check(IEnumerable<double> data, out string errorMsg) {
-      ConfigureParameters(data);
-      return base.Check(data, out errorMsg);
-    }
-
-    public override void ConfigureParameters(IEnumerable<double> data) {
-      double originalRangeStart = data.Min();
-      double originalRangeEnd = data.Max();
-
-      double originalRangeWidth = originalRangeEnd - originalRangeStart;
-      double targetRangeWidth = Range.End - Range.Start;
-
-      Multiplier = targetRangeWidth / originalRangeWidth;
-      Addend = Range.Start - originalRangeStart * Multiplier;
-    }
-  }
-}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationTransformationModel.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationTransformationModel.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationTransformationModel.cs	(working copy)
@@ -0,0 +1,27 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IClassificationTransformationModel : IDataAnalysisTransformationModel, IClassificationModel {
+    new IClassificationModel OriginalModel { get; }
+  }
+}
\ No newline at end of file
Index: HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringTransformationModel.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringTransformationModel.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringTransformationModel.cs	(working copy)
@@ -0,0 +1,26 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IClusteringTransformationModel : IDataAnalysisTransformationModel, IClusteringModel {
+    new IClusteringModel OriginalModel { get; }
+  }
+}
\ No newline at end of file
Index: HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblemData.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblemData.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblemData.cs	(working copy)
@@ -42,7 +42,7 @@
     IEnumerable<int> TrainingIndices { get; }
     IEnumerable<int> TestIndices { get; }
 
-    IEnumerable<ITransformation> Transformations { get; }
+    IEnumerable<IDataAnalysisTransformation> Transformations { get; }
 
     bool IsTrainingSample(int index);
     bool IsTestSample(int index);
Index: HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisTransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisTransformation.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisTransformation.cs	(working copy)
@@ -0,0 +1,32 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IDataAnalysisTransformation : INamedItem {
+
+    string OriginalVariable { get; }
+    string TransformedVariable { get; }
+
+    ITransformation Transformation { get; }
+  }
+}
\ No newline at end of file
Index: HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisTransformationModel.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisTransformationModel.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisTransformationModel.cs	(working copy)
@@ -0,0 +1,33 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IDataAnalysisTransformationModel : IDataAnalysisModel {
+    IDataAnalysisModel OriginalModel { get; }
+
+    /// <summary>
+    /// Transformations that are used on the model's inputs.
+    /// </summary>
+    IEnumerable<IDataAnalysisTransformation> InputTransformations { get; }
+  }
+}
\ No newline at end of file
Index: HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/ITransformation.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/ITransformation.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/ITransformation.cs	(working copy)
@@ -23,14 +23,38 @@
 using HeuristicLab.Core;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  public interface ITransformation : IParameterizedItem {
-    string ShortName { get; }
-    string Column { get; }
+  public interface ITransformation : IParameterizedNamedItem {
   }
 
   public interface ITransformation<T> : ITransformation {
-    void ConfigureParameters(IEnumerable<T> data);
-    IEnumerable<T> ConfigureAndApply(IEnumerable<T> data);
+    /// <summary>
+    /// Checks if the data is valid for the transformation.
+    /// Calling <code>Apply</code> or <code>Configure</code> on invalid data will throw an exception.
+    /// </summary>
+    /// <param name="data"></param>
+    /// <param name="errorMessage"></param>
+    /// <returns></returns>
+    bool Check(IEnumerable<T> data, out string errorMessage);
+
+    /// <summary>
+    /// Configure the internal parameter of the transformation for the given data.
+    /// </summary>
+    /// <param name="data"></param>
+    void Configure(IEnumerable<T> data);
+
+    /// <summary>
+    /// Transforms the given data based on the transformation's external and internal parameters.
+    /// </summary>
+    /// <param name="data"></param>
+    /// <returns></returns>
     IEnumerable<T> Apply(IEnumerable<T> data);
+    /// <summary>
+    /// Inverse-transforms the given data based on the transformation's external and internal parameters.
+    /// </summary>
+    /// <param name="data"></param>
+    /// <returns></returns>
+    /// <remarks>If the data cannot be inverse transformed, i.e. if the original data was not in the domain of the transformation, 
+    /// the returned values can contain invalid values or <code>InverseApply</code> might throw an exception.</remarks>
+    IEnumerable<T> InverseApply(IEnumerable<T> data);
   }
 }
Index: HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/ITransformationMapper.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/ITransformationMapper.cs	(revision 15884)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/ITransformationMapper.cs	(nonexistent)
@@ -1,28 +0,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  public interface ITransformationMapper<out T> {
-    T GenerateModel(ITransformation transformation);
-    T GenerateInverseModel(ITransformation transformation);
-  }
-}
Index: HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionTransformationModel.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionTransformationModel.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionTransformationModel.cs	(working copy)
@@ -0,0 +1,30 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IRegressionTransformationModel : IDataAnalysisTransformationModel, IRegressionModel {
+    new IRegressionModel OriginalModel { get; }
+
+    IEnumerable<IDataAnalysisTransformation> TargetTransformations { get; }
+  }
+}
\ No newline at end of file
Index: HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisTransformationModel.cs
===================================================================
--- HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisTransformationModel.cs	(nonexistent)
+++ HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisTransformationModel.cs	(working copy)
@@ -0,0 +1,26 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface ITimeSeriesPrognosisTransformationModel : IRegressionTransformationModel, ITimeSeriesPrognosisModel {
+    new ITimeSeriesPrognosisModel OriginalModel { get; }
+  }
+}
\ No newline at end of file
