Index: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/HeuristicLab.DataPreprocessing-3.4.csproj
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/HeuristicLab.DataPreprocessing-3.4.csproj	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/HeuristicLab.DataPreprocessing-3.4.csproj	(revision 12053)
@@ -0,0 +1,196 @@
+﻿<?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.5</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>
+    <Prefer32Bit>false</Prefer32Bit>
+  </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>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <PlatformTarget>x64</PlatformTarget>
+    <OutputPath>..\..\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <PlatformTarget>x64</PlatformTarget>
+    <OutputPath>..\..\bin\</OutputPath>
+    <Optimize>true</Optimize>
+    <Prefer32Bit>false</Prefer32Bit>
+  </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>
+    <Prefer32Bit>false</Prefer32Bit>
+  </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>
+    <Prefer32Bit>false</Prefer32Bit>
+  </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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/CorrelationMatrixContent.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/CorrelationMatrixContent.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/CorrelationMatrixContent.cs	(revision 12053)
@@ -0,0 +1,64 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/DataCompletenessChartContent.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/DataCompletenessChartContent.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/DataCompletenessChartContent.cs	(revision 12053)
@@ -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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/DataGridContent.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/DataGridContent.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/DataGridContent.cs	(revision 12053)
@@ -0,0 +1,164 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/Filter/ComparisonFilter.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/Filter/ComparisonFilter.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/Filter/ComparisonFilter.cs	(revision 12053)
@@ -0,0 +1,140 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/Filter/IFilter.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/Filter/IFilter.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/Filter/IFilter.cs	(revision 12053)
@@ -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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/FilterContent.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/FilterContent.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/FilterContent.cs	(revision 12053)
@@ -0,0 +1,70 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/FilterLogic.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/FilterLogic.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/FilterLogic.cs	(revision 12053)
@@ -0,0 +1,96 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/FilteredPreprocessingData.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/FilteredPreprocessingData.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/FilteredPreprocessingData.cs	(revision 12053)
@@ -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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/HistogramContent.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/HistogramContent.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/HistogramContent.cs	(revision 12053)
@@ -0,0 +1,74 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/LineChartContent.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/LineChartContent.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/LineChartContent.cs	(revision 12053)
@@ -0,0 +1,47 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/ManipulationContent.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/ManipulationContent.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/ManipulationContent.cs	(revision 12053)
@@ -0,0 +1,57 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 theFilterLogic) {
+      manipulationLogic = theManipulationLogic;
+      searchLogic = theSearchLogic;
+      filterLogic = theFilterLogic;
+    }
+
+    public ManipulationContent(ManipulationContent content, Cloner cloner) : base(content, cloner) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ManipulationContent(this, cloner);
+    }
+
+
+  }
+}
Index: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/ManipulationLogic.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/ManipulationLogic.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/ManipulationLogic.cs	(revision 12053)
@@ -0,0 +1,405 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 Shuffle(bool shuffleRangesSeparately) {
+      Random random = new Random();
+      var ranges = new[] { preprocessingData.TestPartition, preprocessingData.TrainingPartition };
+      if (shuffleRangesSeparately) {
+        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);
+          }
+        });
+      } else {
+        preprocessingData.InTransaction(() => {
+          var indices = ranges.SelectMany(x => Enumerable.Range(x.Start, x.Size)).ToList();
+          var shuffledIndices = indices.OrderBy(x => random.Next());
+          ShuffleToIndices(indices.Zip(shuffledIndices, (i, j) => new Tuple<int, int>(i, j)).ToList());
+        });
+      }
+    }
+
+    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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingChartContent.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingChartContent.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingChartContent.cs	(revision 12053)
@@ -0,0 +1,142 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingContext.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingContext.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingContext.cs	(revision 12053)
@@ -0,0 +1,96 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingData.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingData.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingData.cs	(revision 12053)
@@ -0,0 +1,212 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingDataTable.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingDataTable.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/PreprocessingDataTable.cs	(revision 12053)
@@ -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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/ScatterPlotContent.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/ScatterPlotContent.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/ScatterPlotContent.cs	(revision 12053)
@@ -0,0 +1,74 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/SearchLogic.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/SearchLogic.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/SearchLogic.cs	(revision 12053)
@@ -0,0 +1,153 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/StatisticsContent.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/StatisticsContent.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/StatisticsContent.cs	(revision 12053)
@@ -0,0 +1,57 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/StatisticsLogic.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/StatisticsLogic.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/StatisticsLogic.cs	(revision 12053)
@@ -0,0 +1,198 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/TransactionalPreprocessingData.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/TransactionalPreprocessingData.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/TransactionalPreprocessingData.cs	(revision 12053)
@@ -0,0 +1,325 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/TransformationContent.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/TransformationContent.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Implementations/TransformationContent.cs	(revision 12053)
@@ -0,0 +1,56 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IDataGridContent.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IDataGridContent.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IDataGridContent.cs	(revision 12053)
@@ -0,0 +1,38 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IDataGridLogic.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IDataGridLogic.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IDataGridLogic.cs	(revision 12053)
@@ -0,0 +1,47 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IFilterLogic.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IFilterLogic.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IFilterLogic.cs	(revision 12053)
@@ -0,0 +1,43 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IFilteredPreprocessingData.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IFilteredPreprocessingData.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IFilteredPreprocessingData.cs	(revision 12053)
@@ -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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IManipulationLogic.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IManipulationLogic.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IManipulationLogic.cs	(revision 12053)
@@ -0,0 +1,48 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 Shuffle(bool shuffleRangesSeparately);
+    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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IPreprocessingContext.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IPreprocessingContext.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IPreprocessingContext.cs	(revision 12053)
@@ -0,0 +1,41 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IPreprocessingData.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IPreprocessingData.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IPreprocessingData.cs	(revision 12053)
@@ -0,0 +1,76 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/ISearchLogic.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/ISearchLogic.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/ISearchLogic.cs	(revision 12053)
@@ -0,0 +1,48 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IStatisticsLogic.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IStatisticsLogic.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IStatisticsLogic.cs	(revision 12053)
@@ -0,0 +1,54 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/ITransactionalPreprocessingData.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/ITransactionalPreprocessingData.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/ITransactionalPreprocessingData.cs	(revision 12053)
@@ -0,0 +1,36 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/ITransformationLogic.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/ITransformationLogic.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/ITransformationLogic.cs	(revision 12053)
@@ -0,0 +1,26 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IViewChartShortcut.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IViewChartShortcut.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IViewChartShortcut.cs	(revision 12053)
@@ -0,0 +1,27 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IViewShortcut.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IViewShortcut.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Interfaces/IViewShortcut.cs	(revision 12053)
@@ -0,0 +1,27 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Plugin.cs.frame
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Plugin.cs.frame	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Plugin.cs.frame	(revision 12053)
@@ -0,0 +1,40 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.1.$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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/PreprocessingTransformator.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/PreprocessingTransformator.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/PreprocessingTransformator.cs	(revision 12053)
@@ -0,0 +1,178 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/ProblemDataCreator.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/ProblemDataCreator.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/ProblemDataCreator.cs	(revision 12053)
@@ -0,0 +1,115 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.Problems.DataAnalysis;
+
+namespace HeuristicLab.DataPreprocessing {
+  public class ProblemDataCreator {
+
+    private readonly IPreprocessingContext context;
+
+    private Dataset ExportedDataset {
+      get {
+        return context.Data.ExportToDataset();
+      }
+    }
+
+    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);
+      // set the input variables to the correct checked state
+      var inputVariables = problemData.InputVariables.ToDictionary(x => x.Value, x => x);
+      foreach (var variable in oldProblemData.InputVariables) {
+        bool @checked = oldProblemData.InputVariables.ItemChecked(variable);
+        problemData.InputVariables.SetItemCheckedState(inputVariables[variable.Value], @checked);
+      }
+
+      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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Properties/AssemblyInfo.cs.frame	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Properties/AssemblyInfo.cs.frame	(revision 12053)
@@ -0,0 +1,56 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.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("HEAL")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2015 HEAL")]
+[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.1.$WCREV$")]
Index: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Properties/Resources.Designer.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Properties/Resources.Designer.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Properties/Resources.Designer.cs	(revision 12053)
@@ -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: /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Utils/DataPreprocessingChangedEvent.cs
===================================================================
--- /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Utils/DataPreprocessingChangedEvent.cs	(revision 12053)
+++ /branches/DataPreprocessingImprovements/HeuristicLab.DataPreprocessing/3.4/Utils/DataPreprocessingChangedEvent.cs	(revision 12053)
@@ -0,0 +1,49 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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);
+}
