Index: stable/HeuristicLab 3.3.sln
===================================================================
--- stable/HeuristicLab 3.3.sln	(revision 11158)
+++ stable/HeuristicLab 3.3.sln	(revision 11159)
@@ -68,8 +68,10 @@
 		{96E5ED5B-187D-4012-9CDA-D85CDAD38342} = {96E5ED5B-187D-4012-9CDA-D85CDAD38342}
 		{C664305E-497C-4533-A140-967DEDB05C19} = {C664305E-497C-4533-A140-967DEDB05C19}
+		{3FC7515E-D8A0-41FE-8CFA-50E3ADA61A1E} = {3FC7515E-D8A0-41FE-8CFA-50E3ADA61A1E}
 		{7EA0985E-A1D6-4FA7-B30A-2633FDFB01F0} = {7EA0985E-A1D6-4FA7-B30A-2633FDFB01F0}
 		{E10F395F-C8A6-48AD-B470-9AA7A1F43809} = {E10F395F-C8A6-48AD-B470-9AA7A1F43809}
 		{B7A64A60-B538-479F-9C47-A3180C458F6C} = {B7A64A60-B538-479F-9C47-A3180C458F6C}
 		{0C378762-D5DB-488A-8931-2BA42B1B7CBF} = {0C378762-D5DB-488A-8931-2BA42B1B7CBF}
+		{3B90F866-70F8-43EF-A541-51819D255B7B} = {3B90F866-70F8-43EF-A541-51819D255B7B}
 		{07486E68-1517-4B9D-A58D-A38E99AE71AB} = {07486E68-1517-4B9D-A58D-A38E99AE71AB}
 		{4AE3FC69-C575-42D2-BC46-0FAD5850EFC5} = {4AE3FC69-C575-42D2-BC46-0FAD5850EFC5}
@@ -115,4 +117,5 @@
 		{AB687BBE-1BFE-476B-906D-44237135431D} = {AB687BBE-1BFE-476B-906D-44237135431D}
 		{66D249C3-A01D-42A8-82A2-919BC8EC3D83} = {66D249C3-A01D-42A8-82A2-919BC8EC3D83}
+		{362A5DC3-969D-43FB-A552-D2F52B780188} = {362A5DC3-969D-43FB-A552-D2F52B780188}
 		{21977CC3-1757-4B3B-87BD-FF817AAA900F} = {21977CC3-1757-4B3B-87BD-FF817AAA900F}
 		{E4CFB0C3-0589-4893-B38E-8BEDF885C765} = {E4CFB0C3-0589-4893-B38E-8BEDF885C765}
@@ -395,4 +398,8 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.ExternalEvaluation.Matlab-3.3", "HeuristicLab.Problems.ExternalEvaluation.Matlab\3.3\HeuristicLab.Problems.ExternalEvaluation.Matlab-3.3.csproj", "{362A5DC3-969D-43FB-A552-D2F52B780188}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.DataPreprocessing-3.4", "HeuristicLab.DataPreprocessing\3.4\HeuristicLab.DataPreprocessing-3.4.csproj", "{3B90F866-70F8-43EF-A541-51819D255B7B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.DataPreprocessing.Views-3.4", "HeuristicLab.DataPreprocessing.Views\3.4\HeuristicLab.DataPreprocessing.Views-3.4.csproj", "{3FC7515E-D8A0-41FE-8CFA-50E3ADA61A1E}"
 EndProject
 Global
@@ -1930,4 +1937,24 @@
 		{362A5DC3-969D-43FB-A552-D2F52B780188}.Release|x86.ActiveCfg = Release|x86
 		{362A5DC3-969D-43FB-A552-D2F52B780188}.Release|x86.Build.0 = Release|x86
+		{3B90F866-70F8-43EF-A541-51819D255B7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{3B90F866-70F8-43EF-A541-51819D255B7B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{3B90F866-70F8-43EF-A541-51819D255B7B}.Debug|x64.ActiveCfg = Debug|x64
+		{3B90F866-70F8-43EF-A541-51819D255B7B}.Debug|x64.Build.0 = Debug|x64
+		{3B90F866-70F8-43EF-A541-51819D255B7B}.Debug|x86.ActiveCfg = Debug|x86
+		{3B90F866-70F8-43EF-A541-51819D255B7B}.Debug|x86.Build.0 = Debug|x86
+		{3B90F866-70F8-43EF-A541-51819D255B7B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{3B90F866-70F8-43EF-A541-51819D255B7B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{3B90F866-70F8-43EF-A541-51819D255B7B}.Release|x64.ActiveCfg = Release|x64
+		{3B90F866-70F8-43EF-A541-51819D255B7B}.Release|x64.Build.0 = Release|x64
+		{3B90F866-70F8-43EF-A541-51819D255B7B}.Release|x86.ActiveCfg = Release|x86
+		{3B90F866-70F8-43EF-A541-51819D255B7B}.Release|x86.Build.0 = Release|x86
+		{3FC7515E-D8A0-41FE-8CFA-50E3ADA61A1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{3FC7515E-D8A0-41FE-8CFA-50E3ADA61A1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{3FC7515E-D8A0-41FE-8CFA-50E3ADA61A1E}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{3FC7515E-D8A0-41FE-8CFA-50E3ADA61A1E}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{3FC7515E-D8A0-41FE-8CFA-50E3ADA61A1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{3FC7515E-D8A0-41FE-8CFA-50E3ADA61A1E}.Release|Any CPU.Build.0 = Release|Any CPU
+		{3FC7515E-D8A0-41FE-8CFA-50E3ADA61A1E}.Release|x64.ActiveCfg = Release|Any CPU
+		{3FC7515E-D8A0-41FE-8CFA-50E3ADA61A1E}.Release|x86.ActiveCfg = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: stable/HeuristicLab.Data.Views/3.3/StringConvertibleMatrixView.cs
===================================================================
--- stable/HeuristicLab.Data.Views/3.3/StringConvertibleMatrixView.cs	(revision 11158)
+++ stable/HeuristicLab.Data.Views/3.3/StringConvertibleMatrixView.cs	(revision 11159)
@@ -36,5 +36,5 @@
   public partial class StringConvertibleMatrixView : AsynchronousContentView {
     protected int[] virtualRowIndices;
-    private List<KeyValuePair<int, SortOrder>> sortedColumnIndices;
+    protected List<KeyValuePair<int, SortOrder>> sortedColumnIndices;
     private RowComparer rowComparer;
 
@@ -261,5 +261,5 @@
 
     #region DataGridView Events
-    private void dataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) {
+    protected virtual void dataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) {
       if (!dataGridView.ReadOnly) {
         string errorMessage;
@@ -270,5 +270,5 @@
       }
     }
-    private void dataGridView_CellParsing(object sender, DataGridViewCellParsingEventArgs e) {
+    protected virtual void dataGridView_CellParsing(object sender, DataGridViewCellParsingEventArgs e) {
       if (!dataGridView.ReadOnly) {
         string value = e.Value.ToString();
@@ -364,5 +364,5 @@
     }
 
-    private void PasteValuesToDataGridView() {
+    protected virtual void PasteValuesToDataGridView() {
       string[,] values = SplitClipboardString(Clipboard.GetText());
       int rowIndex = 0;
@@ -432,5 +432,5 @@
     }
 
-    private void Sort() {
+    protected void Sort() {
       virtualRowIndices = Sort(sortedColumnIndices);
       UpdateSortGlyph();
@@ -542,5 +542,5 @@
     }
 
-    private void dataGridView_SelectionChanged(object sender, EventArgs e) {
+    protected virtual void dataGridView_SelectionChanged(object sender, EventArgs e) {
       string stringFormat = "{0,20:0.0000}";
       statisticsTextBox.Text = string.Empty;
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/CheckedFilterCollectionView.Designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/CheckedFilterCollectionView.Designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/CheckedFilterCollectionView.Designer.cs	(revision 11159)
@@ -0,0 +1,39 @@
+﻿using HeuristicLab.Core.Views;
+using HeuristicLab.DataPreprocessing.Filter;
+namespace HeuristicLab.DataPreprocessing.Views
+{
+  partial class CheckedFilterCollectionView
+  {
+    /// <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: stable/HeuristicLab.DataPreprocessing.Views/3.4/CheckedFilterCollectionView.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/CheckedFilterCollectionView.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/CheckedFilterCollectionView.cs	(revision 11159)
@@ -0,0 +1,34 @@
+﻿using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using HeuristicLab.Core.Views;
+using HeuristicLab.Collections;
+using HeuristicLab.MainForm;
+using HeuristicLab.Core;
+using HeuristicLab.DataPreprocessing.Filter;
+
+namespace HeuristicLab.DataPreprocessing.Views
+{
+  [View("CheckedFilterCollection View")]
+  [Content(typeof(ICheckedItemCollection<>), false)]
+  [Content(typeof(CheckedItemCollection<>), false)]
+  public partial class CheckedFilterCollectionView : CheckedItemCollectionView<IFilter>
+  {
+    public CheckedFilterCollectionView()
+    {
+      InitializeComponent();
+    }
+
+    protected override void addButton_Click(object sender, EventArgs e)
+    {
+      IFilter filter = new ComparisonFilter();
+      Content.Add(filter);
+      Content.SetItemCheckedState(filter, false);
+    }
+
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/CheckedTransformationListView.Designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/CheckedTransformationListView.Designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/CheckedTransformationListView.Designer.cs	(revision 11159)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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: stable/HeuristicLab.DataPreprocessing.Views/3.4/CheckedTransformationListView.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/CheckedTransformationListView.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/CheckedTransformationListView.cs	(revision 11159)
@@ -0,0 +1,74 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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(RunCollectionConstraintCollection), true)]
+  [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.Data.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: stable/HeuristicLab.DataPreprocessing.Views/3.4/ComparisonFilterView.Designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/ComparisonFilterView.Designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/ComparisonFilterView.Designer.cs	(revision 11159)
@@ -0,0 +1,153 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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 ComparisonFilterView {
+    /// <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.components = new System.ComponentModel.Container();
+      this.lblAttr = new System.Windows.Forms.Label();
+      this.lblFilterOperation = new System.Windows.Forms.Label();
+      this.lblFilterData = new System.Windows.Forms.Label();
+      this.cbAttr = new System.Windows.Forms.ComboBox();
+      this.cbFilterOperation = new System.Windows.Forms.ComboBox();
+      this.tbFilterData = new System.Windows.Forms.TextBox();
+      this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // lblAttr
+      // 
+      this.lblAttr.AutoSize = true;
+      this.lblAttr.Location = new System.Drawing.Point(3, 15);
+      this.lblAttr.Name = "lblAttr";
+      this.lblAttr.Size = new System.Drawing.Size(49, 13);
+      this.lblAttr.TabIndex = 0;
+      this.lblAttr.Text = "Attribute:";
+      // 
+      // lblFilterOperation
+      // 
+      this.lblFilterOperation.AutoSize = true;
+      this.lblFilterOperation.Location = new System.Drawing.Point(3, 42);
+      this.lblFilterOperation.Name = "lblFilterOperation";
+      this.lblFilterOperation.Size = new System.Drawing.Size(81, 13);
+      this.lblFilterOperation.TabIndex = 1;
+      this.lblFilterOperation.Text = "Filter Operation:";
+      // 
+      // lblFilterData
+      // 
+      this.lblFilterData.AutoSize = true;
+      this.lblFilterData.Location = new System.Drawing.Point(3, 69);
+      this.lblFilterData.Name = "lblFilterData";
+      this.lblFilterData.Size = new System.Drawing.Size(58, 13);
+      this.lblFilterData.TabIndex = 2;
+      this.lblFilterData.Text = "Filter Data:";
+      // 
+      // cbAttr
+      // 
+      this.cbAttr.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.cbAttr.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.cbAttr.FormattingEnabled = true;
+      this.cbAttr.Location = new System.Drawing.Point(92, 12);
+      this.cbAttr.Name = "cbAttr";
+      this.cbAttr.Size = new System.Drawing.Size(235, 21);
+      this.cbAttr.TabIndex = 3;
+      this.cbAttr.SelectedIndexChanged += new System.EventHandler(this.cbAttr_SelectedIndexChanged);
+      // 
+      // cbFilterOperation
+      // 
+      this.cbFilterOperation.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.cbFilterOperation.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.cbFilterOperation.FormattingEnabled = true;
+      this.cbFilterOperation.Location = new System.Drawing.Point(92, 39);
+      this.cbFilterOperation.Name = "cbFilterOperation";
+      this.cbFilterOperation.Size = new System.Drawing.Size(235, 21);
+      this.cbFilterOperation.TabIndex = 4;
+      this.cbFilterOperation.SelectedIndexChanged += new System.EventHandler(this.cbFilterOperation_SelectedIndexChanged);
+      // 
+      // tbFilterData
+      // 
+      this.tbFilterData.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.tbFilterData.Location = new System.Drawing.Point(92, 67);
+      this.tbFilterData.Name = "tbFilterData";
+      this.tbFilterData.Size = new System.Drawing.Size(235, 20);
+      this.tbFilterData.TabIndex = 5;
+      this.tbFilterData.Validating += new System.ComponentModel.CancelEventHandler(this.tbFilterData_Validating);
+      this.tbFilterData.Validated += new System.EventHandler(this.tbFilterData_Validated);
+      // 
+      // errorProvider
+      // 
+      this.errorProvider.ContainerControl = this;
+      // 
+      // ComparisonFilterView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.tbFilterData);
+      this.Controls.Add(this.cbFilterOperation);
+      this.Controls.Add(this.cbAttr);
+      this.Controls.Add(this.lblFilterData);
+      this.Controls.Add(this.lblFilterOperation);
+      this.Controls.Add(this.lblAttr);
+      this.Name = "ComparisonFilterView";
+      this.Size = new System.Drawing.Size(348, 97);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Label lblAttr;
+    private System.Windows.Forms.Label lblFilterOperation;
+    private System.Windows.Forms.Label lblFilterData;
+    private System.Windows.Forms.ComboBox cbAttr;
+    private System.Windows.Forms.ComboBox cbFilterOperation;
+    private System.Windows.Forms.TextBox tbFilterData;
+    private System.Windows.Forms.ErrorProvider errorProvider;
+
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/ComparisonFilterView.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/ComparisonFilterView.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/ComparisonFilterView.cs	(revision 11159)
@@ -0,0 +1,182 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Linq;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.Data;
+using HeuristicLab.DataPreprocessing.Filter;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+  [View("Comparison Filter View")]
+  [Content(typeof(ComparisonFilter), false)]
+  public partial class ComparisonFilterView : ItemView {
+    public ComparisonFilterView() {
+      InitializeComponent();
+    }
+
+    public new ComparisonFilter Content {
+      get { return (ComparisonFilter)base.Content; }
+      set { base.Content = value; }
+    }
+
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      cbAttr.Items.Clear(); //cmbConstraintColumn.Items.Clear();
+      cbFilterOperation.Items.Clear(); //cmbConstraintOperation.Items.Clear();
+      tbFilterData.Text = string.Empty;
+      if (Content != null) {
+        cbFilterOperation.Items.AddRange(Content.AllowedConstraintOperations.ToArray());
+        if (Content.ConstraintOperation != null)
+          cbFilterOperation.SelectedItem = Content.ConstraintOperation;
+        else if (cbFilterOperation.Items.Count != 0)
+          cbFilterOperation.SelectedIndex = 0;
+        UpdateColumnComboBox();
+        ReadOnly = Content.Active;
+        if (Content.ConstraintData != null) {
+          tbFilterData.Text = Content.ConstraintData.GetValue();
+        } else {
+          this.Content_ConstraintColumnChanged(cbAttr, EventArgs.Empty); // TODO
+        }
+      }
+      if (Content == null || Content.ConstraintData == null) {
+        tbFilterData.Text = string.Empty;
+      } else {
+        tbFilterData.Text = Content.ConstraintData.GetValue();
+      }
+    }
+
+    protected virtual void UpdateColumnComboBox() {
+      this.cbAttr.Items.Clear();
+      if (Content.ConstrainedValue != null) {
+        this.cbAttr.Items.AddRange(Content.ConstrainedValue.VariableNames.ToArray<string>());
+        this.cbAttr.SelectedItem = this.cbAttr.Items[Content.ConstraintColumn];
+        cbAttr.SelectedItem = Content.ConstraintColumn;
+        if (Content.ConstraintData != null)
+          tbFilterData.Text = Content.ConstraintData.GetValue();
+        else
+          this.Content_ConstraintColumnChanged(cbAttr, EventArgs.Empty);
+      }
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      this.Content.ActiveChanged += new EventHandler(Content_ActiveChanged);
+      this.Content.ConstraintOperationChanged += new EventHandler(Content_ComparisonOperationChanged);
+      this.Content.ConstraintColumnChanged += new EventHandler(Content_ConstraintColumnChanged);
+      this.Content.ConstrainedValueChanged += new EventHandler(Content_ConstrainedValueChanged);
+      this.Content.ConstraintDataChanged += new EventHandler(Content_ConstrainedDataChanged);
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      this.Content.ActiveChanged -= new EventHandler(Content_ActiveChanged);
+      this.Content.ConstraintOperationChanged -= new EventHandler(Content_ComparisonOperationChanged);
+      this.Content.ConstraintColumnChanged -= new EventHandler(Content_ConstraintColumnChanged);
+      this.Content.ConstrainedValueChanged -= new EventHandler(Content_ConstrainedValueChanged);
+      this.Content.ConstraintDataChanged -= new EventHandler(Content_ConstrainedDataChanged);
+    }
+
+    protected virtual void Content_ConstrainedValueChanged(object sender, EventArgs e) {
+      this.UpdateColumnComboBox();
+    }
+
+    private void Content_ConstrainedDataChanged(object sender, EventArgs e) {
+      if (Content.ConstraintData != null)
+        tbFilterData.Text = Content.ConstraintData.GetValue();
+      else
+        tbFilterData.Text = string.Empty;
+    }
+
+    protected virtual void Content_ConstraintColumnChanged(object sender, EventArgs e) {
+      if (Content.ConstrainedValue != null) {
+        if (cbAttr.Items.IndexOf(cbAttr.SelectedItem) != Content.ConstraintColumn) {
+          cbAttr.SelectedItem = this.cbAttr.Items[Content.ConstraintColumn];
+        }
+      }
+      if (Content.ConstraintData == null) {
+        this.Content.ConstraintData = CreateStringConvertibleValue(cbAttr.SelectedIndex);
+      }
+    }
+
+
+    protected virtual void Content_ComparisonOperationChanged(object sender, EventArgs e) {
+      if (Content.ConstraintOperation != (ConstraintOperation)this.cbFilterOperation.SelectedItem)
+        this.cbFilterOperation.SelectedItem = Content.ConstraintOperation;
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      cbAttr.Enabled = Content != null && !Content.Active;
+      cbFilterOperation.Enabled = Content != null && !Content.Active;
+      tbFilterData.Enabled = Content != null && !Content.Active;
+    }
+
+    private void cbAttr_SelectedIndexChanged(object sender, EventArgs e) {
+      if (Content.ConstrainedValue != null) {
+        Content.ConstraintColumn = Content.ConstrainedValue.GetColumnIndex(cbAttr.SelectedItem.ToString());
+      }
+    }
+
+    private void cbFilterOperation_SelectedIndexChanged(object sender, EventArgs e) {
+      Content.ConstraintOperation = (ConstraintOperation)this.cbFilterOperation.SelectedItem;
+    }
+
+    protected virtual void Content_ActiveChanged(object sender, EventArgs e) {
+      this.ReadOnly = !Content.Active;
+      SetEnabledStateOfControls();
+      Refresh(); ResumeRepaint(true);
+    }
+
+    private void tbFilterData_Validated(object sender, EventArgs e) {
+      IStringConvertibleValue value = CreateStringConvertibleValue(cbAttr.SelectedIndex);
+      value.SetValue(tbFilterData.Text);
+      Content.ConstraintData = value;
+    }
+
+    private IStringConvertibleValue CreateStringConvertibleValue(int columnIndex) {
+      IStringConvertibleValue value;
+      if (Content.ConstrainedValue.VariableHasType<double>(columnIndex)) {
+        value = new DoubleValue();
+      } else if (Content.ConstrainedValue.VariableHasType<String>(columnIndex)) {
+        value = new StringValue();
+      } else if (Content.ConstrainedValue.VariableHasType<DateTime>(columnIndex)) {
+        value = new DateTimeValue();
+      } else {
+        throw new ArgumentException("unsupported type");
+      }
+      return value;
+    }
+
+    private void tbFilterData_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      string errorMessage = string.Empty;
+      if (!Content.ConstraintData.Validate(tbFilterData.Text, out errorMessage)) {
+        errorProvider.SetError(tbFilterData, errorMessage);
+        e.Cancel = true;
+      } else
+        errorProvider.Clear();
+    }
+
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/DataCompletenessView.Designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/DataCompletenessView.Designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/DataCompletenessView.Designer.cs	(revision 11159)
@@ -0,0 +1,65 @@
+﻿namespace HeuristicLab.DataPreprocessing.Views {
+  partial class DataCompletenessView
+  {
+    /// <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.components = new System.ComponentModel.Container();
+      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+      System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
+      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // chart
+      // 
+      this.chart.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)));
+      chartArea1.Name = "ChartArea1";
+      this.chart.ChartAreas.Add(chartArea1);
+      legend1.Name = "Legend1";
+      this.chart.Legends.Add(legend1);
+      this.chart.Location = new System.Drawing.Point(4, 4);
+      this.chart.Name = "chart";
+      this.chart.Size = new System.Drawing.Size(486, 337);
+      this.chart.TabIndex = 0;
+      this.chart.Text = "enhancedChart1";
+      // 
+      // DataCompletenessView
+      // 
+      this.Controls.Add(this.chart);
+      this.Name = "DataCompletenessView";
+      this.Size = new System.Drawing.Size(493, 344);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private Visualization.ChartControlsExtensions.EnhancedChart chart;
+
+
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/DataCompletenessView.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/DataCompletenessView.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/DataCompletenessView.cs	(revision 11159)
@@ -0,0 +1,176 @@
+﻿using System;
+using System.Windows.Forms;
+using HeuristicLab.Analysis;
+using HeuristicLab.MainForm;
+using HeuristicLab.Core.Views;
+using System.Collections.Generic;
+using HeuristicLab.DataPreprocessing.Implementations;
+using System.Drawing;
+using System.Windows.Forms.DataVisualization.Charting;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+
+  [View("Histogram View")]
+  [Content(typeof(DataCompletenessChartContent), true)]
+  public partial class DataCompletenessView : ItemView
+  {
+
+    //list of columns, bool indicates wether the cell is a missing value or not
+    private List<List<bool>> matrix = new List<List<bool>>();
+    //series colors
+    private static Color colorNonMissingVal = Color.CornflowerBlue;
+    private static Color colorMissingVal = Color.Orange;
+
+    public new DataCompletenessChartContent Content
+    {
+      get { return (DataCompletenessChartContent)base.Content; }
+      set { base.Content = value; }
+    }
+
+
+    public DataCompletenessView()
+    {
+      InitializeComponent();
+    }
+
+    protected override void OnContentChanged()
+    {
+      base.OnContentChanged();
+      if (Content != null)
+      {
+        InitData();
+      }
+    }
+
+    private void InitData()
+    {
+      IDictionary<int, IList<int>> missingValueIndices = Content.SearchLogic.GetMissingValueIndices();
+      for (int i = 0; i < Content.SearchLogic.Columns; i++)
+      {
+        //append column
+        List<bool> column = new List<bool>();
+        for (int j = 0; j < Content.SearchLogic.Rows; j++) {
+          column.Add(missingValueIndices[i].Contains(j));
+        }
+        matrix.Add(column);
+      }
+      List<List<int>> yValuesPerColumn = ProcessMatrixForCharting(matrix, missingValueIndices);
+      PrepareChart();
+      CreateSeries(yValuesPerColumn);
+    }
+
+    private void PrepareChart()
+    {
+      chart.Titles.Add("DataCompletenessChart");
+      chart.EnableDoubleClickResetsZoom = true;
+      chart.ChartAreas[0].AxisX.MajorGrid.LineWidth = 0;
+      chart.ChartAreas[0].AxisY.MajorGrid.LineWidth = 0;
+      chart.ChartAreas[0].AxisX.IsMarginVisible = false;
+      chart.ChartAreas[0].AxisY.IsMarginVisible = false;
+      chart.ChartAreas[0].CursorX.IsUserEnabled = true;
+      chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
+      chart.ChartAreas[0].CursorY.IsUserEnabled = true;
+      chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
+      //custom x axis label
+      double from = 0.5;
+      foreach (String columnName in Content.SearchLogic.VariableNames)
+      {
+        double to = from + 1;
+        chart.ChartAreas[0].AxisX.CustomLabels.Add(from, to, columnName);
+        from = to;
+      }
+      //custom y axis label
+      chart.ChartAreas[0].AxisY.IsReversed = true;
+    }
+
+    private void CreateSeries(List<List<int>> yValuesPerColumn)
+    {
+      //prepare series
+      int seriesCount = DetermineSeriesCount(yValuesPerColumn);
+      for (int i = 0; i < seriesCount; i++)
+      {
+        chart.Series.Add(CreateSeriesName(i));
+        Series series = chart.Series[CreateSeriesName(i)];
+        series.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.StackedColumn;
+        series.IsVisibleInLegend = false;
+        series["PointWidth"] = "1.0";
+        if (i % 2 == 0)
+        {
+          if (i == 0) //show legend for non missing values only once
+            series.IsVisibleInLegend = true;
+          series.Color = colorNonMissingVal;
+        }
+        else
+        {
+          if (i == 1) //show legend for missing values only once
+            series.IsVisibleInLegend = true;
+          series.Color = colorMissingVal;
+        }
+      }
+      //fill series
+      for (int i = 0; i < yValuesPerColumn.Count; i++)
+      {
+        List<int> column = yValuesPerColumn[i];
+        for (int j = 0; j < seriesCount; j++) {
+          if (column.Count - 1 < j) {
+            chart.Series[CreateSeriesName(j)].Points.AddY(0);
+          } else {
+            chart.Series[CreateSeriesName(j)].Points.AddY(column[j]);
+          }
+        }
+      }
+    }
+
+    private String CreateSeriesName(int index)
+    {
+      if (index == 0)
+        return "non-missing value";
+      else if (index == 1)
+        return "missing value";
+      return "series" + index;
+    }
+
+    #region data_preparation_for_chartseries
+    private int DetermineSeriesCount(List<List<int>> yValuesPerColumn)
+    {
+      int highest = 0;
+      foreach (List<int> values in yValuesPerColumn) {
+        highest = Math.Max(values.Count, highest);
+      }
+      return highest;
+    }
+
+    private List<List<int>> ProcessMatrixForCharting(List<List<bool>> matrix, IDictionary<int, IList<int>> missingValueIndices)
+    {
+      List<List<int>> columnsYValues = new List<List<int>>();
+      for (int i=0; i < matrix.Count; i++) //column
+      {
+        List<int> yValues = new List<int>();
+        List<bool> column = matrix[i];
+        bool missingState = false;
+        int valueCount = 0;
+        for (int j = 0; j < column.Count; j++ ) {
+          if (missingState == missingValueIndices[i].Contains(j))
+          {
+            valueCount++;
+          }
+          else
+          {
+            yValues.Add(valueCount);
+            valueCount = 1;
+            missingState = !missingState;
+          }
+        }
+        yValues.Add(valueCount);
+        if (missingState) //handle last missing
+        {
+          yValues.Add(0);
+        }
+        //yValues.Reverse();
+        columnsYValues.Add(yValues);
+      }
+      return columnsYValues;
+    }
+    #endregion
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/DataGridContentView.Designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/DataGridContentView.Designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/DataGridContentView.Designer.cs	(revision 11159)
@@ -0,0 +1,268 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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 DataGridContentView {
+    /// <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 Windows Form 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.components = new System.ComponentModel.Container();
+      this.btnApplySort = new System.Windows.Forms.Button();
+      this.contextMenuCell = new System.Windows.Forms.ContextMenuStrip(this.components);
+      this.replaceValueOverColumnToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.averageToolStripMenuItem_Column = new System.Windows.Forms.ToolStripMenuItem();
+      this.medianToolStripMenuItem_Column = new System.Windows.Forms.ToolStripMenuItem();
+      this.randomToolStripMenuItem_Column = new System.Windows.Forms.ToolStripMenuItem();
+      this.mostCommonToolStripMenuItem_Column = new System.Windows.Forms.ToolStripMenuItem();
+      this.interpolationToolStripMenuItem_Column = new System.Windows.Forms.ToolStripMenuItem();
+      this.smoothingToolStripMenuItem_Column = new System.Windows.Forms.ToolStripMenuItem();
+      this.replaceValueOverSelectionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.averageToolStripMenuItem_Selection = new System.Windows.Forms.ToolStripMenuItem();
+      this.medianToolStripMenuItem_Selection = new System.Windows.Forms.ToolStripMenuItem();
+      this.randomToolStripMenuItem_Selection = new System.Windows.Forms.ToolStripMenuItem();
+      this.mostCommonToolStripMenuItem_Selection = new System.Windows.Forms.ToolStripMenuItem();
+      this.btnSearch = new System.Windows.Forms.Button();
+      this.btnReplace = new System.Windows.Forms.Button();
+      this.toolTip = new System.Windows.Forms.ToolTip(this.components);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.contextMenuCell.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // rowsTextBox
+      // 
+      this.rowsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)));
+      this.rowsTextBox.Enabled = false;
+      this.errorProvider.SetIconAlignment(this.rowsTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.rowsTextBox, 2);
+      this.rowsTextBox.ReadOnly = true;
+      this.rowsTextBox.Size = new System.Drawing.Size(71, 20);
+      // 
+      // columnsTextBox
+      // 
+      this.columnsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)));
+      this.columnsTextBox.Enabled = false;
+      this.columnsTextBox.ReadOnly = true;
+      this.columnsTextBox.Size = new System.Drawing.Size(71, 20);
+      // 
+      // statisticsTextBox
+      // 
+      this.statisticsTextBox.Size = new System.Drawing.Size(522, 13);
+      // 
+      // btnApplySort
+      // 
+      this.btnApplySort.Location = new System.Drawing.Point(349, 19);
+      this.btnApplySort.Name = "btnApplySort";
+      this.btnApplySort.Size = new System.Drawing.Size(75, 23);
+      this.btnApplySort.TabIndex = 7;
+      this.btnApplySort.Text = "Apply Sort";
+      this.toolTip.SetToolTip(this.btnApplySort, "The current sorting is applied on the data itself.");
+      this.btnApplySort.UseVisualStyleBackColor = true;
+      this.btnApplySort.Click += new System.EventHandler(this.btnApplySort_Click);
+      // 
+      // contextMenuCell
+      // 
+      this.contextMenuCell.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.replaceValueOverColumnToolStripMenuItem,
+            this.replaceValueOverSelectionToolStripMenuItem});
+      this.contextMenuCell.Name = "contextMenuCell";
+      this.contextMenuCell.Size = new System.Drawing.Size(225, 70);
+      // 
+      // replaceValueOverColumnToolStripMenuItem
+      // 
+      this.replaceValueOverColumnToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.averageToolStripMenuItem_Column,
+            this.medianToolStripMenuItem_Column,
+            this.randomToolStripMenuItem_Column,
+            this.mostCommonToolStripMenuItem_Column,
+            this.interpolationToolStripMenuItem_Column,
+            this.smoothingToolStripMenuItem_Column});
+      this.replaceValueOverColumnToolStripMenuItem.Name = "replaceValueOverColumnToolStripMenuItem";
+      this.replaceValueOverColumnToolStripMenuItem.Size = new System.Drawing.Size(224, 22);
+      this.replaceValueOverColumnToolStripMenuItem.Text = "Replace Value over Column";
+      // 
+      // averageToolStripMenuItem_Column
+      // 
+      this.averageToolStripMenuItem_Column.Name = "averageToolStripMenuItem_Column";
+      this.averageToolStripMenuItem_Column.Size = new System.Drawing.Size(155, 22);
+      this.averageToolStripMenuItem_Column.Text = "Average";
+      this.averageToolStripMenuItem_Column.Click += new System.EventHandler(this.ReplaceWithAverage_Column_Click);
+      // 
+      // medianToolStripMenuItem_Column
+      // 
+      this.medianToolStripMenuItem_Column.Name = "medianToolStripMenuItem_Column";
+      this.medianToolStripMenuItem_Column.Size = new System.Drawing.Size(155, 22);
+      this.medianToolStripMenuItem_Column.Text = "Median";
+      this.medianToolStripMenuItem_Column.Click += new System.EventHandler(this.ReplaceWithMedian_Column_Click);
+      // 
+      // randomToolStripMenuItem_Column
+      // 
+      this.randomToolStripMenuItem_Column.Name = "randomToolStripMenuItem_Column";
+      this.randomToolStripMenuItem_Column.Size = new System.Drawing.Size(155, 22);
+      this.randomToolStripMenuItem_Column.Text = "Random";
+      this.randomToolStripMenuItem_Column.Click += new System.EventHandler(this.ReplaceWithRandom_Column_Click);
+      // 
+      // mostCommonToolStripMenuItem_Column
+      // 
+      this.mostCommonToolStripMenuItem_Column.Name = "mostCommonToolStripMenuItem_Column";
+      this.mostCommonToolStripMenuItem_Column.Size = new System.Drawing.Size(155, 22);
+      this.mostCommonToolStripMenuItem_Column.Text = "Most Common";
+      this.mostCommonToolStripMenuItem_Column.Click += new System.EventHandler(this.ReplaceWithMostCommon_Column_Click);
+      // 
+      // interpolationToolStripMenuItem_Column
+      // 
+      this.interpolationToolStripMenuItem_Column.Name = "interpolationToolStripMenuItem_Column";
+      this.interpolationToolStripMenuItem_Column.Size = new System.Drawing.Size(155, 22);
+      this.interpolationToolStripMenuItem_Column.Text = "Interpolation";
+      this.interpolationToolStripMenuItem_Column.Click += new System.EventHandler(this.ReplaceWithInterpolation_Column_Click);
+      // 
+      // smoothingToolStripMenuItem
+      // 
+      this.smoothingToolStripMenuItem_Column.Name = "smoothingToolStripMenuItem";
+      this.smoothingToolStripMenuItem_Column.Size = new System.Drawing.Size(155, 22);
+      this.smoothingToolStripMenuItem_Column.Text = "Smoothing";
+      this.smoothingToolStripMenuItem_Column.Click += new System.EventHandler(this.ReplaceWithSmoothing_Selection_Click);
+      // 
+      // replaceValueOverSelectionToolStripMenuItem
+      // 
+      this.replaceValueOverSelectionToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.averageToolStripMenuItem_Selection,
+            this.medianToolStripMenuItem_Selection,
+            this.randomToolStripMenuItem_Selection,
+            this.mostCommonToolStripMenuItem_Selection});
+      this.replaceValueOverSelectionToolStripMenuItem.Name = "replaceValueOverSelectionToolStripMenuItem";
+      this.replaceValueOverSelectionToolStripMenuItem.Size = new System.Drawing.Size(224, 22);
+      this.replaceValueOverSelectionToolStripMenuItem.Text = "Replace Value over Selection";
+      // 
+      // averageToolStripMenuItem_Selection
+      // 
+      this.averageToolStripMenuItem_Selection.Name = "averageToolStripMenuItem_Selection";
+      this.averageToolStripMenuItem_Selection.Size = new System.Drawing.Size(155, 22);
+      this.averageToolStripMenuItem_Selection.Text = "Average";
+      this.averageToolStripMenuItem_Selection.Click += new System.EventHandler(this.ReplaceWithAverage_Selection_Click);
+      // 
+      // medianToolStripMenuItem_Selection
+      // 
+      this.medianToolStripMenuItem_Selection.Name = "medianToolStripMenuItem_Selection";
+      this.medianToolStripMenuItem_Selection.Size = new System.Drawing.Size(155, 22);
+      this.medianToolStripMenuItem_Selection.Text = "Median";
+      this.medianToolStripMenuItem_Selection.Click += new System.EventHandler(this.ReplaceWithMedian_Selection_Click);
+      // 
+      // randomToolStripMenuItem_Selection
+      // 
+      this.randomToolStripMenuItem_Selection.Name = "randomToolStripMenuItem_Selection";
+      this.randomToolStripMenuItem_Selection.Size = new System.Drawing.Size(155, 22);
+      this.randomToolStripMenuItem_Selection.Text = "Random";
+      this.randomToolStripMenuItem_Selection.Click += new System.EventHandler(this.ReplaceWithRandom_Selection_Click);
+      // 
+      // mostCommonToolStripMenuItem_Selection
+      // 
+      this.mostCommonToolStripMenuItem_Selection.Name = "mostCommonToolStripMenuItem_Selection";
+      this.mostCommonToolStripMenuItem_Selection.Size = new System.Drawing.Size(155, 22);
+      this.mostCommonToolStripMenuItem_Selection.Text = "Most Common";
+      this.mostCommonToolStripMenuItem_Selection.Click += new System.EventHandler(this.ReplaceWithMostCommon_Selection_Click);
+      // 
+      // btnSearch
+      // 
+      this.btnSearch.Location = new System.Drawing.Point(201, 19);
+      this.btnSearch.Name = "btnSearch";
+      this.btnSearch.Size = new System.Drawing.Size(53, 23);
+      this.btnSearch.TabIndex = 8;
+      this.btnSearch.Text = "Search";
+      this.toolTip.SetToolTip(this.btnSearch, "Opens the Search dialog");
+      this.btnSearch.UseVisualStyleBackColor = true;
+      this.btnSearch.Click += new System.EventHandler(this.btnSearch_Click);
+      // 
+      // btnReplace
+      // 
+      this.btnReplace.Location = new System.Drawing.Point(260, 19);
+      this.btnReplace.Name = "btnReplace";
+      this.btnReplace.Size = new System.Drawing.Size(55, 23);
+      this.btnReplace.TabIndex = 9;
+      this.btnReplace.Text = "Replace";
+      this.toolTip.SetToolTip(this.btnReplace, "Opens the Search & Replace dialog");
+      this.btnReplace.UseVisualStyleBackColor = true;
+      this.btnReplace.Click += new System.EventHandler(this.btnReplace_Click);
+      // 
+      // DataGridContentView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.btnReplace);
+      this.Controls.Add(this.btnSearch);
+      this.Controls.Add(this.btnApplySort);
+      this.Name = "DataGridContentView";
+      this.Size = new System.Drawing.Size(528, 404);
+      this.Controls.SetChildIndex(this.statisticsTextBox, 0);
+      this.Controls.SetChildIndex(this.rowsLabel, 0);
+      this.Controls.SetChildIndex(this.columnsLabel, 0);
+      this.Controls.SetChildIndex(this.rowsTextBox, 0);
+      this.Controls.SetChildIndex(this.columnsTextBox, 0);
+      this.Controls.SetChildIndex(this.btnApplySort, 0);
+      this.Controls.SetChildIndex(this.btnSearch, 0);
+      this.Controls.SetChildIndex(this.btnReplace, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.contextMenuCell.ResumeLayout(false);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Button btnApplySort;
+    private System.Windows.Forms.ContextMenuStrip contextMenuCell;
+    private System.Windows.Forms.ToolStripMenuItem replaceValueOverColumnToolStripMenuItem;
+    private System.Windows.Forms.ToolStripMenuItem averageToolStripMenuItem_Column;
+    private System.Windows.Forms.ToolStripMenuItem medianToolStripMenuItem_Column;
+    private System.Windows.Forms.ToolStripMenuItem randomToolStripMenuItem_Column;
+    private System.Windows.Forms.ToolStripMenuItem mostCommonToolStripMenuItem_Column;
+    private System.Windows.Forms.ToolStripMenuItem interpolationToolStripMenuItem_Column;
+    private System.Windows.Forms.ToolStripMenuItem replaceValueOverSelectionToolStripMenuItem;
+    private System.Windows.Forms.ToolStripMenuItem averageToolStripMenuItem_Selection;
+    private System.Windows.Forms.ToolStripMenuItem medianToolStripMenuItem_Selection;
+    private System.Windows.Forms.ToolStripMenuItem randomToolStripMenuItem_Selection;
+    private System.Windows.Forms.ToolStripMenuItem mostCommonToolStripMenuItem_Selection;
+    private System.Windows.Forms.Button btnSearch;
+    private System.Windows.Forms.Button btnReplace;
+    private System.Windows.Forms.ToolTip toolTip;
+    private System.Windows.Forms.ToolStripMenuItem smoothingToolStripMenuItem_Column;
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/DataGridContentView.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/DataGridContentView.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/DataGridContentView.cs	(revision 11159)
@@ -0,0 +1,595 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Windows.Forms;
+using HeuristicLab.Data;
+using HeuristicLab.Data.Views;
+using HeuristicLab.DataPreprocessing.Filter;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+  [View("Data Grid Content View")]
+  [Content(typeof(IDataGridContent), true)]
+  public partial class DataGridContentView : StringConvertibleMatrixView {
+
+    private bool isSearching = false;
+    private bool updateOnMouseUp = false;
+    private SearchAndReplaceDialog findAndReplaceDialog;
+    private IFindPreprocessingItemsIterator searchIterator;
+    private string currentSearchText;
+    private ComparisonOperation currentComparisonOperation;
+    private Tuple<int, int> currentCell;
+
+    public new IDataGridContent Content {
+      get { return (IDataGridContent)base.Content; }
+      set { base.Content = value; }
+    }
+
+    private IDictionary<int, IList<int>> _highlightedCellsBackground;
+    public IDictionary<int, IList<int>> HightlightedCellsBackground {
+      get { return _highlightedCellsBackground; }
+      set {
+        _highlightedCellsBackground = value;
+        Refresh();
+      }
+    }
+
+    public DataGridContentView() {
+      InitializeComponent();
+      dataGridView.CellMouseClick += dataGridView_CellMouseClick;
+      dataGridView.KeyDown += dataGridView_KeyDown;
+      dataGridView.MouseUp += dataGridView_MouseUp;
+      dataGridView.ColumnHeaderMouseClick += dataGridView_ColumnHeaderMouseClick;
+      contextMenuCell.Items.Add(ShowHideColumns);
+      _highlightedCellsBackground = new Dictionary<int, IList<int>>();
+      currentCell = null;
+    }
+
+    protected override void OnContentChanged() {
+      List<KeyValuePair<int, SortOrder>> order = new List<KeyValuePair<int, SortOrder>>(base.sortedColumnIndices);
+      base.OnContentChanged();
+
+      DataGridView.RowHeadersWidth = 70;
+
+      if (Content == null && findAndReplaceDialog != null) {
+        findAndReplaceDialog.Close();
+      }
+
+      if (Content != null) {
+        base.sortedColumnIndices = order;
+        base.Sort();
+      }
+
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.Changed += Content_Changed;
+      Content.FilterLogic.FilterChanged += FilterLogic_FilterChanged;
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.Changed -= Content_Changed;
+      Content.FilterLogic.FilterChanged -= FilterLogic_FilterChanged;
+    }
+
+    private void FilterLogic_FilterChanged(object sender, EventArgs e) {
+      OnContentChanged();
+      searchIterator = null;
+      if (findAndReplaceDialog != null && !findAndReplaceDialog.IsDisposed) {
+        if (Content.FilterLogic.IsFiltered) {
+          findAndReplaceDialog.DisableReplace();
+        } else {
+          findAndReplaceDialog.EnableReplace();
+        }
+      }
+      btnReplace.Enabled = !Content.FilterLogic.IsFiltered;
+    }
+
+    private void Content_Changed(object sender, DataPreprocessingChangedEventArgs e) {
+      OnContentChanged();
+      searchIterator = null;
+    }
+
+    protected override void dataGridView_SelectionChanged(object sender, EventArgs e) {
+      base.dataGridView_SelectionChanged(sender, e);
+      if (Content != null && dataGridView.RowCount != 0 && dataGridView.ColumnCount != 0)
+        Content.Selection = GetSelectedCells();
+    }
+
+    //couldn't use base.dataGridView_CellValidating as the values have to be validated per column individually
+    protected override void dataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) {
+      if (dataGridView.ReadOnly) return;
+      if (Content == null) return;
+      if (Content.Rows == 0 || Content.Columns == 0) return;
+
+      string errorMessage;
+      if (Content != null) {
+        if (dataGridView.IsCurrentCellInEditMode && Content.FilterLogic.IsFiltered) {
+          errorMessage = "A filter is active, you cannot modify data. Press ESC to exit edit mode.";
+        } else {
+          Content.Validate(e.FormattedValue.ToString(), out errorMessage, e.ColumnIndex);
+        }
+
+        if (!String.IsNullOrEmpty(errorMessage)) {
+          e.Cancel = true;
+          dataGridView.Rows[e.RowIndex].ErrorText = errorMessage;
+        }
+
+      }
+    }
+
+
+    //protected override void PasteValuesToDataGridView() {
+    //  base.PasteValuesToDataGridView();
+    //  dataGridView.Refresh();
+    //}
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      rowsTextBox.ReadOnly = true;
+      columnsTextBox.ReadOnly = true;
+    }
+
+    protected override int[] Sort(IEnumerable<KeyValuePair<int, SortOrder>> sortedColumns) {
+      btnApplySort.Enabled = sortedColumns.Any();
+      return base.Sort(sortedColumns);
+    }
+
+    protected override void ClearSorting() {
+      btnApplySort.Enabled = false;
+      base.ClearSorting();
+    }
+
+    private void dataGridView_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) {
+      searchIterator = null;
+    }
+
+    private void dataGridView_MouseUp(object sender, MouseEventArgs e) {
+      if (!updateOnMouseUp)
+        return;
+
+      updateOnMouseUp = false;
+      dataGridView_SelectionChanged(sender, e);
+    }
+
+    private void btnApplySort_Click(object sender, System.EventArgs e) {
+      Content.ManipulationLogic.ReOrderToIndices(virtualRowIndices);
+      OnContentChanged();
+    }
+
+    #region FindAndReplaceDialog
+
+    private void CreateFindAndReplaceDialog() {
+      if (findAndReplaceDialog == null || findAndReplaceDialog.IsDisposed) {
+        findAndReplaceDialog = new SearchAndReplaceDialog();
+        findAndReplaceDialog.Show(this);
+        if (AreMultipleCellsSelected()) {
+          ResetHighlightedCellsBackground();
+          HightlightedCellsBackground = GetSelectedCells();
+          dataGridView.ClearSelection();
+        }
+        findAndReplaceDialog.FindAllEvent += findAndReplaceDialog_FindAllEvent;
+        findAndReplaceDialog.FindNextEvent += findAndReplaceDialog_FindNextEvent;
+        findAndReplaceDialog.ReplaceAllEvent += findAndReplaceDialog_ReplaceAllEvent;
+        findAndReplaceDialog.ReplaceNextEvent += findAndReplaceDialog_ReplaceEvent;
+        findAndReplaceDialog.FormClosing += findAndReplaceDialog_FormClosing;
+        searchIterator = null;
+        DataGridView.SelectionChanged += DataGridView_SelectionChanged_FindAndReplace;
+        if (Content.FilterLogic.IsFiltered) {
+          findAndReplaceDialog.DisableReplace();
+        }
+      }
+    }
+
+    private void DataGridView_SelectionChanged_FindAndReplace(object sender, EventArgs e) {
+      if (Content != null) {
+        if (!isSearching && AreMultipleCellsSelected()) {
+          ResetHighlightedCellsBackground();
+          HightlightedCellsBackground = GetSelectedCells();
+          searchIterator = null;
+        }
+      }
+    }
+
+    void findAndReplaceDialog_FormClosing(object sender, FormClosingEventArgs e) {
+      ResetHighlightedCellsBackground();
+      searchIterator = null;
+      DataGridView.SelectionChanged -= DataGridView_SelectionChanged_FindAndReplace;
+    }
+
+    void findAndReplaceDialog_ReplaceEvent(object sender, EventArgs e) {
+      if (searchIterator != null && searchIterator.GetCurrent() != null) {
+        Replace(TransformToDictionary(currentCell));
+      }
+    }
+
+    void findAndReplaceDialog_ReplaceAllEvent(object sender, EventArgs e) {
+      Replace(FindAll(findAndReplaceDialog.GetSearchText()));
+    }
+
+    void findAndReplaceDialog_FindNextEvent(object sender, EventArgs e) {
+      if (searchIterator == null
+        || currentSearchText != findAndReplaceDialog.GetSearchText()
+        || currentComparisonOperation != findAndReplaceDialog.GetComparisonOperation()) {
+
+        searchIterator = new FindPreprocessingItemsIterator(FindAll(findAndReplaceDialog.GetSearchText()));
+        currentSearchText = findAndReplaceDialog.GetSearchText();
+        currentComparisonOperation = findAndReplaceDialog.GetComparisonOperation();
+      }
+
+      if (IsOneCellSelected()) {
+        var first = GetSelectedCells().First();
+        searchIterator.SetStartCell(first.Key, first.Value[0]);
+      }
+
+      bool moreOccurences = false;
+      currentCell = searchIterator.GetCurrent();
+      moreOccurences = searchIterator.MoveNext();
+      if (IsOneCellSelected() && currentCell != null) {
+        var first = GetSelectedCells().First();
+        if (currentCell.Item1 == first.Key && currentCell.Item2 == first.Value[0]) {
+          if (!moreOccurences) {
+            searchIterator.Reset();
+          }
+          currentCell = searchIterator.GetCurrent();
+          moreOccurences = searchIterator.MoveNext();
+          if (!moreOccurences) {
+            searchIterator.Reset();
+          }
+        }
+      }
+
+      dataGridView.ClearSelection();
+
+      if (currentCell != null) {
+        dataGridView[currentCell.Item1, currentCell.Item2].Selected = true;
+        dataGridView.CurrentCell = dataGridView[currentCell.Item1, currentCell.Item2];
+      }
+    }
+
+    private bool AreMultipleCellsSelected() {
+      return GetSelectedCellCount() > 1;
+    }
+
+    private bool IsOneCellSelected() {
+      return GetSelectedCellCount() == 1;
+    }
+
+    private int GetSelectedCellCount() {
+      int count = 0;
+      foreach (var column in GetSelectedCells()) {
+        count += column.Value.Count();
+      }
+      return count;
+    }
+
+    void findAndReplaceDialog_FindAllEvent(object sender, EventArgs e) {
+      dataGridView.ClearSelection();
+      isSearching = true;
+      SuspendRepaint();
+      var selectedCells = FindAll(findAndReplaceDialog.GetSearchText());
+      foreach (var column in selectedCells) {
+        foreach (var cell in column.Value) {
+          dataGridView[column.Key, cell].Selected = true;
+        }
+      }
+      ResumeRepaint(true);
+      isSearching = false;
+      Content.Selection = selectedCells;
+      //update statistic in base
+      base.dataGridView_SelectionChanged(sender, e);
+    }
+
+    private Core.ConstraintOperation GetConstraintOperation(ComparisonOperation comparisonOperation) {
+      Core.ConstraintOperation constraintOperation = Core.ConstraintOperation.Equal;
+      switch (comparisonOperation) {
+        case ComparisonOperation.Equal:
+          constraintOperation = Core.ConstraintOperation.Equal;
+          break;
+        case ComparisonOperation.Greater:
+          constraintOperation = Core.ConstraintOperation.Greater;
+          break;
+        case ComparisonOperation.GreaterOrEqual:
+          constraintOperation = Core.ConstraintOperation.GreaterOrEqual;
+          break;
+        case ComparisonOperation.Less:
+          constraintOperation = Core.ConstraintOperation.Less;
+          break;
+        case ComparisonOperation.LessOrEqual:
+          constraintOperation = Core.ConstraintOperation.LessOrEqual;
+          break;
+        case ComparisonOperation.NotEqual:
+          constraintOperation = Core.ConstraintOperation.NotEqual;
+          break;
+      }
+      return constraintOperation;
+    }
+
+    private IDictionary<int, IList<int>> FindAll(string match) {
+      bool searchInSelection = HightlightedCellsBackground.Values.Sum(list => list.Count) > 1;
+      ComparisonOperation comparisonOperation = findAndReplaceDialog.GetComparisonOperation();
+      var foundCells = new Dictionary<int, IList<int>>();
+      for (int i = 0; i < Content.FilterLogic.PreprocessingData.Columns; i++) {
+        var filters = CreateFilters(match, comparisonOperation, i);
+
+        bool[] filteredRows = Content.FilterLogic.GetFilterResult(filters, true);
+        var foundIndices = new List<int>();
+        for (int idx = 0; idx < filteredRows.Length; ++idx) {
+          var notFilteredThusFound = !filteredRows[idx];
+          if (notFilteredThusFound) {
+            foundIndices.Add(idx);
+          }
+        }
+        foundCells[i] = foundIndices;
+        IList<int> selectedList;
+        if (searchInSelection && HightlightedCellsBackground.TryGetValue(i, out selectedList)) {
+          foundCells[i] = foundCells[i].Intersect(selectedList).ToList<int>();
+        } else if (searchInSelection) {
+          foundCells[i].Clear();
+        }
+      }
+      return MapToSorting(foundCells);
+    }
+
+    private List<IFilter> CreateFilters(string match, ComparisonOperation comparisonOperation, int columnIndex) {
+      IPreprocessingData preprocessingData = Content.FilterLogic.PreprocessingData;
+      IStringConvertibleValue value;
+      if (preprocessingData.VariableHasType<double>(columnIndex)) {
+        value = new DoubleValue();
+      } else if (preprocessingData.VariableHasType<String>(columnIndex)) {
+        value = new StringValue();
+      } else if (preprocessingData.VariableHasType<DateTime>(columnIndex)) {
+        value = new DateTimeValue();
+      } else {
+        throw new ArgumentException("unsupported type");
+      }
+      value.SetValue(match);
+      var comparisonFilter = new ComparisonFilter(preprocessingData, GetConstraintOperation(comparisonOperation), value, true);
+      comparisonFilter.ConstraintColumn = columnIndex;
+      return new List<Filter.IFilter>() { comparisonFilter };
+    }
+
+    private IDictionary<int, IList<int>> MapToSorting(Dictionary<int, IList<int>> foundCells) {
+      if (sortedColumnIndices.Count == 0) {
+        return foundCells;
+      } else {
+        var sortedFoundCells = new Dictionary<int, IList<int>>();
+
+        var indicesToVirtual = new Dictionary<int, int>();
+        for (int i = 0; i < virtualRowIndices.Length; ++i) {
+          indicesToVirtual.Add(virtualRowIndices[i], i);
+        }
+
+        foreach (var entry in foundCells) {
+          var cells = new List<int>();
+          foreach (var cell in entry.Value) {
+            cells.Add(indicesToVirtual[cell]);
+          }
+          cells.Sort();
+          sortedFoundCells.Add(entry.Key, cells);
+        }
+        return sortedFoundCells;
+      }
+    }
+
+    private void Replace(IDictionary<int, IList<int>> cells) {
+      if (findAndReplaceDialog != null) {
+        ReplaceTransaction(() => {
+          switch (findAndReplaceDialog.GetReplaceAction()) {
+            case ReplaceAction.Value:
+              Content.ManipulationLogic.ReplaceIndicesByValue(cells, findAndReplaceDialog.GetReplaceText());
+              break;
+            case ReplaceAction.Average:
+              Content.ManipulationLogic.ReplaceIndicesByAverageValue(cells, false);
+              break;
+            case ReplaceAction.Median:
+              Content.ManipulationLogic.ReplaceIndicesByMedianValue(cells, false);
+              break;
+            case ReplaceAction.Random:
+              Content.ManipulationLogic.ReplaceIndicesByRandomValue(cells, false);
+              break;
+            case ReplaceAction.MostCommon:
+              Content.ManipulationLogic.ReplaceIndicesByMostCommonValue(cells, false);
+              break;
+            case ReplaceAction.Interpolation:
+              Content.ManipulationLogic.ReplaceIndicesByLinearInterpolationOfNeighbours(cells);
+              break;
+          }
+        });
+      }
+    }
+
+    private IDictionary<int, IList<int>> TransformToDictionary(Tuple<int, int> tuple) {
+      var highlightCells = new Dictionary<int, IList<int>>();
+      highlightCells.Add(tuple.Item1, new List<int>() { tuple.Item2 });
+      return highlightCells;
+    }
+
+    private void ResetHighlightedCellsBackground() {
+      HightlightedCellsBackground = new Dictionary<int, IList<int>>();
+    }
+
+    #endregion FindAndReplaceDialog
+
+    private void dataGridView_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e) {
+      if (Content == null) return;
+      if (e.Button == System.Windows.Forms.MouseButtons.Right) {
+        if (e.ColumnIndex == -1 || e.RowIndex == -1) {
+          replaceValueOverColumnToolStripMenuItem.Visible = false;
+          contextMenuCell.Show(MousePosition);
+        } else {
+          if (!dataGridView.SelectedCells.Contains(dataGridView[e.ColumnIndex, e.RowIndex])) {
+            dataGridView.ClearSelection();
+            dataGridView[e.ColumnIndex, e.RowIndex].Selected = true;
+          }
+
+          var columnIndices = new HashSet<int>();
+          for (int i = 0; i < dataGridView.SelectedCells.Count; i++) {
+            columnIndices.Add(dataGridView.SelectedCells[i].ColumnIndex);
+          }
+
+          replaceValueOverSelectionToolStripMenuItem.Enabled = AreMultipleCellsSelected();
+
+          averageToolStripMenuItem_Column.Enabled =
+            averageToolStripMenuItem_Selection.Enabled =
+            medianToolStripMenuItem_Column.Enabled =
+            medianToolStripMenuItem_Selection.Enabled =
+            randomToolStripMenuItem_Column.Enabled =
+            randomToolStripMenuItem_Selection.Enabled = !Content.PreProcessingData.AreAllStringColumns(columnIndices);
+
+          smoothingToolStripMenuItem_Column.Enabled =
+            interpolationToolStripMenuItem_Column.Enabled = !dataGridView.SelectedCells.Contains(dataGridView[e.ColumnIndex, 0])
+            && !dataGridView.SelectedCells.Contains(dataGridView[e.ColumnIndex, Content.Rows - 1])
+            && !Content.PreProcessingData.AreAllStringColumns(columnIndices);
+
+          replaceValueOverColumnToolStripMenuItem.Visible = true;
+          contextMenuCell.Show(MousePosition);
+        }
+      }
+    }
+
+    private void dataGridView_KeyDown(object sender, KeyEventArgs e) {
+      var selectedRows = dataGridView.SelectedRows;
+      if (e.KeyCode == Keys.Delete && selectedRows.Count > 0) {
+        List<int> rows = new List<int>();
+        for (int i = 0; i < selectedRows.Count; ++i) {
+          rows.Add(selectedRows[i].Index);
+        }
+        Content.DeleteRow(rows);
+      } else if (e.Control && e.KeyCode == Keys.F) {
+        CreateFindAndReplaceDialog();
+        findAndReplaceDialog.ActivateSearch();
+      } else if (e.Control && e.KeyCode == Keys.R) {
+        CreateFindAndReplaceDialog();
+        findAndReplaceDialog.ActivateReplace();
+      }
+    }
+
+    private IDictionary<int, IList<int>> GetSelectedCells() {
+      IDictionary<int, IList<int>> selectedCells = new Dictionary<int, IList<int>>();
+
+      //special case if all cells are selected
+      if (dataGridView.AreAllCellsSelected(true)) {
+        for (int i = 0; i < Content.Columns; i++)
+          selectedCells[i] = Enumerable.Range(0, Content.Rows).ToList();
+        return selectedCells;
+      }
+
+      foreach (var selectedCell in dataGridView.SelectedCells) {
+        var cell = (DataGridViewCell)selectedCell;
+        if (!selectedCells.ContainsKey(cell.ColumnIndex))
+          selectedCells.Add(cell.ColumnIndex, new List<int>(1024));
+        selectedCells[cell.ColumnIndex].Add(cell.RowIndex);
+      }
+
+      return selectedCells;
+    }
+
+    private void StartReplacing() {
+      SuspendRepaint();
+    }
+
+    private void StopReplacing() {
+      ResumeRepaint(true);
+    }
+
+    private void ReplaceTransaction(Action action) {
+      StartReplacing();
+      action();
+      StopReplacing();
+    }
+
+    private void btnSearch_Click(object sender, EventArgs e) {
+      CreateFindAndReplaceDialog();
+      findAndReplaceDialog.ActivateSearch();
+    }
+
+    private void btnReplace_Click(object sender, EventArgs e) {
+      CreateFindAndReplaceDialog();
+      findAndReplaceDialog.ActivateReplace();
+    }
+
+    #region ContextMenu Events
+
+    private void ReplaceWithAverage_Column_Click(object sender, EventArgs e) {
+      ReplaceTransaction(() => {
+        Content.ManipulationLogic.ReplaceIndicesByAverageValue(GetSelectedCells(), false);
+      });
+    }
+    private void ReplaceWithAverage_Selection_Click(object sender, EventArgs e) {
+      ReplaceTransaction(() => {
+        Content.ManipulationLogic.ReplaceIndicesByAverageValue(GetSelectedCells(), true);
+      });
+    }
+
+    private void ReplaceWithMedian_Column_Click(object sender, EventArgs e) {
+      ReplaceTransaction(() => {
+        Content.ManipulationLogic.ReplaceIndicesByMedianValue(GetSelectedCells(), false);
+      });
+    }
+    private void ReplaceWithMedian_Selection_Click(object sender, EventArgs e) {
+      ReplaceTransaction(() => {
+        Content.ManipulationLogic.ReplaceIndicesByMedianValue(GetSelectedCells(), true);
+      });
+    }
+
+    private void ReplaceWithRandom_Column_Click(object sender, EventArgs e) {
+      ReplaceTransaction(() => {
+        Content.ManipulationLogic.ReplaceIndicesByRandomValue(GetSelectedCells(), false);
+      });
+    }
+    private void ReplaceWithRandom_Selection_Click(object sender, EventArgs e) {
+      ReplaceTransaction(() => {
+        Content.ManipulationLogic.ReplaceIndicesByRandomValue(GetSelectedCells(), true);
+      });
+    }
+
+    private void ReplaceWithMostCommon_Column_Click(object sender, EventArgs e) {
+      ReplaceTransaction(() => {
+        Content.ManipulationLogic.ReplaceIndicesByMostCommonValue(GetSelectedCells(), false);
+      });
+    }
+    private void ReplaceWithMostCommon_Selection_Click(object sender, EventArgs e) {
+      ReplaceTransaction(() => {
+        Content.ManipulationLogic.ReplaceIndicesByMostCommonValue(GetSelectedCells(), true);
+      });
+    }
+
+    private void ReplaceWithInterpolation_Column_Click(object sender, EventArgs e) {
+      ReplaceTransaction(() => {
+        Content.ManipulationLogic.ReplaceIndicesByLinearInterpolationOfNeighbours(GetSelectedCells());
+      });
+    }
+
+    private void ReplaceWithSmoothing_Selection_Click(object sender, EventArgs e) {
+      ReplaceTransaction(() => {
+        Content.ManipulationLogic.ReplaceIndicesBySmoothing(GetSelectedCells());
+      });
+    }
+    #endregion
+
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/DataPreprocessingView.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/DataPreprocessingView.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/DataPreprocessingView.cs	(revision 11159)
@@ -0,0 +1,127 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Windows.Forms;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+  [View("DataPreprocessing View")]
+  [Content(typeof(PreprocessingContext), true)]
+  [Content(typeof(IPreprocessingContext), false)]
+  public partial class DataPreprocessingView : ItemView {
+
+    public DataPreprocessingView() {
+      InitializeComponent();
+    }
+
+    public new IPreprocessingContext Content {
+      get { return (IPreprocessingContext)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content != null) {
+        var data = Content.Data;
+        var searchLogic = new SearchLogic(data);
+        var statisticsLogic = new StatisticsLogic(data, searchLogic);
+        var manipulationLogic = new ManipulationLogic(data, searchLogic, statisticsLogic);
+        var filterLogic = new FilterLogic(data);
+
+        var viewShortcuts = new ItemList<IViewShortcut> {
+          new DataGridContent(data, manipulationLogic, filterLogic),
+          new StatisticsContent(statisticsLogic),
+
+          new LineChartContent(data),
+          new HistogramContent(data),
+          new ScatterPlotContent(data),
+          new CorrelationMatrixContent(Content),
+          new DataCompletenessChartContent(searchLogic),
+          
+          new FilterContent(filterLogic),
+          new ManipulationContent(manipulationLogic, searchLogic, filterLogic),
+          new TransformationContent(data, filterLogic)
+        };
+
+        viewShortcutListView.Content = viewShortcuts.AsReadOnly();
+
+        viewShortcutListView.ItemsListView.Items[0].Selected = true;
+        viewShortcutListView.Select();
+
+      } else {
+        viewShortcutListView.Content = null;
+      }
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.Data.FilterChanged += Data_FilterChanged;
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.Data.FilterChanged -= Data_FilterChanged;
+    }
+
+    void Data_FilterChanged(object sender, EventArgs e) {
+      lblFilterActive.Visible = Content.Data.IsFiltered;
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      viewShortcutListView.Enabled = Content != null;
+      applyInNewTabButton.Enabled = Content != null;
+      exportProblemButton.Enabled = Content != null && Content.Problem != null;
+      undoButton.Enabled = Content != null;
+    }
+
+    private void exportProblemButton_Click(object sender, EventArgs e) {
+      var problem = Content.ExportProblem();
+
+      var saveFileDialog = new SaveFileDialog {
+        Title = "Save Item",
+        DefaultExt = "hl",
+        Filter = "Uncompressed HeuristicLab Files|*.hl|HeuristicLab Files|*.hl|All Files|*.*",
+        FilterIndex = 2
+      };
+
+      var content = problem as IStorableContent;
+      if (saveFileDialog.ShowDialog() == DialogResult.OK) {
+        bool compressed = saveFileDialog.FilterIndex != 1;
+        ContentManager.Save(content, saveFileDialog.FileName, compressed);
+      }
+    }
+
+    private void applyInNewTabButton_Click(object sender, EventArgs e) {
+      var item = Content.Export();
+
+      MainFormManager.MainForm.ShowContent(item);
+    }
+
+    private void undoButton_Click(object sender, EventArgs e) {
+      Content.Data.Undo();
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/DataPreprocessingView.designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/DataPreprocessingView.designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/DataPreprocessingView.designer.cs	(revision 11159)
@@ -0,0 +1,139 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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 DataPreprocessingView {
+    /// <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.components = new System.ComponentModel.Container();
+      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DataPreprocessingView));
+      this.undoButton = new System.Windows.Forms.Button();
+      this.applyInNewTabButton = new System.Windows.Forms.Button();
+      this.exportProblemButton = new System.Windows.Forms.Button();
+      this.toolTip = new System.Windows.Forms.ToolTip(this.components);
+      this.lblFilterActive = new System.Windows.Forms.Label();
+      this.viewShortcutListView = new HeuristicLab.DataPreprocessing.Views.ViewShortcutListView();
+      this.SuspendLayout();
+      // 
+      // undoButton
+      // 
+      this.undoButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Undo;
+      this.undoButton.Location = new System.Drawing.Point(64, 3);
+      this.undoButton.Name = "undoButton";
+      this.undoButton.Size = new System.Drawing.Size(24, 24);
+      this.undoButton.TabIndex = 3;
+      this.toolTip.SetToolTip(this.undoButton, "Undo");
+      this.undoButton.UseVisualStyleBackColor = true;
+      this.undoButton.Click += new System.EventHandler(this.undoButton_Click);
+      // 
+      // applyInNewTabButton
+      // 
+      this.applyInNewTabButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Play;
+      this.applyInNewTabButton.Location = new System.Drawing.Point(34, 3);
+      this.applyInNewTabButton.Name = "applyInNewTabButton";
+      this.applyInNewTabButton.Size = new System.Drawing.Size(24, 24);
+      this.applyInNewTabButton.TabIndex = 2;
+      this.toolTip.SetToolTip(this.applyInNewTabButton, "Apply in new tab");
+      this.applyInNewTabButton.UseVisualStyleBackColor = true;
+      this.applyInNewTabButton.Click += new System.EventHandler(this.applyInNewTabButton_Click);
+      // 
+      // exportProblemButton
+      // 
+      this.exportProblemButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Save;
+      this.exportProblemButton.Location = new System.Drawing.Point(4, 3);
+      this.exportProblemButton.Name = "exportProblemButton";
+      this.exportProblemButton.Size = new System.Drawing.Size(24, 24);
+      this.exportProblemButton.TabIndex = 1;
+      this.toolTip.SetToolTip(this.exportProblemButton, "Export problem");
+      this.exportProblemButton.UseVisualStyleBackColor = true;
+      this.exportProblemButton.Click += new System.EventHandler(this.exportProblemButton_Click);
+      // 
+      // lblFilterActive
+      // 
+      this.lblFilterActive.AutoSize = true;
+      this.lblFilterActive.Location = new System.Drawing.Point(220, 12);
+      this.lblFilterActive.Name = "lblFilterActive";
+      this.lblFilterActive.Size = new System.Drawing.Size(277, 13);
+      this.lblFilterActive.TabIndex = 5;
+      this.lblFilterActive.Text = "Attention! The data is read-only, because a filter is active.";
+      this.lblFilterActive.Visible = false;
+      // 
+      // viewShortcutListView
+      // 
+      this.viewShortcutListView.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.viewShortcutListView.Caption = "ViewShortcutCollection View";
+      this.viewShortcutListView.Content = null;
+      this.viewShortcutListView.Location = new System.Drawing.Point(4, 33);
+      this.viewShortcutListView.Name = "viewShortcutListView";
+      this.viewShortcutListView.ReadOnly = false;
+      this.viewShortcutListView.Size = new System.Drawing.Size(831, 413);
+      this.viewShortcutListView.TabIndex = 4;
+      // 
+      // DataPreprocessingView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.lblFilterActive);
+      this.Controls.Add(this.viewShortcutListView);
+      this.Controls.Add(this.undoButton);
+      this.Controls.Add(this.applyInNewTabButton);
+      this.Controls.Add(this.exportProblemButton);
+      this.Name = "DataPreprocessingView";
+      this.Size = new System.Drawing.Size(838, 449);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Button exportProblemButton;
+    private System.Windows.Forms.Button applyInNewTabButton;
+    private System.Windows.Forms.Button undoButton;
+    private System.Windows.Forms.ToolTip toolTip;
+    private ViewShortcutListView viewShortcutListView;
+    private System.Windows.Forms.Label lblFilterActive;
+
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/DataPreprocessorStarter.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/DataPreprocessorStarter.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/DataPreprocessorStarter.cs	(revision 11159)
@@ -0,0 +1,62 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.Optimization;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Problems.DataAnalysis.Views;
+using View = HeuristicLab.MainForm.WindowsForms.View;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+  public class DataPreprocessorStarter : IDataPreprocessorStarter {
+
+    public void Start(IDataAnalysisProblemData problemData, View currentView) {
+      IAlgorithm algorithm;
+      IDataAnalysisProblem problem;
+      IItem parentItem = GetMostOuterContent(currentView, out algorithm, out problem);
+      var context = new PreprocessingContext(problemData, algorithm, problem);
+      MainFormManager.MainForm.ShowContent(context);
+    }
+
+    private IItem GetMostOuterContent(Control control, out IAlgorithm algorithm, out IDataAnalysisProblem problem) {
+      algorithm = null;
+      problem = null;
+      ItemView itemView = null;
+      do {
+        control = control.Parent;
+        if (control is ItemView) {
+          itemView = (ItemView)control;
+          if (itemView.Content is IAlgorithm) {
+            algorithm = (IAlgorithm)itemView.Content;
+          }
+          if (itemView.Content is IDataAnalysisProblem) {
+            problem = (IDataAnalysisProblem)itemView.Content;
+          }
+        }
+      } while (control != null);
+
+      return itemView.Content;
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/FilterView.Designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/FilterView.Designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/FilterView.Designer.cs	(revision 11159)
@@ -0,0 +1,291 @@
+﻿namespace HeuristicLab.DataPreprocessing.Views
+{
+  partial class FilterView
+  {
+    /// <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.groupBoxFilter = new System.Windows.Forms.GroupBox();
+      this.checkedFilterView = new HeuristicLab.DataPreprocessing.Views.CheckedFilterCollectionView();
+      this.groupBoxFilterInfo = new System.Windows.Forms.GroupBox();
+      this.lblPercentage = new System.Windows.Forms.Label();
+      this.tbPercentage = new System.Windows.Forms.TextBox();
+      this.tbRemaining = new System.Windows.Forms.TextBox();
+      this.lblRemaining = new System.Windows.Forms.Label();
+      this.tbTotal = new System.Windows.Forms.TextBox();
+      this.lblTotal = new System.Windows.Forms.Label();
+      this.applyFilterButton = new System.Windows.Forms.Button();
+      this.rBtnOr = new System.Windows.Forms.RadioButton();
+      this.rBtnAnd = new System.Windows.Forms.RadioButton();
+      this.groupBox1 = new System.Windows.Forms.GroupBox();
+      this.label4 = new System.Windows.Forms.Label();
+      this.label1 = new System.Windows.Forms.Label();
+      this.label2 = new System.Windows.Forms.Label();
+      this.label3 = new System.Windows.Forms.Label();
+      this.groupBoxFilter.SuspendLayout();
+      this.groupBoxFilterInfo.SuspendLayout();
+      this.groupBox1.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // groupBoxFilter
+      // 
+      this.groupBoxFilter.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.groupBoxFilter.Controls.Add(this.checkedFilterView);
+      this.groupBoxFilter.Location = new System.Drawing.Point(4, 4);
+      this.groupBoxFilter.Name = "groupBoxFilter";
+      this.groupBoxFilter.Size = new System.Drawing.Size(658, 327);
+      this.groupBoxFilter.TabIndex = 0;
+      this.groupBoxFilter.TabStop = false;
+      this.groupBoxFilter.Text = "Filter";
+      // 
+      // checkedFilterView
+      // 
+      this.checkedFilterView.Caption = "filterView";
+      this.checkedFilterView.Content = null;
+      this.checkedFilterView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.checkedFilterView.Location = new System.Drawing.Point(3, 16);
+      this.checkedFilterView.Name = "checkedFilterView";
+      this.checkedFilterView.ReadOnly = false;
+      this.checkedFilterView.ShowDetails = true;
+      this.checkedFilterView.Size = new System.Drawing.Size(652, 308);
+      this.checkedFilterView.TabIndex = 0;
+      // 
+      // groupBoxFilterInfo
+      // 
+      this.groupBoxFilterInfo.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.groupBoxFilterInfo.Controls.Add(this.lblPercentage);
+      this.groupBoxFilterInfo.Controls.Add(this.tbPercentage);
+      this.groupBoxFilterInfo.Controls.Add(this.tbRemaining);
+      this.groupBoxFilterInfo.Controls.Add(this.lblRemaining);
+      this.groupBoxFilterInfo.Controls.Add(this.tbTotal);
+      this.groupBoxFilterInfo.Controls.Add(this.lblTotal);
+      this.groupBoxFilterInfo.Location = new System.Drawing.Point(4, 337);
+      this.groupBoxFilterInfo.Name = "groupBoxFilterInfo";
+      this.groupBoxFilterInfo.Size = new System.Drawing.Size(659, 102);
+      this.groupBoxFilterInfo.TabIndex = 1;
+      this.groupBoxFilterInfo.TabStop = false;
+      this.groupBoxFilterInfo.Text = "Filter Preview";
+      // 
+      // lblPercentage
+      // 
+      this.lblPercentage.AutoSize = true;
+      this.lblPercentage.Location = new System.Drawing.Point(15, 74);
+      this.lblPercentage.Name = "lblPercentage";
+      this.lblPercentage.Size = new System.Drawing.Size(65, 13);
+      this.lblPercentage.TabIndex = 11;
+      this.lblPercentage.Text = "Percentage:";
+      // 
+      // tbPercentage
+      // 
+      this.tbPercentage.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.tbPercentage.Enabled = false;
+      this.tbPercentage.Location = new System.Drawing.Point(104, 71);
+      this.tbPercentage.Name = "tbPercentage";
+      this.tbPercentage.Size = new System.Drawing.Size(549, 20);
+      this.tbPercentage.TabIndex = 10;
+      // 
+      // tbFiltered
+      // 
+      this.tbRemaining.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.tbRemaining.Enabled = false;
+      this.tbRemaining.Location = new System.Drawing.Point(104, 45);
+      this.tbRemaining.Name = "tbRemaining";
+      this.tbRemaining.Size = new System.Drawing.Size(549, 20);
+      this.tbRemaining.TabIndex = 9;
+      // 
+      // lblFiltered
+      // 
+      this.lblRemaining.AutoSize = true;
+      this.lblRemaining.Location = new System.Drawing.Point(15, 47);
+      this.lblRemaining.Name = "lblRemaining";
+      this.lblRemaining.Size = new System.Drawing.Size(60, 13);
+      this.lblRemaining.TabIndex = 8;
+      this.lblRemaining.Text = "Remaining:";
+      // 
+      // tbTotal
+      // 
+      this.tbTotal.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.tbTotal.Enabled = false;
+      this.tbTotal.Location = new System.Drawing.Point(104, 19);
+      this.tbTotal.Name = "tbTotal";
+      this.tbTotal.Size = new System.Drawing.Size(549, 20);
+      this.tbTotal.TabIndex = 7;
+      // 
+      // lblTotal
+      // 
+      this.lblTotal.AutoSize = true;
+      this.lblTotal.Location = new System.Drawing.Point(15, 21);
+      this.lblTotal.Name = "lblTotal";
+      this.lblTotal.Size = new System.Drawing.Size(34, 13);
+      this.lblTotal.TabIndex = 6;
+      this.lblTotal.Text = "Total:";
+      // 
+      // applyFilterButton
+      // 
+      this.applyFilterButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.applyFilterButton.Cursor = System.Windows.Forms.Cursors.Default;
+      this.applyFilterButton.Enabled = false;
+      this.applyFilterButton.Location = new System.Drawing.Point(554, 628);
+      this.applyFilterButton.Name = "applyFilterButton";
+      this.applyFilterButton.Size = new System.Drawing.Size(107, 23);
+      this.applyFilterButton.TabIndex = 2;
+      this.applyFilterButton.Text = "Apply Filters";
+      this.applyFilterButton.UseVisualStyleBackColor = true;
+      this.applyFilterButton.Click += new System.EventHandler(this.applyFilterButton_Click);
+      // 
+      // rBtnOr
+      // 
+      this.rBtnOr.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.rBtnOr.AutoSize = true;
+      this.rBtnOr.Cursor = System.Windows.Forms.Cursors.Default;
+      this.rBtnOr.Enabled = false;
+      this.rBtnOr.Location = new System.Drawing.Point(60, 634);
+      this.rBtnOr.Name = "rBtnOr";
+      this.rBtnOr.Size = new System.Drawing.Size(36, 17);
+      this.rBtnOr.TabIndex = 3;
+      this.rBtnOr.Text = "Or";
+      this.rBtnOr.UseVisualStyleBackColor = true;
+      // 
+      // rBtnAnd
+      // 
+      this.rBtnAnd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.rBtnAnd.AutoSize = true;
+      this.rBtnAnd.Checked = true;
+      this.rBtnAnd.Cursor = System.Windows.Forms.Cursors.Default;
+      this.rBtnAnd.Enabled = false;
+      this.rBtnAnd.Location = new System.Drawing.Point(10, 634);
+      this.rBtnAnd.Name = "rBtnAnd";
+      this.rBtnAnd.Size = new System.Drawing.Size(44, 17);
+      this.rBtnAnd.TabIndex = 4;
+      this.rBtnAnd.TabStop = true;
+      this.rBtnAnd.Text = "And";
+      this.rBtnAnd.UseVisualStyleBackColor = true;
+      this.rBtnAnd.CheckedChanged += new System.EventHandler(this.rBtnAnd_CheckedChanged);
+      // 
+      // groupBox1
+      // 
+      this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.groupBox1.Controls.Add(this.label4);
+      this.groupBox1.Controls.Add(this.label1);
+      this.groupBox1.Controls.Add(this.label2);
+      this.groupBox1.Controls.Add(this.label3);
+      this.groupBox1.Location = new System.Drawing.Point(7, 445);
+      this.groupBox1.Name = "groupBox1";
+      this.groupBox1.Size = new System.Drawing.Size(659, 130);
+      this.groupBox1.TabIndex = 12;
+      this.groupBox1.TabStop = false;
+      this.groupBox1.Text = "Filter Info";
+      // 
+      // label4
+      // 
+      this.label4.AutoSize = true;
+      this.label4.Location = new System.Drawing.Point(15, 98);
+      this.label4.Name = "label4";
+      this.label4.Size = new System.Drawing.Size(455, 13);
+      this.label4.TabIndex = 12;
+      this.label4.Text = "The Apply Filter Button permanently activates the filters. This means unfiltered " +
+    "rows are deleted.";
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(15, 74);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(529, 13);
+      this.label1.TabIndex = 11;
+      this.label1.Text = "All preprocessing views are updated when a filter gets activated or deactivated b" +
+    "ut the unfiltered rows still exist.";
+      // 
+      // label2
+      // 
+      this.label2.AutoSize = true;
+      this.label2.Location = new System.Drawing.Point(15, 47);
+      this.label2.Name = "label2";
+      this.label2.Size = new System.Drawing.Size(402, 13);
+      this.label2.TabIndex = 8;
+      this.label2.Text = "In the Filter Preview all effects of the activated filters on the dataset are sum" +
+    "marized.";
+      // 
+      // label3
+      // 
+      this.label3.AutoSize = true;
+      this.label3.Location = new System.Drawing.Point(15, 21);
+      this.label3.Name = "label3";
+      this.label3.Size = new System.Drawing.Size(249, 13);
+      this.label3.TabIndex = 6;
+      this.label3.Text = "A filter specifies the data rows which should remain.";
+      // 
+      // FilterView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.groupBox1);
+      this.Controls.Add(this.rBtnAnd);
+      this.Controls.Add(this.rBtnOr);
+      this.Controls.Add(this.applyFilterButton);
+      this.Controls.Add(this.groupBoxFilterInfo);
+      this.Controls.Add(this.groupBoxFilter);
+      this.Name = "FilterView";
+      this.Size = new System.Drawing.Size(670, 660);
+      this.groupBoxFilter.ResumeLayout(false);
+      this.groupBoxFilterInfo.ResumeLayout(false);
+      this.groupBoxFilterInfo.PerformLayout();
+      this.groupBox1.ResumeLayout(false);
+      this.groupBox1.PerformLayout();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.GroupBox groupBoxFilter;
+    private System.Windows.Forms.GroupBox groupBoxFilterInfo;
+    private System.Windows.Forms.Button applyFilterButton;
+    private System.Windows.Forms.TextBox tbTotal;
+    private System.Windows.Forms.Label lblTotal;
+    private System.Windows.Forms.Label lblPercentage;
+    private System.Windows.Forms.TextBox tbPercentage;
+    private System.Windows.Forms.TextBox tbRemaining;
+    private System.Windows.Forms.Label lblRemaining;
+    private System.Windows.Forms.RadioButton rBtnOr;
+    private System.Windows.Forms.RadioButton rBtnAnd;
+    private CheckedFilterCollectionView checkedFilterView;
+    private System.Windows.Forms.GroupBox groupBox1;
+    private System.Windows.Forms.Label label4;
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.Label label2;
+    private System.Windows.Forms.Label label3;
+
+
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/FilterView.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/FilterView.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/FilterView.cs	(revision 11159)
@@ -0,0 +1,120 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Collections;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.Data;
+using HeuristicLab.DataPreprocessing.Filter;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+  [View("CheckedFilterCollection View")]
+  [Content(typeof(FilterContent), true)]
+  public partial class FilterView : ItemView {
+
+    public FilterView() {
+      InitializeComponent();
+      tbTotal.Text = "0";
+      tbRemaining.Text = "0";
+      tbPercentage.Text = "0%";
+    }
+
+    private void InitData()
+    {
+        checkedFilterView.Content = Content.Filters;
+        checkedFilterView.Content.ItemsAdded += Content_ItemsAdded;
+        checkedFilterView.Content.ItemsRemoved += Content_ItemsRemoved;
+        checkedFilterView.Content.CheckedItemsChanged += Content_CheckedItemsChanged;
+    }
+
+    public new FilterContent Content {
+      get { return (FilterContent)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged()
+    {
+      base.OnContentChanged();
+      if (Content != null)
+      {
+        InitData();
+        UpdateFilterInfo();
+      }
+    }
+
+    private void Content_CheckedItemsChanged(object sender, Collections.CollectionItemsChangedEventArgs<IFilter> e) {
+      if (Content != null)
+      {
+        foreach (IFilter filter in e.Items)
+        {
+          filter.Active = checkedFilterView.Content.ItemChecked(filter);
+        }
+        UpdateFilterInfo();
+      }
+    }
+
+    private void UpdateFilterInfo() {
+        List<IFilter> filters = Content.Filters.ToList();
+        int activeFilters = filters.Count(c => c.Active);
+        applyFilterButton.Enabled = (activeFilters > 0);
+        rBtnAnd.Enabled = (activeFilters > 0);
+        rBtnOr.Enabled = (activeFilters > 0);
+        Content.FilterLogic.Reset();
+        bool[] result = Content.FilterLogic.Preview(filters, rBtnAnd.Checked);
+
+        int filteredCnt = result.Count(c => !c);
+
+        tbRemaining.Text = filteredCnt.ToString();
+        double percentage = result.Length == 0 ? 0.0 : filteredCnt * 100 / (double)result.Length;
+        tbPercentage.Text = String.Format("{0:0.0000}%", percentage);
+        tbTotal.Text = result.Length.ToString();
+    }
+
+    private void applyFilterButton_Click(object sender, EventArgs e) {
+      if (Content != null)
+      {
+        List<IFilter> filters = Content.Filters.ToList();
+        //apply filters
+        Content.FilterLogic.Apply(filters, rBtnAnd.Checked);
+        //deactivate checked filters
+        filters = checkedFilterView.Content.CheckedItems.ToList();
+        foreach (IFilter filter in filters)
+        {
+          checkedFilterView.Content.SetItemCheckedState(filter, false);
+          filter.Active = false;
+        }
+        UpdateFilterInfo();
+      }
+    }
+
+    //whenever a new filter is added the preprocessing data is set to the filter
+    private void Content_ItemsAdded(object sender, Collections.CollectionItemsChangedEventArgs<IFilter> e) {
+      if (Content != null)
+      {
+        foreach (IFilter filter in e.Items)
+        {
+          filter.ConstrainedValue = Content.FilterLogic.PreprocessingData;
+        }
+      }
+    }
+
+    private void Content_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IFilter> e) {
+      if (Content != null)
+      {
+        UpdateFilterInfo();
+      }
+    }
+
+    private void rBtnAnd_CheckedChanged(object sender, EventArgs e)
+    {
+      if (Content != null)
+      {
+        UpdateFilterInfo();
+        Content.IsAndCombination = rBtnAnd.Checked;
+      }
+    }
+
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/HeuristicLab.DataPreprocessing.Views-3.4.csproj
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/HeuristicLab.DataPreprocessing.Views-3.4.csproj	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/HeuristicLab.DataPreprocessing.Views-3.4.csproj	(revision 11159)
@@ -0,0 +1,296 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{3FC7515E-D8A0-41FE-8CFA-50E3ADA61A1E}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.DataPreprocessing.Views</RootNamespace>
+    <AssemblyName>HeuristicLab.DataPreprocessing.Views-3.4</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Windows.Forms.DataVisualization" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="PreprocessingFeatureCorrelationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="PreprocessingFeatureCorrelationView.Designer.cs">
+      <DependentUpon>PreprocessingFeatureCorrelationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="CheckedFilterCollectionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="CheckedFilterCollectionView.Designer.cs">
+      <DependentUpon>CheckedFilterCollectionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="CheckedTransformationListView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="CheckedTransformationListView.Designer.cs">
+      <DependentUpon>CheckedTransformationListView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ComparisonFilterView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ComparisonFilterView.Designer.cs">
+      <DependentUpon>ComparisonFilterView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ScatterPlotSingleView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ScatterPlotSingleView.Designer.cs">
+      <DependentUpon>ScatterPlotSingleView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="DataCompletenessView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="DataCompletenessView.Designer.cs">
+      <DependentUpon>DataCompletenessView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="DataGridContentView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="DataGridContentView.Designer.cs">
+      <DependentUpon>DataGridContentView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="DataPreprocessingView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="DataPreprocessingView.designer.cs">
+      <DependentUpon>DataPreprocessingView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="DataPreprocessorStarter.cs" />
+    <Compile Include="PreprocessingDataTableView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="PreprocessingDataTableView.Designer.cs">
+      <DependentUpon>PreprocessingDataTableView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="FilterView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="FilterView.Designer.cs">
+      <DependentUpon>FilterView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ScatterPlotMultiView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ScatterPlotMultiView.Designer.cs">
+      <DependentUpon>ScatterPlotMultiView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="PreprocessingScatterPlotView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="PreprocessingScatterPlotView.Designer.cs">
+      <DependentUpon>PreprocessingScatterPlotView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="SearchAndReplaceDialog.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="SearchAndReplaceDialog.Designer.cs">
+      <DependentUpon>SearchAndReplaceDialog.cs</DependentUpon>
+    </Compile>
+    <Compile Include="HistogramView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="HistogramView.Designer.cs">
+      <DependentUpon>HistogramView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="LineChartView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="LineChartView.Designer.cs">
+      <DependentUpon>LineChartView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ManipulationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ManipulationView.Designer.cs">
+      <DependentUpon>ManipulationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Plugin.cs" />
+    <Compile Include="PreprocessingChartView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="PreprocessingChartView.Designer.cs">
+      <DependentUpon>PreprocessingChartView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="PreprocessingCheckedItemListView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="PreprocessingCheckedItemListView.Designer.cs">
+      <DependentUpon>PreprocessingCheckedItemListView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="StatisticsView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="StatisticsView.Designer.cs">
+      <DependentUpon>StatisticsView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="TransformationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="TransformationView.Designer.cs">
+      <DependentUpon>TransformationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Utils\FindPreprocessingItemsIterator.cs" />
+    <Compile Include="Utils\IFindPreprocessingItemsIterator.cs" />
+    <Compile Include="ViewShortcutListView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ViewShortcutListView.Designer.cs">
+      <DependentUpon>ViewShortcutListView.cs</DependentUpon>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Plugin.cs.frame" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis.Views\3.3\HeuristicLab.Analysis.Views-3.3.csproj">
+      <Project>{76945d76-ca61-4147-9dc2-0acdcddf87f9}</Project>
+      <Name>HeuristicLab.Analysis.Views-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
+      <Project>{887425b4-4348-49ed-a457-b7d2c26ddbf9}</Project>
+      <Name>HeuristicLab.Analysis-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Collections\3.3\HeuristicLab.Collections-3.3.csproj">
+      <Project>{958b43bc-cc5c-4fa2-8628-2b3b01d890b6}</Project>
+      <Name>HeuristicLab.Collections-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common.Resources\3.3\HeuristicLab.Common.Resources-3.3.csproj">
+      <Project>{0e27a536-1c4a-4624-a65e-dc4f4f23e3e1}</Project>
+      <Name>HeuristicLab.Common.Resources-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common\3.3\HeuristicLab.Common-3.3.csproj">
+      <Project>{a9ad58b9-3ef9-4cc1-97e5-8d909039ff5c}</Project>
+      <Name>HeuristicLab.Common-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Core.Views\3.3\HeuristicLab.Core.Views-3.3.csproj">
+      <Project>{e226881d-315f-423d-b419-a766fe0d8685}</Project>
+      <Name>HeuristicLab.Core.Views-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Core\3.3\HeuristicLab.Core-3.3.csproj">
+      <Project>{c36bd924-a541-4a00-afa8-41701378ddc5}</Project>
+      <Name>HeuristicLab.Core-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Data.Views\3.3\HeuristicLab.Data.Views-3.3.csproj">
+      <Project>{72104a0b-90e7-42f3-9abe-9bbbadd4b943}</Project>
+      <Name>HeuristicLab.Data.Views-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.DataPreprocessing\3.4\HeuristicLab.DataPreprocessing-3.4.csproj">
+      <Project>{3b90f866-70f8-43ef-a541-51819d255b7b}</Project>
+      <Name>HeuristicLab.DataPreprocessing-3.4</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
+      <Project>{bbab9df5-5ef3-4ba8-ade9-b36e82114937}</Project>
+      <Name>HeuristicLab.Data-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.MainForm.WindowsForms\3.3\HeuristicLab.MainForm.WindowsForms-3.3.csproj">
+      <Project>{ab687bbe-1bfe-476b-906d-44237135431d}</Project>
+      <Name>HeuristicLab.MainForm.WindowsForms-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.MainForm\3.3\HeuristicLab.MainForm-3.3.csproj">
+      <Project>{3bd61258-31da-4b09-89c0-4f71fef5f05a}</Project>
+      <Name>HeuristicLab.MainForm-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
+      <Project>{14ab8d24-25bc-400c-a846-4627aa945192}</Project>
+      <Name>HeuristicLab.Optimization-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.PluginInfrastructure\3.3\HeuristicLab.PluginInfrastructure-3.3.csproj">
+      <Project>{94186a6a-5176-4402-ae83-886557b53cca}</Project>
+      <Name>HeuristicLab.PluginInfrastructure-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis.Views\3.4\HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj">
+      <Project>{3e9e8944-44ff-40bb-a622-3a4a7dd0f198}</Project>
+      <Name>HeuristicLab.Problems.DataAnalysis.Views-3.4</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis\3.4\HeuristicLab.Problems.DataAnalysis-3.4.csproj">
+      <Project>{df87c13e-a889-46ff-8153-66dcaa8c5674}</Project>
+      <Name>HeuristicLab.Problems.DataAnalysis-3.4</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Visualization.ChartControlsExtensions\3.3\HeuristicLab.Visualization.ChartControlsExtensions-3.3.csproj">
+      <Project>{315bda09-3f4f-49b3-9790-b37cfc1c5750}</Project>
+      <Name>HeuristicLab.Visualization.ChartControlsExtensions-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+<PropertyGroup>
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd
+</PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
+  </PropertyGroup>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/HistogramView.Designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/HistogramView.Designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/HistogramView.Designer.cs	(revision 11159)
@@ -0,0 +1,83 @@
+﻿namespace HeuristicLab.DataPreprocessing.Views {
+  partial class HistogramView {
+    /// <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.optionsBox = new System.Windows.Forms.GroupBox();
+      this.label1 = new System.Windows.Forms.Label();
+      this.classifierComboBox = new System.Windows.Forms.ComboBox();
+      this.optionsBox.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // optionsBox
+      // 
+      this.optionsBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.optionsBox.Controls.Add(this.label1);
+      this.optionsBox.Controls.Add(this.classifierComboBox);
+      this.optionsBox.Location = new System.Drawing.Point(4, 263);
+      this.optionsBox.Name = "optionsBox";
+      this.optionsBox.Size = new System.Drawing.Size(152, 134);
+      this.optionsBox.TabIndex = 7;
+      this.optionsBox.TabStop = false;
+      this.optionsBox.Text = "Options";
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(6, 26);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(91, 13);
+      this.label1.TabIndex = 2;
+      this.label1.Text = "Classifier variable:";
+      // 
+      // classifierComboBox
+      // 
+      this.classifierComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.classifierComboBox.FormattingEnabled = true;
+      this.classifierComboBox.Location = new System.Drawing.Point(9, 52);
+      this.classifierComboBox.Name = "classifierComboBox";
+      this.classifierComboBox.Size = new System.Drawing.Size(121, 21);
+      this.classifierComboBox.TabIndex = 1;
+      this.classifierComboBox.SelectedIndexChanged += new System.EventHandler(this.classifierComboBox_SelectedIndexChanged);
+      // 
+      // HistogramView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.optionsBox);
+      this.Name = "HistogramView";
+      this.Controls.SetChildIndex(this.optionsBox, 0);
+      this.optionsBox.ResumeLayout(false);
+      this.optionsBox.PerformLayout();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.GroupBox optionsBox;
+    private System.Windows.Forms.ComboBox classifierComboBox;
+    private System.Windows.Forms.Label label1;
+
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/HistogramView.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/HistogramView.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/HistogramView.cs	(revision 11159)
@@ -0,0 +1,76 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 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.Windows.Forms;
+using HeuristicLab.Analysis;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+
+  [View("Histogram View")]
+  [Content(typeof(HistogramContent), true)]
+  public partial class HistogramView : PreprocessingChartView {
+    private const string HISTOGRAM_CHART_TITLE = "Histogram";
+
+    public HistogramView() {
+      InitializeComponent();
+      chartType = DataRowVisualProperties.DataRowChartType.Histogram;
+      chartTitle = HISTOGRAM_CHART_TITLE;
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content != null) {
+        classifierComboBox.Items.Clear();
+        classifierComboBox.Items.Add("None");
+
+        foreach (string var in Content.GetVariableNamesForHistogramClassification()) {
+          classifierComboBox.Items.Add(var);
+        }
+
+        if (classifierComboBox.SelectedItem == null && Content.ClassifierVariableIndex < classifierComboBox.Items.Count) {
+          classifierComboBox.SelectedIndex = Content.ClassifierVariableIndex;
+        }
+      }
+    }
+
+    public new HistogramContent Content {
+      get { return (HistogramContent)base.Content; }
+      set { base.Content = value; }
+    }
+
+    private void classifierComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      if (classifierComboBox.SelectedItem == null)
+        return;
+
+      if (classifierComboBox.SelectedIndex != 0) {
+        int columndIndex = Content.PreprocessingData.GetColumnIndex(classifierComboBox.SelectedItem.ToString());
+        Classification = Content.PreprocessingData.GetValues<double>(columndIndex);
+      } else {
+        Classification = null;
+      }
+
+      Content.ClassifierVariableIndex = classifierComboBox.SelectedIndex;
+
+      GenerateChart();
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/LineChartView.Designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/LineChartView.Designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/LineChartView.Designer.cs	(revision 11159)
@@ -0,0 +1,73 @@
+﻿namespace HeuristicLab.DataPreprocessing.Views {
+  partial class LineChartView {
+    /// <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.optionsBox = new System.Windows.Forms.GroupBox();
+      this.allInOneCheckBox = new System.Windows.Forms.CheckBox();
+      this.optionsBox.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // optionsBox
+      // 
+      this.optionsBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.optionsBox.Controls.Add(this.allInOneCheckBox);
+      this.optionsBox.Location = new System.Drawing.Point(4, 262);
+      this.optionsBox.Name = "optionsBox";
+      this.optionsBox.Size = new System.Drawing.Size(151, 134);
+      this.optionsBox.TabIndex = 7;
+      this.optionsBox.TabStop = false;
+      this.optionsBox.Text = "Options";
+      // 
+      // allInOneCheckBox
+      // 
+      this.allInOneCheckBox.AutoSize = true;
+      this.allInOneCheckBox.Checked = true;
+      this.allInOneCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.allInOneCheckBox.Location = new System.Drawing.Point(6, 19);
+      this.allInOneCheckBox.Name = "allInOneCheckBox";
+      this.allInOneCheckBox.Size = new System.Drawing.Size(69, 17);
+      this.allInOneCheckBox.TabIndex = 0;
+      this.allInOneCheckBox.Text = "All in one";
+      this.allInOneCheckBox.UseVisualStyleBackColor = true;
+      this.allInOneCheckBox.CheckedChanged += new System.EventHandler(this.allInOneCheckBox_CheckedChanged);
+      // 
+      // LineChartView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.optionsBox);
+      this.Name = "LineChartView";
+      this.Controls.SetChildIndex(this.optionsBox, 0);
+      this.optionsBox.ResumeLayout(false);
+      this.optionsBox.PerformLayout();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.GroupBox optionsBox;
+    private System.Windows.Forms.CheckBox allInOneCheckBox;
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/LineChartView.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/LineChartView.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/LineChartView.cs	(revision 11159)
@@ -0,0 +1,61 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Windows.Forms;
+using HeuristicLab.Analysis;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+
+  [View("Line Chart View")]
+  [Content(typeof(LineChartContent), true)]
+  public partial class LineChartView : PreprocessingChartView {
+
+    private const string LINE_CHART_TITLE = "Line Chart";
+
+    public LineChartView() {
+      InitializeComponent();
+      chartType = DataRowVisualProperties.DataRowChartType.Line;
+      chartTitle = LINE_CHART_TITLE;
+    }
+
+    public new LineChartContent Content {
+      get { return (LineChartContent)base.Content; }
+      set { base.Content = value; }
+    }
+
+    private void allInOneCheckBox_CheckedChanged(object sender, EventArgs e) {
+      Content.AllInOneMode = allInOneCheckBox.Checked;
+ 
+      GenerateChart();
+    }
+
+    protected override void OnContentChanged()
+    {
+      base.OnContentChanged();
+      if (Content != null)
+      {
+        allInOneCheckBox.Checked = Content.AllInOneMode;
+      }
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/ManipulationView.Designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/ManipulationView.Designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/ManipulationView.Designer.cs	(revision 11159)
@@ -0,0 +1,626 @@
+﻿namespace HeuristicLab.DataPreprocessing.Views {
+  partial class ManipulationView {
+    /// <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.lstMethods = new System.Windows.Forms.ListBox();
+      this.btnApply = new System.Windows.Forms.Button();
+      this.grpBoxData = new System.Windows.Forms.GroupBox();
+      this.tabsData = new System.Windows.Forms.TabControl();
+      this.tabPage1 = new System.Windows.Forms.TabPage();
+      this.label7 = new System.Windows.Forms.Label();
+      this.tabDataDeleteColumnsInformation = new System.Windows.Forms.TabPage();
+      this.label2 = new System.Windows.Forms.Label();
+      this.txtDeleteColumnsInfo = new System.Windows.Forms.TextBox();
+      this.label1 = new System.Windows.Forms.Label();
+      this.tabDataDeleteColumnsVariance = new System.Windows.Forms.TabPage();
+      this.txtDeleteColumnsVariance = new System.Windows.Forms.TextBox();
+      this.label4 = new System.Windows.Forms.Label();
+      this.tabDataDeleteRowsInfo = new System.Windows.Forms.TabPage();
+      this.label3 = new System.Windows.Forms.Label();
+      this.txtDeleteRowsInfo = new System.Windows.Forms.TextBox();
+      this.label5 = new System.Windows.Forms.Label();
+      this.tabReplaceMissingValues = new System.Windows.Forms.TabPage();
+      this.txtReplaceValue = new System.Windows.Forms.TextBox();
+      this.cmbVariableNames = new System.Windows.Forms.ComboBox();
+      this.cmbReplaceWith = new System.Windows.Forms.ComboBox();
+      this.lblValueColon = new System.Windows.Forms.Label();
+      this.label8 = new System.Windows.Forms.Label();
+      this.label10 = new System.Windows.Forms.Label();
+      this.tabDataShuffle = new System.Windows.Forms.TabPage();
+      this.label6 = new System.Windows.Forms.Label();
+      this.grpBoxPreview = new System.Windows.Forms.GroupBox();
+      this.tabsPreview = new System.Windows.Forms.TabControl();
+      this.tabPreviewInactive = new System.Windows.Forms.TabPage();
+      this.lblPreviewInActive = new System.Windows.Forms.Label();
+      this.tabPreviewDeleteColumnsInfo = new System.Windows.Forms.TabPage();
+      this.lblPreviewColumnsInfo = new System.Windows.Forms.Label();
+      this.tabPreviewDeleteColumnsVariance = new System.Windows.Forms.TabPage();
+      this.label12 = new System.Windows.Forms.Label();
+      this.lblPreviewColumnsVariance = new System.Windows.Forms.Label();
+      this.tabPreviewDeleteRowsInfo = new System.Windows.Forms.TabPage();
+      this.lblPreviewRowsInfo = new System.Windows.Forms.Label();
+      this.tabPreviewReplaceMissingValues = new System.Windows.Forms.TabPage();
+      this.lblPreviewReplaceMissingValues = new System.Windows.Forms.Label();
+      this.tabPreviewShuffle = new System.Windows.Forms.TabPage();
+      this.lblPreviewShuffle = new System.Windows.Forms.Label();
+      this.label9 = new System.Windows.Forms.Label();
+      this.grpBoxData.SuspendLayout();
+      this.tabsData.SuspendLayout();
+      this.tabPage1.SuspendLayout();
+      this.tabDataDeleteColumnsInformation.SuspendLayout();
+      this.tabDataDeleteColumnsVariance.SuspendLayout();
+      this.tabDataDeleteRowsInfo.SuspendLayout();
+      this.tabReplaceMissingValues.SuspendLayout();
+      this.tabDataShuffle.SuspendLayout();
+      this.grpBoxPreview.SuspendLayout();
+      this.tabsPreview.SuspendLayout();
+      this.tabPreviewInactive.SuspendLayout();
+      this.tabPreviewDeleteColumnsInfo.SuspendLayout();
+      this.tabPreviewDeleteColumnsVariance.SuspendLayout();
+      this.tabPreviewDeleteRowsInfo.SuspendLayout();
+      this.tabPreviewReplaceMissingValues.SuspendLayout();
+      this.tabPreviewShuffle.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // lstMethods
+      // 
+      this.lstMethods.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.lstMethods.FormattingEnabled = true;
+      this.lstMethods.Items.AddRange(new object[] {
+            "Delete Columns with insufficient Information",
+            "Delete Columns with insufficient Variance",
+            "Delete Rows with insufficient Information",
+            "Replace Missing Values",
+            "Shuffle Data"});
+      this.lstMethods.Location = new System.Drawing.Point(3, 3);
+      this.lstMethods.Name = "lstMethods";
+      this.lstMethods.Size = new System.Drawing.Size(733, 95);
+      this.lstMethods.Sorted = true;
+      this.lstMethods.TabIndex = 0;
+      this.lstMethods.SelectedIndexChanged += new System.EventHandler(this.lstMethods_SelectedIndexChanged);
+      // 
+      // btnApply
+      // 
+      this.btnApply.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.btnApply.Enabled = false;
+      this.btnApply.Location = new System.Drawing.Point(603, 500);
+      this.btnApply.Name = "btnApply";
+      this.btnApply.Size = new System.Drawing.Size(129, 23);
+      this.btnApply.TabIndex = 2;
+      this.btnApply.Text = "Apply Manipulation";
+      this.btnApply.UseVisualStyleBackColor = true;
+      this.btnApply.Click += new System.EventHandler(this.btnApply_Click);
+      // 
+      // grpBoxData
+      // 
+      this.grpBoxData.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.grpBoxData.Controls.Add(this.tabsData);
+      this.grpBoxData.Location = new System.Drawing.Point(4, 105);
+      this.grpBoxData.Name = "grpBoxData";
+      this.grpBoxData.Size = new System.Drawing.Size(732, 189);
+      this.grpBoxData.TabIndex = 3;
+      this.grpBoxData.TabStop = false;
+      this.grpBoxData.Text = "Properties";
+      // 
+      // tabsData
+      // 
+      this.tabsData.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.tabsData.Controls.Add(this.tabPage1);
+      this.tabsData.Controls.Add(this.tabDataDeleteColumnsInformation);
+      this.tabsData.Controls.Add(this.tabDataDeleteColumnsVariance);
+      this.tabsData.Controls.Add(this.tabDataDeleteRowsInfo);
+      this.tabsData.Controls.Add(this.tabReplaceMissingValues);
+      this.tabsData.Controls.Add(this.tabDataShuffle);
+      this.tabsData.ItemSize = new System.Drawing.Size(58, 18);
+      this.tabsData.Location = new System.Drawing.Point(6, 19);
+      this.tabsData.Name = "tabsData";
+      this.tabsData.SelectedIndex = 0;
+      this.tabsData.Size = new System.Drawing.Size(719, 164);
+      this.tabsData.TabIndex = 3;
+      // 
+      // tabPage1
+      // 
+      this.tabPage1.Controls.Add(this.label7);
+      this.tabPage1.Location = new System.Drawing.Point(4, 22);
+      this.tabPage1.Name = "tabPage1";
+      this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
+      this.tabPage1.Size = new System.Drawing.Size(711, 138);
+      this.tabPage1.TabIndex = 5;
+      this.tabPage1.Text = "tabDataInactive";
+      this.tabPage1.UseVisualStyleBackColor = true;
+      // 
+      // label7
+      // 
+      this.label7.AutoSize = true;
+      this.label7.Enabled = false;
+      this.label7.Location = new System.Drawing.Point(3, 3);
+      this.label7.Name = "label7";
+      this.label7.Size = new System.Drawing.Size(259, 13);
+      this.label7.TabIndex = 1;
+      this.label7.Text = "Please select one of the manipulation methods above";
+      // 
+      // tabDataDeleteColumnsInformation
+      // 
+      this.tabDataDeleteColumnsInformation.Controls.Add(this.label2);
+      this.tabDataDeleteColumnsInformation.Controls.Add(this.txtDeleteColumnsInfo);
+      this.tabDataDeleteColumnsInformation.Controls.Add(this.label1);
+      this.tabDataDeleteColumnsInformation.Location = new System.Drawing.Point(4, 22);
+      this.tabDataDeleteColumnsInformation.Name = "tabDataDeleteColumnsInformation";
+      this.tabDataDeleteColumnsInformation.Padding = new System.Windows.Forms.Padding(3);
+      this.tabDataDeleteColumnsInformation.Size = new System.Drawing.Size(711, 138);
+      this.tabDataDeleteColumnsInformation.TabIndex = 0;
+      this.tabDataDeleteColumnsInformation.Text = "del columns info";
+      this.tabDataDeleteColumnsInformation.UseVisualStyleBackColor = true;
+      // 
+      // label2
+      // 
+      this.label2.AutoSize = true;
+      this.label2.Location = new System.Drawing.Point(204, 3);
+      this.label2.Name = "label2";
+      this.label2.Size = new System.Drawing.Size(89, 13);
+      this.label2.TabIndex = 5;
+      this.label2.Text = "% missing values.";
+      // 
+      // txtDeleteColumnsInfo
+      // 
+      this.txtDeleteColumnsInfo.Location = new System.Drawing.Point(164, 0);
+      this.txtDeleteColumnsInfo.Name = "txtDeleteColumnsInfo";
+      this.txtDeleteColumnsInfo.Size = new System.Drawing.Size(34, 20);
+      this.txtDeleteColumnsInfo.TabIndex = 4;
+      this.txtDeleteColumnsInfo.TextChanged += new System.EventHandler(this.txtDeleteColumnsInfo_TextChanged);
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(3, 3);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(155, 13);
+      this.label1.TabIndex = 3;
+      this.label1.Text = "Delete columns with more than ";
+      // 
+      // tabDataDeleteColumnsVariance
+      // 
+      this.tabDataDeleteColumnsVariance.Controls.Add(this.txtDeleteColumnsVariance);
+      this.tabDataDeleteColumnsVariance.Controls.Add(this.label4);
+      this.tabDataDeleteColumnsVariance.Location = new System.Drawing.Point(4, 22);
+      this.tabDataDeleteColumnsVariance.Name = "tabDataDeleteColumnsVariance";
+      this.tabDataDeleteColumnsVariance.Padding = new System.Windows.Forms.Padding(3);
+      this.tabDataDeleteColumnsVariance.Size = new System.Drawing.Size(711, 138);
+      this.tabDataDeleteColumnsVariance.TabIndex = 1;
+      this.tabDataDeleteColumnsVariance.Text = "del columns variance";
+      this.tabDataDeleteColumnsVariance.UseVisualStyleBackColor = true;
+      // 
+      // txtDeleteColumnsVariance
+      // 
+      this.txtDeleteColumnsVariance.Location = new System.Drawing.Point(229, 0);
+      this.txtDeleteColumnsVariance.Name = "txtDeleteColumnsVariance";
+      this.txtDeleteColumnsVariance.Size = new System.Drawing.Size(135, 20);
+      this.txtDeleteColumnsVariance.TabIndex = 4;
+      this.txtDeleteColumnsVariance.TextChanged += new System.EventHandler(this.txtDeleteColumnsVariance_TextChanged);
+      // 
+      // label4
+      // 
+      this.label4.AutoSize = true;
+      this.label4.Location = new System.Drawing.Point(3, 3);
+      this.label4.Name = "label4";
+      this.label4.Size = new System.Drawing.Size(220, 13);
+      this.label4.TabIndex = 3;
+      this.label4.Text = "Delete columns with a variance smaller than  ";
+      // 
+      // tabDataDeleteRowsInfo
+      // 
+      this.tabDataDeleteRowsInfo.Controls.Add(this.label3);
+      this.tabDataDeleteRowsInfo.Controls.Add(this.txtDeleteRowsInfo);
+      this.tabDataDeleteRowsInfo.Controls.Add(this.label5);
+      this.tabDataDeleteRowsInfo.Location = new System.Drawing.Point(4, 22);
+      this.tabDataDeleteRowsInfo.Name = "tabDataDeleteRowsInfo";
+      this.tabDataDeleteRowsInfo.Padding = new System.Windows.Forms.Padding(3);
+      this.tabDataDeleteRowsInfo.Size = new System.Drawing.Size(711, 138);
+      this.tabDataDeleteRowsInfo.TabIndex = 2;
+      this.tabDataDeleteRowsInfo.Text = "del rows info";
+      this.tabDataDeleteRowsInfo.UseVisualStyleBackColor = true;
+      // 
+      // label3
+      // 
+      this.label3.AutoSize = true;
+      this.label3.Location = new System.Drawing.Point(189, 3);
+      this.label3.Name = "label3";
+      this.label3.Size = new System.Drawing.Size(89, 13);
+      this.label3.TabIndex = 8;
+      this.label3.Text = "% missing values.";
+      // 
+      // txtDeleteRowsInfo
+      // 
+      this.txtDeleteRowsInfo.Location = new System.Drawing.Point(147, 0);
+      this.txtDeleteRowsInfo.Name = "txtDeleteRowsInfo";
+      this.txtDeleteRowsInfo.Size = new System.Drawing.Size(34, 20);
+      this.txtDeleteRowsInfo.TabIndex = 7;
+      this.txtDeleteRowsInfo.TextChanged += new System.EventHandler(this.txtDeleteRowsInfo_TextChanged);
+      // 
+      // label5
+      // 
+      this.label5.AutoSize = true;
+      this.label5.Location = new System.Drawing.Point(3, 3);
+      this.label5.Name = "label5";
+      this.label5.Size = new System.Drawing.Size(138, 13);
+      this.label5.TabIndex = 6;
+      this.label5.Text = "Delete rows with more than ";
+      // 
+      // tabReplaceMissingValues
+      // 
+      this.tabReplaceMissingValues.Controls.Add(this.txtReplaceValue);
+      this.tabReplaceMissingValues.Controls.Add(this.cmbVariableNames);
+      this.tabReplaceMissingValues.Controls.Add(this.cmbReplaceWith);
+      this.tabReplaceMissingValues.Controls.Add(this.lblValueColon);
+      this.tabReplaceMissingValues.Controls.Add(this.label8);
+      this.tabReplaceMissingValues.Controls.Add(this.label10);
+      this.tabReplaceMissingValues.Location = new System.Drawing.Point(4, 22);
+      this.tabReplaceMissingValues.Name = "tabReplaceMissingValues";
+      this.tabReplaceMissingValues.Padding = new System.Windows.Forms.Padding(3);
+      this.tabReplaceMissingValues.Size = new System.Drawing.Size(711, 138);
+      this.tabReplaceMissingValues.TabIndex = 6;
+      this.tabReplaceMissingValues.Text = "repl missing vals";
+      this.tabReplaceMissingValues.UseVisualStyleBackColor = true;
+      // 
+      // txtReplaceValue
+      // 
+      this.txtReplaceValue.Location = new System.Drawing.Point(173, 27);
+      this.txtReplaceValue.Name = "txtReplaceValue";
+      this.txtReplaceValue.Size = new System.Drawing.Size(100, 20);
+      this.txtReplaceValue.TabIndex = 2;
+      this.txtReplaceValue.TextChanged += new System.EventHandler(this.txtReplaceValue_TextChanged);
+      // 
+      // cmbVariableNames
+      // 
+      this.cmbVariableNames.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.cmbVariableNames.FormattingEnabled = true;
+      this.cmbVariableNames.Location = new System.Drawing.Point(142, 0);
+      this.cmbVariableNames.Name = "cmbVariableNames";
+      this.cmbVariableNames.Size = new System.Drawing.Size(121, 21);
+      this.cmbVariableNames.TabIndex = 1;
+      this.cmbVariableNames.SelectedIndexChanged += new System.EventHandler(this.cmbReplaceWith_SelectedIndexChanged);
+      // 
+      // cmbReplaceWith
+      // 
+      this.cmbReplaceWith.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.cmbReplaceWith.FormattingEnabled = true;
+      this.cmbReplaceWith.Items.AddRange(new object[] {
+            "Value",
+            "Average",
+            "Median",
+            "Most Common",
+            "Random"});
+      this.cmbReplaceWith.Location = new System.Drawing.Point(35, 27);
+      this.cmbReplaceWith.Name = "cmbReplaceWith";
+      this.cmbReplaceWith.Size = new System.Drawing.Size(121, 21);
+      this.cmbReplaceWith.TabIndex = 1;
+      this.cmbReplaceWith.SelectedIndexChanged += new System.EventHandler(this.cmbReplaceWith_SelectedIndexChanged);
+      // 
+      // lblValueColon
+      // 
+      this.lblValueColon.AutoSize = true;
+      this.lblValueColon.Location = new System.Drawing.Point(157, 30);
+      this.lblValueColon.Name = "lblValueColon";
+      this.lblValueColon.Size = new System.Drawing.Size(10, 13);
+      this.lblValueColon.TabIndex = 0;
+      this.lblValueColon.Text = ":";
+      // 
+      // label8
+      // 
+      this.label8.AutoSize = true;
+      this.label8.Location = new System.Drawing.Point(3, 30);
+      this.label8.Name = "label8";
+      this.label8.Size = new System.Drawing.Size(26, 13);
+      this.label8.TabIndex = 0;
+      this.label8.Text = "with";
+      // 
+      // label10
+      // 
+      this.label10.AutoSize = true;
+      this.label10.Location = new System.Drawing.Point(3, 3);
+      this.label10.Name = "label10";
+      this.label10.Size = new System.Drawing.Size(133, 13);
+      this.label10.TabIndex = 0;
+      this.label10.Text = "Replace missing values for";
+      // 
+      // tabDataShuffle
+      // 
+      this.tabDataShuffle.Controls.Add(this.label6);
+      this.tabDataShuffle.Location = new System.Drawing.Point(4, 22);
+      this.tabDataShuffle.Name = "tabDataShuffle";
+      this.tabDataShuffle.Padding = new System.Windows.Forms.Padding(3);
+      this.tabDataShuffle.Size = new System.Drawing.Size(711, 138);
+      this.tabDataShuffle.TabIndex = 4;
+      this.tabDataShuffle.Text = "shuffle";
+      this.tabDataShuffle.UseVisualStyleBackColor = true;
+      // 
+      // label6
+      // 
+      this.label6.AutoSize = true;
+      this.label6.Enabled = false;
+      this.label6.Location = new System.Drawing.Point(3, 3);
+      this.label6.Name = "label6";
+      this.label6.Size = new System.Drawing.Size(115, 13);
+      this.label6.TabIndex = 0;
+      this.label6.Text = "No properties available";
+      // 
+      // grpBoxPreview
+      // 
+      this.grpBoxPreview.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.grpBoxPreview.Controls.Add(this.tabsPreview);
+      this.grpBoxPreview.Location = new System.Drawing.Point(4, 301);
+      this.grpBoxPreview.Name = "grpBoxPreview";
+      this.grpBoxPreview.Size = new System.Drawing.Size(732, 193);
+      this.grpBoxPreview.TabIndex = 4;
+      this.grpBoxPreview.TabStop = false;
+      this.grpBoxPreview.Text = "Preview";
+      // 
+      // tabsPreview
+      // 
+      this.tabsPreview.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.tabsPreview.Controls.Add(this.tabPreviewInactive);
+      this.tabsPreview.Controls.Add(this.tabPreviewDeleteColumnsInfo);
+      this.tabsPreview.Controls.Add(this.tabPreviewDeleteColumnsVariance);
+      this.tabsPreview.Controls.Add(this.tabPreviewDeleteRowsInfo);
+      this.tabsPreview.Controls.Add(this.tabPreviewReplaceMissingValues);
+      this.tabsPreview.Controls.Add(this.tabPreviewShuffle);
+      this.tabsPreview.ItemSize = new System.Drawing.Size(58, 18);
+      this.tabsPreview.Location = new System.Drawing.Point(6, 19);
+      this.tabsPreview.Name = "tabsPreview";
+      this.tabsPreview.SelectedIndex = 0;
+      this.tabsPreview.Size = new System.Drawing.Size(719, 168);
+      this.tabsPreview.TabIndex = 3;
+      // 
+      // tabPreviewInactive
+      // 
+      this.tabPreviewInactive.Controls.Add(this.lblPreviewInActive);
+      this.tabPreviewInactive.Location = new System.Drawing.Point(4, 22);
+      this.tabPreviewInactive.Name = "tabPreviewInactive";
+      this.tabPreviewInactive.Padding = new System.Windows.Forms.Padding(3);
+      this.tabPreviewInactive.Size = new System.Drawing.Size(711, 142);
+      this.tabPreviewInactive.TabIndex = 5;
+      this.tabPreviewInactive.Text = "inactive";
+      this.tabPreviewInactive.UseVisualStyleBackColor = true;
+      // 
+      // lblPreviewInActive
+      // 
+      this.lblPreviewInActive.AutoSize = true;
+      this.lblPreviewInActive.Location = new System.Drawing.Point(3, 3);
+      this.lblPreviewInActive.Name = "lblPreviewInActive";
+      this.lblPreviewInActive.Size = new System.Drawing.Size(361, 39);
+      this.lblPreviewInActive.TabIndex = 2;
+      this.lblPreviewInActive.Text = "Filters are active and thus manipulations cannot be applied!\r\n\r\nPlease deactive t" +
+    "he filter(s) first in order to be able to perform manipulations.";
+      this.lblPreviewInActive.Visible = false;
+      // 
+      // tabPreviewDeleteColumnsInfo
+      // 
+      this.tabPreviewDeleteColumnsInfo.Controls.Add(this.lblPreviewColumnsInfo);
+      this.tabPreviewDeleteColumnsInfo.Location = new System.Drawing.Point(4, 22);
+      this.tabPreviewDeleteColumnsInfo.Name = "tabPreviewDeleteColumnsInfo";
+      this.tabPreviewDeleteColumnsInfo.Padding = new System.Windows.Forms.Padding(3);
+      this.tabPreviewDeleteColumnsInfo.Size = new System.Drawing.Size(711, 142);
+      this.tabPreviewDeleteColumnsInfo.TabIndex = 0;
+      this.tabPreviewDeleteColumnsInfo.Text = "del columns info";
+      this.tabPreviewDeleteColumnsInfo.UseVisualStyleBackColor = true;
+      // 
+      // lblPreviewColumnsInfo
+      // 
+      this.lblPreviewColumnsInfo.AutoSize = true;
+      this.lblPreviewColumnsInfo.Location = new System.Drawing.Point(3, 3);
+      this.lblPreviewColumnsInfo.Name = "lblPreviewColumnsInfo";
+      this.lblPreviewColumnsInfo.Size = new System.Drawing.Size(318, 13);
+      this.lblPreviewColumnsInfo.TabIndex = 1;
+      this.lblPreviewColumnsInfo.Text = "{0} columns with more than {1} % missing values would be deleted";
+      // 
+      // tabPreviewDeleteColumnsVariance
+      // 
+      this.tabPreviewDeleteColumnsVariance.Controls.Add(this.label12);
+      this.tabPreviewDeleteColumnsVariance.Controls.Add(this.lblPreviewColumnsVariance);
+      this.tabPreviewDeleteColumnsVariance.Location = new System.Drawing.Point(4, 22);
+      this.tabPreviewDeleteColumnsVariance.Name = "tabPreviewDeleteColumnsVariance";
+      this.tabPreviewDeleteColumnsVariance.Padding = new System.Windows.Forms.Padding(3);
+      this.tabPreviewDeleteColumnsVariance.Size = new System.Drawing.Size(711, 142);
+      this.tabPreviewDeleteColumnsVariance.TabIndex = 1;
+      this.tabPreviewDeleteColumnsVariance.Text = "del columns variance";
+      this.tabPreviewDeleteColumnsVariance.UseVisualStyleBackColor = true;
+      // 
+      // label12
+      // 
+      this.label12.AutoSize = true;
+      this.label12.Location = new System.Drawing.Point(6, 22);
+      this.label12.Name = "label12";
+      this.label12.Size = new System.Drawing.Size(0, 13);
+      this.label12.TabIndex = 2;
+      // 
+      // lblPreviewColumnsVariance
+      // 
+      this.lblPreviewColumnsVariance.AutoSize = true;
+      this.lblPreviewColumnsVariance.Location = new System.Drawing.Point(3, 3);
+      this.lblPreviewColumnsVariance.Name = "lblPreviewColumnsVariance";
+      this.lblPreviewColumnsVariance.Size = new System.Drawing.Size(301, 13);
+      this.lblPreviewColumnsVariance.TabIndex = 2;
+      this.lblPreviewColumnsVariance.Text = "{0} columns with a variance smaller than {1} would be deleted.";
+      // 
+      // tabPreviewDeleteRowsInfo
+      // 
+      this.tabPreviewDeleteRowsInfo.Controls.Add(this.lblPreviewRowsInfo);
+      this.tabPreviewDeleteRowsInfo.Location = new System.Drawing.Point(4, 22);
+      this.tabPreviewDeleteRowsInfo.Name = "tabPreviewDeleteRowsInfo";
+      this.tabPreviewDeleteRowsInfo.Padding = new System.Windows.Forms.Padding(3);
+      this.tabPreviewDeleteRowsInfo.Size = new System.Drawing.Size(711, 142);
+      this.tabPreviewDeleteRowsInfo.TabIndex = 2;
+      this.tabPreviewDeleteRowsInfo.Text = "del rows info";
+      this.tabPreviewDeleteRowsInfo.UseVisualStyleBackColor = true;
+      // 
+      // lblPreviewRowsInfo
+      // 
+      this.lblPreviewRowsInfo.AutoSize = true;
+      this.lblPreviewRowsInfo.Location = new System.Drawing.Point(3, 3);
+      this.lblPreviewRowsInfo.Name = "lblPreviewRowsInfo";
+      this.lblPreviewRowsInfo.Size = new System.Drawing.Size(301, 13);
+      this.lblPreviewRowsInfo.TabIndex = 2;
+      this.lblPreviewRowsInfo.Text = "{0} rows with more than {1} % missing values would be deleted";
+      // 
+      // tabPreviewReplaceMissingValues
+      // 
+      this.tabPreviewReplaceMissingValues.Controls.Add(this.lblPreviewReplaceMissingValues);
+      this.tabPreviewReplaceMissingValues.Location = new System.Drawing.Point(4, 22);
+      this.tabPreviewReplaceMissingValues.Name = "tabPreviewReplaceMissingValues";
+      this.tabPreviewReplaceMissingValues.Padding = new System.Windows.Forms.Padding(3);
+      this.tabPreviewReplaceMissingValues.Size = new System.Drawing.Size(711, 142);
+      this.tabPreviewReplaceMissingValues.TabIndex = 6;
+      this.tabPreviewReplaceMissingValues.Text = "repl missing vals";
+      this.tabPreviewReplaceMissingValues.UseVisualStyleBackColor = true;
+      // 
+      // lblPreviewReplaceMissingValues
+      // 
+      this.lblPreviewReplaceMissingValues.AutoSize = true;
+      this.lblPreviewReplaceMissingValues.Location = new System.Drawing.Point(3, 3);
+      this.lblPreviewReplaceMissingValues.Name = "lblPreviewReplaceMissingValues";
+      this.lblPreviewReplaceMissingValues.Size = new System.Drawing.Size(343, 13);
+      this.lblPreviewReplaceMissingValues.TabIndex = 3;
+      this.lblPreviewReplaceMissingValues.Text = "{0} cells detected with missing values which would be replaced with {1}";
+      // 
+      // tabPreviewShuffle
+      // 
+      this.tabPreviewShuffle.Controls.Add(this.lblPreviewShuffle);
+      this.tabPreviewShuffle.Location = new System.Drawing.Point(4, 22);
+      this.tabPreviewShuffle.Name = "tabPreviewShuffle";
+      this.tabPreviewShuffle.Padding = new System.Windows.Forms.Padding(3);
+      this.tabPreviewShuffle.Size = new System.Drawing.Size(711, 142);
+      this.tabPreviewShuffle.TabIndex = 4;
+      this.tabPreviewShuffle.Text = "shuffle";
+      this.tabPreviewShuffle.UseVisualStyleBackColor = true;
+      // 
+      // lblPreviewShuffle
+      // 
+      this.lblPreviewShuffle.AutoSize = true;
+      this.lblPreviewShuffle.Location = new System.Drawing.Point(3, 3);
+      this.lblPreviewShuffle.Name = "lblPreviewShuffle";
+      this.lblPreviewShuffle.Size = new System.Drawing.Size(252, 13);
+      this.lblPreviewShuffle.TabIndex = 0;
+      this.lblPreviewShuffle.Text = "Data will be shuffled randomly - preview not possible";
+      // 
+      // label9
+      // 
+      this.label9.Location = new System.Drawing.Point(0, 0);
+      this.label9.Name = "label9";
+      this.label9.Size = new System.Drawing.Size(100, 23);
+      this.label9.TabIndex = 0;
+      // 
+      // ManipulationView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.btnApply);
+      this.Controls.Add(this.grpBoxPreview);
+      this.Controls.Add(this.grpBoxData);
+      this.Controls.Add(this.lstMethods);
+      this.Name = "ManipulationView";
+      this.Size = new System.Drawing.Size(739, 529);
+      this.grpBoxData.ResumeLayout(false);
+      this.tabsData.ResumeLayout(false);
+      this.tabPage1.ResumeLayout(false);
+      this.tabPage1.PerformLayout();
+      this.tabDataDeleteColumnsInformation.ResumeLayout(false);
+      this.tabDataDeleteColumnsInformation.PerformLayout();
+      this.tabDataDeleteColumnsVariance.ResumeLayout(false);
+      this.tabDataDeleteColumnsVariance.PerformLayout();
+      this.tabDataDeleteRowsInfo.ResumeLayout(false);
+      this.tabDataDeleteRowsInfo.PerformLayout();
+      this.tabReplaceMissingValues.ResumeLayout(false);
+      this.tabReplaceMissingValues.PerformLayout();
+      this.tabDataShuffle.ResumeLayout(false);
+      this.tabDataShuffle.PerformLayout();
+      this.grpBoxPreview.ResumeLayout(false);
+      this.tabsPreview.ResumeLayout(false);
+      this.tabPreviewInactive.ResumeLayout(false);
+      this.tabPreviewInactive.PerformLayout();
+      this.tabPreviewDeleteColumnsInfo.ResumeLayout(false);
+      this.tabPreviewDeleteColumnsInfo.PerformLayout();
+      this.tabPreviewDeleteColumnsVariance.ResumeLayout(false);
+      this.tabPreviewDeleteColumnsVariance.PerformLayout();
+      this.tabPreviewDeleteRowsInfo.ResumeLayout(false);
+      this.tabPreviewDeleteRowsInfo.PerformLayout();
+      this.tabPreviewReplaceMissingValues.ResumeLayout(false);
+      this.tabPreviewReplaceMissingValues.PerformLayout();
+      this.tabPreviewShuffle.ResumeLayout(false);
+      this.tabPreviewShuffle.PerformLayout();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.ListBox lstMethods;
+    private System.Windows.Forms.Button btnApply;
+    private System.Windows.Forms.GroupBox grpBoxData;
+    private System.Windows.Forms.GroupBox grpBoxPreview;
+    private System.Windows.Forms.TabControl tabsPreview;
+    private System.Windows.Forms.TabPage tabPreviewDeleteColumnsInfo;
+    private System.Windows.Forms.TabPage tabPreviewDeleteColumnsVariance;
+    private System.Windows.Forms.TabPage tabPreviewDeleteRowsInfo;
+    private System.Windows.Forms.TabPage tabPreviewShuffle;
+    private System.Windows.Forms.Label lblPreviewShuffle;
+    private System.Windows.Forms.TabPage tabPreviewInactive;
+    private System.Windows.Forms.Label lblPreviewColumnsInfo;
+    private System.Windows.Forms.Label label12;
+    private System.Windows.Forms.Label lblPreviewColumnsVariance;
+    private System.Windows.Forms.Label lblPreviewRowsInfo;
+    private System.Windows.Forms.TabPage tabPreviewReplaceMissingValues;
+    private System.Windows.Forms.Label lblPreviewReplaceMissingValues;
+    private System.Windows.Forms.Label label9;
+    private System.Windows.Forms.TabControl tabsData;
+    private System.Windows.Forms.TabPage tabPage1;
+    private System.Windows.Forms.Label label7;
+    private System.Windows.Forms.TabPage tabDataDeleteColumnsInformation;
+    private System.Windows.Forms.Label label2;
+    private System.Windows.Forms.TextBox txtDeleteColumnsInfo;
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.TabPage tabDataDeleteColumnsVariance;
+    private System.Windows.Forms.TextBox txtDeleteColumnsVariance;
+    private System.Windows.Forms.Label label4;
+    private System.Windows.Forms.TabPage tabDataDeleteRowsInfo;
+    private System.Windows.Forms.Label label3;
+    private System.Windows.Forms.TextBox txtDeleteRowsInfo;
+    private System.Windows.Forms.Label label5;
+    private System.Windows.Forms.TabPage tabReplaceMissingValues;
+    private System.Windows.Forms.TextBox txtReplaceValue;
+    private System.Windows.Forms.ComboBox cmbReplaceWith;
+    private System.Windows.Forms.Label lblValueColon;
+    private System.Windows.Forms.Label label10;
+    private System.Windows.Forms.TabPage tabDataShuffle;
+    private System.Windows.Forms.Label label6;
+    private System.Windows.Forms.ComboBox cmbVariableNames;
+    private System.Windows.Forms.Label label8;
+    private System.Windows.Forms.Label lblPreviewInActive;
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/ManipulationView.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/ManipulationView.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/ManipulationView.cs	(revision 11159)
@@ -0,0 +1,303 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Drawing;
+using System.Windows.Forms;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+
+  [View("Manipulation Chart View")]
+  [Content(typeof(ManipulationContent), true)]
+  public partial class ManipulationView : ItemView {
+
+    private Action[] validators;
+    private Action[] manipulations;
+
+    public ManipulationView() {
+      InitializeComponent();
+      cmbReplaceWith.SelectedIndex = 0;
+      tabsData.Appearance = TabAppearance.FlatButtons;
+      tabsData.ItemSize = new Size(0, 1);
+      tabsData.SizeMode = TabSizeMode.Fixed;
+      tabsPreview.Appearance = TabAppearance.FlatButtons;
+      tabsPreview.ItemSize = new Size(0, 1);
+      tabsPreview.SizeMode = TabSizeMode.Fixed;
+
+      validators = new Action[] { 
+        ()=>validateDeleteColumnsInfo(),
+        ()=>validateDeleteColumnsVariance(),
+        ()=>validateDeleteRowsInfo(),
+        ()=>validateReplaceWith(),
+        ()=>{btnApply.Enabled = true; lblPreviewShuffle.Text = "Data will be shuffled randomly - preview not possible";} //shuffle
+      };
+
+      manipulations = new Action[] { 
+        ()=>Content.ManipulationLogic.DeleteColumnsWithMissingValuesGreater(getDeleteColumnsInfo()),
+        ()=>Content.ManipulationLogic.DeleteColumnsWithVarianceSmaller(getDeleteColumnsVariance()),
+        ()=>Content.ManipulationLogic.DeleteRowsWithMissingValuesGreater(getRowsColumnsInfo()),
+        ()=>replaceMissingValues(),
+        ()=>Content.ManipulationLogic.ShuffleWithRanges()
+      };
+
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content != null) {
+        cmbVariableNames.Items.Clear();
+        foreach (var name in Content.ManipulationLogic.VariableNames) {
+          cmbVariableNames.Items.Add(name);
+        }
+        cmbVariableNames.SelectedIndex = 0;
+        CheckFilters();
+      }
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.FilterLogic.FilterChanged += FilterLogic_FilterChanged;
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.FilterLogic.FilterChanged -= FilterLogic_FilterChanged;
+      base.DeregisterContentEvents();
+    }
+
+    private void FilterLogic_FilterChanged(object sender, EventArgs e) {
+      if (Content != null) {
+        CheckFilters();
+      }
+    }
+
+    private void CheckFilters() {
+      if (Content.FilterLogic.IsFiltered) {
+        tabsPreview.SelectedIndex = 0;
+        lstMethods.Enabled = false;
+        tabsData.Enabled = false;
+        tabsPreview.Enabled = false;
+        lblPreviewInActive.Visible = true;
+        btnApply.Enabled = false;
+      } else {
+        lblPreviewInActive.Visible = false;
+        tabsData.Enabled = true;
+        tabsPreview.Enabled = true;
+        lstMethods.Enabled = true;
+        lstMethods_SelectedIndexChanged(null, null);
+      }
+    }
+
+    private double getDeleteColumnsInfo() {
+      return double.Parse(txtDeleteColumnsInfo.Text);
+    }
+
+    private double getDeleteColumnsVariance() {
+      return double.Parse(txtDeleteColumnsVariance.Text);
+    }
+
+    private double getRowsColumnsInfo() {
+      return double.Parse(txtDeleteRowsInfo.Text);
+    }
+
+    private void replaceMissingValues() {
+      var allIndices = Content.SearchLogic.GetMissingValueIndices();
+      var columnIndex = cmbVariableNames.SelectedIndex;
+      var columnIndices = new Dictionary<int, IList<int>>{
+          {columnIndex,   allIndices[columnIndex]}
+      };
+
+      switch (cmbReplaceWith.SelectedIndex) {
+        case 0: //Value
+          Content.ManipulationLogic.ReplaceIndicesByValue(columnIndices, txtReplaceValue.Text);
+          break;
+        case 1: //Average
+          Content.ManipulationLogic.ReplaceIndicesByAverageValue(columnIndices);
+          break;
+        case 2: //Median
+          Content.ManipulationLogic.ReplaceIndicesByMedianValue(columnIndices);
+          break;
+        case 3: //Most Common
+          Content.ManipulationLogic.ReplaceIndicesByMostCommonValue(columnIndices);
+          break;
+        case 4: //Random
+          Content.ManipulationLogic.ReplaceIndicesByRandomValue(columnIndices);
+          break;
+      }
+    }
+
+    private void validateDeleteColumnsInfo() {
+      validateDoubleTextBox(txtDeleteColumnsInfo.Text);
+      if (btnApply.Enabled) {
+        int count = Content.ManipulationLogic.ColumnsWithMissingValuesGreater(getDeleteColumnsInfo()).Count;
+        int rowCount = Content.FilterLogic.PreprocessingData.Rows;
+        lblPreviewColumnsInfo.Text = count + " column" + (count > 1 || count == 0 ? "s" : "") + " of " + rowCount + " (" + string.Format("{0:F2}%", 100d / rowCount * count) + ") were detected with more than " + txtDeleteColumnsInfo.Text + "% missing values.";
+        if (count > 0) {
+          lblPreviewColumnsInfo.Text += Environment.NewLine + Environment.NewLine + "Please press the button \"Apply Manipulation\" if you wish to delete those columns.";
+        } else {
+          btnApply.Enabled = false;
+        }
+      } else {
+        lblPreviewColumnsInfo.Text = "Preview not possible yet - please input the limit above.";
+      }
+    }
+
+    private void validateDeleteColumnsVariance() {
+      validateDoubleTextBox(txtDeleteColumnsVariance.Text);
+      if (btnApply.Enabled) {
+        int count = Content.ManipulationLogic.ColumnsWithVarianceSmaller(getDeleteColumnsVariance()).Count;
+        int rowCount = Content.FilterLogic.PreprocessingData.Rows;
+        lblPreviewColumnsVariance.Text = count + " column" + (count > 1 || count == 0 ? "s" : "") + " of " + rowCount + " (" + string.Format("{0:F2}%", 100d / rowCount * count) + ") were detected with a variance smaller than " + txtDeleteColumnsVariance.Text + ".";
+        if (count > 0) {
+          lblPreviewColumnsVariance.Text += Environment.NewLine + Environment.NewLine + "Please press the button \"Apply Manipulation\" if you wish to delete those columns.";
+        } else {
+          btnApply.Enabled = false;
+        }
+      } else {
+        lblPreviewColumnsVariance.Text = "Preview not possible yet - please input the limit for the variance above.";
+      }
+    }
+
+    private void validateDeleteRowsInfo() {
+      validateDoubleTextBox(txtDeleteRowsInfo.Text);
+      if (btnApply.Enabled) {
+        int count = Content.ManipulationLogic.RowsWithMissingValuesGreater(getRowsColumnsInfo()).Count;
+        int rowCount = Content.FilterLogic.PreprocessingData.Rows;
+        lblPreviewRowsInfo.Text = count + " row" + (count > 1 || count == 0 ? "s" : "") + " of " + rowCount + " (" + string.Format("{0:F2}%", 100d / rowCount * count) + ") were detected with more than " + txtDeleteRowsInfo.Text + "% missing values.";
+        if (count > 0) {
+          lblPreviewRowsInfo.Text += Environment.NewLine + Environment.NewLine + "Please press the button \"Apply Manipulation\" if you wish to delete those rows.";
+        } else {
+          btnApply.Enabled = false;
+        }
+      } else {
+        lblPreviewRowsInfo.Text = "Preview not possible yet - please input the limit above.";
+      }
+    }
+
+    private void validateReplaceWith() {
+      btnApply.Enabled = false;
+      string replaceWith = (string)cmbReplaceWith.SelectedItem;
+      int columnIndex = cmbVariableNames.SelectedIndex;
+
+      if (cmbReplaceWith.SelectedIndex == 0) {
+        string errorMessage;
+        string replaceValue = txtReplaceValue.Text;
+        if (string.IsNullOrEmpty(replaceValue)) {
+          lblPreviewReplaceMissingValues.Text = "Preview not possible yet - please input the text which will be used as replacement.";
+        } else if (!Content.ManipulationLogic.PreProcessingData.Validate(txtReplaceValue.Text, out errorMessage, columnIndex)) {
+          lblPreviewReplaceMissingValues.Text = "Preview not possible yet - " + errorMessage;
+        } else {
+          btnApply.Enabled = true;
+        }
+        replaceWith = "\"" + replaceValue + "\"";
+      } else {
+        btnApply.Enabled = true;
+      }
+      if (btnApply.Enabled) {
+        var allIndices = Content.SearchLogic.GetMissingValueIndices();
+        int count = allIndices[columnIndex].Count;
+        int cellCount = Content.FilterLogic.PreprocessingData.Rows * Content.FilterLogic.PreprocessingData.Columns;
+        lblPreviewReplaceMissingValues.Text = count + " cell" + (count > 1 || count == 0 ? "s" : "")
+          + " of " + cellCount + " (" + string.Format("{0:F2}%", 100d / cellCount * count) + ") were detected with missing values which would be replaced with " + replaceWith;
+        if (count > 0) {
+          lblPreviewReplaceMissingValues.Text += Environment.NewLine + Environment.NewLine + "Please press the button \"Apply Manipulation\" if you wish to perform the replacement.";
+        } else {
+          btnApply.Enabled = false;
+        }
+      }
+    }
+
+    public new ManipulationContent Content {
+      get { return (ManipulationContent)base.Content; }
+      set { base.Content = value; }
+    }
+
+    private void lstMethods_SelectedIndexChanged(object sender, System.EventArgs e) {
+      int index = lstMethods.SelectedIndex;
+      tabsData.SelectedIndex = index + 1;
+      tabsPreview.SelectedIndex = index + 1;
+      btnApply.Enabled = false;
+
+      //in order that button is enabled if necessary input was already entered
+      if (index >= 0) {
+        validators[index]();
+      }
+    }
+
+    private void btnApply_Click(object sender, System.EventArgs e) {
+      manipulations[lstMethods.SelectedIndex]();
+      switch (lstMethods.SelectedIndex) {
+        case 0:
+          lblPreviewColumnsInfo.Text = "columns successfully deleted.";
+          break;
+        case 1:
+          lblPreviewColumnsVariance.Text = "columns successfully deleted.";
+          break;
+        case 2:
+          lblPreviewRowsInfo.Text = "rows successfully deleted.";
+          break;
+        case 3:
+          lblPreviewReplaceMissingValues.Text = "missing values successfully replaced.";
+          btnApply.Enabled = false;
+          break;
+        case 4:
+          lblPreviewShuffle.Text = "dataset shuffled successfully.";
+          btnApply.Enabled = false;
+          break;
+      }
+    }
+
+    private void validateDoubleTextBox(String text) {
+      btnApply.Enabled = false;
+      if (!string.IsNullOrEmpty(text)) {
+        double percent;
+        if (Double.TryParse(text, out percent)) {
+          btnApply.Enabled = true;
+        }
+      }
+    }
+
+    private void txtDeleteColumnsInfo_TextChanged(object sender, EventArgs e) {
+      validateDeleteColumnsInfo();
+    }
+
+    private void txtDeleteColumnsVariance_TextChanged(object sender, EventArgs e) {
+      validateDeleteColumnsVariance();
+    }
+
+    private void txtDeleteRowsInfo_TextChanged(object sender, EventArgs e) {
+      validateDeleteRowsInfo();
+    }
+
+    private void cmbReplaceWith_SelectedIndexChanged(object sender, EventArgs e) {
+      bool isReplaceWithValueSelected = cmbReplaceWith.SelectedIndex == 0;
+      lblValueColon.Visible = isReplaceWithValueSelected;
+      txtReplaceValue.Visible = isReplaceWithValueSelected;
+      validateReplaceWith();
+    }
+
+    private void txtReplaceValue_TextChanged(object sender, EventArgs e) {
+      validateReplaceWith();
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/Plugin.cs.frame
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/Plugin.cs.frame	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/Plugin.cs.frame	(revision 11159)
@@ -0,0 +1,48 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.PluginInfrastructure;
+
+namespace HeuristicLab.DataPreprocessing {
+  /// <summary>
+  /// Plugin class for HeuristicLab.Data plugin.
+  /// </summary>
+  [Plugin("HeuristicLab.DataPreprocessing.Views", "3.4.0.$WCREV$")]
+  [PluginFile("HeuristicLab.DataPreprocessing.Views-3.4.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Analysis", "3.3")]
+  [PluginDependency("HeuristicLab.Analysis.Views", "3.3")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Core.Views", "3.3")]
+  [PluginDependency("HeuristicLab.Data","3.3")]
+  [PluginDependency("HeuristicLab.Data.Views","3.3")]
+  [PluginDependency("HeuristicLab.DataPreprocessing", "3.4")]
+  [PluginDependency("HeuristicLab.MainForm", "3.3")]
+  [PluginDependency("HeuristicLab.MainForm.WindowsForms", "3.3")] 
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis", "3.4")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis.Views", "3.4")]
+  [PluginDependency("HeuristicLab.Visualization.ChartControlsExtensions", "3.3")]
+  public class HeuristicLabDataPreprocessingViewPlugin : PluginBase {
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingChartView.Designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingChartView.Designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingChartView.Designer.cs	(revision 11159)
@@ -0,0 +1,113 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Data;
+namespace HeuristicLab.DataPreprocessing.Views {
+  partial class PreprocessingChartView {
+    /// <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.dataTableView = new DataPreprocessing.Views.PreprocessingDataTableView();
+      this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
+      this.checkedItemList = new HeuristicLab.DataPreprocessing.Views.PreprocessingCheckedItemListView();
+      this.tableLayoutPanel.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // dataTableView
+      // 
+      this.dataTableView.Caption = "DataTable View";
+      this.dataTableView.Content = null;
+      this.dataTableView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.dataTableView.Location = new System.Drawing.Point(3, 3);
+      this.dataTableView.Name = "dataTableView";
+      this.dataTableView.ReadOnly = false;
+      this.dataTableView.Size = new System.Drawing.Size(486, 390);
+      this.dataTableView.TabIndex = 0;
+      // 
+      // tableLayoutPanel
+      // 
+      this.tableLayoutPanel.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.tableLayoutPanel.AutoScroll = true;
+      this.tableLayoutPanel.ColumnCount = 1;
+      this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+      this.tableLayoutPanel.Controls.Add(this.dataTableView, 0, 0);
+      this.tableLayoutPanel.Location = new System.Drawing.Point(162, 4);
+      this.tableLayoutPanel.Name = "tableLayoutPanel";
+      this.tableLayoutPanel.RowCount = 1;
+      this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
+      this.tableLayoutPanel.Size = new System.Drawing.Size(492, 396);
+      this.tableLayoutPanel.TabIndex = 6;
+      this.tableLayoutPanel.Layout += new System.Windows.Forms.LayoutEventHandler(this.tableLayoutPanel_Layout);
+      // 
+      // checkedItemList
+      // 
+      this.checkedItemList.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left)));
+      this.checkedItemList.Caption = "View";
+      this.checkedItemList.Content = null;
+      this.checkedItemList.Location = new System.Drawing.Point(4, 4);
+      this.checkedItemList.Name = "checkedItemList";
+      this.checkedItemList.ReadOnly = false;
+      this.checkedItemList.Size = new System.Drawing.Size(152, 252);
+      this.checkedItemList.TabIndex = 4;
+      // 
+      // PreprocessingChartView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.tableLayoutPanel);
+      this.Controls.Add(this.checkedItemList);
+      this.Name = "PreprocessingChartView";
+      this.Size = new System.Drawing.Size(654, 403);
+      this.tableLayoutPanel.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private PreprocessingCheckedItemListView checkedItemList;
+    private DataPreprocessing.Views.PreprocessingDataTableView dataTableView;
+    private System.Windows.Forms.TableLayoutPanel tableLayoutPanel;
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingChartView.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingChartView.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingChartView.cs	(revision 11159)
@@ -0,0 +1,384 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Windows.Forms;
+using HeuristicLab.Analysis;
+using HeuristicLab.Collections;
+using HeuristicLab.Core.Views;
+using HeuristicLab.Data;
+using HeuristicLab.DataPreprocessing.Implementations;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+
+  [View("Preprocessing Chart View")]
+  [Content(typeof(PreprocessingChartContent), false)]
+  public partial class PreprocessingChartView : ItemView {
+
+    private PreprocessingDataTable dataTable;
+    private List<PreprocessingDataTable> dataTablePerVariable;
+    private List<DataRow> dataRows;
+    private List<DataRow> selectedDataRows;
+
+    protected DataRowVisualProperties.DataRowChartType chartType;
+    protected string chartTitle;
+
+    private const string DEFAULT_CHART_TITLE = "Chart";
+    private const int FIXED_CHART_SIZE = 300;
+    private const int MAX_TABLE_AUTO_SIZE_ROWS = 3;
+
+    public IEnumerable<double> Classification { get; set; }
+
+    public PreprocessingChartView() {
+      InitializeComponent();
+      chartType = DataRowVisualProperties.DataRowChartType.Line;
+      chartTitle = DEFAULT_CHART_TITLE;
+    }
+
+    //Variable selection changed
+    //Add or remove data row
+    private void CheckedItemsChanged(object sender, CollectionItemsChangedEventArgs<IndexedItem<StringValue>> checkedItems) {
+      foreach (IndexedItem<StringValue> item in checkedItems.Items) {
+        string variableName = item.Value.Value;
+
+        //variable is displayed -> remove
+        if (VariableIsDisplayed(variableName)) {
+          dataTable.Rows.Remove(variableName);
+          dataTable.SelectedRows.Remove(variableName);
+          dataTablePerVariable.Remove(dataTablePerVariable.Find(x => (x.Name == variableName)));
+          //variable isnt't displayed -> add
+        } else {
+          DataRow row = GetDataRow(variableName);
+          DataRow selectedRow = GetSelectedDataRow(variableName);
+          dataTable.Rows.Add(row);
+
+          PreprocessingDataTable pdt = new PreprocessingDataTable(variableName);
+          pdt.Rows.Add(row);
+          dataTablePerVariable.Add(pdt);
+
+          //update selection
+          if (selectedRow != null) {
+            dataTable.SelectedRows.Add(selectedRow);
+            pdt.SelectedRows.Add(selectedRow);
+          }
+        }
+      }
+
+      // update chart if not in all in one mode
+      if (Content != null && !Content.AllInOneMode)
+        GenerateChart();
+
+    }
+
+    private bool VariableIsDisplayed(string name) {
+
+      foreach (var item in dataTable.Rows) {
+        if (item.Name == name)
+          return true;
+      }
+      return false;
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.PreprocessingData.Changed += PreprocessingData_Changed;
+      Content.PreprocessingData.SelectionChanged += PreprocessingData_SelctionChanged;
+
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.PreprocessingData.Changed -= PreprocessingData_Changed;
+      Content.PreprocessingData.SelectionChanged -= PreprocessingData_SelctionChanged;
+    }
+
+    public new PreprocessingChartContent Content {
+      get { return (PreprocessingChartContent)base.Content; }
+      set { base.Content = value; }
+    }
+
+    private void InitData() {
+      if (Content.VariableItemList == null) {
+        Content.VariableItemList = Content.CreateVariableItemList();
+      }
+      checkedItemList.Content = Content.VariableItemList;
+
+      //Create data tables and data rows
+      dataRows = Content.CreateAllDataRows(chartType);
+      dataTable = new PreprocessingDataTable(chartTitle);
+      dataTablePerVariable = new List<PreprocessingDataTable>();
+
+      //add data rows to data tables according to checked item list
+      foreach (var checkedItem in Content.VariableItemList.CheckedItems) {
+        string variableName = Content.VariableItemList[checkedItem.Index].Value;
+        PreprocessingDataTable d = new PreprocessingDataTable(variableName);
+        DataRow row = GetDataRow(variableName);
+
+        //add row to data table 
+        dataTable.Rows.Add(row);
+
+        //add row to data table per variable
+        d.Rows.Add(row);
+        dataTablePerVariable.Add(d);
+      }
+
+      UpdateSelection();
+    }
+
+    private void UpdateSelection() {
+
+      //update data table selection
+      selectedDataRows = Content.CreateAllSelectedDataRows(chartType);
+      dataTable.SelectedRows.Clear();
+      foreach (var selectedRow in selectedDataRows) {
+        if(VariableIsDisplayed(selectedRow.Name))
+          dataTable.SelectedRows.Add(selectedRow);
+      }
+
+      //update data table per variable selection
+      foreach (PreprocessingDataTable d in dataTablePerVariable) {
+        d.SelectedRows.Clear();
+        DataRow row = selectedDataRows.Find(x => x.Name == d.Name);
+        if (row != null)
+          d.SelectedRows.Add(row);
+      }
+
+    }
+
+    private DataRow GetSelectedDataRow(string variableName) {
+      foreach (DataRow row in selectedDataRows) {
+        if (row.Name == variableName)
+          return row;
+      }
+      return null;
+    }
+
+    private DataRow GetDataRow(string variableName) {
+      foreach (DataRow row in dataRows) {
+        if (row.Name == variableName)
+          return row;
+      }
+      return null;
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content != null) {
+        InitData();
+        Content.VariableItemList.CheckedItemsChanged += CheckedItemsChanged;
+        GenerateChart();
+      }
+    }
+
+    // TODO : handle also other changed events
+    void PreprocessingData_Changed(object sender, DataPreprocessingChangedEventArgs e) {
+      switch (e.Type) {
+        case DataPreprocessingChangedEventType.DeleteColumn:
+          RemoveVariable(Content.PreprocessingData.GetVariableName(e.Column));
+          break;
+        case DataPreprocessingChangedEventType.AddColumn:
+          AddVariable(Content.PreprocessingData.GetVariableName(e.Column));
+          break;
+        case DataPreprocessingChangedEventType.ChangeColumn:
+        case DataPreprocessingChangedEventType.ChangeItem:
+          UpdateDataForVariable(Content.PreprocessingData.GetVariableName(e.Column));
+          break;
+        case DataPreprocessingChangedEventType.DeleteRow:
+        case DataPreprocessingChangedEventType.AddRow:
+        case DataPreprocessingChangedEventType.Any:
+        default:
+          //TODO: test with transform
+          InitData();
+          GenerateChart();
+          break;
+      }
+    }
+
+    private void PreprocessingData_SelctionChanged(object sender, EventArgs e) {
+      UpdateSelection();
+    }
+
+    private void UpdateDataForVariable(string variableName) {
+      DataRow newRow = Content.CreateDataRow(variableName, chartType);
+      dataTable.Rows.Remove(variableName);
+      dataTable.Rows.Add(newRow);
+      DataTable dt = dataTablePerVariable.Find(x => x.Rows.Find(y => y.Name == variableName) != null);
+      if (dt != null) {
+        dt.Rows.Remove(variableName);
+        dt.Rows.Add(newRow);
+      }
+    }
+
+    // add variable to data table and item list
+    private void AddVariable(string name) {
+      DataRow row = Content.CreateDataRow(name, chartType);
+      dataTable.Rows.Add(row);
+      PreprocessingDataTable d = new PreprocessingDataTable(name);
+      d.Rows.Add(row);
+      dataTablePerVariable.Add(d);
+      Content.VariableItemList.Add(new StringValue(name));
+      if (!Content.AllInOneMode)
+        GenerateChart();
+    }
+
+    // remove variable from data table and item list
+    private void RemoveVariable(string name) {
+      dataTable.Rows.Remove(name);
+      dataTablePerVariable.Remove(dataTablePerVariable.Find(x => (x.Name == name)));
+
+      StringValue stringValue = FindVariableItemList(name);
+      if (stringValue != null)
+        Content.VariableItemList.Remove(stringValue);
+      if (!Content.AllInOneMode)
+        GenerateChart();
+    }
+
+    private StringValue FindVariableItemList(string name) {
+      foreach (StringValue stringValue in Content.VariableItemList) {
+        if (stringValue.Value == name)
+          return stringValue;
+      }
+      return null;
+    }
+
+    protected void GenerateChart() {
+      ClearTableLayout();
+      if (Content.AllInOneMode) {
+        GenerateSingleChartLayout();
+      } else
+        GenerateMultiChartLayout();
+    }
+
+    private void ClearTableLayout() {
+      //Clear out the existing controls
+      tableLayoutPanel.Controls.Clear();
+
+      //Clear out the existing row and column styles
+      tableLayoutPanel.ColumnStyles.Clear();
+      tableLayoutPanel.RowStyles.Clear();
+      tableLayoutPanel.AutoScroll = false;
+      tableLayoutPanel.AutoScroll = true;
+    }
+
+    private void GenerateSingleChartLayout() {
+      tableLayoutPanel.ColumnCount = 1;
+      tableLayoutPanel.RowCount = 1;
+      tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100));
+      tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
+      tableLayoutPanel.Controls.Add(dataTableView, 0, 0);
+      dataTableView.Content = dataTable;
+    }
+
+    private int GetNrOfMultiChartColumns(int itemCount) {
+      int columns = 0;
+      if (itemCount <= 2)
+        columns = 1;
+      else if (itemCount <= 6)
+        columns = 2;
+      else
+        columns = 3;
+      return columns;
+    }
+
+    private int GetNrOfMultiChartRows(int itemCount, int columns) {
+      int rows = 0;
+      if (columns == 3)
+        rows = (itemCount + 2) / columns;
+      else if (columns == 2)
+        rows = (itemCount + 1) / columns;
+      else
+        rows = itemCount / columns;
+      return rows;
+    }
+
+
+    private void GenerateMultiChartLayout() {
+      int checkedItemsCnt = 0;
+      foreach (var item in Content.VariableItemList.CheckedItems)
+        checkedItemsCnt++;
+
+      // set columns and rows based on number of items
+      int columns = GetNrOfMultiChartColumns(checkedItemsCnt);
+      int rows = GetNrOfMultiChartRows(checkedItemsCnt, columns);
+
+      tableLayoutPanel.ColumnCount = columns;
+      tableLayoutPanel.RowCount = rows;
+
+      List<PreprocessingDataTable>.Enumerator enumerator = dataTablePerVariable.GetEnumerator();
+      for (int x = 0; x < columns; x++) {
+
+        if (rows <= MAX_TABLE_AUTO_SIZE_ROWS)
+          tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100 / columns));
+        else
+          //scrollbar is shown if there are more than 3 rows -> remove scroll bar width from total width
+          tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, (tableLayoutPanel.Width - System.Windows.Forms.SystemInformation.VerticalScrollBarWidth) / columns));
+        for (int y = 0; y < rows; y++) {
+          //Add a row only when creating the first column
+          if (x == 0) {
+            // fixed chart size when there are more than 3 tables
+            if (rows > MAX_TABLE_AUTO_SIZE_ROWS)
+              tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, FIXED_CHART_SIZE));
+            else
+              tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100 / rows));
+          }
+
+          enumerator.MoveNext();
+          PreprocessingDataTable d = enumerator.Current;
+          AddDataTableToTableLayout(d, x, y);
+
+        }
+      }
+    }
+
+    private void AddDataTableToTableLayout(PreprocessingDataTable dataTable, int x, int y) {
+      PreprocessingDataTableView dataView = new PreprocessingDataTableView();
+      dataView.Classification = Classification;
+
+      if (dataTable == null) {
+        // dummy panel for empty field 
+        Panel p = new Panel();
+        p.Dock = DockStyle.Fill;
+        tableLayoutPanel.Controls.Add(p, y, x);
+      } else {
+        dataView.Content = dataTable;
+        dataView.Dock = DockStyle.Fill;
+        tableLayoutPanel.Controls.Add(dataView, y, x);
+      }
+    }
+
+    //Remove horizontal scroll bar if visible
+    private void tableLayoutPanel_Layout(object sender, LayoutEventArgs e) {
+      if (tableLayoutPanel.HorizontalScroll.Visible) {
+        // Add padding on the right in order to accomodate the vertical scrollbar
+        int vWidth = SystemInformation.VerticalScrollBarWidth;
+        tableLayoutPanel.Padding = new Padding(0, 0, vWidth, 0);
+      } else {
+        // Reset padding
+        tableLayoutPanel.Padding = new Padding(0);
+      }
+    }
+
+  }
+}
+
+
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingCheckedItemListView.Designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingCheckedItemListView.Designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingCheckedItemListView.Designer.cs	(revision 11159)
@@ -0,0 +1,55 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2014 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 PreprocessingCheckedItemListView {
+    /// <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: stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingCheckedItemListView.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingCheckedItemListView.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingCheckedItemListView.cs	(revision 11159)
@@ -0,0 +1,57 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2014 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.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+
+  [View("PreprocessingCheckedItemList View")]
+  [Content(typeof(CheckedItemList<StringValue>), false)]
+  [Content(typeof(ICheckedItemList<StringValue>), false)]
+  public partial class PreprocessingCheckedItemListView : CheckedItemListView<StringValue> {
+
+    public new ICheckedItemList<StringValue> Content {
+      get { return (ICheckedItemList<StringValue>)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public PreprocessingCheckedItemListView()
+      : base() {
+      InitializeComponent();
+      DisableDetails();
+    }
+
+    private void DisableDetails() {
+      splitContainer.Panel2Collapsed = true;
+      viewHost.Content = null;
+      showDetailsCheckBox.Visible = false;
+
+    }
+  }
+
+
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingDataTableView.Designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingDataTableView.Designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingDataTableView.Designer.cs	(revision 11159)
@@ -0,0 +1,110 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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 PreprocessingDataTableView {
+    /// <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) {
+        if (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.components = new System.ComponentModel.Container();
+      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+      System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
+      System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
+      System.Windows.Forms.DataVisualization.Charting.Title title1 = new System.Windows.Forms.DataVisualization.Charting.Title();
+      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // chart
+      // 
+      this.chart.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.chart.BorderlineColor = System.Drawing.Color.Black;
+      this.chart.BorderlineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;
+      chartArea1.AxisX.Minimum = 0D;
+      chartArea1.CursorX.IsUserEnabled = true;
+      chartArea1.CursorX.IsUserSelectionEnabled = true;
+      chartArea1.CursorY.IsUserEnabled = true;
+      chartArea1.CursorY.IsUserSelectionEnabled = true;
+      chartArea1.Name = "Default";
+      this.chart.ChartAreas.Add(chartArea1);
+      legend1.Alignment = System.Drawing.StringAlignment.Center;
+      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend1.Name = "Default";
+      this.chart.Legends.Add(legend1);
+      this.chart.Location = new System.Drawing.Point(0, 0);
+      this.chart.Name = "chart";
+      series1.ChartArea = "Default";
+      series1.Legend = "Default";
+      series1.Name = "Default";
+      this.chart.Series.Add(series1);
+      this.chart.Size = new System.Drawing.Size(359, 274);
+      this.chart.TabIndex = 3;
+      this.chart.Text = "chart";
+      title1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+      title1.Name = "Default";
+      title1.Text = "Title";
+      title1.Visible = false;
+      this.chart.Titles.Add(title1);
+      this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
+      this.chart.DoubleClick += new System.EventHandler(this.chart_DoubleClick);
+      this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
+      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
+      // 
+      // PreprocessingDataTableView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.chart);
+      this.Name = "PreprocessingDataTableView";
+      this.Size = new System.Drawing.Size(359, 274);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    protected HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
+
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingDataTableView.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingDataTableView.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingDataTableView.cs	(revision 11159)
@@ -0,0 +1,831 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.Collections;
+using HeuristicLab.Core.Views;
+using HeuristicLab.DataPreprocessing.Implementations;
+using HeuristicLab.MainForm;
+using HeuristicLab.Analysis;
+using HeuristicLab.Analysis.Views;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+  [View("Preprocessing DataTable View")]
+  [Content(typeof(PreprocessingDataTable), false)]
+  public partial class PreprocessingDataTableView : ItemView, IConfigureableView {
+    protected List<Series> invisibleSeries;
+    protected Dictionary<IObservableList<double>, DataRow> valuesRowsTable;
+    private event EventHandler chartDoubleClick;
+
+    public new PreprocessingDataTable Content {
+      get { return (PreprocessingDataTable)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public IEnumerable<double> Classification { get; set; }
+
+    public PreprocessingDataTableView() {
+      InitializeComponent();
+      valuesRowsTable = new Dictionary<IObservableList<double>, DataRow>();
+      invisibleSeries = new List<Series>();
+      chart.CustomizeAllChartAreas();
+      chart.ChartAreas[0].CursorX.Interval = 1;
+    }
+
+    #region Event Handler Registration
+    protected override void DeregisterContentEvents() {
+      foreach (DataRow row in Content.Rows)
+        DeregisterDataRowEvents(row);
+      Content.VisualPropertiesChanged -= new EventHandler(Content_VisualPropertiesChanged);
+      Content.Rows.ItemsAdded -= new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsAdded);
+      Content.Rows.ItemsRemoved -= new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsRemoved);
+      Content.Rows.ItemsReplaced -= new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsReplaced);
+      Content.Rows.CollectionReset -= new CollectionItemsChangedEventHandler<DataRow>(Rows_CollectionReset);
+
+      Content.SelectedRows.ItemsAdded -= new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsAdded);
+      Content.SelectedRows.ItemsRemoved -= new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsRemoved);
+      Content.SelectedRows.ItemsReplaced -= new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsReplaced);
+      Content.SelectedRows.CollectionReset -= new CollectionItemsChangedEventHandler<DataRow>(Rows_CollectionReset);
+      base.DeregisterContentEvents();
+    }
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.VisualPropertiesChanged += new EventHandler(Content_VisualPropertiesChanged);
+      Content.Rows.ItemsAdded += new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsAdded);
+      Content.Rows.ItemsRemoved += new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsRemoved);
+      Content.Rows.ItemsReplaced += new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsReplaced);
+      Content.Rows.CollectionReset += new CollectionItemsChangedEventHandler<DataRow>(Rows_CollectionReset);
+
+      Content.SelectedRows.ItemsAdded += new CollectionItemsChangedEventHandler<DataRow>(SelectedRows_ItemsAdded);
+      Content.SelectedRows.ItemsRemoved += new CollectionItemsChangedEventHandler<DataRow>(SelectedRows_ItemsRemoved);
+      Content.SelectedRows.ItemsReplaced += new CollectionItemsChangedEventHandler<DataRow>(SelectedRows_ItemsReplaced);
+      Content.SelectedRows.CollectionReset += new CollectionItemsChangedEventHandler<DataRow>(SelectedRows_CollectionReset);
+    }
+
+
+    protected virtual void RegisterDataRowEvents(DataRow row) {
+      row.NameChanged += new EventHandler(Row_NameChanged);
+      row.VisualPropertiesChanged += new EventHandler(Row_VisualPropertiesChanged);
+      valuesRowsTable.Add(row.Values, row);
+      row.Values.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsAdded);
+      row.Values.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsRemoved);
+      row.Values.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsReplaced);
+      row.Values.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsMoved);
+      row.Values.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_CollectionReset);
+    }
+    protected virtual void DeregisterDataRowEvents(DataRow row) {
+      row.Values.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsAdded);
+      row.Values.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsRemoved);
+      row.Values.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsReplaced);
+      row.Values.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsMoved);
+      row.Values.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_CollectionReset);
+      valuesRowsTable.Remove(row.Values);
+      row.VisualPropertiesChanged -= new EventHandler(Row_VisualPropertiesChanged);
+      row.NameChanged -= new EventHandler(Row_NameChanged);
+    }
+    #endregion
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      invisibleSeries.Clear();
+      chart.ChartAreas[0].AxisX.Title = string.Empty;
+      chart.ChartAreas[0].AxisY.Title = string.Empty;
+      chart.ChartAreas[0].AxisY2.Title = string.Empty;
+      chart.Series.Clear();
+      if (Content != null) {
+
+        if (Classification != null)
+          chart.Titles[0].Text = Content.Name;
+
+        AddDataRows(Content.Rows);
+        AddSelectedDataRows(Content.SelectedRows);
+        ConfigureChartArea(chart.ChartAreas[0]);
+        RecalculateAxesScale(chart.ChartAreas[0]);
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      chart.Enabled = Content != null;
+    }
+
+    public void ShowConfiguration() {
+      if (Content != null) {
+        using (var dialog = new DataTableVisualPropertiesDialog(Content)) {
+          dialog.ShowDialog(this);
+        }
+      } else MessageBox.Show("Nothing to configure.");
+    }
+
+    protected virtual void AddDataRows(IEnumerable<DataRow> rows) {
+      foreach (var row in rows) {
+        RegisterDataRowEvents(row);
+        var series = new Series(row.Name);
+        if (row.VisualProperties.DisplayName.Trim() != String.Empty) series.LegendText = row.VisualProperties.DisplayName;
+        else series.LegendText = row.Name;
+        ConfigureSeries(series, row);
+        FillSeriesWithRowValues(series, row);
+
+        if (Classification == null)
+          chart.Series.Add(series);
+      }
+
+      ConfigureChartArea(chart.ChartAreas[0]);
+      RecalculateAxesScale(chart.ChartAreas[0]);
+      UpdateYCursorInterval();
+    }
+
+    protected virtual void AddSelectedDataRows(IEnumerable<DataRow> rows) {
+
+      // only paint selection for line chart
+      if (rows.Count() > 0 && rows.ElementAt(0).VisualProperties.ChartType == DataRowVisualProperties.DataRowChartType.Line) {
+        // add dummy series for selction entry in legend
+        if (rows.Count() > 0 && chart.Series.FindByName("(Selection)") == null) {
+          Series series = new Series("(Selection)");
+          series.IsVisibleInLegend = true;
+          series.Color = Color.Green;
+          series.BorderWidth = 1;
+          series.BorderDashStyle = ChartDashStyle.Solid;
+          series.BorderColor = Color.Empty;
+          series.ChartType = SeriesChartType.FastLine;
+          chart.Series.Add(series);
+        }
+
+        foreach (var row in rows) {
+          row.VisualProperties.IsVisibleInLegend = false;
+          row.VisualProperties.Color = Color.Green;
+          //add selected to name in order to avoid naming conflict
+          var series = new Series(row.Name + "(Selected)");
+          ConfigureSeries(series, row);
+          FillSeriesWithRowValues(series, row);
+
+          if (Classification == null)
+            chart.Series.Add(series);
+
+        }
+      }
+    }
+
+    protected virtual void RemoveSelectedDataRows(IEnumerable<DataRow> rows) {
+
+      // only remove selection for line chart
+      if (rows.Count() > 0 && rows.ElementAt(0).VisualProperties.ChartType == DataRowVisualProperties.DataRowChartType.Line) {
+        //remove selection entry in legend
+        if (Content.SelectedRows.Count == 0) {
+          Series series = chart.Series["(Selection)"];
+          chart.Series.Remove(series);
+        }
+
+        foreach (var row in rows) {
+          Series series = chart.Series[row.Name + "(Selected)"];
+          chart.Series.Remove(series);
+        }
+      }
+    }
+
+    protected virtual void RemoveDataRows(IEnumerable<DataRow> rows) {
+      foreach (var row in rows) {
+        DeregisterDataRowEvents(row);
+        Series series = chart.Series[row.Name];
+        chart.Series.Remove(series);
+        if (invisibleSeries.Contains(series))
+          invisibleSeries.Remove(series);
+      }
+      RecalculateAxesScale(chart.ChartAreas[0]);
+    }
+
+    private void ConfigureSeries(Series series, DataRow row) {
+      RemoveCustomPropertyIfExists(series, "PointWidth");
+      series.BorderWidth = 1;
+      series.BorderDashStyle = ChartDashStyle.Solid;
+      series.BorderColor = Color.Empty;
+
+      if (row.VisualProperties.Color != Color.Empty)
+        series.Color = row.VisualProperties.Color;
+      else series.Color = Color.Empty;
+      series.IsVisibleInLegend = row.VisualProperties.IsVisibleInLegend;
+
+      switch (row.VisualProperties.ChartType) {
+        case DataRowVisualProperties.DataRowChartType.Line:
+          series.ChartType = SeriesChartType.FastLine;
+          series.BorderWidth = row.VisualProperties.LineWidth;
+          series.BorderDashStyle = ConvertLineStyle(row.VisualProperties.LineStyle);
+          break;
+        case DataRowVisualProperties.DataRowChartType.Bars:
+          // Bar is incompatible with anything but Bar and StackedBar*
+          if (!chart.Series.Any(x => x.ChartType != SeriesChartType.Bar && x.ChartType != SeriesChartType.StackedBar && x.ChartType != SeriesChartType.StackedBar100))
+            series.ChartType = SeriesChartType.Bar;
+          else {
+            series.ChartType = SeriesChartType.FastPoint; //default
+            row.VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Points;
+          }
+          break;
+        case DataRowVisualProperties.DataRowChartType.Columns:
+          series.ChartType = SeriesChartType.Column;
+          break;
+        case DataRowVisualProperties.DataRowChartType.Points:
+          series.ChartType = SeriesChartType.FastPoint;
+          break;
+        case DataRowVisualProperties.DataRowChartType.Histogram:
+          series.ChartType = SeriesChartType.StackedColumn;
+          series.SetCustomProperty("PointWidth", "1");
+          if (!series.Color.IsEmpty && series.Color.GetBrightness() < 0.25)
+            series.BorderColor = Color.White;
+          else series.BorderColor = Color.Black;
+          break;
+        case DataRowVisualProperties.DataRowChartType.StepLine:
+          series.ChartType = SeriesChartType.StepLine;
+          series.BorderWidth = row.VisualProperties.LineWidth;
+          series.BorderDashStyle = ConvertLineStyle(row.VisualProperties.LineStyle);
+          break;
+        default:
+          series.ChartType = SeriesChartType.FastPoint;
+          break;
+      }
+      series.YAxisType = row.VisualProperties.SecondYAxis ? AxisType.Secondary : AxisType.Primary;
+      series.XAxisType = row.VisualProperties.SecondXAxis ? AxisType.Secondary : AxisType.Primary;
+      if (row.VisualProperties.DisplayName.Trim() != String.Empty) series.LegendText = row.VisualProperties.DisplayName;
+      else series.LegendText = row.Name;
+
+      string xAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.XAxisTitle)
+                      ? "X"
+                      : Content.VisualProperties.XAxisTitle;
+      string yAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.YAxisTitle)
+                            ? "Y"
+                            : Content.VisualProperties.YAxisTitle;
+      series.ToolTip =
+        series.LegendText + Environment.NewLine +
+        xAxisTitle + " = " + "#INDEX," + Environment.NewLine +
+        yAxisTitle + " = " + "#VAL";
+    }
+
+    private void ConfigureChartArea(ChartArea area) {
+      if (Content.VisualProperties.TitleFont != null) chart.Titles[0].Font = Content.VisualProperties.TitleFont;
+      if (!Content.VisualProperties.TitleColor.IsEmpty) chart.Titles[0].ForeColor = Content.VisualProperties.TitleColor;
+      chart.Titles[0].Text = Content.VisualProperties.Title;
+
+      if (Content.VisualProperties.AxisTitleFont != null) area.AxisX.TitleFont = Content.VisualProperties.AxisTitleFont;
+      if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisX.TitleForeColor = Content.VisualProperties.AxisTitleColor;
+      area.AxisX.Title = Content.VisualProperties.XAxisTitle;
+
+      if (Content.VisualProperties.AxisTitleFont != null) area.AxisX2.TitleFont = Content.VisualProperties.AxisTitleFont;
+      if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisX2.TitleForeColor = Content.VisualProperties.AxisTitleColor;
+      area.AxisX2.Title = Content.VisualProperties.SecondXAxisTitle;
+
+      if (Content.VisualProperties.AxisTitleFont != null) area.AxisY.TitleFont = Content.VisualProperties.AxisTitleFont;
+      if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisY.TitleForeColor = Content.VisualProperties.AxisTitleColor;
+      area.AxisY.Title = Content.VisualProperties.YAxisTitle;
+
+      if (Content.VisualProperties.AxisTitleFont != null) area.AxisY2.TitleFont = Content.VisualProperties.AxisTitleFont;
+      if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisY2.TitleForeColor = Content.VisualProperties.AxisTitleColor;
+      area.AxisY2.Title = Content.VisualProperties.SecondYAxisTitle;
+
+      area.AxisX.IsLogarithmic = Content.VisualProperties.XAxisLogScale;
+      area.AxisX2.IsLogarithmic = Content.VisualProperties.SecondXAxisLogScale;
+      area.AxisY.IsLogarithmic = Content.VisualProperties.YAxisLogScale;
+      area.AxisY2.IsLogarithmic = Content.VisualProperties.SecondYAxisLogScale;
+    }
+
+    private void RecalculateAxesScale(ChartArea area) {
+      // Reset the axes bounds so that RecalculateAxesScale() will assign new bounds
+      foreach (Axis a in area.Axes) {
+        a.Minimum = double.NaN;
+        a.Maximum = double.NaN;
+      }
+      area.RecalculateAxesScale();
+      area.AxisX.IsMarginVisible = false;
+      area.AxisX2.IsMarginVisible = false;
+
+      if (!Content.VisualProperties.XAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.XAxisMinimumFixedValue)) area.AxisX.Minimum = Content.VisualProperties.XAxisMinimumFixedValue;
+      if (!Content.VisualProperties.XAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.XAxisMaximumFixedValue)) area.AxisX.Maximum = Content.VisualProperties.XAxisMaximumFixedValue;
+      if (!Content.VisualProperties.SecondXAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.SecondXAxisMinimumFixedValue)) area.AxisX2.Minimum = Content.VisualProperties.SecondXAxisMinimumFixedValue;
+      if (!Content.VisualProperties.SecondXAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.SecondXAxisMaximumFixedValue)) area.AxisX2.Maximum = Content.VisualProperties.SecondXAxisMaximumFixedValue;
+      if (!Content.VisualProperties.YAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.YAxisMinimumFixedValue)) area.AxisY.Minimum = Content.VisualProperties.YAxisMinimumFixedValue;
+      if (!Content.VisualProperties.YAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.YAxisMaximumFixedValue)) area.AxisY.Maximum = Content.VisualProperties.YAxisMaximumFixedValue;
+      if (!Content.VisualProperties.SecondYAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.SecondYAxisMinimumFixedValue)) area.AxisY2.Minimum = Content.VisualProperties.SecondYAxisMinimumFixedValue;
+      if (!Content.VisualProperties.SecondYAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.SecondYAxisMaximumFixedValue)) area.AxisY2.Maximum = Content.VisualProperties.SecondYAxisMaximumFixedValue;
+      if (area.AxisX.Minimum >= area.AxisX.Maximum) area.AxisX.Maximum = area.AxisX.Minimum + 1;
+      if (area.AxisX2.Minimum >= area.AxisX2.Maximum) area.AxisX2.Maximum = area.AxisX2.Minimum + 1;
+      if (area.AxisY.Minimum >= area.AxisY.Maximum) area.AxisY.Maximum = area.AxisY.Minimum + 1;
+      if (area.AxisY2.Minimum >= area.AxisY2.Maximum) area.AxisY2.Maximum = area.AxisY2.Minimum + 1;
+    }
+
+    protected virtual void UpdateYCursorInterval() {
+      double interestingValuesRange = (
+        from series in chart.Series
+        where series.Enabled
+        let values = (from point in series.Points
+                      where !point.IsEmpty
+                      select point.YValues[0]).DefaultIfEmpty(1.0)
+        let range = values.Max() - values.Min()
+        where range > 0.0
+        select range
+        ).DefaultIfEmpty(1.0).Min();
+
+      double digits = (int)Math.Log10(interestingValuesRange) - 3;
+      double yZoomInterval = Math.Pow(10, digits);
+      this.chart.ChartAreas[0].CursorY.Interval = yZoomInterval;
+    }
+
+    #region Event Handlers
+    #region Content Event Handlers
+    private void Content_VisualPropertiesChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_VisualPropertiesChanged), sender, e);
+      else {
+        ConfigureChartArea(chart.ChartAreas[0]);
+        RecalculateAxesScale(chart.ChartAreas[0]); // axes min/max could have changed
+      }
+    }
+    #endregion
+    #region Rows Event Handlers
+
+    private void SelectedRows_CollectionReset(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsReplaced), sender, e);
+      else {
+        RemoveSelectedDataRows(e.OldItems);
+        AddSelectedDataRows(e.Items);
+      }
+    }
+
+    private void SelectedRows_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsReplaced), sender, e);
+      else {
+        RemoveSelectedDataRows(e.OldItems);
+        AddSelectedDataRows(e.Items);
+      }
+    }
+
+    private void SelectedRows_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsRemoved), sender, e);
+      else {
+        RemoveSelectedDataRows(e.Items);
+      }
+    }
+
+    private void SelectedRows_ItemsAdded(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsAdded), sender, e);
+      else {
+        AddSelectedDataRows(e.Items);
+      }
+    }
+
+
+    private void Rows_ItemsAdded(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsAdded), sender, e);
+      else {
+        AddDataRows(e.Items);
+      }
+    }
+    private void Rows_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsRemoved), sender, e);
+      else {
+        RemoveDataRows(e.Items);
+      }
+    }
+    private void Rows_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsReplaced), sender, e);
+      else {
+        RemoveDataRows(e.OldItems);
+        AddDataRows(e.Items);
+      }
+    }
+    private void Rows_CollectionReset(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_CollectionReset), sender, e);
+      else {
+        RemoveDataRows(e.OldItems);
+        AddDataRows(e.Items);
+      }
+    }
+    #endregion
+    #region Row Event Handlers
+    private void Row_VisualPropertiesChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Row_VisualPropertiesChanged), sender, e);
+      else {
+        DataRow row = (DataRow)sender;
+        Series series = chart.Series[row.Name];
+        series.Points.Clear();
+        ConfigureSeries(series, row);
+        FillSeriesWithRowValues(series, row);
+        RecalculateAxesScale(chart.ChartAreas[0]);
+      }
+    }
+    private void Row_NameChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Row_NameChanged), sender, e);
+      else {
+        DataRow row = (DataRow)sender;
+        chart.Series[row.Name].Name = row.Name;
+      }
+    }
+    #endregion
+    #region Values Event Handlers
+    private void Values_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsAdded), sender, e);
+      else {
+        DataRow row = null;
+        valuesRowsTable.TryGetValue((IObservableList<double>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            rowSeries.Points.Clear();
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    private void Values_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsRemoved), sender, e);
+      else {
+        DataRow row = null;
+        valuesRowsTable.TryGetValue((IObservableList<double>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            rowSeries.Points.Clear();
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    private void Values_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsReplaced), sender, e);
+      else {
+        DataRow row = null;
+        valuesRowsTable.TryGetValue((IObservableList<double>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            if (row.VisualProperties.ChartType == DataRowVisualProperties.DataRowChartType.Histogram) {
+              rowSeries.Points.Clear();
+              FillSeriesWithRowValues(rowSeries, row);
+            } else {
+              foreach (IndexedItem<double> item in e.Items) {
+                if (IsInvalidValue(item.Value))
+                  rowSeries.Points[item.Index].IsEmpty = true;
+                else {
+                  rowSeries.Points[item.Index].YValues = new double[] { item.Value };
+                  rowSeries.Points[item.Index].IsEmpty = false;
+                }
+              }
+            }
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    private void Values_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsMoved), sender, e);
+      else {
+        DataRow row = null;
+        valuesRowsTable.TryGetValue((IObservableList<double>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            rowSeries.Points.Clear();
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+
+    private void Values_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_CollectionReset), sender, e);
+      else {
+        DataRow row = null;
+        valuesRowsTable.TryGetValue((IObservableList<double>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            rowSeries.Points.Clear();
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    #endregion
+    #endregion
+
+    #region Chart Event Handlers
+    private void chart_MouseDown(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem) {
+        ToggleSeriesVisible(result.Series);
+      }
+    }
+    private void chart_MouseMove(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem)
+        this.Cursor = Cursors.Hand;
+      else
+        this.Cursor = Cursors.Default;
+    }
+    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
+      foreach (LegendItem legendItem in e.LegendItems) {
+        var series = chart.Series[legendItem.SeriesName];
+        if (series != null) {
+          bool seriesIsInvisible = invisibleSeries.Contains(series);
+          foreach (LegendCell cell in legendItem.Cells) {
+            cell.ForeColor = seriesIsInvisible ? Color.Gray : Color.Black;
+          }
+        }
+      }
+    }
+    #endregion
+
+    private void ToggleSeriesVisible(Series series) {
+
+      if (!Content.Rows.Any(x => x.Name == series.Name))
+        return;
+
+      if (!invisibleSeries.Contains(series)) {
+        series.Points.Clear();
+        invisibleSeries.Add(series);
+      } else {
+        invisibleSeries.Remove(series);
+        if (Content != null) {
+
+          var row = (from r in Content.Rows
+                     where r.Name == series.Name
+                     select r).Single();
+          FillSeriesWithRowValues(series, row);
+          this.chart.Legends[series.Legend].ForeColor = Color.Black;
+          RecalculateAxesScale(chart.ChartAreas[0]);
+          UpdateYCursorInterval();
+        }
+      }
+    }
+
+    private void FillSeriesWithRowValues(Series series, DataRow row) {
+      switch (row.VisualProperties.ChartType) {
+        case DataRowVisualProperties.DataRowChartType.Histogram:
+          CalculateHistogram(series, row);
+          break;
+        default: {
+            bool yLogarithmic = series.YAxisType == AxisType.Primary
+                                  ? Content.VisualProperties.YAxisLogScale
+                                  : Content.VisualProperties.SecondYAxisLogScale;
+            bool xLogarithmic = series.XAxisType == AxisType.Primary
+                                  ? Content.VisualProperties.XAxisLogScale
+                                  : Content.VisualProperties.SecondXAxisLogScale;
+            for (int i = 0; i < row.Values.Count; i++) {
+              var value = row.Values[i];
+              var point = new DataPoint();
+              point.XValue = row.VisualProperties.StartIndexZero && !xLogarithmic ? i : i + 1;
+              if (IsInvalidValue(value) || (yLogarithmic && value <= 0))
+                point.IsEmpty = true;
+              else
+                point.YValues = new double[] { value };
+              series.Points.Add(point);
+            }
+          }
+          break;
+      }
+    }
+
+    // get minimum ignores nan values
+    private double GetMinimum(IEnumerable<double> values) {
+      double min = Double.MaxValue;
+
+      foreach (double value in values) {
+        if (!Double.IsNaN(value) && value < min)
+          min = value;
+      }
+      return min;
+    }
+
+    //get maximium ignores nan values
+    private double GetMaximum(IEnumerable<double> values) {
+      double max = Double.MinValue;
+
+      foreach (double value in values) {
+        if (!Double.IsNaN(value) && value > max)
+          max = value;
+      }
+      return max;
+    }
+
+    protected virtual void CalculateHistogram(Series series, DataRow row) {
+      if (Classification != null) {
+
+        var valuesPerClass = row.Values.Select((i, index) => new { i, j = Classification.ToList()[index] })
+                                       .GroupBy((x) => x.j)
+                                       .ToDictionary(x => x.Key, x => x.Select(v => v.i)
+                                       .ToList());
+
+        chart.Titles.Add(row.Name);
+
+        foreach (KeyValuePair<double, List<double>> entry in valuesPerClass) {
+          var s = new Series(row.Name + entry.Key);
+
+          ConfigureSeries(s, row);
+          AddPointsToHistogramSeries(s, row, entry.Value);
+
+          s.LegendText = entry.Key.ToString();
+
+          chart.Series.Add(s);
+        }
+      } else {
+        series.Points.Clear();
+        ConfigureSeries(series, row);
+        AddPointsToHistogramSeries(series, row, null);
+      }
+    }
+
+    private void AddPointsToHistogramSeries(Series series, DataRow row, List<double> values) {
+      if (!row.Values.Any()) return;
+      int bins = row.VisualProperties.Bins;
+
+      double minValue = GetMinimum(row.Values);
+      double maxValue = GetMaximum(row.Values);
+      double intervalWidth = (maxValue - minValue) / bins;
+      if (intervalWidth < 0) return;
+      if (intervalWidth == 0) {
+        series.Points.AddXY(minValue, row.Values.Count);
+        return;
+      }
+
+
+      if (!row.VisualProperties.ExactBins) {
+        intervalWidth = HumanRoundRange(intervalWidth);
+        minValue = Math.Floor(minValue / intervalWidth) * intervalWidth;
+        maxValue = Math.Ceiling(maxValue / intervalWidth) * intervalWidth;
+      }
+
+      double intervalCenter = intervalWidth / 2;
+
+      double min = 0.0, max = 0.0;
+      if (!Double.IsNaN(Content.VisualProperties.XAxisMinimumFixedValue) && !Content.VisualProperties.XAxisMinimumAuto)
+        min = Content.VisualProperties.XAxisMinimumFixedValue;
+      else min = minValue;
+      if (!Double.IsNaN(Content.VisualProperties.XAxisMaximumFixedValue) && !Content.VisualProperties.XAxisMaximumAuto)
+        max = Content.VisualProperties.XAxisMaximumFixedValue;
+      else max = maxValue + intervalWidth;
+
+      double axisInterval = intervalWidth / row.VisualProperties.ScaleFactor;
+
+      var area = chart.ChartAreas[0];
+      area.AxisX.Interval = axisInterval;
+
+      series.SetCustomProperty("PointWidth", "1"); // 0.8 is the default value
+
+      // get the range or intervals which define the grouping of the frequency values
+      var doubleRange = DoubleRange(min, max, intervalWidth).Skip(1).ToList();
+
+
+      if (values == null) {
+        values = row.Values.ToList(); ;
+      }
+
+      // aggregate the row values by unique key and frequency value
+      var valueFrequencies = (from v in values
+                              where !IsInvalidValue(v)
+                              orderby v
+                              group v by v into g
+                              select new Tuple<double, double>(g.First(), g.Count())).ToList();
+
+      //  shift the chart to the left so the bars are placed on the intervals
+      if (Classification != null || valueFrequencies.First().Item1 < doubleRange.First()) {
+        series.Points.Add(new DataPoint(min - intervalWidth, 0));
+        series.Points.Add(new DataPoint(max + intervalWidth, 0));
+      }
+
+      // add data points
+      int j = 0;
+      foreach (var d in doubleRange) {
+        double sum = 0.0;
+        // sum the frequency values that fall within the same interval
+        while (j < valueFrequencies.Count && valueFrequencies[j].Item1 < d) {
+          sum += valueFrequencies[j].Item2;
+          ++j;
+        }
+        string xAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.XAxisTitle)
+                              ? "X"
+                              : Content.VisualProperties.XAxisTitle;
+        string yAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.YAxisTitle)
+                              ? "Y"
+                              : Content.VisualProperties.YAxisTitle;
+        series.Points.Add(new DataPoint(d - intervalCenter, sum) {
+          ToolTip =
+            xAxisTitle + ": [" + (d - intervalWidth) + "-" + d + ")" + Environment.NewLine +
+            yAxisTitle + ": " + sum
+        });
+      }
+    }
+
+    public event EventHandler ChartDoubleClick {
+      add { chartDoubleClick += value; }
+      remove { chartDoubleClick -= value; }
+    }
+
+    #region Helpers
+    public static IEnumerable<double> DoubleRange(double min, double max, double step) {
+      double i;
+      for (i = min; i <= max; i += step)
+        yield return i;
+
+      if (i != max + step)
+        yield return i;
+    }
+
+    protected void RemoveCustomPropertyIfExists(Series series, string property) {
+      if (series.IsCustomPropertySet(property)) series.DeleteCustomProperty(property);
+    }
+
+    private double HumanRoundRange(double range) {
+      double base10 = Math.Pow(10.0, Math.Floor(Math.Log10(range)));
+      double rounding = range / base10;
+      if (rounding <= 1.5) rounding = 1;
+      else if (rounding <= 2.25) rounding = 2;
+      else if (rounding <= 3.75) rounding = 2.5;
+      else if (rounding <= 7.5) rounding = 5;
+      else rounding = 10;
+      return rounding * base10;
+    }
+
+    private double HumanRoundMax(double max) {
+      double base10;
+      if (max > 0) base10 = Math.Pow(10.0, Math.Floor(Math.Log10(max)));
+      else base10 = Math.Pow(10.0, Math.Ceiling(Math.Log10(-max)));
+      double rounding = (max > 0) ? base10 : -base10;
+      while (rounding < max) rounding += base10;
+      return rounding;
+    }
+
+    private ChartDashStyle ConvertLineStyle(DataRowVisualProperties.DataRowLineStyle dataRowLineStyle) {
+      switch (dataRowLineStyle) {
+        case DataRowVisualProperties.DataRowLineStyle.Dash:
+          return ChartDashStyle.Dash;
+        case DataRowVisualProperties.DataRowLineStyle.DashDot:
+          return ChartDashStyle.DashDot;
+        case DataRowVisualProperties.DataRowLineStyle.DashDotDot:
+          return ChartDashStyle.DashDotDot;
+        case DataRowVisualProperties.DataRowLineStyle.Dot:
+          return ChartDashStyle.Dot;
+        case DataRowVisualProperties.DataRowLineStyle.NotSet:
+          return ChartDashStyle.NotSet;
+        case DataRowVisualProperties.DataRowLineStyle.Solid:
+          return ChartDashStyle.Solid;
+        default:
+          return ChartDashStyle.NotSet;
+      }
+    }
+
+    protected static bool IsInvalidValue(double x) {
+      return double.IsNaN(x) || x < (double)decimal.MinValue || x > (double)decimal.MaxValue;
+    }
+    #endregion
+
+    //bubble double click event with data table view as sender
+    private void chart_DoubleClick(object sender, EventArgs e) {
+      if (chartDoubleClick != null)
+        chartDoubleClick(this, e);
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingFeatureCorrelationView.Designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingFeatureCorrelationView.Designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingFeatureCorrelationView.Designer.cs	(revision 11159)
@@ -0,0 +1,55 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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 PreprocessingFeatureCorrelationView {
+    /// <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.components = new System.ComponentModel.Container();     
+      this.ResumeLayout(false);
+    }
+
+    #endregion
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingFeatureCorrelationView.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingFeatureCorrelationView.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingFeatureCorrelationView.cs	(revision 11159)
@@ -0,0 +1,79 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.ComponentModel;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+using HeuristicLab.PluginInfrastructure;
+using System;
+using HeuristicLab.DataPreprocessing;
+using HeuristicLab.Problems.DataAnalysis.Views;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Preprocessing Feature Correlation View")]
+  [Content(typeof(CorrelationMatrixContent), false)]
+  public partial class PreprocessingFeatureCorrelationView : AsynchronousContentView {
+
+    public new CorrelationMatrixContent Content
+    {
+      get { return (CorrelationMatrixContent) base.Content; }
+      set { base.Content = value; }
+    }
+
+    FeatureCorrelationView correlationView;
+
+    public PreprocessingFeatureCorrelationView() {
+      InitializeComponent();
+      correlationView = new FeatureCorrelationView();
+      correlationView.Dock = DockStyle.Fill;
+      this.Controls.Add(correlationView);
+    }
+
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.Changed += Data_Changed;      
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.Changed -= Data_Changed;      
+      base.DeregisterContentEvents();
+    }
+
+    private void Data_Changed(object sender, DataPreprocessingChangedEventArgs e) {
+      OnContentChanged();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        correlationView.Content = null;
+        return;
+      }
+
+      correlationView.Content = Content.ProblemData;
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingScatterPlotView.Designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingScatterPlotView.Designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingScatterPlotView.Designer.cs	(revision 11159)
@@ -0,0 +1,109 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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 PreprocessingScatterPlotView {
+    /// <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) {
+        if (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.components = new System.ComponentModel.Container();
+      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+      System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
+      System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
+      System.Windows.Forms.DataVisualization.Charting.Title title1 = new System.Windows.Forms.DataVisualization.Charting.Title();
+      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // chart
+      // 
+      this.chart.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.chart.BorderlineColor = System.Drawing.Color.Black;
+      this.chart.BorderlineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;
+      chartArea1.AxisX.Minimum = 0D;
+      chartArea1.CursorX.IsUserEnabled = true;
+      chartArea1.CursorX.IsUserSelectionEnabled = true;
+      chartArea1.CursorY.IsUserEnabled = true;
+      chartArea1.CursorY.IsUserSelectionEnabled = true;
+      chartArea1.Name = "Default";
+      this.chart.ChartAreas.Add(chartArea1);
+      legend1.Alignment = System.Drawing.StringAlignment.Center;
+      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend1.Name = "Default";
+      this.chart.Legends.Add(legend1);
+      this.chart.Location = new System.Drawing.Point(0, 0);
+      this.chart.Name = "chart";
+      series1.ChartArea = "Default";
+      series1.Legend = "Default";
+      series1.Name = "Default";
+      this.chart.Series.Add(series1);
+      this.chart.Size = new System.Drawing.Size(359, 274);
+      this.chart.TabIndex = 3;
+      this.chart.Text = "chart";
+      title1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+      title1.Name = "Default";
+      title1.Text = "Title";
+      title1.Visible = false;
+      this.chart.Titles.Add(title1);
+      this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
+      this.chart.DoubleClick += new System.EventHandler(this.chart_DoubleClick);
+      this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
+      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
+      // 
+      // PreprocessingScatterPlotView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.chart);
+      this.Name = "PreprocessingScatterPlotView";
+      this.Size = new System.Drawing.Size(359, 274);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    protected HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
+
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingScatterPlotView.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingScatterPlotView.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/PreprocessingScatterPlotView.cs	(revision 11159)
@@ -0,0 +1,466 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.Analysis;
+using HeuristicLab.Analysis.Views;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+  [View("Preprocessing ScatterPlot View")]
+  [Content(typeof(ScatterPlot), false)]
+  public partial class PreprocessingScatterPlotView : ItemView, IConfigureableView {
+    protected List<Series> invisibleSeries;
+    protected Dictionary<IObservableList<Point2D<double>>, ScatterPlotDataRow> pointsRowsTable;
+    private event EventHandler chartDoubleClick;
+
+    public new ScatterPlot Content {
+      get { return (ScatterPlot)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public PreprocessingScatterPlotView() {
+      InitializeComponent();
+      pointsRowsTable = new Dictionary<IObservableList<Point2D<double>>, ScatterPlotDataRow>();
+      invisibleSeries = new List<Series>();
+      chart.CustomizeAllChartAreas();
+      chart.ChartAreas[0].CursorX.Interval = 1;
+    }
+
+    #region Event Handler Registration
+    protected override void DeregisterContentEvents() {
+      foreach (ScatterPlotDataRow row in Content.Rows)
+        DeregisterScatterPlotDataRowEvents(row);
+      Content.VisualPropertiesChanged -= new EventHandler(Content_VisualPropertiesChanged);
+      Content.Rows.ItemsAdded -= new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsAdded);
+      Content.Rows.ItemsRemoved -= new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsRemoved);
+      Content.Rows.ItemsReplaced -= new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsReplaced);
+      Content.Rows.CollectionReset -= new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_CollectionReset);
+      base.DeregisterContentEvents();
+    }
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.VisualPropertiesChanged += new EventHandler(Content_VisualPropertiesChanged);
+      Content.Rows.ItemsAdded += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsAdded);
+      Content.Rows.ItemsRemoved += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsRemoved);
+      Content.Rows.ItemsReplaced += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsReplaced);
+      Content.Rows.CollectionReset += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_CollectionReset);
+    }
+
+    protected virtual void RegisterScatterPlotDataRowEvents(ScatterPlotDataRow row) {
+      row.NameChanged += new EventHandler(Row_NameChanged);
+      row.VisualPropertiesChanged += new EventHandler(Row_VisualPropertiesChanged);
+      pointsRowsTable.Add(row.Points, row);
+      row.Points.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsAdded);
+      row.Points.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsRemoved);
+      row.Points.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsReplaced);
+      row.Points.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_CollectionReset);
+    }
+    protected virtual void DeregisterScatterPlotDataRowEvents(ScatterPlotDataRow row) {
+      row.Points.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsAdded);
+      row.Points.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsRemoved);
+      row.Points.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsReplaced);
+      row.Points.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_CollectionReset);
+      pointsRowsTable.Remove(row.Points);
+      row.VisualPropertiesChanged -= new EventHandler(Row_VisualPropertiesChanged);
+      row.NameChanged -= new EventHandler(Row_NameChanged);
+    }
+    #endregion
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      invisibleSeries.Clear();
+      chart.ChartAreas[0].AxisX.Title = string.Empty;
+      chart.ChartAreas[0].AxisY.Title = string.Empty;
+      chart.Series.Clear();
+      if (Content != null) {
+        AddScatterPlotDataRows(Content.Rows);
+        ConfigureChartArea(chart.ChartAreas[0]);
+        RecalculateAxesScale(chart.ChartAreas[0]);
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      chart.Enabled = Content != null;
+    }
+
+    public void ShowConfiguration() {
+      if (Content != null) {
+        using (ScatterPlotVisualPropertiesDialog dialog = new ScatterPlotVisualPropertiesDialog(Content)) {
+          dialog.ShowDialog(this);
+        }
+      } else MessageBox.Show("Nothing to configure.");
+    }
+
+    protected virtual void AddScatterPlotDataRows(IEnumerable<ScatterPlotDataRow> rows) {
+      foreach (var row in rows) {
+        RegisterScatterPlotDataRowEvents(row);
+        Series series = new Series(row.Name);
+        if (row.VisualProperties.DisplayName.Trim() != String.Empty) series.LegendText = row.VisualProperties.DisplayName;
+        else series.LegendText = row.Name;
+        ConfigureSeries(series, row);
+        FillSeriesWithRowValues(series, row);
+        chart.Series.Add(series);
+      }
+      ConfigureChartArea(chart.ChartAreas[0]);
+      RecalculateAxesScale(chart.ChartAreas[0]);
+      UpdateYCursorInterval();
+    }
+
+    protected virtual void RemoveScatterPlotDataRows(IEnumerable<ScatterPlotDataRow> rows) {
+      foreach (var row in rows) {
+        DeregisterScatterPlotDataRowEvents(row);
+        Series series = chart.Series[row.Name];
+        chart.Series.Remove(series);
+        if (invisibleSeries.Contains(series))
+          invisibleSeries.Remove(series);
+      }
+      RecalculateAxesScale(chart.ChartAreas[0]);
+    }
+
+    private void ConfigureSeries(Series series, ScatterPlotDataRow row) {
+      series.BorderWidth = 1;
+      series.BorderDashStyle = ChartDashStyle.Solid;
+      series.BorderColor = Color.Empty;
+
+      if (row.VisualProperties.Color != Color.Empty)
+        series.Color = row.VisualProperties.Color;
+      else series.Color = Color.Empty;
+      series.IsVisibleInLegend = row.VisualProperties.IsVisibleInLegend;
+      series.ChartType = SeriesChartType.FastPoint;
+      series.MarkerSize = row.VisualProperties.PointSize;
+      series.MarkerStyle = ConvertPointStyle(row.VisualProperties.PointStyle);
+      series.XAxisType = AxisType.Primary;
+      series.YAxisType = AxisType.Primary;
+
+      if (row.VisualProperties.DisplayName.Trim() != String.Empty) series.LegendText = row.VisualProperties.DisplayName;
+      else series.LegendText = row.Name;
+
+      string xAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.XAxisTitle)
+                      ? "X"
+                      : Content.VisualProperties.XAxisTitle;
+      string yAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.YAxisTitle)
+                            ? "Y"
+                            : Content.VisualProperties.YAxisTitle;
+      series.ToolTip =
+        series.LegendText + Environment.NewLine +
+        xAxisTitle + " = " + "#VALX," + Environment.NewLine +
+        yAxisTitle + " = " + "#VAL";
+    }
+
+    private void ConfigureChartArea(ChartArea area) {
+
+      if (Content.VisualProperties.AxisTitleFont != null) area.AxisX.TitleFont = Content.VisualProperties.AxisTitleFont;
+      if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisX.TitleForeColor = Content.VisualProperties.AxisTitleColor;
+      area.AxisX.Title = Content.VisualProperties.XAxisTitle;
+      area.AxisX.MajorGrid.Enabled = Content.VisualProperties.XAxisGrid;
+
+      if (Content.VisualProperties.AxisTitleFont != null) area.AxisY.TitleFont = Content.VisualProperties.AxisTitleFont;
+      if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisY.TitleForeColor = Content.VisualProperties.AxisTitleColor;
+      area.AxisY.Title = Content.VisualProperties.YAxisTitle;
+      area.AxisY.MajorGrid.Enabled = Content.VisualProperties.YAxisGrid;
+    }
+
+    private void RecalculateAxesScale(ChartArea area) {
+      // Reset the axes bounds so that RecalculateAxesScale() will assign new bounds
+      foreach (Axis a in area.Axes) {
+        a.Minimum = double.NaN;
+        a.Maximum = double.NaN;
+      }
+      area.RecalculateAxesScale();
+      area.AxisX.IsMarginVisible = false;
+
+      if (!Content.VisualProperties.XAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.XAxisMinimumFixedValue)) area.AxisX.Minimum = Content.VisualProperties.XAxisMinimumFixedValue;
+      if (!Content.VisualProperties.XAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.XAxisMaximumFixedValue)) area.AxisX.Maximum = Content.VisualProperties.XAxisMaximumFixedValue;
+      if (!Content.VisualProperties.YAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.YAxisMinimumFixedValue)) area.AxisY.Minimum = Content.VisualProperties.YAxisMinimumFixedValue;
+      if (!Content.VisualProperties.YAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.YAxisMaximumFixedValue)) area.AxisY.Maximum = Content.VisualProperties.YAxisMaximumFixedValue;
+      if (area.AxisX.Minimum >= area.AxisX.Maximum) area.AxisX.Maximum = area.AxisX.Minimum + 1;
+      if (area.AxisY.Minimum >= area.AxisY.Maximum) area.AxisY.Maximum = area.AxisY.Minimum + 1;
+    }
+
+    protected virtual void UpdateYCursorInterval() {
+      double interestingValuesRange = (
+        from series in chart.Series
+        where series.Enabled
+        let values = (from point in series.Points
+                      where !point.IsEmpty
+                      select point.YValues[0]).DefaultIfEmpty(1.0)
+        let range = values.Max() - values.Min()
+        where range > 0.0
+        select range
+        ).DefaultIfEmpty(1.0).Min();
+
+      double digits = (int)Math.Log10(interestingValuesRange) - 3;
+      double yZoomInterval = Math.Pow(10, digits);
+      this.chart.ChartAreas[0].CursorY.Interval = yZoomInterval;
+    }
+
+
+    public event EventHandler ChartDoubleClick {
+      add { chartDoubleClick += value; }
+      remove { chartDoubleClick -= value; }
+    }
+
+    #region Event Handlers
+    #region Content Event Handlers
+
+    private void Content_VisualPropertiesChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_VisualPropertiesChanged), sender, e);
+      else {
+        ConfigureChartArea(chart.ChartAreas[0]);
+        RecalculateAxesScale(chart.ChartAreas[0]); // axes min/max could have changed
+      }
+    }
+    #endregion
+    #region Rows Event Handlers
+    private void Rows_ItemsAdded(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsAdded), sender, e);
+      else {
+        AddScatterPlotDataRows(e.Items);
+      }
+    }
+    private void Rows_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsRemoved), sender, e);
+      else {
+        RemoveScatterPlotDataRows(e.Items);
+      }
+    }
+    private void Rows_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsReplaced), sender, e);
+      else {
+        RemoveScatterPlotDataRows(e.OldItems);
+        AddScatterPlotDataRows(e.Items);
+      }
+    }
+    private void Rows_CollectionReset(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_CollectionReset), sender, e);
+      else {
+        RemoveScatterPlotDataRows(e.OldItems);
+        AddScatterPlotDataRows(e.Items);
+      }
+    }
+    #endregion
+    #region Row Event Handlers
+    private void Row_VisualPropertiesChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Row_VisualPropertiesChanged), sender, e);
+      else {
+        ScatterPlotDataRow row = (ScatterPlotDataRow)sender;
+        Series series = chart.Series[row.Name];
+        series.Points.Clear();
+        ConfigureSeries(series, row);
+        FillSeriesWithRowValues(series, row);
+        RecalculateAxesScale(chart.ChartAreas[0]);
+      }
+    }
+    private void Row_NameChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Row_NameChanged), sender, e);
+      else {
+        ScatterPlotDataRow row = (ScatterPlotDataRow)sender;
+        chart.Series[row.Name].Name = row.Name;
+      }
+    }
+    #endregion
+    #region Points Event Handlers
+    private void Points_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsAdded), sender, e);
+      else {
+        ScatterPlotDataRow row = null;
+        pointsRowsTable.TryGetValue((IObservableList<Point2D<double>>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            rowSeries.Points.Clear();
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    private void Points_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsRemoved), sender, e);
+      else {
+        ScatterPlotDataRow row = null;
+        pointsRowsTable.TryGetValue((IObservableList<Point2D<double>>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            rowSeries.Points.Clear();
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    private void Points_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsReplaced), sender, e);
+      else {
+        ScatterPlotDataRow row = null;
+        pointsRowsTable.TryGetValue((IObservableList<Point2D<double>>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            rowSeries.Points.Clear();
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    private void Points_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_CollectionReset), sender, e);
+      else {
+        ScatterPlotDataRow row = null;
+        pointsRowsTable.TryGetValue((IObservableList<Point2D<double>>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            rowSeries.Points.Clear();
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    #endregion
+    #endregion
+
+    #region Chart Event Handlers
+    private void chart_MouseDown(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem) {
+        ToggleSeriesVisible(result.Series);
+      }
+    }
+    private void chart_MouseMove(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem)
+        this.Cursor = Cursors.Hand;
+      else
+        this.Cursor = Cursors.Default;
+    }
+    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
+      foreach (LegendItem legendItem in e.LegendItems) {
+        var series = chart.Series[legendItem.SeriesName];
+        if (series != null) {
+          bool seriesIsInvisible = invisibleSeries.Contains(series);
+          foreach (LegendCell cell in legendItem.Cells) {
+            cell.ForeColor = seriesIsInvisible ? Color.Gray : Color.Black;
+          }
+        }
+      }
+    }
+    #endregion
+
+    private void ToggleSeriesVisible(Series series) {
+      if (!invisibleSeries.Contains(series)) {
+        series.Points.Clear();
+        invisibleSeries.Add(series);
+      } else {
+        invisibleSeries.Remove(series);
+        if (Content != null) {
+
+          var row = (from r in Content.Rows
+                     where r.Name == series.Name
+                     select r).Single();
+          FillSeriesWithRowValues(series, row);
+          this.chart.Legends[series.Legend].ForeColor = Color.Black;
+          RecalculateAxesScale(chart.ChartAreas[0]);
+          UpdateYCursorInterval();
+        }
+      }
+    }
+
+    private void FillSeriesWithRowValues(Series series, ScatterPlotDataRow row) {
+      for (int i = 0; i < row.Points.Count; i++) {
+        var value = row.Points[i];
+        DataPoint point = new DataPoint();
+        if (IsInvalidValue(value.X) || IsInvalidValue(value.Y))
+          point.IsEmpty = true;
+        else {
+          point.XValue = value.X;
+          point.YValues = new double[] { value.Y };
+        }
+        series.Points.Add(point);
+      }
+    }
+
+    #region Helpers
+    private MarkerStyle ConvertPointStyle(ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle pointStyle) {
+      switch (pointStyle) {
+        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Circle:
+          return MarkerStyle.Circle;
+        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Cross:
+          return MarkerStyle.Cross;
+        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Diamond:
+          return MarkerStyle.Diamond;
+        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Square:
+          return MarkerStyle.Square;
+        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Star4:
+          return MarkerStyle.Star4;
+        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Star5:
+          return MarkerStyle.Star5;
+        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Star6:
+          return MarkerStyle.Star6;
+        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Star10:
+          return MarkerStyle.Star10;
+        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Triangle:
+          return MarkerStyle.Triangle;
+        default:
+          return MarkerStyle.None;
+      }
+    }
+
+    protected static bool IsInvalidValue(double x) {
+      return double.IsNaN(x) || x < (double)decimal.MinValue || x > (double)decimal.MaxValue;
+    }
+    #endregion
+
+    //bubble double click event with scatter plot view as sender
+    private void chart_DoubleClick(object sender, EventArgs e) {
+      if (chartDoubleClick != null)
+        chartDoubleClick(this, e);
+    } 
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/Properties/AssemblyInfo.cs.frame
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/Properties/AssemblyInfo.cs.frame	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/Properties/AssemblyInfo.cs.frame	(revision 11159)
@@ -0,0 +1,36 @@
+﻿using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.DataPreprocessing.Views")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("FH-Hagenberg")]
+[assembly: AssemblyProduct("HeuristicLab.DataPreprocessing.Views")]
+[assembly: AssemblyCopyright("Copyright © FH-Hagenberg 2014")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("49b6ce71-b783-47f7-99af-c63365261c45")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("3.4.0.0")]
+[assembly: AssemblyFileVersion("3.4.0.$WCREV$")]
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/ScatterPlotMultiView.Designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/ScatterPlotMultiView.Designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/ScatterPlotMultiView.Designer.cs	(revision 11159)
@@ -0,0 +1,62 @@
+﻿namespace HeuristicLab.DataPreprocessing.Views {
+  partial class ScatterPlotMultiView {
+    /// <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.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
+      this.SuspendLayout();
+      // 
+      // tableLayoutPanel
+      // 
+      this.tableLayoutPanel.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.tableLayoutPanel.AutoScroll = true;
+      this.tableLayoutPanel.ColumnCount = 1;
+      this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+      this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
+      this.tableLayoutPanel.Location = new System.Drawing.Point(3, 3);
+      this.tableLayoutPanel.Name = "tableLayoutPanel";
+      this.tableLayoutPanel.RowCount = 1;
+      this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
+      this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 514F));
+      this.tableLayoutPanel.Size = new System.Drawing.Size(860, 514);
+      this.tableLayoutPanel.TabIndex = 1;
+      // 
+      // MultiScatterPlotView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.tableLayoutPanel);
+      this.Name = "MultiScatterPlotView";
+      this.Size = new System.Drawing.Size(863, 517);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.TableLayoutPanel tableLayoutPanel;
+
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/ScatterPlotMultiView.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/ScatterPlotMultiView.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/ScatterPlotMultiView.cs	(revision 11159)
@@ -0,0 +1,180 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core.Views;
+using HeuristicLab.DataPreprocessing.Implementations;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+
+  [View("Scatter Plot Multi View")]
+  [Content(typeof(ScatterPlotContent), false)]
+  public partial class ScatterPlotMultiView : ItemView {
+
+    private const int HEADER_WIDTH = 50;
+    private const int HEADER_HEIGHT = 50;
+    private const int MAX_AUTO_SIZE_ELEMENTS = 6;
+    private const int FIXED_CHART_WIDTH = 250;
+    private const int FIXED_CHART_HEIGHT = 150;
+
+    public ScatterPlotMultiView() {
+      InitializeComponent();
+    }
+
+    public new ScatterPlotContent Content {
+      get { return (ScatterPlotContent)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content != null) {
+        GenerateMultiLayout();
+      }
+    }
+
+    //Add header elements to the table layout panel
+    private void addHeaderToTableLayoutPanels() {
+
+      List<string> variables = Content.PreprocessingData.GetDoubleVariableNames().ToList();
+
+      for (int i = 1; i < variables.Count + 1; i++) {
+        // Use buttons for header elements
+        Button xButton = new Button();
+        xButton.Enabled = false;
+        xButton.BackColor = Color.Gainsboro;
+        xButton.Text = variables[i - 1];
+        xButton.Dock = DockStyle.Fill;
+        tableLayoutPanel.Controls.Add(xButton, 0, i);
+        Button yButton = new Button();
+        yButton.Enabled = false;
+        yButton.BackColor = Color.Gainsboro;
+        yButton.Text = variables[i - 1];
+        yButton.Dock = DockStyle.Fill;
+        tableLayoutPanel.Controls.Add(yButton, i, 0);
+      }
+    }
+
+    private void GenerateMultiLayout() {
+      List<string> variables = Content.PreprocessingData.GetDoubleVariableNames().ToList();
+
+      tableLayoutPanel.Controls.Clear();
+      //Clear out the existing row and column styles
+      tableLayoutPanel.ColumnStyles.Clear();
+      tableLayoutPanel.RowStyles.Clear();
+
+      //Set row and column count
+      tableLayoutPanel.ColumnCount = variables.Count + 1;
+      tableLayoutPanel.RowCount = variables.Count + 1;
+
+      tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, HEADER_WIDTH));
+      tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, HEADER_HEIGHT));
+      // set column and row layout
+      for (int x = 0; x < variables.Count; x++) {
+        // auto size
+        if (variables.Count <= MAX_AUTO_SIZE_ELEMENTS) {
+          tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, (tableLayoutPanel.Width - HEADER_WIDTH) / variables.Count));
+          tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, (tableLayoutPanel.Height - HEADER_HEIGHT) / variables.Count));
+        }
+          // fixed size
+        else {
+          tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, FIXED_CHART_WIDTH));
+          tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, FIXED_CHART_HEIGHT));
+        }
+      }
+
+      addHeaderToTableLayoutPanels();
+      addChartsToTableLayoutPanel();
+
+    }
+
+    private void addChartsToTableLayoutPanel() {
+
+      List<string> variables = Content.PreprocessingData.GetDoubleVariableNames().ToList();
+
+      //set scatter plots and histograms
+      for (int x = 1; x < variables.Count + 1; x++) {
+
+        for (int y = 1; y < variables.Count + 1; y++) {
+          // use historgram if x and y variable are equal
+          if (x == y) {
+            PreprocessingDataTable dataTable = new PreprocessingDataTable();
+            DataRow dataRow = Content.CreateDataRow(variables[x - 1], DataRowVisualProperties.DataRowChartType.Histogram);
+            dataTable.Rows.Add(dataRow);
+            PreprocessingDataTableView pcv = new PreprocessingDataTableView();
+            pcv.ChartDoubleClick += HistogramDoubleClick;
+            pcv.Content = dataTable;
+            tableLayoutPanel.Controls.Add(pcv, y, x);
+          }
+            //scatter plot
+          else {
+            ScatterPlot scatterPlot = Content.CreateScatterPlot(variables[x - 1], variables[y - 1]);
+            PreprocessingScatterPlotView pspv = new PreprocessingScatterPlotView();
+            pspv.ChartDoubleClick += ScatterPlotDoubleClick;
+            pspv.Content = scatterPlot;
+            pspv.Dock = DockStyle.Fill;
+            tableLayoutPanel.Controls.Add(pspv, x, y);
+          }
+        }
+      }
+    }
+
+    //Open scatter plot in new tab with new content when double clicked
+    private void ScatterPlotDoubleClick(object sender, EventArgs e) {
+      PreprocessingScatterPlotView pspv = (PreprocessingScatterPlotView)sender;
+      ScatterPlotContent scatterContent = new ScatterPlotContent(Content, new Cloner());  // create new content
+      ScatterPlot scatterPlot = pspv.Content;
+      setVariablesInContentFromScatterPlot(scatterContent, scatterPlot);
+
+      MainFormManager.MainForm.ShowContent(scatterContent, typeof(ScatterPlotSingleView));  // open in new tab
+    }
+
+    //Extract variable names from scatter plot and set them in content
+    private void setVariablesInContentFromScatterPlot(ScatterPlotContent scatterContent, ScatterPlot scatterPlot) {
+
+      // only one data row should be in scatter plot
+      if (scatterPlot.Rows.Count == 1) {
+        string[] variables = scatterPlot.Rows.ElementAt(0).Name.Split(new string[] { " - " }, StringSplitOptions.None); // extract variable names from string
+        scatterContent.SelectedXVariable = variables[0];
+        scatterContent.SelectedYVariable = variables[1];
+      }
+    }
+
+    //Set variable item list from with variable from data table
+    private void setVariableItemListFromDataTable(HistogramContent histoContent, PreprocessingDataTable dataTable) {
+
+      // only one data row should be in data table 
+      if (dataTable.Rows.Count == 1) {
+        string variableName = dataTable.Rows.ElementAt(0).Name;
+
+        // set only variable name checked
+        foreach (var checkedItem in histoContent.VariableItemList) {
+          if (checkedItem.Value == variableName)
+            histoContent.VariableItemList.SetItemCheckedState(checkedItem, true);
+          else
+            histoContent.VariableItemList.SetItemCheckedState(checkedItem, false);
+
+        }
+      }
+    }
+
+    //open histogram in new tab with new content when double clicked
+    private void HistogramDoubleClick(object sender, EventArgs e) {
+      PreprocessingDataTableView pcv = (PreprocessingDataTableView)sender;
+      HistogramContent histoContent = new HistogramContent(Content.PreprocessingData);  // create new content     
+      histoContent.VariableItemList = Content.CreateVariableItemList();
+      PreprocessingDataTable dataTable = pcv.Content;
+      setVariableItemListFromDataTable(histoContent, dataTable);
+
+      MainFormManager.MainForm.ShowContent(histoContent, typeof(HistogramView));  // open in new tab
+    }
+
+
+  }
+
+
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/ScatterPlotSingleView.Designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/ScatterPlotSingleView.Designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/ScatterPlotSingleView.Designer.cs	(revision 11159)
@@ -0,0 +1,124 @@
+﻿namespace HeuristicLab.DataPreprocessing.Views {
+  partial class ScatterPlotSingleView {
+    /// <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.scatterPlotView = new HeuristicLab.DataPreprocessing.Views.PreprocessingScatterPlotView();
+      this.groupBox1 = new System.Windows.Forms.GroupBox();
+      this.label2 = new System.Windows.Forms.Label();
+      this.label1 = new System.Windows.Forms.Label();
+      this.comboBoxYVariable = new System.Windows.Forms.ComboBox();
+      this.comboBoxXVariable = new System.Windows.Forms.ComboBox();
+      this.groupBox1.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // scatterPlotView
+      // 
+      this.scatterPlotView.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.scatterPlotView.Caption = "ScatterPlot View";
+      this.scatterPlotView.Content = null;
+      this.scatterPlotView.Location = new System.Drawing.Point(169, 3);
+      this.scatterPlotView.Name = "scatterPlotView";
+      this.scatterPlotView.ReadOnly = false;
+      this.scatterPlotView.Size = new System.Drawing.Size(689, 509);
+      this.scatterPlotView.TabIndex = 0;
+      // 
+      // groupBox1
+      // 
+      this.groupBox1.Controls.Add(this.label2);
+      this.groupBox1.Controls.Add(this.label1);
+      this.groupBox1.Controls.Add(this.comboBoxYVariable);
+      this.groupBox1.Controls.Add(this.comboBoxXVariable);
+      this.groupBox1.Location = new System.Drawing.Point(3, 3);
+      this.groupBox1.Name = "groupBox1";
+      this.groupBox1.Size = new System.Drawing.Size(160, 140);
+      this.groupBox1.TabIndex = 1;
+      this.groupBox1.TabStop = false;
+      this.groupBox1.Text = "Options";
+      // 
+      // label2
+      // 
+      this.label2.AutoSize = true;
+      this.label2.Location = new System.Drawing.Point(17, 80);
+      this.label2.Name = "label2";
+      this.label2.Size = new System.Drawing.Size(55, 13);
+      this.label2.TabIndex = 3;
+      this.label2.Text = "Y Variable";
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(17, 25);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(55, 13);
+      this.label1.TabIndex = 2;
+      this.label1.Text = "X Variable";
+      // 
+      // comboBoxYVariable
+      // 
+      this.comboBoxYVariable.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.comboBoxYVariable.FormattingEnabled = true;
+      this.comboBoxYVariable.Location = new System.Drawing.Point(20, 103);
+      this.comboBoxYVariable.Margin = new System.Windows.Forms.Padding(3, 10, 3, 3);
+      this.comboBoxYVariable.Name = "comboBoxYVariable";
+      this.comboBoxYVariable.Size = new System.Drawing.Size(121, 21);
+      this.comboBoxYVariable.TabIndex = 1;
+      this.comboBoxYVariable.SelectedIndexChanged += new System.EventHandler(this.comboBox_SelectedIndexChanged);
+      // 
+      // comboBoxXVariable
+      // 
+      this.comboBoxXVariable.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.comboBoxXVariable.FormattingEnabled = true;
+      this.comboBoxXVariable.Location = new System.Drawing.Point(20, 48);
+      this.comboBoxXVariable.Margin = new System.Windows.Forms.Padding(3, 10, 3, 3);
+      this.comboBoxXVariable.Name = "comboBoxXVariable";
+      this.comboBoxXVariable.Size = new System.Drawing.Size(121, 21);
+      this.comboBoxXVariable.TabIndex = 0;
+      this.comboBoxXVariable.SelectedIndexChanged += new System.EventHandler(this.comboBox_SelectedIndexChanged);
+      // 
+      // ScatterPlotSingleView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.groupBox1);
+      this.Controls.Add(this.scatterPlotView);
+      this.Name = "ScatterPlotSingleView";
+      this.Size = new System.Drawing.Size(863, 517);
+      this.groupBox1.ResumeLayout(false);
+      this.groupBox1.PerformLayout();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private HeuristicLab.DataPreprocessing.Views.PreprocessingScatterPlotView scatterPlotView;
+    private System.Windows.Forms.GroupBox groupBox1;
+    private System.Windows.Forms.Label label2;
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.ComboBox comboBoxYVariable;
+    private System.Windows.Forms.ComboBox comboBoxXVariable;
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/ScatterPlotSingleView.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/ScatterPlotSingleView.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/ScatterPlotSingleView.cs	(revision 11159)
@@ -0,0 +1,75 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Analysis;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+
+  [View("Scatter Plot Single View")]
+  [Content(typeof(ScatterPlotContent), true)]
+  public partial class ScatterPlotSingleView : ItemView {
+
+    public new ScatterPlotContent Content {
+      get { return (ScatterPlotContent)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ScatterPlotSingleView()
+    {
+      InitializeComponent();
+    }
+
+    public void InitData() {
+
+      IEnumerable<string> variables = Content.PreprocessingData.GetDoubleVariableNames();
+
+      // add variables to combo boxes
+      comboBoxXVariable.Items.Clear();
+      comboBoxYVariable.Items.Clear();
+      comboBoxXVariable.Items.AddRange(variables.ToArray());
+      comboBoxYVariable.Items.AddRange(variables.ToArray());
+
+      // use x and y variable from content
+      if (Content.SelectedXVariable != null && Content.SelectedYVariable != null) {
+        comboBoxXVariable.SelectedItem = Content.SelectedXVariable;
+        comboBoxYVariable.SelectedItem = Content.SelectedYVariable;
+      } else {
+        if (variables.Count() >= 2) {
+          comboBoxXVariable.SelectedIndex = 0;
+          comboBoxYVariable.SelectedIndex = 1;
+          UpdateScatterPlot();
+
+        }
+      }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content != null) {
+        InitData();
+      }
+    }
+
+    private void comboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      UpdateScatterPlot();
+    }
+
+    private void UpdateScatterPlot() {
+      if (comboBoxXVariable.SelectedItem != null && comboBoxYVariable.SelectedItem != null) {
+        //get scatter plot with selected x and y variable
+        ScatterPlot scatterPlot = Content.CreateScatterPlot((string)comboBoxXVariable.SelectedItem, (string)comboBoxYVariable.SelectedItem);
+        scatterPlotView.Content = scatterPlot;
+
+        //save selected x and y variable in content
+        this.Content.SelectedXVariable = (string)comboBoxXVariable.SelectedItem;
+        this.Content.SelectedYVariable = (string)comboBoxYVariable.SelectedItem;
+      }
+    }
+
+  }
+
+
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/SearchAndReplaceDialog.Designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/SearchAndReplaceDialog.Designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/SearchAndReplaceDialog.Designer.cs	(revision 11159)
@@ -0,0 +1,221 @@
+﻿namespace HeuristicLab.DataPreprocessing.Views {
+  partial class SearchAndReplaceDialog {
+    /// <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 Windows Form 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.tabSearchReplace = new System.Windows.Forms.TabControl();
+      this.tabSearch = new System.Windows.Forms.TabPage();
+      this.tabReplace = new System.Windows.Forms.TabPage();
+      this.cmbComparisonOperator = new System.Windows.Forms.ComboBox();
+      this.txtSearchString = new System.Windows.Forms.TextBox();
+      this.lblSearch = new System.Windows.Forms.Label();
+      this.btnFindAll = new System.Windows.Forms.Button();
+      this.btnFindNext = new System.Windows.Forms.Button();
+      this.lblValue = new System.Windows.Forms.Label();
+      this.btnReplaceAll = new System.Windows.Forms.Button();
+      this.btnReplace = new System.Windows.Forms.Button();
+      this.cmbReplaceWith = new System.Windows.Forms.ComboBox();
+      this.txtValue = new System.Windows.Forms.TextBox();
+      this.label1 = new System.Windows.Forms.Label();
+      this.tabSearchReplace.SuspendLayout();
+      this.tabReplace.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // tabSearchReplace
+      // 
+      this.tabSearchReplace.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.tabSearchReplace.Controls.Add(this.tabSearch);
+      this.tabSearchReplace.Controls.Add(this.tabReplace);
+      this.tabSearchReplace.Location = new System.Drawing.Point(12, 12);
+      this.tabSearchReplace.Name = "tabSearchReplace";
+      this.tabSearchReplace.SelectedIndex = 0;
+      this.tabSearchReplace.Size = new System.Drawing.Size(564, 132);
+      this.tabSearchReplace.TabIndex = 0;
+      this.tabSearchReplace.SelectedIndexChanged += new System.EventHandler(this.tabSearchReplace_SelectedIndexChanged);
+      // 
+      // tabSearch
+      // 
+      this.tabSearch.Location = new System.Drawing.Point(4, 22);
+      this.tabSearch.Name = "tabSearch";
+      this.tabSearch.Padding = new System.Windows.Forms.Padding(3);
+      this.tabSearch.Size = new System.Drawing.Size(556, 106);
+      this.tabSearch.TabIndex = 0;
+      this.tabSearch.Text = "Search";
+      this.tabSearch.UseVisualStyleBackColor = true;
+      // 
+      // tabReplace
+      // 
+      this.tabReplace.Controls.Add(this.cmbComparisonOperator);
+      this.tabReplace.Controls.Add(this.txtSearchString);
+      this.tabReplace.Controls.Add(this.lblSearch);
+      this.tabReplace.Controls.Add(this.btnFindAll);
+      this.tabReplace.Controls.Add(this.btnFindNext);
+      this.tabReplace.Controls.Add(this.lblValue);
+      this.tabReplace.Controls.Add(this.btnReplaceAll);
+      this.tabReplace.Controls.Add(this.btnReplace);
+      this.tabReplace.Controls.Add(this.cmbReplaceWith);
+      this.tabReplace.Controls.Add(this.txtValue);
+      this.tabReplace.Controls.Add(this.label1);
+      this.tabReplace.Location = new System.Drawing.Point(4, 22);
+      this.tabReplace.Name = "tabReplace";
+      this.tabReplace.Padding = new System.Windows.Forms.Padding(3);
+      this.tabReplace.Size = new System.Drawing.Size(556, 106);
+      this.tabReplace.TabIndex = 1;
+      this.tabReplace.Text = "Replace";
+      this.tabReplace.UseVisualStyleBackColor = true;
+      // 
+      // cmbComparisonOperator
+      // 
+      this.cmbComparisonOperator.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.cmbComparisonOperator.FormattingEnabled = true;
+      this.cmbComparisonOperator.Location = new System.Drawing.Point(103, 19);
+      this.cmbComparisonOperator.Name = "cmbComparisonOperator";
+      this.cmbComparisonOperator.Size = new System.Drawing.Size(45, 21);
+      this.cmbComparisonOperator.TabIndex = 24;
+      // 
+      // txtSearchString
+      // 
+      this.txtSearchString.Location = new System.Drawing.Point(154, 20);
+      this.txtSearchString.Name = "txtSearchString";
+      this.txtSearchString.Size = new System.Drawing.Size(203, 20);
+      this.txtSearchString.TabIndex = 23;
+      // 
+      // lblSearch
+      // 
+      this.lblSearch.AutoSize = true;
+      this.lblSearch.Location = new System.Drawing.Point(41, 26);
+      this.lblSearch.Name = "lblSearch";
+      this.lblSearch.Size = new System.Drawing.Size(56, 13);
+      this.lblSearch.TabIndex = 22;
+      this.lblSearch.Text = "Search for";
+      // 
+      // btnFindAll
+      // 
+      this.btnFindAll.Location = new System.Drawing.Point(458, 20);
+      this.btnFindAll.Name = "btnFindAll";
+      this.btnFindAll.Size = new System.Drawing.Size(80, 23);
+      this.btnFindAll.TabIndex = 21;
+      this.btnFindAll.Text = "Find All";
+      this.btnFindAll.UseVisualStyleBackColor = true;
+      // 
+      // btnFindNext
+      // 
+      this.btnFindNext.Location = new System.Drawing.Point(372, 20);
+      this.btnFindNext.Name = "btnFindNext";
+      this.btnFindNext.Size = new System.Drawing.Size(80, 23);
+      this.btnFindNext.TabIndex = 20;
+      this.btnFindNext.Text = "Find Next";
+      this.btnFindNext.UseVisualStyleBackColor = true;
+      // 
+      // lblValue
+      // 
+      this.lblValue.AutoSize = true;
+      this.lblValue.Location = new System.Drawing.Point(64, 76);
+      this.lblValue.Name = "lblValue";
+      this.lblValue.Size = new System.Drawing.Size(34, 13);
+      this.lblValue.TabIndex = 19;
+      this.lblValue.Text = "Value";
+      // 
+      // btnReplaceAll
+      // 
+      this.btnReplaceAll.Location = new System.Drawing.Point(458, 47);
+      this.btnReplaceAll.Name = "btnReplaceAll";
+      this.btnReplaceAll.Size = new System.Drawing.Size(80, 23);
+      this.btnReplaceAll.TabIndex = 18;
+      this.btnReplaceAll.Text = "Replace All";
+      this.btnReplaceAll.UseVisualStyleBackColor = true;
+      // 
+      // btnReplace
+      // 
+      this.btnReplace.Location = new System.Drawing.Point(372, 47);
+      this.btnReplace.Name = "btnReplace";
+      this.btnReplace.Size = new System.Drawing.Size(80, 23);
+      this.btnReplace.TabIndex = 17;
+      this.btnReplace.Text = "Replace";
+      this.btnReplace.UseVisualStyleBackColor = true;
+      // 
+      // cmbReplaceWith
+      // 
+      this.cmbReplaceWith.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.cmbReplaceWith.FormattingEnabled = true;
+      this.cmbReplaceWith.Location = new System.Drawing.Point(103, 46);
+      this.cmbReplaceWith.Name = "cmbReplaceWith";
+      this.cmbReplaceWith.Size = new System.Drawing.Size(254, 21);
+      this.cmbReplaceWith.TabIndex = 16;
+      this.cmbReplaceWith.SelectedIndexChanged += new System.EventHandler(this.cmbReplaceWith_SelectedIndexChanged);
+      // 
+      // txtValue
+      // 
+      this.txtValue.Location = new System.Drawing.Point(103, 73);
+      this.txtValue.Name = "txtValue";
+      this.txtValue.Size = new System.Drawing.Size(254, 20);
+      this.txtValue.TabIndex = 15;
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(28, 49);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(69, 13);
+      this.label1.TabIndex = 14;
+      this.label1.Text = "Replace with";
+      // 
+      // SearchAndReplaceDialog
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.ClientSize = new System.Drawing.Size(588, 156);
+      this.Controls.Add(this.tabSearchReplace);
+      this.MaximizeBox = false;
+      this.MinimizeBox = false;
+      this.Name = "SearchAndReplaceDialog";
+      this.ShowIcon = false;
+      this.ShowInTaskbar = false;
+      this.Text = "Search and Replace";
+      this.tabSearchReplace.ResumeLayout(false);
+      this.tabReplace.ResumeLayout(false);
+      this.tabReplace.PerformLayout();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.TabControl tabSearchReplace;
+    private System.Windows.Forms.TabPage tabSearch;
+    private System.Windows.Forms.TabPage tabReplace;
+    private System.Windows.Forms.TextBox txtSearchString;
+    private System.Windows.Forms.Label lblSearch;
+    private System.Windows.Forms.Button btnFindAll;
+    private System.Windows.Forms.Button btnFindNext;
+    private System.Windows.Forms.Label lblValue;
+    private System.Windows.Forms.Button btnReplaceAll;
+    private System.Windows.Forms.Button btnReplace;
+    private System.Windows.Forms.ComboBox cmbReplaceWith;
+    private System.Windows.Forms.TextBox txtValue;
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.ComboBox cmbComparisonOperator;
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/SearchAndReplaceDialog.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/SearchAndReplaceDialog.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/SearchAndReplaceDialog.cs	(revision 11159)
@@ -0,0 +1,110 @@
+﻿using System;
+using System.Windows.Forms;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+  public enum ReplaceAction {
+    Value,
+    Average,
+    Median,
+    Random,
+    MostCommon,
+    Interpolation
+  }
+
+  public enum ComparisonOperation {
+    Equal,
+    Less,
+    LessOrEqual,
+    Greater,
+    GreaterOrEqual,
+    NotEqual
+  }
+
+
+
+  public partial class SearchAndReplaceDialog : Form {
+    private string[] cmbItemsText = { "Value", "Average", "Median", "Random", "Most Common", "Interpolation" };
+    private string[] cmbComparisonOperatorText = { "==", "<", "<=", ">", ">=", "!=" };
+
+    public SearchAndReplaceDialog() {
+      InitializeComponent();
+      cmbReplaceWith.Items.AddRange(cmbItemsText);
+      cmbReplaceWith.SelectedIndex = (int)ReplaceAction.Value;
+      cmbComparisonOperator.Items.AddRange(cmbComparisonOperatorText);
+      cmbComparisonOperator.SelectedIndex = (int)ComparisonOperation.Equal;
+    }
+
+    public void ActivateSearch() {
+      tabSearchReplace.SelectTab(tabSearch);
+      AddControlsToCurrentTab();
+    }
+
+    public void ActivateReplace() {
+      tabSearchReplace.SelectTab(tabReplace);
+      AddControlsToCurrentTab();
+    }
+
+    public void DisableReplace() {
+      tabSearchReplace.SelectTab(tabSearch);
+      tabReplace.Enabled = false;
+    }
+
+    public void EnableReplace() {
+      tabReplace.Enabled = true;
+    }
+
+    private void tabSearchReplace_SelectedIndexChanged(object sender, System.EventArgs e) {
+      AddControlsToCurrentTab();
+    }
+
+    private void cmbReplaceWith_SelectedIndexChanged(object sender, System.EventArgs e) {
+      lblValue.Visible = txtValue.Visible = cmbReplaceWith.SelectedIndex == (int)ReplaceAction.Value;
+    }
+
+    private void AddControlsToCurrentTab() {
+      tabSearchReplace.SelectedTab.Controls.Add(btnFindAll);
+      tabSearchReplace.SelectedTab.Controls.Add(btnFindNext);
+      tabSearchReplace.SelectedTab.Controls.Add(lblSearch);
+      tabSearchReplace.SelectedTab.Controls.Add(txtSearchString);
+      tabSearchReplace.SelectedTab.Controls.Add(cmbComparisonOperator);
+      ActiveControl = txtSearchString;
+      AcceptButton = btnFindNext;
+    }
+
+    public String GetSearchText() {
+      return txtSearchString.Text;
+    }
+
+    public string GetReplaceText() {
+      return txtValue.Text;
+    }
+
+    public ReplaceAction GetReplaceAction() {
+      return (ReplaceAction)cmbReplaceWith.SelectedIndex;
+    }
+
+    public ComparisonOperation GetComparisonOperation() {
+      return (ComparisonOperation)cmbComparisonOperator.SelectedIndex;
+    }
+
+    public event EventHandler FindAllEvent {
+      add { btnFindAll.Click += value; }
+      remove { btnFindAll.Click -= value; }
+    }
+
+    public event EventHandler FindNextEvent {
+      add { btnFindNext.Click += value; }
+      remove { btnFindNext.Click -= value; }
+    }
+
+    public event EventHandler ReplaceAllEvent {
+      add { btnReplaceAll.Click += value; }
+      remove { btnReplaceAll.Click -= value; }
+    }
+
+    public event EventHandler ReplaceNextEvent {
+      add { btnReplace.Click += value; }
+      remove { btnReplace.Click -= value; }
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/StatisticsView.Designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/StatisticsView.Designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/StatisticsView.Designer.cs	(revision 11159)
@@ -0,0 +1,206 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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 StatisticsView {
+    /// <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.lblRows = new System.Windows.Forms.Label();
+      this.txtRows = new System.Windows.Forms.Label();
+      this.lblColumns = new System.Windows.Forms.Label();
+      this.lblMissingValuesTotal = new System.Windows.Forms.Label();
+      this.txtColumns = new System.Windows.Forms.Label();
+      this.txtNumericColumns = new System.Windows.Forms.Label();
+      this.txtNominalColumns = new System.Windows.Forms.Label();
+      this.lblNumericColumns = new System.Windows.Forms.Label();
+      this.lblNominalColumns = new System.Windows.Forms.Label();
+      this.txtMissingValuesTotal = new System.Windows.Forms.Label();
+      this.dataGridView = new System.Windows.Forms.DataGridView();
+      ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // lblRows
+      // 
+      this.lblRows.AutoSize = true;
+      this.lblRows.Location = new System.Drawing.Point(3, 11);
+      this.lblRows.Name = "lblRows";
+      this.lblRows.Size = new System.Drawing.Size(34, 13);
+      this.lblRows.TabIndex = 0;
+      this.lblRows.Text = "Rows";
+      // 
+      // txtRows
+      // 
+      this.txtRows.AutoSize = true;
+      this.txtRows.Location = new System.Drawing.Point(115, 11);
+      this.txtRows.Name = "txtRows";
+      this.txtRows.Size = new System.Drawing.Size(19, 13);
+      this.txtRows.TabIndex = 1;
+      this.txtRows.Text = "12";
+      // 
+      // lblColumns
+      // 
+      this.lblColumns.AutoSize = true;
+      this.lblColumns.Location = new System.Drawing.Point(3, 31);
+      this.lblColumns.Name = "lblColumns";
+      this.lblColumns.Size = new System.Drawing.Size(47, 13);
+      this.lblColumns.TabIndex = 2;
+      this.lblColumns.Text = "Columns";
+      // 
+      // lblMissingValuesTotal
+      // 
+      this.lblMissingValuesTotal.AutoSize = true;
+      this.lblMissingValuesTotal.Location = new System.Drawing.Point(3, 92);
+      this.lblMissingValuesTotal.Name = "lblMissingValuesTotal";
+      this.lblMissingValuesTotal.Size = new System.Drawing.Size(100, 13);
+      this.lblMissingValuesTotal.TabIndex = 3;
+      this.lblMissingValuesTotal.Text = "Missing Values total";
+      // 
+      // txtColumns
+      // 
+      this.txtColumns.AutoSize = true;
+      this.txtColumns.Location = new System.Drawing.Point(115, 31);
+      this.txtColumns.Name = "txtColumns";
+      this.txtColumns.Size = new System.Drawing.Size(25, 13);
+      this.txtColumns.TabIndex = 1;
+      this.txtColumns.Text = "123";
+      // 
+      // txtNumericColumns
+      // 
+      this.txtNumericColumns.AutoSize = true;
+      this.txtNumericColumns.Location = new System.Drawing.Point(115, 51);
+      this.txtNumericColumns.Name = "txtNumericColumns";
+      this.txtNumericColumns.Size = new System.Drawing.Size(25, 13);
+      this.txtNumericColumns.TabIndex = 1;
+      this.txtNumericColumns.Text = "456";
+      // 
+      // txtNominalColumns
+      // 
+      this.txtNominalColumns.AutoSize = true;
+      this.txtNominalColumns.Location = new System.Drawing.Point(115, 72);
+      this.txtNominalColumns.Name = "txtNominalColumns";
+      this.txtNominalColumns.Size = new System.Drawing.Size(25, 13);
+      this.txtNominalColumns.TabIndex = 1;
+      this.txtNominalColumns.Text = "789";
+      // 
+      // lblNumericColumns
+      // 
+      this.lblNumericColumns.AutoSize = true;
+      this.lblNumericColumns.Location = new System.Drawing.Point(3, 51);
+      this.lblNumericColumns.Name = "lblNumericColumns";
+      this.lblNumericColumns.Size = new System.Drawing.Size(89, 13);
+      this.lblNumericColumns.TabIndex = 3;
+      this.lblNumericColumns.Text = "Numeric Columns";
+      // 
+      // lblNominalColumns
+      // 
+      this.lblNominalColumns.AutoSize = true;
+      this.lblNominalColumns.Location = new System.Drawing.Point(3, 72);
+      this.lblNominalColumns.Name = "lblNominalColumns";
+      this.lblNominalColumns.Size = new System.Drawing.Size(88, 13);
+      this.lblNominalColumns.TabIndex = 3;
+      this.lblNominalColumns.Text = "Nominal Columns";
+      // 
+      // txtMissingValuesTotal
+      // 
+      this.txtMissingValuesTotal.AutoSize = true;
+      this.txtMissingValuesTotal.Location = new System.Drawing.Point(115, 92);
+      this.txtMissingValuesTotal.Name = "txtMissingValuesTotal";
+      this.txtMissingValuesTotal.Size = new System.Drawing.Size(25, 13);
+      this.txtMissingValuesTotal.TabIndex = 1;
+      this.txtMissingValuesTotal.Text = "102";
+      // 
+      // dataGridView
+      // 
+      this.dataGridView.AllowUserToAddRows = false;
+      this.dataGridView.AllowUserToDeleteRows = false;
+      this.dataGridView.AllowUserToOrderColumns = true;
+      this.dataGridView.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.dataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+      this.dataGridView.Location = new System.Drawing.Point(5, 117);
+      this.dataGridView.Name = "dataGridView";
+      this.dataGridView.ReadOnly = true;
+      this.dataGridView.RowHeadersWidth = 80;
+      this.dataGridView.Size = new System.Drawing.Size(530, 278);
+      this.dataGridView.TabIndex = 4;
+      this.dataGridView.VirtualMode = true;
+      this.dataGridView.CellValueNeeded += new System.Windows.Forms.DataGridViewCellValueEventHandler(this.dataGridView_CellValueNeeded);
+      // 
+      // StatisticsView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.dataGridView);
+      this.Controls.Add(this.lblNominalColumns);
+      this.Controls.Add(this.lblNumericColumns);
+      this.Controls.Add(this.lblMissingValuesTotal);
+      this.Controls.Add(this.txtMissingValuesTotal);
+      this.Controls.Add(this.txtNominalColumns);
+      this.Controls.Add(this.lblColumns);
+      this.Controls.Add(this.txtNumericColumns);
+      this.Controls.Add(this.txtColumns);
+      this.Controls.Add(this.txtRows);
+      this.Controls.Add(this.lblRows);
+      this.Name = "StatisticsView";
+      this.Size = new System.Drawing.Size(549, 408);
+      ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Label lblRows;
+    private System.Windows.Forms.Label txtRows;
+    private System.Windows.Forms.Label lblColumns;
+    private System.Windows.Forms.Label lblMissingValuesTotal;
+    private System.Windows.Forms.Label txtColumns;
+    private System.Windows.Forms.Label txtNumericColumns;
+    private System.Windows.Forms.Label txtNominalColumns;
+    private System.Windows.Forms.Label lblNumericColumns;
+    private System.Windows.Forms.Label lblNominalColumns;
+    private System.Windows.Forms.Label txtMissingValuesTotal;
+    private System.Windows.Forms.DataGridView dataGridView;
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/StatisticsView.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/StatisticsView.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/StatisticsView.cs	(revision 11159)
@@ -0,0 +1,218 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Windows.Forms;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+
+  [View("Statistics View")]
+  [Content(typeof(StatisticsContent), true)]
+  public partial class StatisticsView : ItemView {
+
+    private List<List<string>> columnsRowsMatrix;
+    private readonly int COLUMNS = 10;
+
+    public new StatisticsContent Content {
+      get { return (StatisticsContent)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public StatisticsView() {
+      InitializeComponent();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        txtRows.Text = "";
+        txtColumns.Text = "";
+        txtNumericColumns.Text = "";
+        txtNominalColumns.Text = "";
+        txtMissingValuesTotal.Text = "";
+        dataGridView.Columns.Clear();
+      } else {
+        UpdateData();
+      }
+    }
+
+    /// <summary>
+    /// Adds eventhandlers to the current instance.
+    /// </summary>
+    protected override void RegisterContentEvents() {
+      Content.Changed += Content_Changed;
+    }
+
+
+    /// <summary>
+    /// Removes the eventhandlers from the current instance.
+    /// </summary>
+    protected override void DeregisterContentEvents() {
+      Content.Changed -= Content_Changed;
+    }
+
+    private void UpdateData() {
+      var logic = Content.StatisticsLogic;
+      var rowCount = logic.GetRowCount();
+      txtRows.Text = rowCount.ToString();
+      txtColumns.Text = logic.GetColumnCount().ToString();
+      txtNumericColumns.Text = logic.GetNumericColumnCount().ToString();
+      txtNominalColumns.Text = logic.GetNominalColumnCount().ToString();
+      txtMissingValuesTotal.Text = logic.GetMissingValueCount().ToString();
+
+      columnsRowsMatrix = new List<List<string>>();
+      DataGridViewColumn[] columns = new DataGridViewColumn[10];
+      for (int i = 0; i < COLUMNS; ++i) {
+        var column = new DataGridViewTextBoxColumn();
+        column.SortMode = DataGridViewColumnSortMode.Automatic;
+        column.FillWeight = 1;
+        columns[i] = column;
+      }
+
+      columns[0].HeaderCell.Value = "Type";
+      columns[1].HeaderCell.Value = "Missing Values";
+      columns[2].HeaderCell.Value = "Min";
+      columns[3].HeaderCell.Value = "Max";
+      columns[4].HeaderCell.Value = "Median";
+      columns[5].HeaderCell.Value = "Average";
+      columns[6].HeaderCell.Value = "std. Deviation";
+      columns[7].HeaderCell.Value = "Variance";
+      columns[8].HeaderCell.Value = "Most Common Value";
+      columns[9].HeaderCell.Value = "Num. diff. Values";
+
+      if (rowCount > 0) {
+        for (int i = 0; i < logic.GetColumnCount(); ++i) {
+          columnsRowsMatrix.Add(GetList(i));
+        }
+      }
+
+      dataGridView.Columns.Clear();
+      dataGridView.Columns.AddRange(columns);
+      dataGridView.RowCount = columnsRowsMatrix.Count;
+
+      for (int i = 0; i < columnsRowsMatrix.Count; ++i) {
+        dataGridView.Rows[i].HeaderCell.Value = logic.GetVariableName(i);
+      }
+
+      dataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.DisplayedCells);
+      dataGridView.AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders);
+      dataGridView.AllowUserToResizeColumns = true;
+    }
+
+    private List<string> GetList(int i) {
+      List<string> list;
+      var logic = Content.StatisticsLogic;
+      if (logic.VariableHasType<double>(i)) {
+        list = GetDoubleColumns(i);
+      } else if (logic.VariableHasType<string>(i)) {
+        list = GetStringColumns(i);
+      } else if (logic.VariableHasType<DateTime>(i)) {
+        list = GetDateTimeColumns(i);
+      } else {
+        list = new List<string>();
+        for (int j = 0; j < COLUMNS; ++j) {
+          list.Add("unknown column type");
+        }
+      }
+      return list;
+    }
+
+    private List<string> GetDoubleColumns(int columnIndex) {
+      var logic = Content.StatisticsLogic;
+      return new List<string> {
+        logic.GetColumnTypeAsString(columnIndex),
+        logic.GetMissingValueCount(columnIndex).ToString(),
+        logic.GetMin<double>(columnIndex).ToString(),
+        logic.GetMax<double>(columnIndex).ToString(),
+        logic.GetMedian(columnIndex).ToString(),
+        logic.GetAverage(columnIndex).ToString(),
+        logic.GetStandardDeviation(columnIndex).ToString(),
+        logic.GetVariance(columnIndex).ToString(),
+        logic.GetMostCommonValue<double>(columnIndex).ToString(),
+        logic.GetDifferentValuesCount<double>(columnIndex).ToString()
+      };
+    }
+
+    private List<string> GetStringColumns(int columnIndex) {
+      var logic = Content.StatisticsLogic;
+      return new List<string> {
+        logic.GetColumnTypeAsString(columnIndex),
+        logic.GetMissingValueCount(columnIndex).ToString(),
+        "", //min
+        "", //max
+        "", //median
+        "", //average
+        "", //standard deviation
+        "", //variance
+        logic.GetMostCommonValue<string>(columnIndex).ToString(),
+        logic.GetDifferentValuesCount<string>(columnIndex).ToString()
+      };
+    }
+
+    private List<string> GetDateTimeColumns(int columnIndex) {
+      var logic = Content.StatisticsLogic;
+      return new List<string> {
+        logic.GetColumnTypeAsString(columnIndex),
+        logic.GetMissingValueCount(columnIndex).ToString(),
+        logic.GetMin<DateTime>(columnIndex).ToString(),
+        logic.GetMax<DateTime>(columnIndex).ToString(),
+        logic.GetMedianDateTime(columnIndex).ToString(), 
+        logic.GetAverageDateTime(columnIndex).ToString(),
+        logic.GetStandardDeviation(columnIndex).ToString(),
+        logic.GetVariance(columnIndex).ToString(), //variance
+        logic.GetMostCommonValue<DateTime>(columnIndex).ToString(),
+        logic.GetDifferentValuesCount<DateTime>(columnIndex).ToString()
+      };
+    }
+
+    private void dataGridView_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e) {
+      if (Content != null && e.RowIndex < columnsRowsMatrix.Count && e.ColumnIndex < columnsRowsMatrix[0].Count) {
+        e.Value = columnsRowsMatrix[e.RowIndex][e.ColumnIndex];
+      }
+    }
+
+    private void Content_Changed(object sender, DataPreprocessingChangedEventArgs e) {
+      switch (e.Type) {
+        case DataPreprocessingChangedEventType.DeleteColumn:
+          columnsRowsMatrix.RemoveAt(e.Column);
+          break;
+        case DataPreprocessingChangedEventType.AddColumn:
+          columnsRowsMatrix.Insert(e.Row, GetList(e.Column));
+          dataGridView.RowCount++;
+          break;
+        case DataPreprocessingChangedEventType.ChangeItem:
+          columnsRowsMatrix[e.Column] = GetList(e.Column);
+          break;
+        case DataPreprocessingChangedEventType.DeleteRow:
+        case DataPreprocessingChangedEventType.AddRow:
+        default:
+          for (int i = 0; i < columnsRowsMatrix.Count; ++i) {
+            columnsRowsMatrix[i] = GetList(e.Column);
+          }
+          break;
+      }
+      dataGridView.Refresh();
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/TransformationView.Designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/TransformationView.Designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/TransformationView.Designer.cs	(revision 11159)
@@ -0,0 +1,120 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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 TransformationView {
+    /// <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.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.SuspendLayout();
+      // 
+      // applyButton
+      // 
+      this.applyButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.applyButton.Location = new System.Drawing.Point(490, 488);
+      this.applyButton.Name = "applyButton";
+      this.applyButton.Size = new System.Drawing.Size(134, 23);
+      this.applyButton.TabIndex = 1;
+      this.applyButton.Text = "Apply Transformations";
+      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)));
+      this.lblFilterNotice.AutoSize = true;
+      this.lblFilterNotice.Location = new System.Drawing.Point(20, 493);
+      this.lblFilterNotice.Name = "lblFilterNotice";
+      this.lblFilterNotice.Size = new System.Drawing.Size(274, 13);
+      this.lblFilterNotice.TabIndex = 3;
+      this.lblFilterNotice.Text = "Transformations cannot be applied since a filter is active!";
+      this.lblFilterNotice.Visible = false;
+      // 
+      // transformationListView
+      // 
+      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;
+      this.transformationListView.Location = new System.Drawing.Point(0, 0);
+      this.transformationListView.Name = "transformationListView";
+      this.transformationListView.ReadOnly = false;
+      this.transformationListView.Size = new System.Drawing.Size(627, 482);
+      this.transformationListView.TabIndex = 0;
+      // 
+      // TransformationView
+      // 
+      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";
+      this.Size = new System.Drawing.Size(627, 514);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+    private CheckedTransformationListView transformationListView;
+    private System.Windows.Forms.Button applyButton;
+    private System.Windows.Forms.CheckBox preserveColumnsCheckbox;
+    private System.Windows.Forms.Label lblFilterNotice;
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/TransformationView.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/TransformationView.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/TransformationView.cs	(revision 11159)
@@ -0,0 +1,106 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Linq;
+using System.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+
+  [View("Transformation View")]
+  [Content(typeof(TransformationContent), true)]
+  public partial class TransformationView : AsynchronousContentView {
+
+    public new TransformationContent Content {
+      get { return (TransformationContent)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public TransformationView() {
+      InitializeComponent();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        transformationListView.Content = null;
+      } else {
+        transformationListView.Content = Content.CheckedTransformationList;
+        CheckFilters();
+      }
+    }
+
+    /// <summary>
+    /// Adds eventhandlers to the current instance.
+    /// </summary>
+    protected override void RegisterContentEvents() {
+      Content.FilterLogic.FilterChanged += FilterLogic_FilterChanged;
+    }
+
+    /// <summary>
+    /// Removes the eventhandlers from the current instance.
+    /// </summary>
+    protected override void DeregisterContentEvents() {
+      Content.FilterLogic.FilterChanged -= FilterLogic_FilterChanged;
+    }
+
+    void FilterLogic_FilterChanged(object sender, EventArgs e) {
+      if (Content != null) {
+        CheckFilters();
+      }
+    }
+
+    private void CheckFilters() {
+      if (Content.FilterLogic.IsFiltered) {
+        applyButton.Enabled = false;
+        lblFilterNotice.Visible = true;
+      } else {
+        applyButton.Enabled = true;
+        lblFilterNotice.Visible = false;
+      }
+    }
+
+    private void applyButton_Click(object sender, EventArgs e) {
+      var transformations = Content.CheckedTransformationList.CheckedItems.Select(x => x.Value);
+
+      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.Data);
+      bool preserve = preserveColumnsCheckbox.CheckState == CheckState.Checked;
+      string errorMsg;
+      bool success = transformator.ApplyTransformations(transformations, preserve, out errorMsg);
+      if (success) {
+        Content.CheckedTransformationList.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);
+      }
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/Utils/FindPreprocessingItemsIterator.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/Utils/FindPreprocessingItemsIterator.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/Utils/FindPreprocessingItemsIterator.cs	(revision 11159)
@@ -0,0 +1,109 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+  class FindPreprocessingItemsIterator : IFindPreprocessingItemsIterator {
+
+    private IDictionary<int, IList<int>> items;
+    private Tuple<int, int> currentCell;
+
+    public FindPreprocessingItemsIterator(IDictionary<int, IList<int>> items) {
+      this.items = items;
+      Reset(); 
+    }
+
+    public void SetStartCell(int columnIndex, int rowIndex) {
+      Tuple<int, int> startCell = GetNextFoundCell(columnIndex, rowIndex);
+      if (startCell == null) {
+        int tmpColumnIndex = columnIndex;
+        do {
+          ++tmpColumnIndex;
+          if (!items.ContainsKey(tmpColumnIndex)) {
+            tmpColumnIndex = 0;
+          }
+          startCell = GetNextFoundCell(tmpColumnIndex, 0);
+        } while (startCell == null && tmpColumnIndex != columnIndex);
+
+        if (startCell == null && tmpColumnIndex == columnIndex && rowIndex != 0) {
+          startCell = GetNextFoundCell(columnIndex, 0);
+        }
+      }
+      currentCell = startCell;
+    }
+
+    private Tuple<int, int> GetNextFoundCell(int columnIndex, int rowIndex) {
+      Tuple<int, int> next = null;
+      for (int i = 0; i < items[columnIndex].Count; ++i) {
+        if (items[columnIndex][i] >= rowIndex) {
+          next = new Tuple<int, int>(columnIndex, i);
+          break;
+        }
+      }
+      return next;
+    }
+
+    public bool MoveNext() {
+      bool result = false;
+      bool endReached = false;
+      if (CurrentCellExists()) {
+        do {
+          if (currentCell.Item2 < items[currentCell.Item1].Count - 1) {
+            currentCell = new Tuple<int, int>(currentCell.Item1, currentCell.Item2 + 1);
+          } else if (currentCell.Item1 < items.Count - 1) {
+            currentCell = new Tuple<int, int>(currentCell.Item1 + 1, 0);
+          } else {
+            endReached = true;
+          }
+        } while (!endReached && !CurrentCellExists());
+        result = !endReached;
+      }
+      return result;
+    }
+
+    public Tuple<int, int> GetCurrent() {
+      Tuple<int, int> resultCell = null;
+      if (items != null && CurrentCellExists()) {
+        int cellRow = items[currentCell.Item1].ElementAt(currentCell.Item2);
+        resultCell = new Tuple<int, int>(currentCell.Item1, cellRow);
+      }
+      return resultCell;
+    }
+
+    public void Reset() {
+      SetStartCell(0, 0);
+      if (!CurrentCellExists()) {
+        MoveNext();
+      }
+    }
+
+    private bool CurrentCellExists() {
+      bool result = false;
+      if (currentCell != null && items != null) {
+        result = items.ContainsKey(currentCell.Item1) && currentCell.Item2 < items[currentCell.Item1].Count;
+      }
+      return result;
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/Utils/IFindPreprocessingItemsIterator.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/Utils/IFindPreprocessingItemsIterator.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/Utils/IFindPreprocessingItemsIterator.cs	(revision 11159)
@@ -0,0 +1,31 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+  interface IFindPreprocessingItemsIterator {
+    Tuple<int, int> GetCurrent();
+    bool MoveNext();
+    void Reset();
+    void SetStartCell(int columnIndex, int rowIndex); 
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/ViewShortcutListView.Designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/ViewShortcutListView.Designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/ViewShortcutListView.Designer.cs	(revision 11159)
@@ -0,0 +1,60 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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 ViewShortcutListView {
+    /// <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.SuspendLayout();
+      // 
+      // ViewShortcutListView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.Name = "ViewShortcutListView";
+      this.Size = new System.Drawing.Size(532, 383);
+      this.ResumeLayout(false);
+    }
+
+    #endregion
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing.Views/3.4/ViewShortcutListView.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing.Views/3.4/ViewShortcutListView.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing.Views/3.4/ViewShortcutListView.cs	(revision 11159)
@@ -0,0 +1,57 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.DataPreprocessing.Views {
+  [View("ViewShortcutCollection View")]
+  [Content(typeof(IItemList<IViewShortcut>), true)]
+  public partial class ViewShortcutListView : ItemListView<IViewShortcut> {
+
+    public ViewShortcutListView() {
+      InitializeComponent();
+      itemsGroupBox.Text = "View Shortcuts";
+    }
+
+    //Open item in new tab on double click
+    //Clone chart items
+    protected override void itemsListView_DoubleClick(object sender, EventArgs e) {
+      if (itemsListView.SelectedItems.Count == 1) {
+        IViewShortcut item = itemsListView.SelectedItems[0].Tag as IViewShortcut;
+        if (item != null) {
+
+          if (item is IViewChartShortcut)
+            item = (IViewChartShortcut)item.Clone(new Cloner());
+
+          IContentView view = MainFormManager.MainForm.ShowContent(item);
+          if (view != null) {
+            view.ReadOnly = ReadOnly;
+            view.Locked = Locked;
+          }
+        }
+      }
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/HeuristicLab.DataPreprocessing-3.4.csproj
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/HeuristicLab.DataPreprocessing-3.4.csproj	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/HeuristicLab.DataPreprocessing-3.4.csproj	(revision 11159)
@@ -0,0 +1,190 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{3B90F866-70F8-43EF-A541-51819D255B7B}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.DataPreprocessing</RootNamespace>
+    <AssemblyName>HeuristicLab.DataPreprocessing-3.4</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <UseVSHostingProcess>false</UseVSHostingProcess>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <PlatformTarget>x64</PlatformTarget>
+    <OutputPath>..\..\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <PlatformTarget>x64</PlatformTarget>
+    <OutputPath>..\..\bin\</OutputPath>
+    <Optimize>true</Optimize>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>..\..\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Drawing" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Implementations\ScatterPlotContent.cs" />
+    <Compile Include="Implementations\DataCompletenessChartContent.cs" />
+    <Compile Include="Implementations\FilteredPreprocessingData.cs" />
+    <Compile Include="Implementations\ManipulationContent.cs" />
+    <Compile Include="Implementations\PreprocessingChartContent.cs" />
+    <Compile Include="Implementations\PreprocessingData.cs" />
+    <Compile Include="Implementations\PreprocessingDataTable.cs" />
+    <Compile Include="Interfaces\IViewChartShortcut.cs" />
+    <Compile Include="Interfaces\IFilteredPreprocessingData.cs" />
+    <Compile Include="Implementations\CorrelationMatrixContent.cs" />
+    <Compile Include="PreprocessingTransformator.cs" />
+    <Compile Include="Utils\DataPreprocessingChangedEvent.cs" />
+    <Compile Include="Implementations\Filter\ComparisonFilter.cs" />
+    <Compile Include="Implementations\Filter\IFilter.cs" />
+    <Compile Include="Implementations\ManipulationLogic.cs" />
+    <Compile Include="Interfaces\IPreprocessingData.cs" />
+    <Compile Include="Interfaces\IDataGridLogic.cs" />
+    <Compile Include="Implementations\FilterContent.cs" />
+    <Compile Include="Implementations\FilterLogic.cs" />
+    <Compile Include="Implementations\HistogramContent.cs" />
+    <Compile Include="Implementations\LineChartContent.cs" />
+    <Compile Include="Implementations\StatisticsContent.cs" />
+    <Compile Include="Implementations\TransformationContent.cs" />
+    <Compile Include="Interfaces\IFilterLogic.cs" />
+    <Compile Include="Interfaces\IManipulationLogic.cs" />
+    <Compile Include="Interfaces\ITransformationLogic.cs" />
+    <Compile Include="Interfaces\IViewShortcut.cs" />
+    <Compile Include="ProblemDataCreator.cs" />
+    <None Include="Plugin.cs.frame" />
+    <Compile Include="Implementations\DataGridContent.cs" />
+    <Compile Include="Implementations\PreprocessingContext.cs" />
+    <Compile Include="Implementations\TransactionalPreprocessingData.cs" />
+    <Compile Include="Implementations\SearchLogic.cs" />
+    <Compile Include="Implementations\StatisticsLogic.cs" />
+    <Compile Include="Interfaces\IDataGridContent.cs" />
+    <Compile Include="Interfaces\IPreprocessingContext.cs" />
+    <Compile Include="Interfaces\ISearchLogic.cs" />
+    <Compile Include="Interfaces\IStatisticsLogic.cs" />
+    <Compile Include="Interfaces\ITransactionalPreprocessingData.cs" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
+      <Project>{887425b4-4348-49ed-a457-b7d2c26ddbf9}</Project>
+      <Name>HeuristicLab.Analysis-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Collections\3.3\HeuristicLab.Collections-3.3.csproj">
+      <Project>{958b43bc-cc5c-4fa2-8628-2b3b01d890b6}</Project>
+      <Name>HeuristicLab.Collections-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common.Resources\3.3\HeuristicLab.Common.Resources-3.3.csproj">
+      <Project>{0e27a536-1c4a-4624-a65e-dc4f4f23e3e1}</Project>
+      <Name>HeuristicLab.Common.Resources-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common\3.3\HeuristicLab.Common-3.3.csproj">
+      <Project>{a9ad58b9-3ef9-4cc1-97e5-8d909039ff5c}</Project>
+      <Name>HeuristicLab.Common-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Core\3.3\HeuristicLab.Core-3.3.csproj">
+      <Project>{c36bd924-a541-4a00-afa8-41701378ddc5}</Project>
+      <Name>HeuristicLab.Core-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
+      <Project>{bbab9df5-5ef3-4ba8-ade9-b36e82114937}</Project>
+      <Name>HeuristicLab.Data-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
+      <Project>{14ab8d24-25bc-400c-a846-4627aa945192}</Project>
+      <Name>HeuristicLab.Optimization-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.PluginInfrastructure\3.3\HeuristicLab.PluginInfrastructure-3.3.csproj">
+      <Project>{94186a6a-5176-4402-ae83-886557b53cca}</Project>
+      <Name>HeuristicLab.PluginInfrastructure-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis\3.4\HeuristicLab.Problems.DataAnalysis-3.4.csproj">
+      <Project>{df87c13e-a889-46ff-8153-66dcaa8c5674}</Project>
+      <Name>HeuristicLab.Problems.DataAnalysis-3.4</Name>
+      <Private>False</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd
+</PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
+  </PropertyGroup>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/CorrelationMatrixContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/CorrelationMatrixContent.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/CorrelationMatrixContent.cs	(revision 11159)
@@ -0,0 +1,64 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 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.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.DataPreprocessing {
+  [Item("Feature Correlation Matrix", "Represents the feature correlation matrix.")]
+  public class CorrelationMatrixContent : Item, IViewChartShortcut {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Gradient; }
+    }
+
+    private IPreprocessingContext Context { get; set; }
+    private ITransactionalPreprocessingData PreprocessingData {
+      get { return Context.Data; }
+    }
+
+    public DataAnalysisProblemData ProblemData {
+      get {
+        var creator = new ProblemDataCreator(Context);
+        return (DataAnalysisProblemData)creator.CreateProblemData();
+      }
+    }
+
+    public CorrelationMatrixContent(IPreprocessingContext context) {
+      Context = context;
+    }
+
+    public CorrelationMatrixContent(CorrelationMatrixContent original, Cloner cloner)
+      : base(original, cloner) {
+        Context = original.Context;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CorrelationMatrixContent(this, cloner);
+    }
+
+    public event DataPreprocessingChangedEventHandler Changed {
+      add { PreprocessingData.Changed += value; }
+      remove { PreprocessingData.Changed -= value; }
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/DataCompletenessChartContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/DataCompletenessChartContent.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/DataCompletenessChartContent.cs	(revision 11159)
@@ -0,0 +1,29 @@
+﻿using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.DataPreprocessing {
+  [Item("DataCompletenessChart", "Represents a datacompleteness chart.")]
+
+  public class DataCompletenessChartContent : Item, IViewChartShortcut {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.EditBrightnessContrast; }
+    }
+
+    public IDataGridLogic DataGridLogic { get; private set; }
+    public ISearchLogic SearchLogic { get; private set; }
+
+    public DataCompletenessChartContent(SearchLogic searchLogic) {
+      SearchLogic = searchLogic;
+    }
+
+    public DataCompletenessChartContent(DataCompletenessChartContent content, Cloner cloner)
+      : base(content, cloner) {
+      SearchLogic = content.SearchLogic;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DataCompletenessChartContent(this, cloner);
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/DataGridContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/DataGridContent.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/DataGridContent.cs	(revision 11159)
@@ -0,0 +1,164 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Drawing;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.DataPreprocessing {
+
+  [Item("DataGrid", "Represents a data grid.")]
+  public class DataGridContent : Item, IViewShortcut, IDataGridContent {
+
+    public ITransactionalPreprocessingData PreProcessingData { get; private set; }
+
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Table; }
+    }
+
+    public IManipulationLogic ManipulationLogic { get; private set; }
+    public IFilterLogic FilterLogic { get; private set; }
+
+    private IEnumerable<string> rowNames;
+
+    public int Rows {
+      get {
+        return PreProcessingData.Rows;
+      }
+      set {
+        //does nothing
+      }
+    }
+
+    public int Columns {
+      get {
+        return PreProcessingData.Columns;
+      }
+      set {
+        //does nothing
+      }
+    }
+
+    public IEnumerable<string> ColumnNames {
+      get {
+        return PreProcessingData.VariableNames;
+      }
+      set {
+
+      }
+    }
+
+    public IEnumerable<string> RowNames {
+      get {
+        return rowNames;
+      }
+      set {
+        //not supported
+      }
+    }
+
+    public bool SortableView {
+      get {
+        return true;
+      }
+      set {
+        //not supported
+      }
+    }
+
+    public bool ReadOnly {
+      get { return false; }
+    }
+
+
+    public IDictionary<int, IList<int>> Selection {
+      get { return PreProcessingData.Selection; }
+      set { PreProcessingData.Selection = value; }
+    }
+
+
+    public DataGridContent(ITransactionalPreprocessingData preProcessingData, IManipulationLogic theManipulationLogic, IFilterLogic theFilterLogic) {
+      ManipulationLogic = theManipulationLogic;
+      FilterLogic = theFilterLogic;
+      PreProcessingData = preProcessingData;
+      createRowNames();
+    }
+
+    public DataGridContent(DataGridContent dataGridContent, Cloner cloner)
+      : base(dataGridContent, cloner) {
+
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DataGridContent(this, cloner);
+    }
+
+    public void DeleteRow(IEnumerable<int> rows) {
+      PreProcessingData.DeleteRowsWithIndices(rows);
+      createRowNames();
+    }
+
+    public bool Validate(string value, out string errorMessage, int columnIndex) {
+      return PreProcessingData.Validate(value, out errorMessage, columnIndex);
+    }
+
+    public string GetValue(int rowIndex, int columnIndex) {
+      return PreProcessingData.GetCellAsString(columnIndex, rowIndex);
+    }
+
+    public bool SetValue(string value, int rowIndex, int columnIndex) {
+      return PreProcessingData.SetValue(value, columnIndex, rowIndex);
+    }
+
+    private void createRowNames() {
+      rowNames = Enumerable.Range(1, Rows).Select(n => n.ToString());
+    }
+
+    public event DataPreprocessingChangedEventHandler Changed {
+      add { PreProcessingData.Changed += value; }
+      remove { PreProcessingData.Changed -= value; }
+    }
+
+
+    #region unused stuff/not implemented but necessary due to IStringConvertibleMatrix
+#pragma warning disable 0067
+    // Is not used since DataGridContentView overrides dataGridView_CellValidating and uses 
+    // DataGridLogic#Validate(string value, out string errorMessage, int columnIndex)
+    public bool Validate(string value, out string errorMessage) {
+      errorMessage = string.Empty;
+      return true;
+    }
+
+    public event EventHandler ColumnsChanged;
+    public event EventHandler RowsChanged;
+    public event EventHandler ColumnNamesChanged;
+    public event EventHandler RowNamesChanged;
+    public event EventHandler SortableViewChanged;
+    public event EventHandler<EventArgs<int, int>> ItemChanged;
+    public event EventHandler Reset;
+
+#pragma warning restore 0067
+    #endregion
+
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/Filter/ComparisonFilter.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/Filter/ComparisonFilter.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/Filter/ComparisonFilter.cs	(revision 11159)
@@ -0,0 +1,140 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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 HeuristicLab.Common;
+using HeuristicLab.Common.Resources;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.DataPreprocessing.Filter {
+  [Item("ComparisonFilter", "A filter which compares the member of the preprocessing data with the constraint data.")]
+  public class ComparisonFilter : ComparisonConstraint, IFilter {
+
+    public override string ItemName {
+      get { return "ComparisonFilter"; }
+    }
+
+    public override Image ItemImage {
+      get { return VSImageLibrary.Filter; }
+    }
+
+    public new IPreprocessingData ConstrainedValue {
+      get { return (IPreprocessingData)base.ConstrainedValue; }
+      set { base.ConstrainedValue = value; }
+    }
+
+    public new IStringConvertibleValue ConstraintData {
+      get { return (IStringConvertibleValue)base.ConstraintData; }
+      set {
+        if (!(value is IComparable))
+          throw new ArgumentException("Only IComparables allowed for ConstraintData");
+        base.ConstraintData = value;
+      }
+    }
+
+    public ComparisonFilter() : base() { }
+    protected ComparisonFilter(bool deserializing) : base(deserializing) { }
+
+    public ComparisonFilter(IPreprocessingData constrainedValue, ConstraintOperation constraintOperation, object constraintData)
+      : base(constrainedValue, constraintOperation, constraintData) {
+    }
+
+    public ComparisonFilter(IPreprocessingData constrainedValue, ConstraintOperation constraintOperation, object constraintData, bool active)
+      : base(constrainedValue, constraintOperation, constraintData, active) {
+    }
+
+    protected ComparisonFilter(ComparisonFilter original, Cloner cloner)
+      : base(original, cloner) {
+      constraintColumn = original.constraintColumn;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ComparisonFilter(this, cloner);
+    }
+
+    private int constraintColumn;
+    public int ConstraintColumn {
+      get { return constraintColumn; }
+      set {
+        if (ConstrainedValue.Columns < value)
+          throw new ArgumentException("Could not set ConstraintData to not existing column index.");
+
+        if (constraintColumn != value) {
+          constraintColumn = value;
+          this.OnConstraintColumnChanged();
+          this.OnToStringChanged();
+        }
+      }
+    }
+
+    public new bool[] Check() {
+      bool[] result = new bool[ConstrainedValue.Rows];
+
+      if (!Active)
+        return result;
+
+      for (int row = 0; row < ConstrainedValue.Rows; ++row) {
+        object item = null;
+        if (ConstrainedValue.VariableHasType<double>(constraintColumn)) {
+          item = new HeuristicLab.Data.DoubleValue(ConstrainedValue.GetCell<double>(ConstraintColumn, row));
+        } else if (ConstrainedValue.VariableHasType<DateTime>(constraintColumn)) {
+          item = new HeuristicLab.Data.DateTimeValue(ConstrainedValue.GetCell<DateTime>(ConstraintColumn, row));
+        } else {
+          item = new StringValue(ConstrainedValue.GetCell<string>(ConstraintColumn, row));
+        }
+
+        result[row] = !base.Check(item);
+      }
+
+      return result;
+    }
+
+    public new bool[] Check(out string errorMessage) {
+      errorMessage = string.Empty;
+      return this.Check();
+    }
+
+    public override string ToString() {
+      string s = string.Empty;
+      if (ConstrainedValue != null)
+        s += ConstrainedValue.GetVariableName(ConstraintColumn) + " ";
+
+      if (ConstraintOperation != null)
+        s += ConstraintOperation.ToString() + " ";
+
+      if (ConstraintData != null)
+        s += ConstraintData.ToString();
+      else
+        s += "null";
+
+      s += ".";
+      return s;
+    }
+
+    public event EventHandler ConstraintColumnChanged;
+    protected virtual void OnConstraintColumnChanged() {
+      EventHandler handler = ConstraintColumnChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/Filter/IFilter.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/Filter/IFilter.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/Filter/IFilter.cs	(revision 11159)
@@ -0,0 +1,14 @@
+﻿using HeuristicLab.Core;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace HeuristicLab.DataPreprocessing.Filter
+{
+  public interface IFilter : IConstraint
+  {
+    new bool[] Check();
+    new bool[] Check(out string errorMessage);
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/FilterContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/FilterContent.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/FilterContent.cs	(revision 11159)
@@ -0,0 +1,70 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.DataPreprocessing.Filter;
+
+namespace HeuristicLab.DataPreprocessing {
+  [Item("Filter", "Represents the filter grid.")]
+  public class FilterContent : Item, IViewShortcut {
+
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Filter; }
+    }
+
+    private ICheckedItemCollection<IFilter> filters = new CheckedItemCollection<IFilter>();
+
+    public IFilterLogic FilterLogic { get; private set; }
+
+    public ICheckedItemCollection<IFilter> Filters {
+      get {
+        return this.filters;
+      }
+      set {
+        this.filters = value;
+      }
+    }
+
+    private bool isAndCombination = true;
+    public bool IsAndCombination {
+      get {
+        return this.isAndCombination;
+      }
+      set {
+        this.isAndCombination = value;
+      }
+    }
+
+    public FilterContent(IFilterLogic filterLogic) {
+      FilterLogic = filterLogic;
+    }
+
+    protected FilterContent(FilterContent content, Cloner cloner)
+      : base(content, cloner) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new FilterContent(this, cloner);
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/FilterLogic.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/FilterLogic.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/FilterLogic.cs	(revision 11159)
@@ -0,0 +1,96 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.DataPreprocessing.Filter;
+using HeuristicLab.DataPreprocessing.Interfaces;
+namespace HeuristicLab.DataPreprocessing {
+  public class FilterLogic : IFilterLogic {
+
+    public IFilteredPreprocessingData PreprocessingData { get; private set; }
+
+    public bool IsFiltered {
+      get {
+        return PreprocessingData.IsFiltered;
+      }
+    }
+
+    public FilterLogic(IFilteredPreprocessingData preprocessingData) {
+      PreprocessingData = preprocessingData;
+    }
+
+    public bool[] GetFilterResult(IList<IFilter> filters, bool isAndCombination) {
+      IList<IFilter> activeFilters = filters.Where(f => f.Active && f.ConstraintData != null).ToList<IFilter>();
+
+      if (activeFilters.Count == 0) {
+        return CreateBoolArray(PreprocessingData.Rows, false);
+      }
+      return GetActiveFilterResult(activeFilters, isAndCombination);
+    }
+
+    private bool[] GetActiveFilterResult(IList<IFilter> activeFilters, bool isAndCombination) {
+      bool[] result = CreateBoolArray(PreprocessingData.Rows, !isAndCombination);
+
+      foreach (IFilter filter in activeFilters) {
+        bool[] filterResult = filter.Check();
+        for (int row = 0; row < result.Length; ++row) {
+          result[row] = Result(result[row], filterResult[row], isAndCombination);
+        }
+      }
+      return result;
+    }
+
+    public bool[] Preview(IList<IFilter> filters, bool isAndCombination) {
+      IList<IFilter> activeFilters = filters.Where(f => f.Active && f.ConstraintData != null).ToList<IFilter>();
+      if (activeFilters.Count > 0) {
+        var result = GetActiveFilterResult(activeFilters, isAndCombination);
+        PreprocessingData.SetFilter(result);
+        return result;
+      } else {
+        return CreateBoolArray(PreprocessingData.Rows, false);
+      }
+    }
+
+    public bool[] CreateBoolArray(int rows, bool value) {
+      return Enumerable.Repeat<bool>(value, rows).ToArray();
+    }
+
+    public bool Result(bool current, bool addition, bool isAndCombination) {
+      return isAndCombination ? current || addition : current && addition;
+    }
+
+    public void Apply(IList<IFilter> filters, bool isAndCombination) {
+      PreprocessingData.PersistFilter();
+      Reset();
+    }
+
+    public void Reset() {
+      PreprocessingData.ResetFilter();
+    }
+
+    public event EventHandler FilterChanged {
+      add { PreprocessingData.FilterChanged += value; }
+      remove { PreprocessingData.FilterChanged -= value; }
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/FilteredPreprocessingData.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/FilteredPreprocessingData.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/FilteredPreprocessingData.cs	(revision 11159)
@@ -0,0 +1,250 @@
+﻿using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.DataPreprocessing.Interfaces;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.DataPreprocessing.Implementations {
+  public class FilteredPreprocessingData : NamedItem, IFilteredPreprocessingData {
+    private readonly ITransactionalPreprocessingData originalData;
+    private ITransactionalPreprocessingData filteredData;
+
+    public IntRange TrainingPartition {
+      get { return originalData.TrainingPartition; }
+    }
+
+    public IntRange TestPartition {
+      get { return originalData.TestPartition; }
+    }
+
+    public IList<ITransformation> Transformations {
+      get { return originalData.Transformations; }
+    }
+
+    public IEnumerable<string> VariableNames {
+      get { return ActiveData.VariableNames; }
+    }
+
+    public IDictionary<int, IList<int>> Selection {
+      get { return originalData.Selection; }
+      set { originalData.Selection = value; }
+    }
+
+    public int Columns {
+      get { return ActiveData.Columns; }
+    }
+
+    public int Rows {
+      get { return ActiveData.Rows; }
+    }
+
+    public ITransactionalPreprocessingData ActiveData {
+      get { return IsFiltered ? filteredData : originalData; }
+    }
+
+    public bool IsUndoAvailable {
+      get { return IsFiltered ? false : originalData.IsUndoAvailable; }
+    }
+
+    public bool IsFiltered {
+      get { return filteredData != null; }
+    }
+
+
+    public FilteredPreprocessingData(ITransactionalPreprocessingData preporcessingData)
+      : base() {
+      originalData = preporcessingData;
+      filteredData = null;
+    }
+
+    protected FilteredPreprocessingData(FilteredPreprocessingData original, Cloner cloner)
+      : base(original, cloner) {
+      originalData = original.originalData;
+      filteredData = original.filteredData;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new FilteredPreprocessingData(this, cloner);
+    }
+
+    public T GetCell<T>(int columnIndex, int rowIndex) {
+      return ActiveData.GetCell<T>(columnIndex, rowIndex);
+    }
+
+    public void SetCell<T>(int columnIndex, int rowIndex, T value) {
+      if (IsFiltered)
+        throw new InvalidOperationException("SetValues not possible while data is filtered");
+      originalData.SetCell<T>(columnIndex, rowIndex, value);
+    }
+
+    public string GetCellAsString(int columnIndex, int rowIndex) {
+      return ActiveData.GetCellAsString(columnIndex, rowIndex);
+    }
+
+    public IList<T> GetValues<T>(string variableName, bool considerSelection) {
+      return ActiveData.GetValues<T>(variableName, considerSelection);
+    }
+
+    public IList<T> GetValues<T>(int columnIndex, bool considerSelection) {
+      return ActiveData.GetValues<T>(columnIndex, considerSelection);
+    }
+
+    public void SetValues<T>(int columnIndex, IList<T> values) {
+      if (IsFiltered)
+        throw new InvalidOperationException("SetValues not possible while data is filtered");
+
+      originalData.SetValues<T>(columnIndex, values);
+    }
+
+    public void InsertRow(int rowIndex) {
+      if (IsFiltered)
+        throw new InvalidOperationException("InsertRow not possible while data is filtered");
+
+      originalData.InsertRow(rowIndex);
+    }
+
+    public void DeleteRow(int rowIndex) {
+      if (IsFiltered)
+        throw new InvalidOperationException("DeleteRow not possible while data is filtered");
+
+      originalData.DeleteRow(rowIndex);
+    }
+
+    public void InsertColumn<T>(string variableName, int columnIndex) {
+      if (IsFiltered)
+        throw new InvalidOperationException("InsertColumn not possible while data is filtered");
+
+      originalData.InsertColumn<T>(variableName, columnIndex);
+    }
+
+    public void DeleteColumn(int columnIndex) {
+      if (IsFiltered)
+        throw new InvalidOperationException("DeleteColumn not possible while data is filtered");
+      originalData.DeleteColumn(columnIndex);
+    }
+
+    public string GetVariableName(int columnIndex) {
+      return ActiveData.GetVariableName(columnIndex);
+    }
+
+    public int GetColumnIndex(string variableName) {
+      return ActiveData.GetColumnIndex(variableName);
+    }
+
+    public bool VariableHasType<T>(int columnIndex) {
+      return originalData.VariableHasType<T>(columnIndex);
+    }
+
+    public Dataset ExportToDataset() {
+      return originalData.ExportToDataset();
+    }
+
+    public void SetFilter(bool[] rowFilters) {
+      filteredData = (ITransactionalPreprocessingData)originalData.Clone();
+      filteredData.InTransaction(() => {
+        for (int row = (rowFilters.Length - 1); row >= 0; --row) {
+          if (rowFilters[row]) {
+            filteredData.DeleteRow(row);
+          }
+        }
+      });
+      OnFilterChanged();
+    }
+
+    public void PersistFilter() {
+      originalData.InTransaction(() => {
+        for (int i = 0; i < filteredData.Columns; ++i) {
+          if (filteredData.VariableHasType<double>(i)) {
+            originalData.SetValues<double>(i, filteredData.GetValues<double>(i));
+          } else if (filteredData.VariableHasType<string>(i)) {
+            originalData.SetValues<string>(i, filteredData.GetValues<string>(i));
+          } else if (filteredData.VariableHasType<DateTime>(i)) {
+            originalData.SetValues<DateTime>(i, filteredData.GetValues<DateTime>(i));
+          } else {
+            throw new ArgumentException("Data types of columns do not match");
+          }
+        }
+      });
+      ResetFilter();
+    }
+
+    public void ResetFilter() {
+      filteredData = null;
+      OnFilterChanged();
+    }
+
+    private void OnFilterChanged() {
+      if (FilterChanged != null) {
+        FilterChanged(this, new EventArgs());
+      }
+    }
+
+    public event DataPreprocessingChangedEventHandler Changed {
+      add { originalData.Changed += value; }
+      remove { originalData.Changed -= value; }
+    }
+
+    public bool SetValue(string value, int columnIndex, int rowIndex) {
+      if (IsFiltered)
+        throw new InvalidOperationException("SetValue not possible while data is filtered");
+      return originalData.SetValue(value, columnIndex, rowIndex);
+    }
+
+    public bool AreAllStringColumns(IEnumerable<int> columnIndices) {
+      return originalData.AreAllStringColumns(columnIndices);
+    }
+
+    public void DeleteRowsWithIndices(IEnumerable<int> rows) {
+      if (IsFiltered)
+        throw new InvalidOperationException("DeleteRowsWithIndices not possible while data is filtered");
+
+      originalData.DeleteRowsWithIndices(rows);
+    }
+
+    public void Undo() {
+      if (IsFiltered)
+        throw new InvalidOperationException("Undo not possible while data is filtered");
+
+      originalData.Undo();
+    }
+
+    public void InTransaction(Action action, DataPreprocessingChangedEventType type = DataPreprocessingChangedEventType.Any) {
+      if (IsFiltered)
+        throw new InvalidOperationException("Transaction not possible while data is filtered");
+      originalData.InTransaction(action, type);
+    }
+
+    public void BeginTransaction(DataPreprocessingChangedEventType type) {
+      if (IsFiltered)
+        throw new InvalidOperationException("Transaction not possible while data is filtered");
+      originalData.BeginTransaction(type);
+    }
+
+    public void EndTransaction() {
+      originalData.EndTransaction();
+    }
+
+    public IEnumerable<string> GetDoubleVariableNames() {
+      return originalData.GetDoubleVariableNames();
+    }
+
+    public void ClearSelection() {
+      originalData.ClearSelection();
+    }
+
+    public event EventHandler SelectionChanged {
+      add { originalData.SelectionChanged += value; }
+      remove { originalData.SelectionChanged -= value; }
+    }
+
+    #region IPreprocessingData Members
+
+    public bool Validate(string value, out string errorMessage, int columnIndex) {
+      return originalData.Validate(value, out errorMessage, columnIndex);
+    }
+
+    public event EventHandler FilterChanged;
+    #endregion
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/HistogramContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/HistogramContent.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/HistogramContent.cs	(revision 11159)
@@ -0,0 +1,74 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Drawing;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.DataPreprocessing.Interfaces;
+
+namespace HeuristicLab.DataPreprocessing {
+  [Item("Histogram", "Represents the histogram grid.")]
+  public class HistogramContent : PreprocessingChartContent {
+
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Statistics; }
+    }
+    private const int MAX_DISTINCT_VALUES_FOR_CLASSIFCATION = 20;
+
+    private int classifierVariableIndex = 0;
+
+    public int ClassifierVariableIndex {
+      get { return this.classifierVariableIndex; }
+      set { this.classifierVariableIndex = value; }
+    }
+
+
+    public HistogramContent(IFilteredPreprocessingData preprocessingData)
+      : base(preprocessingData) {
+      AllInOneMode = false;
+    }
+
+    public HistogramContent(HistogramContent content, Cloner cloner)
+      : base(content, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new HistogramContent(this, cloner);
+    }
+
+    public IEnumerable<string> GetVariableNamesForHistogramClassification() {
+      List<string> doubleVariableNames = new List<string>();
+
+      //only return variable names from type double
+      for (int i = 0; i < PreprocessingData.Columns; ++i) {
+        if (PreprocessingData.VariableHasType<double>(i)) {
+          double distinctValueCount = PreprocessingData.GetValues<double>(i).GroupBy(x => x).Count();
+          bool distinctValuesOk = distinctValueCount <= MAX_DISTINCT_VALUES_FOR_CLASSIFCATION;
+          if (distinctValuesOk)
+            doubleVariableNames.Add(PreprocessingData.GetVariableName(i));
+        }
+      }
+      return doubleVariableNames;
+    }
+
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/LineChartContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/LineChartContent.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/LineChartContent.cs	(revision 11159)
@@ -0,0 +1,47 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.DataPreprocessing.Interfaces;
+
+namespace HeuristicLab.DataPreprocessing {
+
+  [Item("LineChart", "Represents the line chart grid.")]
+  public class LineChartContent : PreprocessingChartContent {
+
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Performance; }
+    }
+
+    public LineChartContent(IFilteredPreprocessingData preprocessingData)
+      : base(preprocessingData) {
+    }
+
+    public LineChartContent(LineChartContent content, Cloner cloner)
+      : base(content, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LineChartContent(this, cloner);
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/ManipulationContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/ManipulationContent.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/ManipulationContent.cs	(revision 11159)
@@ -0,0 +1,57 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.DataPreprocessing {
+
+  [Item("Manipulation", "Represents the available manipulations on a data set.")]
+  public class ManipulationContent : Item, IViewShortcut {
+
+    private IManipulationLogic manipulationLogic;
+    private ISearchLogic searchLogic;
+    private IFilterLogic filterLogic;
+
+    public IManipulationLogic ManipulationLogic { get { return manipulationLogic; } }
+    public ISearchLogic SearchLogic { get { return searchLogic; } }
+    public IFilterLogic FilterLogic { get { return filterLogic; } }
+
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Method; }
+    }
+
+    public ManipulationContent(IManipulationLogic theManipulationLogic, ISearchLogic theSearchLogic, IFilterLogic theFitlerLogic) {
+      manipulationLogic = theManipulationLogic;
+      searchLogic = theSearchLogic;
+      filterLogic = theFitlerLogic;
+    }
+
+    public ManipulationContent(ManipulationContent content, Cloner cloner) : base(content, cloner) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ManipulationContent(this, cloner);
+    }
+
+
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/ManipulationLogic.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/ManipulationLogic.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/ManipulationLogic.cs	(revision 11159)
@@ -0,0 +1,405 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Data;
+
+namespace HeuristicLab.DataPreprocessing {
+  public class ManipulationLogic : IManipulationLogic {
+    private readonly ITransactionalPreprocessingData preprocessingData;
+    private readonly IStatisticsLogic statisticsLogic;
+    private readonly ISearchLogic searchLogic;
+
+    public IEnumerable<string> VariableNames {
+      get { return preprocessingData.VariableNames; }
+    }
+
+    public ITransactionalPreprocessingData PreProcessingData {
+      get { return preprocessingData; }
+    }
+
+    public ManipulationLogic(ITransactionalPreprocessingData _prepocessingData, ISearchLogic theSearchLogic, IStatisticsLogic theStatisticsLogic) {
+      preprocessingData = _prepocessingData;
+      searchLogic = theSearchLogic;
+      statisticsLogic = theStatisticsLogic;
+    }
+
+    public void ReplaceIndicesByValue<T>(int columnIndex, IEnumerable<int> rowIndices, T value) {
+      foreach (int index in rowIndices) {
+        preprocessingData.SetCell<T>(columnIndex, index, value);
+      }
+    }
+
+    public void ReplaceIndicesByAverageValue(IDictionary<int, IList<int>> cells, bool considerSelection) {
+      preprocessingData.InTransaction(() => {
+        foreach (var column in cells) {
+          if (preprocessingData.VariableHasType<double>(column.Key)) {
+            double average = statisticsLogic.GetAverage(column.Key, considerSelection);
+            ReplaceIndicesByValue<double>(column.Key, column.Value, average);
+          } else if (preprocessingData.VariableHasType<DateTime>(column.Key)) {
+            DateTime average = statisticsLogic.GetAverageDateTime(column.Key, considerSelection);
+            ReplaceIndicesByValue<DateTime>(column.Key, column.Value, average);
+          }
+        }
+      });
+    }
+
+    public void ReplaceIndicesByMedianValue(IDictionary<int, IList<int>> cells, bool considerSelection) {
+      preprocessingData.InTransaction(() => {
+        foreach (var column in cells) {
+          if (preprocessingData.VariableHasType<double>(column.Key)) {
+            double median = statisticsLogic.GetMedian(column.Key, considerSelection);
+            ReplaceIndicesByValue<double>(column.Key, column.Value, median);
+          } else if (preprocessingData.VariableHasType<DateTime>(column.Key)) {
+            DateTime median = statisticsLogic.GetMedianDateTime(column.Key, considerSelection);
+            ReplaceIndicesByValue<DateTime>(column.Key, column.Value, median);
+          }
+        }
+      });
+    }
+
+    public void ReplaceIndicesByRandomValue(IDictionary<int, IList<int>> cells, bool considerSelection) {
+      preprocessingData.InTransaction(() => {
+        Random r = new Random();
+
+        foreach (var column in cells) {
+          if (preprocessingData.VariableHasType<double>(column.Key)) {
+            double max = statisticsLogic.GetMax<double>(column.Key, considerSelection);
+            double min = statisticsLogic.GetMin<double>(column.Key, considerSelection);
+            double randMultiplier = (max - min);
+            foreach (int index in column.Value) {
+              double rand = r.NextDouble() * randMultiplier + min;
+              preprocessingData.SetCell<double>(column.Key, index, rand);
+            }
+          } else if (preprocessingData.VariableHasType<DateTime>(column.Key)) {
+            DateTime min = statisticsLogic.GetMin<DateTime>(column.Key, considerSelection);
+            DateTime max = statisticsLogic.GetMax<DateTime>(column.Key, considerSelection);
+            double randMultiplier = (max - min).TotalSeconds;
+            foreach (int index in column.Value) {
+              double rand = r.NextDouble() * randMultiplier;
+              preprocessingData.SetCell<DateTime>(column.Key, index, min.AddSeconds(rand));
+            }
+          }
+        }
+      });
+    }
+
+    public void ReplaceIndicesByLinearInterpolationOfNeighbours(IDictionary<int, IList<int>> cells) {
+      preprocessingData.InTransaction(() => {
+        foreach (var column in cells) {
+          int countValues = 0;
+          if (preprocessingData.VariableHasType<double>(column.Key)) {
+            countValues = preprocessingData.GetValues<double>(column.Key).Count();
+          } else if (preprocessingData.VariableHasType<DateTime>(column.Key)) {
+            countValues = preprocessingData.GetValues<DateTime>(column.Key).Count();
+          }
+
+          IList<Tuple<int, int>> startEndings = GetStartAndEndingsForInterpolation(column);
+          foreach (var tuple in startEndings) {
+            Interpolate(column, tuple.Item1, tuple.Item2);
+          }
+        }
+      });
+    }
+
+    private List<Tuple<int, int>> GetStartAndEndingsForInterpolation(KeyValuePair<int, IList<int>> column) {
+      List<Tuple<int, int>> startEndings = new List<Tuple<int, int>>();
+      var rowIndices = column.Value;
+      rowIndices = rowIndices.OrderBy(x => x).ToList();
+      var count = rowIndices.Count;
+      int start = int.MinValue;
+      for (int i = 0; i < count; ++i) {
+        if (start == int.MinValue) {
+          start = indexOfPrevPresentValue(column.Key, rowIndices[i]);
+        }
+        if (i + 1 == count || (i + 1 < count && rowIndices[i + 1] - rowIndices[i] > 1)) {
+          int next = indexOfNextPresentValue(column.Key, rowIndices[i]);
+          if (start > 0 && next < preprocessingData.Rows) {
+            startEndings.Add(new Tuple<int, int>(start, next));
+          }
+          start = int.MinValue;
+        }
+      }
+      return startEndings;
+    }
+
+    public void ReplaceIndicesBySmoothing(IDictionary<int, IList<int>> cells) {
+      preprocessingData.InTransaction(() => {
+        foreach (var column in cells) {
+          int countValues = preprocessingData.Rows;
+
+          foreach (int index in column.Value) {
+            // dont replace first or last values
+            if (index > 0 && index < countValues) {
+              int prevIndex = indexOfPrevPresentValue(column.Key, index);
+              int nextIndex = indexOfNextPresentValue(column.Key, index);
+
+              // no neighbours found
+              if (prevIndex < 0 || nextIndex >= countValues) {
+                continue;
+              }
+
+              Interpolate(column, prevIndex, nextIndex);
+            }
+          }
+        }
+      });
+    }
+
+    private void Interpolate(KeyValuePair<int, IList<int>> column, int prevIndex, int nextIndex) {
+      int valuesToInterpolate = nextIndex - prevIndex;
+
+      if (preprocessingData.VariableHasType<double>(column.Key)) {
+        double prev = preprocessingData.GetCell<double>(column.Key, prevIndex);
+        double next = preprocessingData.GetCell<double>(column.Key, nextIndex);
+        double interpolationStep = (next - prev) / valuesToInterpolate;
+
+        for (int i = prevIndex; i < nextIndex; ++i) {
+          double interpolated = prev + (interpolationStep * (i - prevIndex));
+          preprocessingData.SetCell<double>(column.Key, i, interpolated);
+        }
+      } else if (preprocessingData.VariableHasType<DateTime>(column.Key)) {
+        DateTime prev = preprocessingData.GetCell<DateTime>(column.Key, prevIndex);
+        DateTime next = preprocessingData.GetCell<DateTime>(column.Key, nextIndex);
+        double interpolationStep = (next - prev).TotalSeconds / valuesToInterpolate;
+
+        for (int i = prevIndex; i < nextIndex; ++i) {
+          DateTime interpolated = prev.AddSeconds(interpolationStep * (i - prevIndex));
+          preprocessingData.SetCell<DateTime>(column.Key, i, interpolated);
+        }
+      }
+    }
+
+    private int indexOfPrevPresentValue(int columnIndex, int start) {
+      int offset = start - 1;
+      while (offset >= 0 && searchLogic.IsMissingValue(columnIndex, offset)) {
+        offset--;
+      }
+
+      return offset;
+    }
+
+    private int indexOfNextPresentValue(int columnIndex, int start) {
+      int offset = start + 1;
+      while (offset < preprocessingData.Rows && searchLogic.IsMissingValue(columnIndex, offset)) {
+        offset++;
+      }
+
+      return offset;
+    }
+
+    public void ReplaceIndicesByMostCommonValue(IDictionary<int, IList<int>> cells, bool considerSelection) {
+      preprocessingData.InTransaction(() => {
+        foreach (var column in cells) {
+          if (preprocessingData.VariableHasType<double>(column.Key)) {
+            ReplaceIndicesByValue<double>(column.Key, column.Value, statisticsLogic.GetMostCommonValue<double>(column.Key, considerSelection));
+          } else if (preprocessingData.VariableHasType<string>(column.Key)) {
+            ReplaceIndicesByValue<string>(column.Key, column.Value, statisticsLogic.GetMostCommonValue<string>(column.Key, considerSelection));
+          } else if (preprocessingData.VariableHasType<DateTime>(column.Key)) {
+            ReplaceIndicesByValue<DateTime>(column.Key, column.Value, statisticsLogic.GetMostCommonValue<DateTime>(column.Key, considerSelection));
+          } else {
+            throw new ArgumentException("column with index: " + column.Key + " contains a non supported type.");
+          }
+        }
+      });
+    }
+
+    public void ShuffleWithRanges() {
+      ShuffleWithRanges(new[] {
+        preprocessingData.TestPartition,
+        preprocessingData.TrainingPartition
+      });
+    }
+
+    public void ShuffleWithRanges(IEnumerable<IntRange> ranges) {
+      // init random outside loop
+      Random random = new Random();
+
+      preprocessingData.InTransaction(() => {
+        // process all given ranges - e.g. TrainingPartition, TestPartition
+        foreach (IntRange range in ranges) {
+          List<Tuple<int, int>> shuffledIndices = new List<Tuple<int, int>>();
+
+          // generate random indices used for shuffeling each column
+          for (int i = range.End - 1; i >= range.Start; --i) {
+            int rand = random.Next(range.Start, i);
+            shuffledIndices.Add(new Tuple<int, int>(i, rand));
+          }
+
+          ShuffleToIndices(shuffledIndices);
+        }
+      });
+    }
+
+    public void ReOrderToIndices(IEnumerable<int> indices) {
+      List<Tuple<int, int>> indicesTuple = new List<Tuple<int, int>>();
+
+      for (int i = 0; i < indices.Count(); ++i) {
+        indicesTuple.Add(new Tuple<int, int>(i, indices.ElementAt(i)));
+      }
+
+      ReOrderToIndices(indicesTuple);
+    }
+
+    public void ReOrderToIndices(IList<System.Tuple<int, int>> indices) {
+      preprocessingData.InTransaction(() => {
+        for (int i = 0; i < preprocessingData.Columns; ++i) {
+          if (preprocessingData.VariableHasType<double>(i)) {
+            reOrderToIndices<double>(i, indices);
+          } else if (preprocessingData.VariableHasType<string>(i)) {
+            reOrderToIndices<string>(i, indices);
+          } else if (preprocessingData.VariableHasType<DateTime>(i)) {
+            reOrderToIndices<DateTime>(i, indices);
+          }
+        }
+      });
+    }
+
+    public void ShuffleToIndices(IList<System.Tuple<int, int>> indices) {
+      preprocessingData.InTransaction(() => {
+        for (int i = 0; i < preprocessingData.Columns; ++i) {
+          if (preprocessingData.VariableHasType<double>(i)) {
+            ShuffleToIndices<double>(i, indices);
+          } else if (preprocessingData.VariableHasType<string>(i)) {
+            ShuffleToIndices<string>(i, indices);
+          } else if (preprocessingData.VariableHasType<DateTime>(i)) {
+            ShuffleToIndices<DateTime>(i, indices);
+          }
+        }
+      });
+    }
+
+    private void reOrderToIndices<T>(int columnIndex, IList<Tuple<int, int>> indices) {
+
+      List<T> originalData = new List<T>(preprocessingData.GetValues<T>(columnIndex));
+
+      // process all columns equally
+      foreach (Tuple<int, int> index in indices) {
+        int originalIndex = index.Item1;
+        int replaceIndex = index.Item2;
+
+        T replaceValue = originalData.ElementAt<T>(replaceIndex);
+        preprocessingData.SetCell<T>(columnIndex, originalIndex, replaceValue);
+      }
+    }
+
+    private void ShuffleToIndices<T>(int columnIndex, IList<Tuple<int, int>> indices) {
+      // process all columns equally
+      foreach (Tuple<int, int> index in indices) {
+        int originalIndex = index.Item1;
+        int replaceIndex = index.Item2;
+
+        T tmp = preprocessingData.GetCell<T>(columnIndex, originalIndex);
+        T replaceValue = preprocessingData.GetCell<T>(columnIndex, replaceIndex);
+
+        preprocessingData.SetCell<T>(columnIndex, originalIndex, replaceValue);
+        preprocessingData.SetCell<T>(columnIndex, replaceIndex, tmp);
+      }
+    }
+
+    public void ReplaceIndicesByValue(IDictionary<int, IList<int>> cells, string value) {
+      preprocessingData.InTransaction(() => {
+        foreach (var column in cells) {
+          foreach (var rowIdx in column.Value) {
+            preprocessingData.SetValue(value, column.Key, rowIdx);
+          }
+        }
+      });
+    }
+
+
+    public List<int> RowsWithMissingValuesGreater(double percent) {
+
+      List<int> rows = new List<int>();
+
+      for (int i = 0; i < preprocessingData.Rows; ++i) {
+        int missingCount = statisticsLogic.GetRowMissingValueCount(i);
+        if (100f / preprocessingData.Columns * missingCount > percent) {
+          rows.Add(i);
+        }
+      }
+
+      return rows;
+    }
+
+    public List<int> ColumnsWithMissingValuesGreater(double percent) {
+
+      List<int> columns = new List<int>();
+      for (int i = 0; i < preprocessingData.Columns; ++i) {
+        int missingCount = statisticsLogic.GetMissingValueCount(i);
+        if (100f / preprocessingData.Rows * missingCount > percent) {
+          columns.Add(i);
+        }
+      }
+
+      return columns;
+    }
+
+    public List<int> ColumnsWithVarianceSmaller(double variance) {
+
+      List<int> columns = new List<int>();
+      for (int i = 0; i < preprocessingData.Columns; ++i) {
+        if (preprocessingData.VariableHasType<double>(i) || preprocessingData.VariableHasType<DateTime>(i)) {
+          double columnVariance = statisticsLogic.GetVariance(i);
+          if (columnVariance < variance) {
+            columns.Add(i);
+          }
+        }
+      }
+      return columns;
+    }
+
+    public void DeleteRowsWithMissingValuesGreater(double percent) {
+      DeleteRows(RowsWithMissingValuesGreater(percent));
+    }
+
+    public void DeleteColumnsWithMissingValuesGreater(double percent) {
+      DeleteColumns(ColumnsWithMissingValuesGreater(percent));
+    }
+
+    public void DeleteColumnsWithVarianceSmaller(double variance) {
+      DeleteColumns(ColumnsWithVarianceSmaller(variance));
+    }
+
+    private void DeleteRows(List<int> rows) {
+      rows.Sort();
+      rows.Reverse();
+      preprocessingData.InTransaction(() => {
+        foreach (int row in rows) {
+          preprocessingData.DeleteRow(row);
+        }
+      });
+    }
+
+    private void DeleteColumns(List<int> columns) {
+      columns.Sort();
+      columns.Reverse();
+      preprocessingData.InTransaction(() => {
+        foreach (int column in columns) {
+          preprocessingData.DeleteColumn(column);
+        }
+      });
+    }
+
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingChartContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingChartContent.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingChartContent.cs	(revision 11159)
@@ -0,0 +1,142 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Drawing;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.DataPreprocessing.Interfaces;
+
+namespace HeuristicLab.DataPreprocessing {
+  [Item("PreprocessingChart", "Represents a preprocessing chart.")]
+  public class PreprocessingChartContent : Item, IViewChartShortcut {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.PieChart; }
+    }
+
+    private bool allInOneMode = true;
+    public bool AllInOneMode {
+      get { return this.allInOneMode; }
+      set { this.allInOneMode = value; }
+    }
+
+    private ICheckedItemList<StringValue> variableItemList = null;
+    public ICheckedItemList<StringValue> VariableItemList {
+      get { return this.variableItemList; }
+      set { this.variableItemList = value; }
+    }
+
+    public IFilteredPreprocessingData PreprocessingData { get; private set; }
+
+    public PreprocessingChartContent(IFilteredPreprocessingData preprocessingData) {
+      PreprocessingData = preprocessingData;
+    }
+
+    public PreprocessingChartContent(PreprocessingChartContent content, Cloner cloner)
+      : base(content, cloner) {
+      this.allInOneMode = content.allInOneMode;
+      this.PreprocessingData = content.PreprocessingData;
+      this.variableItemList = cloner.Clone<ICheckedItemList<StringValue>>(variableItemList);
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PreprocessingChartContent(this, cloner);
+    }
+
+
+    public DataRow CreateDataRow(string variableName, DataRowVisualProperties.DataRowChartType chartType) {
+      IList<double> values = PreprocessingData.GetValues<double>(PreprocessingData.GetColumnIndex(variableName));
+      DataRow row = new DataRow(variableName, "", values);
+      row.VisualProperties.ChartType = chartType;
+      return row;
+    }
+
+    public List<DataRow> CreateAllDataRows(DataRowVisualProperties.DataRowChartType chartType) {
+      List<DataRow> dataRows = new List<DataRow>();
+      foreach (var name in PreprocessingData.GetDoubleVariableNames())
+        dataRows.Add(CreateDataRow(name, chartType));
+      return dataRows;
+    }
+
+    public DataRow CreateSelectedDataRow(string variableName, DataRowVisualProperties.DataRowChartType chartType) {
+
+      IDictionary<int, IList<int>> selection = PreprocessingData.Selection;
+      int variableIndex = PreprocessingData.GetColumnIndex(variableName);
+
+      if (selection.Keys.Contains(variableIndex)) {
+        List<int> selectedIndices = new List<int>(selection[variableIndex]);
+        //need selection with more than 1 value
+        if (selectedIndices.Count < 2)
+          return null;
+
+        selectedIndices.Sort();
+        int start = selectedIndices[0];
+        int end = selectedIndices[selectedIndices.Count - 1];
+
+        DataRow rowSelect = CreateDataRowRange(variableName, start, end, chartType);
+        return rowSelect;
+      } else
+        return null;
+    }
+
+    public DataRow CreateDataRowRange(string variableName, int start, int end, DataRowVisualProperties.DataRowChartType chartType) {
+      IList<double> values = PreprocessingData.GetValues<double>(PreprocessingData.GetColumnIndex(variableName));
+      IList<double> valuesRange = new List<double>();
+      for (int i = 0; i < values.Count; i++) {
+        if (i >= start && i <= end)
+          valuesRange.Add(values[i]);
+        else
+          valuesRange.Add(Double.NaN);
+      }
+
+      DataRow row = new DataRow(variableName, "", valuesRange);
+      row.VisualProperties.ChartType = chartType;
+      return row;
+    }
+
+    public List<DataRow> CreateAllSelectedDataRows(DataRowVisualProperties.DataRowChartType chartType) {
+      List<DataRow> dataRows = new List<DataRow>();
+      foreach (var name in PreprocessingData.GetDoubleVariableNames()) {
+        DataRow row = CreateSelectedDataRow(name, chartType);
+        if (row != null)
+          dataRows.Add(row);
+      }
+      return dataRows;
+    }
+
+
+    public ICheckedItemList<StringValue> CreateVariableItemList() {
+      ICheckedItemList<StringValue> itemList = new CheckedItemList<StringValue>();
+      foreach (string name in PreprocessingData.GetDoubleVariableNames()) {
+        itemList.Add(new StringValue(name), true);
+      }
+      return new ReadOnlyCheckedItemList<StringValue>(itemList);
+    }
+
+    public event DataPreprocessingChangedEventHandler Changed {
+      add { PreprocessingData.Changed += value; }
+      remove { PreprocessingData.Changed -= value; }
+    }
+
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingContext.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingContext.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingContext.cs	(revision 11159)
@@ -0,0 +1,96 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Common;
+using HeuristicLab.Core;
+using HeuristicLab.DataPreprocessing.Implementations;
+using HeuristicLab.DataPreprocessing.Interfaces;
+using HeuristicLab.Optimization;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.DataPreprocessing {
+  [Item("PreprocessingContext", "PreprocessingContext")]
+  public class PreprocessingContext
+    : Item, IPreprocessingContext {
+
+
+    public IFilteredPreprocessingData Data { get; private set; }
+
+    public IAlgorithm Algorithm { get; private set; }
+    public IDataAnalysisProblem Problem { get; private set; }
+    public IDataAnalysisProblemData ProblemData { get; private set; }
+
+    private readonly ProblemDataCreator creator;
+
+    public PreprocessingContext(IDataAnalysisProblemData dataAnalysisProblemData, IAlgorithm algorithm, IDataAnalysisProblem problem) {
+      var transactionalPreprocessingData = new TransactionalPreprocessingData(dataAnalysisProblemData);
+      Data = new FilteredPreprocessingData(transactionalPreprocessingData);
+
+      ProblemData = dataAnalysisProblemData;
+      Algorithm = algorithm;
+      Problem = problem;
+
+      creator = new ProblemDataCreator(this);
+    }
+
+    protected PreprocessingContext(PreprocessingContext original, Cloner cloner)
+      : base(original, cloner) {
+      Data = cloner.Clone(original.Data);
+      Algorithm = original.Algorithm;
+      Problem = original.Problem;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PreprocessingContext(this, cloner);
+    }
+
+    public IItem Export() {
+      if (Algorithm != null)
+        return ExportAlgorithm();
+      else if (Problem != null)
+        return ExportProblem();
+      return ExportProblemData();
+    }
+    public IAlgorithm ExportAlgorithm() {
+      var preprocessedAlgorithm = (IAlgorithm)Algorithm.Clone(new Cloner());
+      preprocessedAlgorithm.Name = preprocessedAlgorithm.Name + "(Preprocessed)";
+      Algorithm.Runs.Clear();
+      var problem = (IDataAnalysisProblem)preprocessedAlgorithm.Problem;
+      SetNewProblemData(problem);
+      return preprocessedAlgorithm;
+    }
+    public IDataAnalysisProblem ExportProblem() {
+      var preprocessedProblem = (IDataAnalysisProblem)Problem.Clone(new Cloner());
+      SetNewProblemData(preprocessedProblem);
+      return preprocessedProblem;
+    }
+
+    public IDataAnalysisProblemData ExportProblemData() {
+      return creator.CreateProblemData();
+    }
+
+    private void SetNewProblemData(IDataAnalysisProblem problem) {
+      var data = creator.CreateProblemData();
+      problem.ProblemDataParameter.ActualValue = data;
+      problem.Name = "Preprocessed " + problem.Name;
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingData.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingData.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingData.cs	(revision 11159)
@@ -0,0 +1,212 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.DataPreprocessing {
+
+  [Item("PreprocessingData", "Represents data used for preprocessing.")]
+  public abstract class PreprocessingData : NamedItem, IPreprocessingData {
+
+    public IntRange TrainingPartition { get; set; }
+    public IntRange TestPartition { get; set; }
+
+    protected IList<ITransformation> transformations;
+    public IList<ITransformation> Transformations {
+      get { return transformations; }
+    }
+
+    protected IList<IList> variableValues;
+    protected IList<string> variableNames;
+
+    public IEnumerable<string> VariableNames {
+      get { return variableNames; }
+    }
+
+    public IEnumerable<string> GetDoubleVariableNames() {
+      var doubleVariableNames = new List<string>();
+      for (int i = 0; i < Columns; ++i) {
+        if (VariableHasType<double>(i)) {
+          doubleVariableNames.Add(variableNames[i]);
+        }
+      }
+      return doubleVariableNames;
+    }
+
+    public int Columns {
+      get { return variableNames.Count; }
+    }
+
+    public int Rows {
+      get { return variableValues.Count > 0 ? variableValues[0].Count : 0; }
+    }
+
+    protected IDictionary<int, IList<int>> selection;
+    public IDictionary<int, IList<int>> Selection {
+      get { return selection; }
+      set {
+        selection = value;
+        OnSelectionChanged();
+      }
+    }
+
+    protected PreprocessingData(PreprocessingData original, Cloner cloner)
+      : base(original, cloner) {
+      variableValues = CopyVariableValues(original.variableValues);
+      variableNames = new List<string>(original.variableNames);
+      TrainingPartition = (IntRange)original.TrainingPartition.Clone(cloner);
+      TestPartition = (IntRange)original.TestPartition.Clone(cloner);
+      transformations = new List<ITransformation>();
+
+      RegisterEventHandler();
+    }
+
+    protected PreprocessingData(IDataAnalysisProblemData problemData)
+      : base() {
+      Name = "Preprocessing Data";
+
+      transformations = new List<ITransformation>();
+      selection = new Dictionary<int, IList<int>>();
+
+      Dataset dataset = problemData.Dataset;
+      variableNames = new List<string>(problemData.Dataset.VariableNames);
+
+      int columnIndex = 0;
+      variableValues = new List<IList>();
+      foreach (var variableName in problemData.Dataset.VariableNames) {
+        if (dataset.VariableHasType<double>(variableName)) {
+          variableValues.Insert(columnIndex, dataset.GetDoubleValues(variableName).ToList());
+        } else if (dataset.VariableHasType<string>(variableName)) {
+          variableValues.Insert(columnIndex, dataset.GetStringValues(variableName).ToList());
+        } else if (dataset.VariableHasType<DateTime>(variableName)) {
+          variableValues.Insert(columnIndex, dataset.GetDateTimeValues(variableName).ToList());
+        } else {
+          throw new ArgumentException("The datatype of column " + variableName + " must be of type double, string or DateTime");
+        }
+        ++columnIndex;
+      }
+
+      TrainingPartition = new IntRange(problemData.TrainingPartition.Start, problemData.TrainingPartition.End);
+      TestPartition = new IntRange(problemData.TestPartition.Start, problemData.TestPartition.End);
+
+      RegisterEventHandler();
+    }
+
+    private void RegisterEventHandler() {
+      Changed += (s, e) => {
+        switch (e.Type) {
+          case DataPreprocessingChangedEventType.DeleteRow:
+            CheckPartitionRanges();
+            break;
+          case DataPreprocessingChangedEventType.Any:
+            CheckPartitionRanges();
+            break;
+          case DataPreprocessingChangedEventType.Transformation:
+            CheckPartitionRanges();
+            break;
+        }
+      };
+    }
+
+    private static IList CreateColumn<T>(Dataset ds, int column, Func<string, T> selector) {
+      var list = new List<T>(ds.Rows);
+      for (int row = 0; row < ds.Rows; ++row) {
+        list.Add(selector(ds.GetValue(row, column)));
+      }
+      return list;
+    }
+
+    private void CheckPartitionRanges() {
+      int maxRowIndex = Math.Max(0, Rows - 1);
+      TrainingPartition.Start = Math.Min(TrainingPartition.Start, maxRowIndex);
+      TrainingPartition.End = Math.Min(TrainingPartition.End, maxRowIndex);
+      TestPartition.Start = Math.Min(TestPartition.Start, maxRowIndex);
+      TestPartition.End = Math.Min(TestPartition.End, maxRowIndex);
+    }
+
+    protected IList<IList> CopyVariableValues(IList<IList> original) {
+      var copy = new List<IList>(original);
+      for (int i = 0; i < original.Count; ++i) {
+        copy[i] = (IList)Activator.CreateInstance(original[i].GetType(), original[i]);
+      }
+      return copy;
+    }
+
+
+    #region IPreprocessingData Members
+
+    public abstract T GetCell<T>(int columnIndex, int rowIndex);
+
+    public abstract void SetCell<T>(int columnIndex, int rowIndex, T value);
+
+    public abstract string GetCellAsString(int columnIndex, int rowIndex);
+
+    public abstract string GetVariableName(int columnIndex);
+
+    public abstract int GetColumnIndex(string variableName);
+
+    public abstract bool VariableHasType<T>(int columnIndex);
+
+    [Obsolete("use the index based variant, is faster")]
+    public abstract IList<T> GetValues<T>(string variableName, bool considerSelection);
+
+    public abstract IList<T> GetValues<T>(int columnIndex, bool considerSelection);
+
+    public abstract void SetValues<T>(int columnIndex, IList<T> values);
+
+    public abstract bool SetValue(string value, int columnIndex, int rowIndex);
+
+    public abstract bool Validate(string value, out string errorMessage, int columnIndex);
+
+    public abstract bool AreAllStringColumns(IEnumerable<int> columnIndices);
+
+    public abstract void DeleteRowsWithIndices(IEnumerable<int> rows);
+
+    public abstract void InsertRow(int rowIndex);
+
+    public abstract void DeleteRow(int rowIndex);
+
+    public abstract void InsertColumn<T>(string variableName, int columnIndex);
+
+    public abstract void DeleteColumn(int columnIndex);
+
+    public abstract Dataset ExportToDataset();
+
+    public abstract void ClearSelection();
+
+    public abstract event EventHandler SelectionChanged;
+    protected abstract void OnSelectionChanged();
+
+    public event DataPreprocessingChangedEventHandler Changed;
+    protected virtual void OnChanged(DataPreprocessingChangedEventType type, int column, int row) {
+      var listeners = Changed;
+      if (listeners != null) listeners(this, new DataPreprocessingChangedEventArgs(type, column, row));
+    }
+    #endregion
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingDataTable.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingDataTable.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingDataTable.cs	(revision 11159)
@@ -0,0 +1,37 @@
+﻿using System;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.DataPreprocessing.Implementations {
+  [Item("PreprossingDataTable", "A table of data values.")]
+  public class PreprocessingDataTable : DataTable {
+
+    public PreprocessingDataTable()
+      : base() {
+      SelectedRows = new NamedItemCollection<DataRow>();
+    }
+    public PreprocessingDataTable(string name)
+      : base(name) {
+      SelectedRows = new NamedItemCollection<DataRow>();
+    }
+
+    protected PreprocessingDataTable(PreprocessingDataTable original, Cloner cloner)
+      : base(original, cloner) {
+      this.selectedRows = cloner.Clone(original.selectedRows);
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PreprocessingDataTable(this, cloner);
+    }
+
+    private NamedItemCollection<DataRow> selectedRows;
+    public NamedItemCollection<DataRow> SelectedRows {
+      get { return selectedRows; }
+      private set {
+        if (selectedRows != null) throw new InvalidOperationException("Rows already set");
+        selectedRows = value;
+      }
+    }
+
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/ScatterPlotContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/ScatterPlotContent.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/ScatterPlotContent.cs	(revision 11159)
@@ -0,0 +1,74 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Drawing;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.DataPreprocessing.Interfaces;
+
+namespace HeuristicLab.DataPreprocessing {
+
+  [Item("ScatterPlot", "Represents a scatter plot.")]
+  public class ScatterPlotContent : PreprocessingChartContent {
+
+    public string SelectedXVariable { get; set; }
+    public string SelectedYVariable { get; set; }
+
+    public ScatterPlotContent(IFilteredPreprocessingData preprocessingData)
+      : base(preprocessingData) {
+    }
+
+    public ScatterPlotContent(ScatterPlotContent content, Cloner cloner)
+      : base(content, cloner) {
+      this.SelectedXVariable = content.SelectedXVariable;
+      this.SelectedYVariable = content.SelectedYVariable;
+    }
+
+    public static new Image StaticItemImage
+    {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Performance; }
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ScatterPlotContent(this, cloner);
+    }
+
+    public ScatterPlot CreateScatterPlot(string variableNameX, string variableNameY) {
+      ScatterPlot scatterPlot = new ScatterPlot();
+
+      IList<double> xValues = PreprocessingData.GetValues<double>(PreprocessingData.GetColumnIndex(variableNameX));
+      IList<double> yValues = PreprocessingData.GetValues<double>(PreprocessingData.GetColumnIndex(variableNameY));
+
+      List<Point2D<double>> points = new List<Point2D<double>>();
+
+      for (int i = 0; i < xValues.Count; i++) {
+        Point2D<double> point = new Point2D<double>(xValues[i], yValues[i]);
+        points.Add(point);
+      }
+
+      ScatterPlotDataRow scdr = new ScatterPlotDataRow(variableNameX + " - " + variableNameY, "", points);
+      scatterPlot.Rows.Add(scdr);
+      return scatterPlot;
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/SearchLogic.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/SearchLogic.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/SearchLogic.cs	(revision 11159)
@@ -0,0 +1,153 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace HeuristicLab.DataPreprocessing {
+  public class SearchLogic : ISearchLogic {
+    private readonly ITransactionalPreprocessingData preprocessingData;
+
+    private Dictionary<int, IList<int>> MissingValueIndicies { get; set; }
+    private Dictionary<int, IList> ValuesWithoutNaN { get; set; }
+
+    public IEnumerable<string> VariableNames {
+      get { return preprocessingData.VariableNames; }
+    }
+
+    public int Columns {
+      get { return preprocessingData.Columns; }
+    }
+
+    public int Rows {
+      get { return preprocessingData.Rows; }
+    }
+
+    public SearchLogic(ITransactionalPreprocessingData thePreprocessingData) {
+      preprocessingData = thePreprocessingData;
+
+      MissingValueIndicies = new Dictionary<int, IList<int>>();
+      ValuesWithoutNaN = new Dictionary<int, IList>();
+
+      preprocessingData.Changed += preprocessingData_Changed;
+    }
+
+    void preprocessingData_Changed(object sender, DataPreprocessingChangedEventArgs e)
+    {
+      switch (e.Type) {
+        case DataPreprocessingChangedEventType.DeleteColumn:
+        case DataPreprocessingChangedEventType.ChangeColumn:
+          MissingValueIndicies.Remove(e.Column);
+          ValuesWithoutNaN.Remove(e.Column);
+          break;
+        case DataPreprocessingChangedEventType.AddColumn:
+          //cache does not need to be updated, will be calculated the first time it is requested
+          break;
+        case DataPreprocessingChangedEventType.DeleteRow:
+        case DataPreprocessingChangedEventType.AddRow:
+        case DataPreprocessingChangedEventType.ChangeItem:
+        case DataPreprocessingChangedEventType.Any:
+        case DataPreprocessingChangedEventType.Transformation:
+        default:
+          MissingValueIndicies = new Dictionary<int, IList<int>>();
+          ValuesWithoutNaN = new Dictionary<int, IList>();
+          break;
+      } 
+    }
+
+    public IDictionary<int, IList<int>> GetMissingValueIndices() {
+      var dic = new Dictionary<int, IList<int>>();
+      for (int i = 0; i < preprocessingData.Columns; ++i) {
+        dic.Add(i, GetMissingValueIndices(i));
+      }
+      return dic;
+    }
+
+    public bool IsMissingValue(int columnIndex, int rowIndex) {
+      if (preprocessingData.VariableHasType<double>(columnIndex)) {
+        return double.IsNaN(preprocessingData.GetCell<double>(columnIndex, rowIndex));
+      } else if (preprocessingData.VariableHasType<string>(columnIndex)) {
+        return string.IsNullOrEmpty(preprocessingData.GetCell<string>(columnIndex, rowIndex));
+      } else if (preprocessingData.VariableHasType<DateTime>(columnIndex)) {
+        return preprocessingData.GetCell<DateTime>(columnIndex, rowIndex).Equals(DateTime.MinValue);
+      } else {
+        throw new ArgumentException("cell in column " + columnIndex + " and row index " + rowIndex + " contains a non supported type.");
+      }
+    }
+
+    public IList<int> GetMissingValueIndices(int columnIndex) {
+      if (!MissingValueIndicies.ContainsKey(columnIndex)){        
+          if (preprocessingData.VariableHasType<double>(columnIndex)) {
+            MissingValueIndicies[columnIndex] = GetMissingValueIndices<double>(columnIndex);
+          } else if (preprocessingData.VariableHasType<string>(columnIndex)) {
+            MissingValueIndicies[columnIndex] = GetMissingValueIndices<string>(columnIndex);
+          } else if (preprocessingData.VariableHasType<DateTime>(columnIndex)) {
+            MissingValueIndicies[columnIndex] = GetMissingValueIndices<DateTime>(columnIndex);
+          } else {
+            throw new ArgumentException("column " + columnIndex + " contains a non supported type.");
+          }
+      } 
+
+      return MissingValueIndicies[columnIndex];
+   }
+    private IList<int> GetMissingValueIndices<T>(int columnIndex) {
+      List<int> missingIndices = new List<int>();
+     
+      for(int row = 0; row < preprocessingData.Rows; ++row) {
+        if (IsMissingValue(columnIndex, row)) {
+          missingIndices.Add(row);
+        }
+      }
+
+      return missingIndices;
+    }
+
+    public IEnumerable<T> GetValuesWithoutNaN<T>(int columnIndex, bool considerSelection)
+    {
+      if (considerSelection) {     
+        var selectedRows =  preprocessingData.Selection[columnIndex];
+        
+        List<T> values = new List<T>();
+        foreach (var rowIdx in selectedRows) {
+          if (!IsMissingValue(columnIndex, rowIdx)) {
+            values.Add(preprocessingData.GetCell<T>(columnIndex, rowIdx));
+          }
+        }
+        return values;
+      } else {
+        if (!ValuesWithoutNaN.ContainsKey(columnIndex)) {
+          List<T> values = new List<T>();
+
+          for (int row = 0; row < preprocessingData.Rows; ++row) {
+            if (!IsMissingValue(columnIndex, row)) {
+              values.Add(preprocessingData.GetCell<T>(columnIndex, row));
+            }
+          }
+
+          ValuesWithoutNaN[columnIndex] = values;
+        }
+        return (IEnumerable<T>)ValuesWithoutNaN[columnIndex];
+      }
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/StatisticsContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/StatisticsContent.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/StatisticsContent.cs	(revision 11159)
@@ -0,0 +1,57 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.DataPreprocessing {
+  [Item("Statistics", "Represents the statistics grid.")]
+  public class StatisticsContent : Item, IViewShortcut {
+
+    private readonly IStatisticsLogic statisticsLogic;
+    public StatisticsContent(IStatisticsLogic theStatisticsLogic) {
+      statisticsLogic = theStatisticsLogic;
+    }
+
+    public StatisticsContent(StatisticsContent content, Cloner cloner)
+      : base(content, cloner) {
+
+    }
+
+    public IStatisticsLogic StatisticsLogic {
+      get { return statisticsLogic; }
+    }
+
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Object; }
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new StatisticsContent(this, cloner);
+    }
+
+    public event DataPreprocessingChangedEventHandler Changed {
+      add { statisticsLogic.Changed += value; }
+      remove { statisticsLogic.Changed -= value; }
+    }
+
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/StatisticsLogic.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/StatisticsLogic.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/StatisticsLogic.cs	(revision 11159)
@@ -0,0 +1,198 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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;
+
+namespace HeuristicLab.DataPreprocessing {
+
+  public class StatisticsLogic : IStatisticsLogic {
+
+    private readonly ITransactionalPreprocessingData preprocessingData;
+    private readonly ISearchLogic searchLogic;
+
+    public StatisticsLogic(ITransactionalPreprocessingData thePreprocessingData, ISearchLogic theSearchLogic) {
+      preprocessingData = thePreprocessingData;
+      searchLogic = theSearchLogic;
+    }
+
+    public int GetColumnCount() {
+      return preprocessingData.Columns;
+    }
+
+    public int GetRowCount() {
+      return preprocessingData.Rows;
+    }
+
+    public int GetNumericColumnCount() {
+      int count = 0;
+
+      for (int i = 0; i < preprocessingData.Columns; ++i) {
+        if (preprocessingData.VariableHasType<double>(i)) {
+          ++count;
+        }
+      }
+      return count;
+    }
+
+    public int GetNominalColumnCount() {
+      return preprocessingData.Columns - GetNumericColumnCount();
+    }
+
+    public int GetMissingValueCount() {
+      int count = 0;
+      for (int i = 0; i < preprocessingData.Columns; ++i) {
+        count += GetMissingValueCount(i);
+      }
+      return count;
+    }
+
+    public int GetMissingValueCount(int columnIndex) {
+      return searchLogic.GetMissingValueIndices(columnIndex).Count();
+    }
+
+    public T GetMin<T>(int columnIndex, bool considerSelection) where T : IComparable<T> {
+      return preprocessingData.GetValues<T>(columnIndex, considerSelection).Min();
+    }
+
+    public T GetMax<T>(int columnIndex, bool considerSelection) where T : IComparable<T> {
+      return preprocessingData.GetValues<T>(columnIndex, considerSelection).Max();
+    }
+
+    public double GetMedian(int columnIndex, bool considerSelection) {
+      double median = double.NaN;
+      if (preprocessingData.VariableHasType<double>(columnIndex)) {
+        median = GetValuesWithoutNaN<double>(columnIndex, considerSelection).Median();
+      }
+      return median;
+    }
+
+    public double GetAverage(int columnIndex, bool considerSelection) {
+      double avg = double.NaN;
+      if (preprocessingData.VariableHasType<double>(columnIndex)) {
+        avg = GetValuesWithoutNaN<double>(columnIndex, considerSelection).Average();
+      }
+      return avg;
+    }
+
+    public DateTime GetMedianDateTime(int columnIndex, bool considerSelection) {
+      DateTime median = new DateTime();
+      if (preprocessingData.VariableHasType<DateTime>(columnIndex)) {
+        median = GetSecondsAsDateTime(GetDateTimeAsSeconds(columnIndex, considerSelection).Median());
+      }
+      return median;
+    }
+
+    public DateTime GetAverageDateTime(int columnIndex, bool considerSelection) {
+      DateTime avg = new DateTime();
+      if (preprocessingData.VariableHasType<DateTime>(columnIndex)) {
+        avg = GetSecondsAsDateTime(GetDateTimeAsSeconds(columnIndex, considerSelection).Average());
+      }
+      return avg;
+    }
+
+    public T GetMostCommonValue<T>(int columnIndex, bool considerSelection) {
+      var t = preprocessingData.GetValues<T>(columnIndex, considerSelection);
+      var t2 = t.GroupBy(x => x);
+      var t3 = t2.Select(g => g.Key);
+
+      return preprocessingData.GetValues<T>(columnIndex, considerSelection)
+                              .GroupBy(x => x)
+                              .OrderByDescending(g => g.Count())
+                              .Select(g => g.Key)
+                              .First();
+    }
+
+
+    public double GetStandardDeviation(int columnIndex) {
+      double stdDev = double.NaN;
+      if (preprocessingData.VariableHasType<double>(columnIndex)) {
+        stdDev = GetValuesWithoutNaN<double>(columnIndex).StandardDeviation();
+      } else if (preprocessingData.VariableHasType<DateTime>(columnIndex)) {
+        stdDev = GetDateTimeAsSeconds(columnIndex).StandardDeviation();
+      }
+      return stdDev;
+    }
+
+    public double GetVariance(int columnIndex) {
+      double variance = double.NaN;
+      if (preprocessingData.VariableHasType<double>(columnIndex)) {
+        variance = GetValuesWithoutNaN<double>(columnIndex).Variance();
+      } else if (preprocessingData.VariableHasType<DateTime>(columnIndex)) {
+        variance = GetDateTimeAsSeconds(columnIndex).Variance();
+      }
+      return variance;
+    }
+
+    public int GetDifferentValuesCount<T>(int columnIndex) {
+      return preprocessingData.GetValues<T>(columnIndex).GroupBy(x => x).Count();
+    }
+
+    public int GetRowMissingValueCount(int rowIndex) {
+      int count = 0;
+      for (int i = 0; i < preprocessingData.Columns; ++i) {
+        if (searchLogic.IsMissingValue(i, rowIndex)) {
+          ++count;
+        }
+      }
+      return count;
+    }
+
+    public string GetVariableName(int columnIndex) {
+      return preprocessingData.GetVariableName(columnIndex);
+    }
+
+    public bool VariableHasType<T>(int columnIndex) {
+      return preprocessingData.VariableHasType<T>(columnIndex);
+    }
+
+    public string GetColumnTypeAsString(int columnIndex) {
+      if (preprocessingData.VariableHasType<double>(columnIndex)) {
+        return "double";
+      } else if (preprocessingData.VariableHasType<string>(columnIndex)) {
+        return "string";
+      } else if (preprocessingData.VariableHasType<DateTime>(columnIndex)) {
+        return "DateTime";
+      }
+      return "Unknown Type";
+    }
+
+    private IEnumerable<double> GetDateTimeAsSeconds(int columnIndex, bool considerSelection = false) {
+      return GetValuesWithoutNaN<DateTime>(columnIndex, considerSelection).Select(x => (double)x.Ticks / TimeSpan.TicksPerSecond);
+    }
+
+    private IEnumerable<T> GetValuesWithoutNaN<T>(int columnIndex, bool considerSelection = false) {
+      return searchLogic.GetValuesWithoutNaN<T>(columnIndex, considerSelection);
+    }
+
+    private DateTime GetSecondsAsDateTime(double seconds) {
+      DateTime dateTime = new DateTime();
+      return dateTime.AddSeconds(seconds);
+    }
+
+    public event DataPreprocessingChangedEventHandler Changed {
+      add { preprocessingData.Changed += value; }
+      remove { preprocessingData.Changed -= value; }
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/TransactionalPreprocessingData.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/TransactionalPreprocessingData.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/TransactionalPreprocessingData.cs	(revision 11159)
@@ -0,0 +1,325 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.DataPreprocessing {
+  [Item("PreprocessingData", "Represents data used for preprocessing.")]
+  public class TransactionalPreprocessingData : PreprocessingData, ITransactionalPreprocessingData {
+
+    private class Snapshot {
+      public IList<IList> VariableValues { get; set; }
+      public IList<string> VariableNames { get; set; }
+
+      public IntRange TrainingPartition { get; set; }
+      public IntRange TestPartition { get; set; }
+      public IList<ITransformation> Transformations { get; set; }
+      public DataPreprocessingChangedEventType ChangedType { get; set; }
+
+      public int ChangedColumn { get; set; }
+      public int ChangedRow { get; set; }
+    }
+
+    private const int MAX_UNDO_DEPTH = 5;
+
+    private readonly IList<Snapshot> undoHistory = new List<Snapshot>();
+    private readonly Stack<DataPreprocessingChangedEventType> eventStack = new Stack<DataPreprocessingChangedEventType>();
+
+    public bool IsInTransaction { get { return eventStack.Count > 0; } }
+
+    public TransactionalPreprocessingData(IDataAnalysisProblemData problemData)
+      : base(problemData) {
+    }
+
+    protected TransactionalPreprocessingData(TransactionalPreprocessingData original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    private void SaveSnapshot(DataPreprocessingChangedEventType changedType, int column, int row) {
+      if (IsInTransaction) return;
+
+      var currentSnapshot = new Snapshot {
+        VariableValues = CopyVariableValues(variableValues),
+        VariableNames = new List<string>(variableNames),
+        TrainingPartition = new IntRange(TrainingPartition.Start, TrainingPartition.End),
+        TestPartition = new IntRange(TestPartition.Start, TestPartition.End),
+        Transformations = new List<ITransformation>(transformations),
+        ChangedType = changedType,
+        ChangedColumn = column,
+        ChangedRow = row
+      };
+
+      if (undoHistory.Count >= MAX_UNDO_DEPTH)
+        undoHistory.RemoveAt(0);
+
+      undoHistory.Add(currentSnapshot);
+    }
+
+    #region NamedItem abstract Member Implementations
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TransactionalPreprocessingData(this, cloner);
+    }
+
+    #endregion
+
+    #region Overridden IPreprocessingData Members
+
+    public override T GetCell<T>(int columnIndex, int rowIndex) {
+      return (T)variableValues[columnIndex][rowIndex];
+    }
+
+    public override void SetCell<T>(int columnIndex, int rowIndex, T value) {
+      SaveSnapshot(DataPreprocessingChangedEventType.ChangeItem, columnIndex, rowIndex);
+      variableValues[columnIndex][rowIndex] = value;
+      if (!IsInTransaction)
+        OnChanged(DataPreprocessingChangedEventType.ChangeItem, columnIndex, rowIndex);
+    }
+
+    public override string GetCellAsString(int columnIndex, int rowIndex) {
+      return variableValues[columnIndex][rowIndex].ToString();
+    }
+
+    public override string GetVariableName(int columnIndex) {
+      return variableNames[columnIndex];
+    }
+
+    public override int GetColumnIndex(string variableName) {
+      return variableNames.IndexOf(variableName);
+    }
+
+    public override bool VariableHasType<T>(int columnIndex) {
+      return variableValues[columnIndex] is List<T>;
+    }
+
+    [Obsolete("use the index based variant, is faster")]
+    public override IList<T> GetValues<T>(string variableName, bool considerSelection) {
+      return GetValues<T>(GetColumnIndex(variableName), considerSelection);
+    }
+
+    public override IList<T> GetValues<T>(int columnIndex, bool considerSelection) {
+      if (considerSelection) {
+        var list = new List<T>();
+        foreach (var rowIdx in selection[columnIndex]) {
+          list.Add((T)variableValues[columnIndex][rowIdx]);
+        }
+        return list;
+      } else {
+        return (IList<T>)variableValues[columnIndex];
+      }
+    }
+
+    public override void SetValues<T>(int columnIndex, IList<T> values) {
+      SaveSnapshot(DataPreprocessingChangedEventType.ChangeColumn, columnIndex, -1);
+      if (VariableHasType<T>(columnIndex)) {
+        variableValues[columnIndex] = (IList)values;
+      } else {
+        throw new ArgumentException("The datatype of column " + columnIndex + " must be of type " + variableValues[columnIndex].GetType().Name + " but was " + typeof(T).Name);
+      }
+      if (!IsInTransaction)
+        OnChanged(DataPreprocessingChangedEventType.ChangeColumn, columnIndex, -1);
+    }
+
+    public override bool SetValue(string value, int columnIndex, int rowIndex) {
+      bool valid = false;
+      if (VariableHasType<double>(columnIndex)) {
+        double val;
+        valid = double.TryParse(value, out val);
+        SetValueIfValid(columnIndex, rowIndex, valid, val);
+      } else if (VariableHasType<string>(columnIndex)) {
+        valid = value != null;
+        SetValueIfValid(columnIndex, rowIndex, valid, value);
+      } else if (VariableHasType<DateTime>(columnIndex)) {
+        DateTime date;
+        valid = DateTime.TryParse(value, out date);
+        SetValueIfValid(columnIndex, rowIndex, valid, date);
+      } else {
+        throw new ArgumentException("column " + columnIndex + " contains a non supported type.");
+      }
+
+      if (!IsInTransaction)
+        OnChanged(DataPreprocessingChangedEventType.ChangeColumn, columnIndex, -1);
+
+      return valid;
+    }
+
+    public override bool Validate(string value, out string errorMessage, int columnIndex) {
+      if (columnIndex < 0 || columnIndex > VariableNames.Count()) {
+        throw new ArgumentOutOfRangeException("column index is out of range");
+      }
+
+      bool valid = false;
+      errorMessage = string.Empty;
+      if (VariableHasType<double>(columnIndex)) {
+        double val;
+        valid = double.TryParse(value, out val);
+        if (!valid) {
+          errorMessage = "Invalid Value (Valid Value Format: \"" + FormatPatterns.GetDoubleFormatPattern() + "\")";
+        }
+      } else if (VariableHasType<string>(columnIndex)) {
+        valid = value != null;
+        if (!valid) {
+          errorMessage = "Invalid Value (string must not be null)";
+        }
+      } else if (VariableHasType<DateTime>(columnIndex)) {
+        DateTime date;
+        valid = DateTime.TryParse(value, out date);
+        if (!valid) {
+          errorMessage = "Invalid Value (Valid Value Format: \"" + CultureInfo.CurrentCulture.DateTimeFormat + "\"";
+        }
+      } else {
+        throw new ArgumentException("column " + columnIndex + " contains a non supported type.");
+      }
+
+      return valid;
+    }
+
+    private void SetValueIfValid<T>(int columnIndex, int rowIndex, bool valid, T value) {
+      if (valid)
+        SetCell<T>(columnIndex, rowIndex, value);
+    }
+
+    public override bool AreAllStringColumns(IEnumerable<int> columnIndices) {
+      return columnIndices.All(x => VariableHasType<string>(x));
+    }
+
+    public override void DeleteRowsWithIndices(IEnumerable<int> rows) {
+      SaveSnapshot(DataPreprocessingChangedEventType.AddRow, -1, -1);
+      foreach (int rowIndex in rows.OrderByDescending(x => x)) {
+        foreach (IList column in variableValues) {
+          column.RemoveAt(rowIndex);
+        }
+      }
+      if (!IsInTransaction)
+        OnChanged(DataPreprocessingChangedEventType.DeleteRow, -1, -1);
+    }
+
+    public override void InsertRow(int rowIndex) {
+      SaveSnapshot(DataPreprocessingChangedEventType.DeleteRow, -1, rowIndex);
+      foreach (IList column in variableValues) {
+        Type type = column.GetType().GetGenericArguments()[0];
+        column.Insert(rowIndex, type.IsValueType ? Activator.CreateInstance(type) : null);
+      }
+      if (!IsInTransaction)
+        OnChanged(DataPreprocessingChangedEventType.AddRow, -1, rowIndex);
+    }
+
+    public override void DeleteRow(int rowIndex) {
+      SaveSnapshot(DataPreprocessingChangedEventType.AddRow, -1, rowIndex);
+      foreach (IList column in variableValues) {
+        column.RemoveAt(rowIndex);
+      }
+      if (!IsInTransaction)
+        OnChanged(DataPreprocessingChangedEventType.DeleteRow, -1, rowIndex);
+    }
+
+    public override void InsertColumn<T>(string variableName, int columnIndex) {
+      SaveSnapshot(DataPreprocessingChangedEventType.DeleteColumn, columnIndex, -1);
+      variableValues.Insert(columnIndex, new List<T>(Rows));
+      variableNames.Insert(columnIndex, variableName);
+      if (!IsInTransaction)
+        OnChanged(DataPreprocessingChangedEventType.AddColumn, columnIndex, -1);
+    }
+
+    public override void DeleteColumn(int columnIndex) {
+      SaveSnapshot(DataPreprocessingChangedEventType.AddColumn, columnIndex, -1);
+      variableValues.RemoveAt(columnIndex);
+      variableNames.RemoveAt(columnIndex);
+      if (!IsInTransaction)
+        OnChanged(DataPreprocessingChangedEventType.DeleteColumn, columnIndex, -1);
+    }
+
+    public override Dataset ExportToDataset() {
+      IList<IList> values = new List<IList>();
+
+      for (int i = 0; i < Columns; ++i) {
+        values.Add(variableValues[i]);
+      }
+
+      var dataset = new Dataset(variableNames, values);
+      return dataset;
+    }
+
+    public override void ClearSelection() {
+      Selection = new Dictionary<int, IList<int>>();
+    }
+
+    public override event EventHandler SelectionChanged;
+
+    protected override void OnSelectionChanged() {
+      var listeners = SelectionChanged;
+      if (listeners != null) listeners(this, EventArgs.Empty);
+    }
+
+
+    #endregion
+
+    #region TransactionalPreprocessingData members
+
+    public bool IsUndoAvailable {
+      get { return undoHistory.Count > 0; }
+    }
+
+    public void Undo() {
+      if (IsUndoAvailable) {
+        Snapshot previousSnapshot = undoHistory[undoHistory.Count - 1];
+        variableValues = previousSnapshot.VariableValues;
+        variableNames = previousSnapshot.VariableNames;
+        TrainingPartition = previousSnapshot.TrainingPartition;
+        TestPartition = previousSnapshot.TestPartition;
+        transformations = previousSnapshot.Transformations;
+        undoHistory.Remove(previousSnapshot);
+        OnChanged(previousSnapshot.ChangedType,
+          previousSnapshot.ChangedColumn,
+          previousSnapshot.ChangedRow);
+      }
+    }
+
+    public void InTransaction(Action action, DataPreprocessingChangedEventType type = DataPreprocessingChangedEventType.Any) {
+      BeginTransaction(type);
+      action();
+      EndTransaction();
+    }
+
+    public void BeginTransaction(DataPreprocessingChangedEventType type) {
+      SaveSnapshot(type, -1, -1);
+      eventStack.Push(type);
+    }
+
+    public void EndTransaction() {
+      if (eventStack.Count == 0)
+        throw new InvalidOperationException("There is no open transaction that can be ended.");
+
+      var @event = eventStack.Pop();
+      OnChanged(@event, -1, -1);
+    }
+
+    #endregion
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Implementations/TransformationContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Implementations/TransformationContent.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Implementations/TransformationContent.cs	(revision 11159)
@@ -0,0 +1,56 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.DataPreprocessing {
+  [Item("Transformation", "Represents the transformation grid.")]
+  public class TransformationContent : Item, IViewShortcut {
+
+    public IPreprocessingData Data { get; private set; }
+    public IFilterLogic FilterLogic { get; private set; }
+
+    public ICheckedItemList<ITransformation> CheckedTransformationList { get; private set; }
+
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Method; }
+    }
+
+    public TransformationContent(IPreprocessingData data, IFilterLogic filterLogic) {
+      Data = data;
+      CheckedTransformationList = new CheckedItemList<ITransformation>();
+      FilterLogic = filterLogic;
+    }
+
+    public TransformationContent(TransformationContent original, Cloner cloner)
+      : base(original, cloner) {
+      Data = original.Data;
+      CheckedTransformationList = new CheckedItemList<ITransformation>(original.CheckedTransformationList);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TransformationContent(this, cloner);
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IDataGridContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IDataGridContent.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IDataGridContent.cs	(revision 11159)
@@ -0,0 +1,38 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Data;
+
+namespace HeuristicLab.DataPreprocessing {
+  public interface IDataGridContent : IStringConvertibleMatrix {
+    ITransactionalPreprocessingData PreProcessingData { get; }
+    IManipulationLogic ManipulationLogic { get; }
+    IFilterLogic FilterLogic { get; }
+
+    IDictionary<int, IList<int>> Selection { get; set; }
+
+    void DeleteRow(IEnumerable<int> rows);
+    bool Validate(string value, out string errorMessage, int columnIndex);
+
+    event DataPreprocessingChangedEventHandler Changed;
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IDataGridLogic.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IDataGridLogic.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IDataGridLogic.cs	(revision 11159)
@@ -0,0 +1,47 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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;
+
+namespace HeuristicLab.DataPreprocessing {
+  public interface IDataGridLogic {
+    IEnumerable<string> ColumnNames { get; }
+    IEnumerable<string> RowNames { get; }
+    int Columns { get; }
+    int Rows { get; }
+
+    string GetValue(int columnIndex, int rowIndex);
+    bool SetValue(string value, int columnIndex, int rowIndex);
+    bool Validate(string value, out string errorMessage, int columnIndex);
+
+    bool AreAllStringColumns(IEnumerable<int> columnIndices);
+
+    event DataPreprocessingChangedEventHandler Changed;
+
+    void DeleteRow(List<int> rows);
+
+    IDictionary<int, IList<int>> Selection { get; set; }
+    void ClearSelection();
+
+    event EventHandler SelectionChanged;
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IFilterLogic.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IFilterLogic.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IFilterLogic.cs	(revision 11159)
@@ -0,0 +1,43 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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 HeuristicLab.DataPreprocessing.Filter;
+using HeuristicLab.DataPreprocessing.Interfaces;
+namespace HeuristicLab.DataPreprocessing {
+  public interface IFilterLogic {
+    bool[] GetFilterResult(IList<IFilter> filters, bool isAndCombination);
+    /// <summary>
+    /// Return an array which indicates whether the corresponding row should be filtered (true) or kept (false)
+    /// </summary>
+    /// <param name="filters"></param>
+    /// <param name="isAndCombination"></param>
+    /// <returns></returns>
+    bool[] Preview(IList<IFilter> filters, bool isAndCombination);
+    void Apply(IList<IFilter> filters, bool isAndCombination);
+    IFilteredPreprocessingData PreprocessingData { get; }
+    void Reset();
+    bool IsFiltered { get; }
+
+    event EventHandler FilterChanged;
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IFilteredPreprocessingData.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IFilteredPreprocessingData.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IFilteredPreprocessingData.cs	(revision 11159)
@@ -0,0 +1,17 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace HeuristicLab.DataPreprocessing.Interfaces
+{
+  public interface IFilteredPreprocessingData : ITransactionalPreprocessingData
+  {
+    void SetFilter(bool[] rowFilters);
+    void PersistFilter();
+    void ResetFilter();
+    bool IsFiltered { get; }
+
+    event EventHandler FilterChanged;
+   }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IManipulationLogic.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IManipulationLogic.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IManipulationLogic.cs	(revision 11159)
@@ -0,0 +1,49 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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;
+
+namespace HeuristicLab.DataPreprocessing {
+  public interface IManipulationLogic {
+    IEnumerable<string> VariableNames { get; }
+    ITransactionalPreprocessingData PreProcessingData { get; }
+    void ReOrderToIndices(IEnumerable<int> indices);
+    void ReOrderToIndices(IList<Tuple<int, int>> indices);
+    void ShuffleToIndices(IList<System.Tuple<int, int>> indices);
+    void ReplaceIndicesByAverageValue(IDictionary<int, IList<int>> cells, bool considerSelection = false);
+    void ReplaceIndicesByMedianValue(IDictionary<int, IList<int>> cells, bool considerSelection = false);
+    void ReplaceIndicesByMostCommonValue(IDictionary<int, IList<int>> cells, bool considerSelection = false);
+    void ReplaceIndicesByRandomValue(IDictionary<int, IList<int>> cells, bool considerSelection = false);
+    void ReplaceIndicesByLinearInterpolationOfNeighbours(IDictionary<int, IList<int>> cells);
+    void ReplaceIndicesBySmoothing(IDictionary<int, IList<int>> cells);
+    void ReplaceIndicesByValue(IDictionary<int, IList<int>> cells, string value);
+    void ReplaceIndicesByValue<T>(int columnIndex, IEnumerable<int> rowIndices, T value);
+    void ShuffleWithRanges();
+    void ShuffleWithRanges(IEnumerable<HeuristicLab.Data.IntRange> ranges);
+    List<int> RowsWithMissingValuesGreater(double percent);
+    List<int> ColumnsWithMissingValuesGreater(double percent);
+    List<int> ColumnsWithVarianceSmaller(double variance);
+    void DeleteRowsWithMissingValuesGreater(double percent);
+    void DeleteColumnsWithMissingValuesGreater(double percent);
+    void DeleteColumnsWithVarianceSmaller(double variance);
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IPreprocessingContext.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IPreprocessingContext.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IPreprocessingContext.cs	(revision 11159)
@@ -0,0 +1,41 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.DataPreprocessing.Interfaces;
+
+namespace HeuristicLab.DataPreprocessing {
+  public interface IPreprocessingContext : IItem {
+    IFilteredPreprocessingData Data { get; }
+
+    IAlgorithm Algorithm { get; }
+    IDataAnalysisProblem Problem { get; }
+    IDataAnalysisProblemData ProblemData { get; }
+
+    IItem Export();
+    IAlgorithm ExportAlgorithm();
+    IDataAnalysisProblem ExportProblem();
+    IDataAnalysisProblemData ExportProblemData();
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IPreprocessingData.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IPreprocessingData.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IPreprocessingData.cs	(revision 11159)
@@ -0,0 +1,76 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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 HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.DataPreprocessing {
+
+  public interface IPreprocessingData : INamedItem {
+    T GetCell<T>(int columnIndex, int rowIndex);
+
+    void SetCell<T>(int columnIndex, int rowIndex, T value);
+
+    string GetCellAsString(int columnIndex, int rowIndex);
+
+    [Obsolete("use the index based variant, is faster")]
+    IList<T> GetValues<T>(string variableName, bool considerSelection = false);
+    IList<T> GetValues<T>(int columnIndex, bool considerSelection = false);
+
+    void SetValues<T>(int columnIndex, IList<T> values);
+    bool SetValue(string value, int columnIndex, int rowIndex);
+
+    void InsertRow(int rowIndex);
+    void DeleteRow(int rowIndex);
+    void DeleteRowsWithIndices(IEnumerable<int> rows);
+    void InsertColumn<T>(string variableName, int columnIndex);
+
+    void DeleteColumn(int columnIndex);
+
+    bool AreAllStringColumns(IEnumerable<int> columnIndices);
+    bool Validate(string value, out string errorMessage, int columnIndex);
+
+    IntRange TrainingPartition { get; }
+    IntRange TestPartition { get; }
+
+    IList<ITransformation> Transformations { get; }
+
+    IEnumerable<string> VariableNames { get; }
+    IEnumerable<string> GetDoubleVariableNames();
+    string GetVariableName(int columnIndex);
+    int GetColumnIndex(string variableName);
+
+    bool VariableHasType<T>(int columnIndex);
+
+    int Columns { get; }
+    int Rows { get; }
+
+    Dataset ExportToDataset();
+
+    IDictionary<int, IList<int>> Selection { get; set; }
+    void ClearSelection();
+
+    event EventHandler SelectionChanged;
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/ISearchLogic.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/ISearchLogic.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/ISearchLogic.cs	(revision 11159)
@@ -0,0 +1,48 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.DataPreprocessing {
+  public interface ISearchLogic {
+
+    int Rows { get; }
+    int Columns { get; }
+    IEnumerable<string> VariableNames { get; }
+
+    /// <summary>
+    /// Return the indices of the missing values where the key 
+    /// correspdonds to the columbn index and the values to the row indices
+    /// </summary>
+    /// <returns></returns>
+    IDictionary<int, IList<int>> GetMissingValueIndices();
+
+    /// <summary>
+    /// Return the row indices of the cells which contain a missing value
+    /// </summary>
+    /// <returns></returns>
+    IList<int> GetMissingValueIndices(int columnIndex);
+
+    bool IsMissingValue(int columnIndex, int rowIndex);
+
+    IEnumerable<T> GetValuesWithoutNaN<T>(int columnIndex, bool considerSelection = false);
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IStatisticsLogic.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IStatisticsLogic.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IStatisticsLogic.cs	(revision 11159)
@@ -0,0 +1,54 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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;
+
+namespace HeuristicLab.DataPreprocessing {
+  public interface IStatisticsLogic {
+
+    int GetColumnCount();
+    int GetRowCount();
+    int GetNumericColumnCount();
+    int GetNominalColumnCount();
+    int GetMissingValueCount();
+    int GetMissingValueCount(int columnIndex);
+    int GetRowMissingValueCount(int rowIndex);
+
+    T GetMin<T>(int columnIndex, bool considerSelection = false) where T : IComparable<T>;
+    T GetMax<T>(int columnIndex, bool considerSelection = false) where T : IComparable<T>;
+
+    double GetMedian(int columnIndex, bool considerSelection = false);
+    double GetAverage(int columnIndex, bool considerSelection = false);
+    DateTime GetMedianDateTime(int columnIndex, bool considerSelection = false);
+    DateTime GetAverageDateTime(int columnIndex, bool considerSelection = false);
+
+    double GetStandardDeviation(int columnIndex);
+    double GetVariance(int columnIndex);
+    T GetMostCommonValue<T>(int columnIndex, bool considerSelection = false);
+    int GetDifferentValuesCount<T>(int columnIndex);
+
+    bool VariableHasType<T>(int columnIndex);
+    string GetColumnTypeAsString(int columnIndex);
+    string GetVariableName(int columnIndex);
+
+    event DataPreprocessingChangedEventHandler Changed;
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/ITransactionalPreprocessingData.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/ITransactionalPreprocessingData.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/ITransactionalPreprocessingData.cs	(revision 11159)
@@ -0,0 +1,36 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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;
+namespace HeuristicLab.DataPreprocessing {
+
+  public interface ITransactionalPreprocessingData : IPreprocessingData {
+
+    event DataPreprocessingChangedEventHandler Changed;
+
+    bool IsUndoAvailable { get; }
+    void Undo();
+    void InTransaction(Action action, DataPreprocessingChangedEventType type = DataPreprocessingChangedEventType.Any);
+    void BeginTransaction(DataPreprocessingChangedEventType type);
+    void EndTransaction();
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/ITransformationLogic.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/ITransformationLogic.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/ITransformationLogic.cs	(revision 11159)
@@ -0,0 +1,26 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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 {
+  public interface ITransformationLogic {
+
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IViewChartShortcut.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IViewChartShortcut.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IViewChartShortcut.cs	(revision 11159)
@@ -0,0 +1,27 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.DataPreprocessing {
+  public interface IViewChartShortcut : IViewShortcut {
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IViewShortcut.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IViewShortcut.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Interfaces/IViewShortcut.cs	(revision 11159)
@@ -0,0 +1,27 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.DataPreprocessing {
+  public interface IViewShortcut : IItem {
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Plugin.cs.frame
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Plugin.cs.frame	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Plugin.cs.frame	(revision 11159)
@@ -0,0 +1,40 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.PluginInfrastructure;
+
+namespace HeuristicLab.DataPreprocessing {
+  /// <summary>
+  /// Plugin class for HeuristicLab.Data plugin.
+  /// </summary>
+  [Plugin("HeuristicLab.DataPreprocessing", "3.4.0.$WCREV$")]
+  [PluginFile("HeuristicLab.DataPreprocessing-3.4.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Analysis", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Data","3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis","3.4")]
+  public class HeuristicLabDataPreprocessingPlugin : PluginBase {
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/PreprocessingTransformator.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/PreprocessingTransformator.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/PreprocessingTransformator.cs	(revision 11159)
@@ -0,0 +1,178 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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 ITransactionalPreprocessingData preprocessingData;
+
+    private readonly IDictionary<string, IList<double>> originalColumns;
+
+    private readonly IDictionary<string, string> renamedColumns;
+
+    public PreprocessingTransformator(IPreprocessingData preprocessingData) {
+      this.preprocessingData = (ITransactionalPreprocessingData)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.Apply(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: stable/HeuristicLab.DataPreprocessing/3.4/ProblemDataCreator.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/ProblemDataCreator.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/ProblemDataCreator.cs	(revision 11159)
@@ -0,0 +1,107 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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 HeuristicLab.Common;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.DataPreprocessing {
+  public class ProblemDataCreator {
+
+    private readonly IPreprocessingContext context;
+
+    private Dataset ExportedDataset {
+      get { return exporteDataset ?? (exporteDataset = context.Data.ExportToDataset()); }
+    }
+    private Dataset exporteDataset;
+
+    private IList<ITransformation> Transformations { get { return context.Data.Transformations; } }
+
+    public ProblemDataCreator(IPreprocessingContext context) {
+      this.context = context;
+    }
+
+    public IDataAnalysisProblemData CreateProblemData() {
+      if (context.Data.Rows == 0 || context.Data.Columns == 0) return null;
+
+      var oldProblemData = context.ProblemData;
+      IDataAnalysisProblemData problemData;
+
+      if (oldProblemData is RegressionProblemData) {
+        problemData = CreateRegressionData((RegressionProblemData)oldProblemData);
+      } else if (oldProblemData is ClassificationProblemData) {
+        problemData = CreateClassificationData((ClassificationProblemData)oldProblemData);
+      } else if (oldProblemData is ClusteringProblemData) {
+        problemData = CreateClusteringData((ClusteringProblemData)oldProblemData);
+      } else {
+        throw new NotImplementedException("The type of the DataAnalysisProblemData is not supported.");
+      }
+
+      SetTrainingAndTestPartition(problemData);
+
+      return problemData;
+    }
+
+    private IDataAnalysisProblemData CreateRegressionData(RegressionProblemData oldProblemData) {
+      var targetVariable = oldProblemData.TargetVariable;
+      // target variable must be double and must exist in the new dataset
+      return new RegressionProblemData(ExportedDataset, GetDoubleInputVariables(targetVariable), targetVariable, Transformations);
+    }
+
+    private IDataAnalysisProblemData CreateClassificationData(ClassificationProblemData oldProblemData) {
+      var targetVariable = oldProblemData.TargetVariable;
+      // target variable must be double and must exist in the new dataset
+      return new ClassificationProblemData(ExportedDataset, GetDoubleInputVariables(targetVariable), targetVariable, Transformations);
+    }
+
+    private IDataAnalysisProblemData CreateClusteringData(ClusteringProblemData oldProblemData) {
+      return new ClusteringProblemData(ExportedDataset, GetDoubleInputVariables(String.Empty), Transformations);
+    }
+
+    private void SetTrainingAndTestPartition(IDataAnalysisProblemData problemData) {
+      var ppData = context.Data;
+
+      problemData.TrainingPartition.Start = ppData.TrainingPartition.Start;
+      problemData.TrainingPartition.End = ppData.TrainingPartition.End;
+      problemData.TestPartition.Start = ppData.TestPartition.Start;
+      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))) {
+
+          variableNames.Add(variableName);
+        }
+      }
+      return variableNames;
+    }
+
+    private bool IsNotConstantInputVariable(IList<double> list) {
+      return context.Data.TrainingPartition.End - context.Data.TrainingPartition.Start > 1 || list.Range() > 0;
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Properties/AssemblyInfo.cs.frame
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Properties/AssemblyInfo.cs.frame	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Properties/AssemblyInfo.cs.frame	(revision 11159)
@@ -0,0 +1,35 @@
+﻿using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.DataPreprocessing")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("FH-Hagenberg")]
+[assembly: AssemblyProduct("HeuristicLab.DataPreprocessing")]
+[assembly: AssemblyCopyright("Copyright © FH-Hagenberg 2014")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("923b1ea4-9504-4afd-b2ad-dd6ee72c7af6")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.4.0.0")]
+[assembly: AssemblyFileVersion("3.4.0.$WCREV$")]
Index: stable/HeuristicLab.DataPreprocessing/3.4/Properties/Resources.Designer.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Properties/Resources.Designer.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Properties/Resources.Designer.cs	(revision 11159)
@@ -0,0 +1,63 @@
+﻿//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.18408
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace HeuristicLab.DataPreprocessing.Properties {
+    using System;
+    
+    
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HeuristicLab.DataPreprocessing.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+    }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Utils/DataPreprocessingChangedEvent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Utils/DataPreprocessingChangedEvent.cs	(revision 11159)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Utils/DataPreprocessingChangedEvent.cs	(revision 11159)
@@ -0,0 +1,49 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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;
+
+namespace HeuristicLab.DataPreprocessing {
+  public enum DataPreprocessingChangedEventType {
+    DeleteColumn,
+    AddColumn,
+    ChangeColumn,
+    DeleteRow,
+    AddRow,
+    ChangeItem,
+    Any,
+    Transformation
+  }
+
+  public class DataPreprocessingChangedEventArgs : EventArgs {
+    public DataPreprocessingChangedEventType Type { get; private set; }
+    public int Row { get; private set; }
+    public int Column { get; private set; }
+
+    public DataPreprocessingChangedEventArgs(DataPreprocessingChangedEventType type, int column, int row) {
+      Type = type;
+      Column = column;
+      Row = row;
+    }
+  }
+
+  public delegate void DataPreprocessingChangedEventHandler(object sender, DataPreprocessingChangedEventArgs e);
+}
Index: stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionView.Designer.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionView.Designer.cs	(revision 11158)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionView.Designer.cs	(revision 11159)
@@ -19,5 +19,4 @@
  */
 #endregion
-
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views {
@@ -49,4 +48,5 @@
       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();
@@ -61,4 +61,5 @@
       this.flowLayoutPanel.Controls.Add(this.btnSimplify);
       this.flowLayoutPanel.Controls.Add(this.exportButton);
+      this.flowLayoutPanel.Controls.Add(this.transformModelButton);
       // 
       // btnSimplify
@@ -90,4 +91,18 @@
       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
       // 
@@ -108,4 +123,5 @@
     protected System.Windows.Forms.Button exportButton;
     protected System.Windows.Forms.Button btnSimplify;
+    protected System.Windows.Forms.Button transformModelButton;
   }
 }
Index: stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionView.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionView.cs	(revision 11158)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionView.cs	(revision 11159)
@@ -45,8 +45,10 @@
       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) {
-      InteractiveSymbolicRegressionSolutionSimplifierView view = new InteractiveSymbolicRegressionSolutionSimplifierView();
+      var view = new InteractiveSymbolicRegressionSolutionSimplifierView();
       view.Content = (SymbolicRegressionSolution)this.Content.Clone();
       view.Show();
@@ -57,5 +59,4 @@
       exportFileDialog.Filter = exporter.FileTypeFilter;
       if (exportFileDialog.ShowDialog(this) == DialogResult.OK) {
-
         var name = exportFileDialog.FileName;
         using (BackgroundWorker bg = new BackgroundWorker()) {
@@ -67,4 +68,17 @@
       }
     }
+
+    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: stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 11158)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 11159)
@@ -126,4 +126,8 @@
       <SubType>Code</SubType>
     </Compile>
+
+    <Compile Include="Interfaces\IModelBacktransformator.cs" />
+
+    <Compile Include="SymbolicExpressionTreeBacktransformator.cs" />
     <Compile Include="SymbolicDataAnalysisExpressionPruningOperator.cs" />
     <Compile Include="Analyzers\SymbolicDataAnalysisVariableFrequencyAnalyzer.cs" />
@@ -142,5 +146,5 @@
     <Compile Include="Crossovers\SymbolicDataAnalysisExpressionSemanticSimilarityCrossover.cs" />
     <Compile Include="Formatters\SymbolicDataAnalysisExpressionExcelFormatter.cs" />
-	<Compile Include="Formatters\SymbolicDataAnalysisExpressionSmalltalkFormatter.cs" />
+    <Compile Include="Formatters\SymbolicDataAnalysisExpressionSmalltalkFormatter.cs" />
     <Compile Include="Interfaces\ISymbolicDataAnalysisExpressionCrossover.cs" />
     <Compile Include="Interfaces\ISymbolicDataAnalysisImpactValuesCalculator.cs" />
@@ -222,4 +226,5 @@
     <Compile Include="Symbols\VariableConditionTreeNode.cs" />
     <Compile Include="Symbols\VariableTreeNode.cs" />
+    <Compile Include="TransformationToSymbolicTreeMapper.cs" />
     <None Include="HeuristicLab.snk" />
     <None Include="Plugin.cs.frame" />
Index: stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/IModelBacktransformator.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/IModelBacktransformator.cs	(revision 11159)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/IModelBacktransformator.cs	(revision 11159)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Symbolic {
+  public interface IModelBacktransformator {
+    ISymbolicDataAnalysisModel Backtransform(ISymbolicDataAnalysisModel model, IEnumerable<ITransformation> transformations, string targetVariable);
+  }
+}
Index: stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicExpressionTreeBacktransformator.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicExpressionTreeBacktransformator.cs	(revision 11159)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicExpressionTreeBacktransformator.cs	(revision 11159)
@@ -0,0 +1,97 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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: stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/TransformationToSymbolicTreeMapper.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/TransformationToSymbolicTreeMapper.cs	(revision 11159)
+++ stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/TransformationToSymbolicTreeMapper.cs	(revision 11159)
@@ -0,0 +1,294 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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: stable/HeuristicLab.Problems.DataAnalysis.Trading/3.4/ProblemData.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Trading/3.4/ProblemData.cs	(revision 11158)
+++ stable/HeuristicLab.Problems.DataAnalysis.Trading/3.4/ProblemData.cs	(revision 11159)
@@ -1627,6 +1627,6 @@
     }
 
-    public ProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable)
-      : base(dataset, allowedInputVariables) {
+    public ProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable, IEnumerable<ITransformation> transformations = null)
+      : base(dataset, allowedInputVariables, transformations ?? Enumerable.Empty<ITransformation>()) {
       var variables = InputVariables.Select(x => x.AsReadOnly()).ToList();
       Parameters.Add(new ConstrainedValueParameter<StringValue>(PriceChangeVariableParameterName, new ItemSet<StringValue>(variables), variables.First(x => x.Value == targetVariable)));
Index: stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.cs	(revision 11158)
+++ stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.cs	(revision 11159)
@@ -57,4 +57,5 @@
       partitionComboBox.DataSource = Partitions;
       partitionComboBox.SelectedItem = TRAININGSAMPLES;
+      progressPanel.Visible = false;
     }
 
@@ -78,4 +79,5 @@
         CalculateCorrelation();
       } else {
+        progressPanel.Visible = false;
         dataView.Maximum = 0;
         dataView.Minimum = 0;
Index: stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 11158)
+++ stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 11159)
@@ -169,4 +169,5 @@
       <DependentUpon>FeatureCorrelationView.cs</DependentUpon>
     </Compile>
+    <Compile Include="Interfaces\IDataPreprocessorStarter.cs" />
     <Compile Include="MenuItems\ShrinkDataAnalysisRunsMenuItem.cs" />
     <Compile Include="Plugin.cs" />
Index: stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IDataPreprocessorStarter.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IDataPreprocessorStarter.cs	(revision 11159)
+++ stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IDataPreprocessorStarter.cs	(revision 11159)
@@ -0,0 +1,28 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  public interface IDataPreprocessorStarter {
+    void Start(IDataAnalysisProblemData problemData, View currentView);
+  }
+}
Index: stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.Designer.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.Designer.cs	(revision 11158)
+++ stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.Designer.cs	(revision 11159)
@@ -46,4 +46,5 @@
     private void InitializeComponent() {
       this.FeatureCorrelationButton = new System.Windows.Forms.Button();
+      this.DataPreprocessingButton = new System.Windows.Forms.Button();
       ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
       this.SuspendLayout();
@@ -71,8 +72,19 @@
       this.FeatureCorrelationButton.Click += new System.EventHandler(this.FeatureCorrelationButton_Click);
       // 
+      // DataPreprocessingButton
+      // 
+      this.DataPreprocessingButton.Location = new System.Drawing.Point(311, 45);
+      this.DataPreprocessingButton.Name = "DataPreprocessingButton";
+      this.DataPreprocessingButton.Size = new System.Drawing.Size(121, 24);
+      this.DataPreprocessingButton.TabIndex = 5;
+      this.DataPreprocessingButton.Text = "Data Preprocessing";
+      this.DataPreprocessingButton.UseVisualStyleBackColor = true;
+      this.DataPreprocessingButton.Click += new System.EventHandler(this.DataPreprocessingButton_Click);
+      // 
       // ProblemDataView
       // 
       this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.DataPreprocessingButton);
       this.Controls.Add(this.FeatureCorrelationButton);
       this.Name = "ProblemDataView";
@@ -82,4 +94,5 @@
       this.Controls.SetChildIndex(this.nameLabel, 0);
       this.Controls.SetChildIndex(this.FeatureCorrelationButton, 0);
+      this.Controls.SetChildIndex(this.DataPreprocessingButton, 0);
       ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
       this.ResumeLayout(false);
@@ -91,4 +104,5 @@
 
     protected System.Windows.Forms.Button FeatureCorrelationButton;
+    protected System.Windows.Forms.Button DataPreprocessingButton;
 
   }
Index: stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.cs	(revision 11158)
+++ stable/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.cs	(revision 11159)
@@ -29,4 +29,5 @@
 using HeuristicLab.MainForm;
 using HeuristicLab.MainForm.WindowsForms;
+using HeuristicLab.PluginInfrastructure;
 
 namespace HeuristicLab.Problems.DataAnalysis.Views {
@@ -100,4 +101,13 @@
       e.Effect = e.AllowedEffect;
     }
+
+    private void DataPreprocessingButton_Click(object sender, EventArgs e) {
+      var preprocessingStarters = ApplicationManager.Manager.GetInstances<IDataPreprocessorStarter>();
+      var starter = preprocessingStarters.FirstOrDefault();
+      // TODO: handle possible multiple starters
+      if (starter != null) {
+        starter.Start(Content, this);
+      }
+    }
   }
 }
Index: stable/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs	(revision 11158)
+++ stable/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs	(revision 11159)
@@ -170,4 +170,29 @@
         yield return value;
     }
+
+    public IEnumerable<string> GetStringValues(string variableName) {
+      IList list;
+      if (!variableValues.TryGetValue(variableName, out list))
+        throw new ArgumentException("The variable " + variableName + " does not exist in the dataset.");
+      List<string> values = list as List<string>;
+      if (values == null) throw new ArgumentException("The variable " + variableName + " is not a string variable.");
+
+      //mkommend yield return used to enable lazy evaluation
+      foreach (string value in values)
+        yield return value;
+    }
+
+    public IEnumerable<DateTime> GetDateTimeValues(string variableName) {
+      IList list;
+      if (!variableValues.TryGetValue(variableName, out list))
+        throw new ArgumentException("The variable " + variableName + " does not exist in the dataset.");
+      List<DateTime> values = list as List<DateTime>;
+      if (values == null) throw new ArgumentException("The variable " + variableName + " is not a datetime variable.");
+
+      //mkommend yield return used to enable lazy evaluation
+      foreach (DateTime value in values)
+        yield return value;
+    }
+
     public ReadOnlyCollection<double> GetReadOnlyDoubleValues(string variableName) {
       IList list;
@@ -194,4 +219,8 @@
 
       return rows.Select(index => values[index]);
+    }
+
+    public bool VariableHasType<T>(string variableName) {
+      return variableValues[variableName] is IList<T>;
     }
 
Index: stable/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 11158)
+++ stable/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 11159)
@@ -141,4 +141,13 @@
     <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisSolution.cs" />
     <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisSolutionBase.cs" />
+    <Compile Include="Implementation\Transformations\CopyColumnTransformation.cs" />
+    <Compile Include="Implementation\Transformations\ExponentialTransformation.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\Transformation.cs" />
     <Compile Include="Interfaces\Classification\IClassificationEnsembleModel.cs">
       <SubType>Code</SubType>
@@ -150,4 +159,6 @@
     <Compile Include="Interfaces\IDataAnalysisSolutionExporter.cs" />
     <Compile Include="Interfaces\IDependencyCalculator.cs" />
+    <Compile Include="Interfaces\ITransformation.cs" />
+    <Compile Include="Interfaces\ITransformationMapper.cs" />
     <Compile Include="Interfaces\Regression\IRegressionEnsembleModel.cs">
       <SubType>Code</SubType>
Index: stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs	(revision 11158)
+++ stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs	(revision 11159)
@@ -300,6 +300,6 @@
     }
 
-    public ClassificationProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable)
-      : base(dataset, allowedInputVariables) {
+    public ClassificationProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable, IEnumerable<ITransformation> transformations = null)
+      : base(dataset, allowedInputVariables, transformations ?? Enumerable.Empty<ITransformation>()) {
       var validTargetVariableValues = CheckVariablesForPossibleTargetVariables(dataset).Select(x => new StringValue(x).AsReadOnly()).ToList();
       var target = validTargetVariableValues.Where(x => x.Value == targetVariable).DefaultIfEmpty(validTargetVariableValues.First()).First();
Index: stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblemData.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblemData.cs	(revision 11158)
+++ stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblemData.cs	(revision 11159)
@@ -21,4 +21,5 @@
 
 using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -86,6 +87,6 @@
     }
 
-    public ClusteringProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables)
-      : base(dataset, allowedInputVariables) {
+    public ClusteringProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, IEnumerable<ITransformation> transformations = null)
+      : base(dataset, allowedInputVariables, transformations ?? Enumerable.Empty<ITransformation>()) {
     }
   }
Index: stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs	(revision 11158)
+++ stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs	(revision 11159)
@@ -38,4 +38,5 @@
     protected const string TrainingPartitionParameterName = "TrainingPartition";
     protected const string TestPartitionParameterName = "TestPartition";
+    protected const string TransformationsParameterName = "Transformations";
 
     #region parameter properites
@@ -51,4 +52,7 @@
     public IFixedValueParameter<IntRange> TestPartitionParameter {
       get { return (IFixedValueParameter<IntRange>)Parameters[TestPartitionParameterName]; }
+    }
+    public IFixedValueParameter<ReadOnlyItemList<ITransformation>> TransformationsParameter {
+      get { return (IFixedValueParameter<ReadOnlyItemList<ITransformation>>)Parameters[TransformationsParameterName]; }
     }
     #endregion
@@ -89,4 +93,8 @@
     }
 
+    public IEnumerable<ITransformation> Transformations {
+      get { return TransformationsParameter.Value; }
+    }
+
     public virtual bool IsTrainingSample(int index) {
       return index >= 0 && index < Dataset.Rows &&
@@ -111,8 +119,12 @@
     [StorableHook(HookType.AfterDeserialization)]
     private void AfterDeserialization() {
+      if (!Parameters.ContainsKey(TransformationsParameterName)) {
+        Parameters.Add(new FixedValueParameter<ReadOnlyItemList<ITransformation>>(TransformationsParameterName, "", new ItemList<ITransformation>().AsReadOnly()));
+        TransformationsParameter.Hidden = true;
+      }
       RegisterEventHandlers();
     }
 
-    protected DataAnalysisProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables) {
+    protected DataAnalysisProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, IEnumerable<ITransformation> transformations = null) {
       if (dataset == null) throw new ArgumentNullException("The dataset must not be null.");
       if (allowedInputVariables == null) throw new ArgumentNullException("The allowedInputVariables must not be null.");
@@ -130,8 +142,13 @@
       int testPartitionEnd = dataset.Rows;
 
+      var transformationsList = new ItemList<ITransformation>(transformations ?? Enumerable.Empty<ITransformation>());
+
       Parameters.Add(new FixedValueParameter<Dataset>(DatasetParameterName, "", 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()));
+
+      TransformationsParameter.Hidden = true;
 
       ((ValueParameter<Dataset>)DatasetParameter).ReactOnValueToStringChangedAndValueItemImageChanged = false;
@@ -144,4 +161,5 @@
       TrainingPartition.ValueChanged += new EventHandler(Parameter_ValueChanged);
       TestPartition.ValueChanged += new EventHandler(Parameter_ValueChanged);
+      TransformationsParameter.ValueChanged += new EventHandler(Parameter_ValueChanged);
     }
 
Index: stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs	(revision 11158)
+++ stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs	(revision 11159)
@@ -137,6 +137,6 @@
     }
 
-    public RegressionProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable)
-      : base(dataset, allowedInputVariables) {
+    public RegressionProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable, IEnumerable<ITransformation> transformations = null)
+      : base(dataset, allowedInputVariables, transformations ?? Enumerable.Empty<ITransformation>()) {
       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()));
Index: stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblemData.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblemData.cs	(revision 11158)
+++ stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblemData.cs	(revision 11159)
@@ -1582,6 +1582,6 @@
       TrainingPartition.Start = 50;
     }
-    public TimeSeriesPrognosisProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable)
-      : base(dataset, allowedInputVariables, targetVariable) {
+    public TimeSeriesPrognosisProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable, IEnumerable<ITransformation> transformations = null)
+      : base(dataset, allowedInputVariables, targetVariable, transformations ?? Enumerable.Empty<ITransformation>()) {
       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)));
@@ -1643,7 +1643,7 @@
 
       var trainingDataStart = TrainingIndices.First();
-      
+
       base.AdjustProblemDataProperties(problemData);
-      
+
       TestPartition.Start = trainingDataStart;
 
Index: stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/CopyColumnTransformation.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/CopyColumnTransformation.cs	(revision 11159)
+++ stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/CopyColumnTransformation.cs	(revision 11159)
@@ -0,0 +1,64 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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 {
+  [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: stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ExponentialTransformation.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ExponentialTransformation.cs	(revision 11159)
+++ stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ExponentialTransformation.cs	(revision 11159)
@@ -0,0 +1,56 @@
+﻿using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [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) {
+      foreach (double d in data) {
+        yield return Math.Pow(Base, d);
+      }
+    }
+
+    public override bool Check(IEnumerable<double> data, out string errorMsg) {
+      errorMsg = "";
+      return true;
+    }
+  }
+}
Index: stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LinearTransformation.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LinearTransformation.cs	(revision 11159)
+++ stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LinearTransformation.cs	(revision 11159)
@@ -0,0 +1,94 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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 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; }
+      protected set {
+        MultiplierParameter.Value.Value = value;
+      }
+    }
+
+    public double Addend {
+      get { return AddendParameter.Value.Value; }
+      protected 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) {
+      return data.Select(e => e * Multiplier + Addend);
+    }
+
+    public override bool Check(IEnumerable<double> data, out string errorMsg) {
+      errorMsg = null;
+      if (Multiplier == 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: stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LogarithmicTransformation.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LogarithmicTransformation.cs	(revision 11159)
+++ stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LogarithmicTransformation.cs	(revision 11159)
@@ -0,0 +1,64 @@
+﻿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("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) {
+      foreach (double i in data) {
+        if (i > 0.0)
+          yield return Math.Log(i, Base);
+        else
+          yield return i;
+      }
+    }
+
+    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: stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/PowerTransformation.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/PowerTransformation.cs	(revision 11159)
+++ stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/PowerTransformation.cs	(revision 11159)
@@ -0,0 +1,55 @@
+﻿using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [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) {
+      foreach (double i in data) {
+        yield return Math.Pow(i, Exponent);
+      }
+    }
+
+    public override bool Check(IEnumerable<double> data, out string errorMsg) {
+      errorMsg = "";
+      return true;
+    }
+
+  }
+}
Index: stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ReciprocalTransformation.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ReciprocalTransformation.cs	(revision 11159)
+++ stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ReciprocalTransformation.cs	(revision 11159)
@@ -0,0 +1,51 @@
+﻿
+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("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
+
+    //TODO: is a special case of Linear
+    [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) {
+      foreach (double i in data) {
+        if (i > 0.0)
+          yield return 1.0 / i;
+        else
+          yield return i;
+      }
+    }
+
+    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: stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftStandardDistributionTransformation.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftStandardDistributionTransformation.cs	(revision 11159)
+++ stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftStandardDistributionTransformation.cs	(revision 11159)
@@ -0,0 +1,104 @@
+﻿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("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);
+    }
+
+    // http://en.wikipedia.org/wiki/Standard_deviation
+    // http://www.statistics4u.info/fundstat_germ/ee_ztransform.html
+    // https://www.uni-due.de/~bm0061/vorl12.pdf p5
+    public override IEnumerable<double> Apply(IEnumerable<double> data) {
+      ConfigureParameters(data);
+      if (OriginalStandardDeviation == 0.0) {
+        foreach (var e in data) {
+          yield return e;
+        }
+        yield break;
+      }
+
+      foreach (var e in data) {
+        double unitNormalDistributedValue = (e - OriginalMean) / OriginalStandardDeviation;
+        yield return unitNormalDistributedValue * StandardDeviation + Mean;
+      }
+    }
+
+    public override bool Check(IEnumerable<double> data, out string errorMsg) {
+      ConfigureParameters(data);
+      errorMsg = "";
+      if (OriginalStandardDeviation == 0.0) {
+        errorMsg = "Standard deviaton for the original data is 0.0, Transformation cannot be applied onto these values.";
+        return false;
+      }
+      return true;
+    }
+
+    protected void ConfigureParameters(IEnumerable<double> data) {
+      OriginalStandardDeviation = data.StandardDeviation();
+      OriginalMean = data.Average();
+    }
+  }
+}
Index: stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftToRangeTransformation.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftToRangeTransformation.cs	(revision 11159)
+++ stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftToRangeTransformation.cs	(revision 11159)
@@ -0,0 +1,66 @@
+﻿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("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 IEnumerable<double> Apply(IEnumerable<double> data) {
+      ConfigureParameters(data);
+      return base.Apply(data);
+    }
+
+    public override bool Check(IEnumerable<double> data, out string errorMsg) {
+      ConfigureParameters(data);
+      return base.Check(data, out errorMsg);
+    }
+
+    protected 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: stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/Transformation.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/Transformation.cs	(revision 11159)
+++ stable/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/Transformation.cs	(revision 11159)
@@ -0,0 +1,72 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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 abstract IEnumerable<T> Apply(IEnumerable<T> data);
+
+    public abstract bool Check(IEnumerable<T> data, out string errorMsg);
+  }
+}
Index: stable/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblemData.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblemData.cs	(revision 11158)
+++ stable/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblemData.cs	(revision 11159)
@@ -39,4 +39,6 @@
     IEnumerable<int> TestIndices { get; }
 
+    IEnumerable<ITransformation> Transformations { get; }
+
     bool IsTrainingSample(int index);
     bool IsTestSample(int index);
Index: stable/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/ITransformation.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/ITransformation.cs	(revision 11159)
+++ stable/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/ITransformation.cs	(revision 11159)
@@ -0,0 +1,34 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Core;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface ITransformation : IParameterizedItem {
+    string ShortName { get; }
+    string Column { get; }
+  }
+
+  public interface ITransformation<T> : ITransformation {
+    IEnumerable<T> Apply(IEnumerable<T> data);
+  }
+}
Index: stable/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/ITransformationMapper.cs
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/ITransformationMapper.cs	(revision 11159)
+++ stable/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/ITransformationMapper.cs	(revision 11159)
@@ -0,0 +1,28 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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: stable/HeuristicLab.Problems.DataAnalysis/3.4/Plugin.cs.frame
===================================================================
--- stable/HeuristicLab.Problems.DataAnalysis/3.4/Plugin.cs.frame	(revision 11158)
+++ stable/HeuristicLab.Problems.DataAnalysis/3.4/Plugin.cs.frame	(revision 11159)
@@ -37,5 +37,5 @@
   [PluginDependency("HeuristicLab.Parameters", "3.3")]
   [PluginDependency("HeuristicLab.Persistence", "3.3")]
-  [PluginDependency("HeuristicLab.Problems.Instances", "3.3")]
+  [PluginDependency("HeuristicLab.Problems.Instances", "3.3")]  
   public class HeuristicLabProblemsDataAnalysisPlugin : PluginBase {
   }
