Index: stable/HeuristicLab.DataPreprocessing/3.4/Content/CorrelationMatrixContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Content/CorrelationMatrixContent.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Content/CorrelationMatrixContent.cs	(revision 15242)
@@ -27,11 +27,11 @@
 namespace HeuristicLab.DataPreprocessing {
   [Item("Feature Correlation Matrix", "Represents the feature correlation matrix.")]
-  public class CorrelationMatrixContent : Item, IViewChartShortcut {
+  public class CorrelationMatrixContent : Item, IViewShortcut {
     public static new Image StaticItemImage {
       get { return HeuristicLab.Common.Resources.VSImageLibrary.Gradient; }
     }
 
-    private PreprocessingContext Context { get; set; }
-    private ITransactionalPreprocessingData PreprocessingData {
+    public PreprocessingContext Context { get; private set; }
+    public ITransactionalPreprocessingData PreprocessingData {
       get { return Context.Data; }
     }
Index: stable/HeuristicLab.DataPreprocessing/3.4/Content/DataCompletenessChartContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Content/DataCompletenessChartContent.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Content/DataCompletenessChartContent.cs	(revision 15242)
@@ -1,15 +1,35 @@
-﻿using System.Drawing;
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Drawing;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 
 namespace HeuristicLab.DataPreprocessing {
-  [Item("DataCompletenessChart", "Represents a datacompleteness chart.")]
+  [Item("Data Completeness Chart", "Represents a datacompleteness chart.")]
 
-  public class DataCompletenessChartContent : Item, IViewChartShortcut {
+  public class DataCompletenessChartContent : Item, IViewShortcut {
     public static new Image StaticItemImage {
       get { return HeuristicLab.Common.Resources.VSImageLibrary.EditBrightnessContrast; }
     }
 
-    //public DataGridLogic DataGridLogic { get; private set; }
     public SearchLogic SearchLogic { get; private set; }
 
Index: stable/HeuristicLab.DataPreprocessing/3.4/Content/DataGridContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Content/DataGridContent.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Content/DataGridContent.cs	(revision 15242)
@@ -30,12 +30,11 @@
 namespace HeuristicLab.DataPreprocessing {
 
-  [Item("DataGrid", "Represents a data grid.")]
+  [Item("Data Grid", "Represents a data grid.")]
   public class DataGridContent : Item, IStringConvertibleMatrix, IViewShortcut {
-
-    public ITransactionalPreprocessingData PreProcessingData { get; private set; }
-
     public static new Image StaticItemImage {
       get { return HeuristicLab.Common.Resources.VSImageLibrary.Table; }
     }
+
+    public ITransactionalPreprocessingData PreProcessingData { get; private set; }
 
     public ManipulationLogic ManipulationLogic { get; private set; }
@@ -43,46 +42,26 @@
 
     public int Rows {
-      get {
-        return PreProcessingData.Rows;
-      }
-      set {
-        //does nothing
-      }
+      get { return PreProcessingData.Rows; }
+      set { }
     }
 
     public int Columns {
-      get {
-        return PreProcessingData.Columns;
-      }
-      set {
-        //does nothing
-      }
+      get { return PreProcessingData.Columns; }
+      set { }
     }
 
     public IEnumerable<string> ColumnNames {
-      get {
-        return PreProcessingData.VariableNames;
-      }
-      set {
-
-      }
+      get { return PreProcessingData.VariableNames; }
+      set { }
     }
 
     public IEnumerable<string> RowNames {
-      get {
-        return Enumerable.Range(1, Rows).Select(n => n.ToString());
-      }
-      set {
-        throw new NotSupportedException();
-      }
+      get { return Enumerable.Range(1, Rows).Select(n => n.ToString()); }
+      set { throw new NotSupportedException(); }
     }
 
     public bool SortableView {
-      get {
-        return true;
-      }
-      set {
-        throw new NotSupportedException();
-      }
+      get { return true; }
+      set { throw new NotSupportedException(); }
     }
 
@@ -91,10 +70,8 @@
     }
 
-
     public IDictionary<int, IList<int>> Selection {
       get { return PreProcessingData.Selection; }
       set { PreProcessingData.Selection = value; }
     }
-
 
     public DataGridContent(ITransactionalPreprocessingData preProcessingData, ManipulationLogic theManipulationLogic, FilterLogic theFilterLogic) {
@@ -137,5 +114,4 @@
     }
 
-
     #region unused stuff/not implemented but necessary due to IStringConvertibleMatrix
 #pragma warning disable 0067
@@ -154,8 +130,6 @@
     public event EventHandler<EventArgs<int, int>> ItemChanged;
     public event EventHandler Reset;
-
 #pragma warning restore 0067
     #endregion
-
   }
 }
Index: stable/HeuristicLab.DataPreprocessing/3.4/Content/FilterContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Content/FilterContent.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Content/FilterContent.cs	(revision 15242)
@@ -28,33 +28,17 @@
   [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 FilterLogic FilterLogic { get; private set; }
 
-    public ICheckedItemCollection<IFilter> Filters {
-      get {
-        return this.filters;
-      }
-      set {
-        this.filters = value;
-      }
-    }
+    public ICheckedItemCollection<IFilter> Filters { get; private set; }
 
-    private bool isAndCombination = true;
-    public bool IsAndCombination {
-      get {
-        return this.isAndCombination;
-      }
-      set {
-        this.isAndCombination = value;
-      }
-    }
+    public bool IsAndCombination { get; set; }
 
     public FilterContent(FilterLogic filterLogic) {
+      Filters = new CheckedItemCollection<IFilter>();
+      IsAndCombination = true;
       FilterLogic = filterLogic;
     }
Index: stable/HeuristicLab.DataPreprocessing/3.4/Content/HistogramContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Content/HistogramContent.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Content/HistogramContent.cs	(revision 15242)
@@ -20,7 +20,8 @@
 #endregion
 
-using System.Collections.Generic;
+using System;
 using System.Drawing;
 using System.Linq;
+using HeuristicLab.Analysis;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -29,22 +30,19 @@
   [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 string GroupingVariableName { get; set; }
 
-    public int ClassifierVariableIndex {
-      get { return this.classifierVariableIndex; }
-      set { this.classifierVariableIndex = value; }
-    }
-    public bool IsDetailedChartViewEnabled { get; set; }
+    public int Bins { get; set; }
+    public bool ExactBins { get; set; }
 
+    public LegendOrder Order { get; set; }
 
     public HistogramContent(IFilteredPreprocessingData preprocessingData)
       : base(preprocessingData) {
-      AllInOneMode = false;
+      Bins = 10;
+      ExactBins = false;
     }
 
@@ -56,19 +54,47 @@
     }
 
-    public IEnumerable<string> GetVariableNamesForHistogramClassification() {
-      List<string> doubleVariableNames = new List<string>();
+    public static DataTable CreateHistogram(IFilteredPreprocessingData preprocessingData, string variableName, string groupingVariableName, DataTableVisualProperties.DataTableHistogramAggregation aggregation, LegendOrder legendOrder = LegendOrder.Alphabetically) {
+      var dataTable = new DataTable {
+        VisualProperties = { Title = variableName, HistogramAggregation = aggregation },
+      };
 
-      //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));
-        }
+      if (string.IsNullOrEmpty(groupingVariableName)) {
+        var row = PreprocessingChartContent.CreateDataRow(preprocessingData, variableName, DataRowVisualProperties.DataRowChartType.Histogram);
+        row.VisualProperties.IsVisibleInLegend = false;
+        dataTable.Rows.Add(row);
+        return dataTable;
       }
-      return doubleVariableNames;
+
+      int variableIndex = preprocessingData.GetColumnIndex(variableName);
+      var variableValues = preprocessingData.GetValues<double>(variableIndex);
+      int groupVariableIndex = preprocessingData.GetColumnIndex(groupingVariableName);
+      var groupingValues = Enumerable.Empty<string>();
+
+      if (preprocessingData.VariableHasType<double>(groupVariableIndex)) {
+        groupingValues = preprocessingData.GetValues<double>(groupVariableIndex).Select(x => x.ToString());
+      } else if (preprocessingData.VariableHasType<string>(groupVariableIndex)) {
+        groupingValues = preprocessingData.GetValues<string>(groupVariableIndex);
+      } else if (preprocessingData.VariableHasType<DateTime>(groupVariableIndex)) {
+        groupingValues = preprocessingData.GetValues<DateTime>(groupVariableIndex).Select(x => x.ToString());
+      }
+
+      var groups = groupingValues.Zip(variableValues, Tuple.Create).GroupBy(t => t.Item1, t => t.Item2);
+
+      if (legendOrder == LegendOrder.Alphabetically)
+        groups = groups.OrderBy(x => x.Key, new NaturalStringComparer());
+
+      foreach (var group in groups) {
+        var classRow = new DataRow {
+          Name = group.Key,
+          VisualProperties = {
+              ChartType = DataRowVisualProperties.DataRowChartType.Histogram,
+              IsVisibleInLegend = !string.IsNullOrEmpty(groupingVariableName)
+            }
+        };
+        classRow.Values.AddRange(group);
+        dataTable.Rows.Add(classRow);
+      }
+      return dataTable;
     }
-
   }
 }
Index: stable/HeuristicLab.DataPreprocessing/3.4/Content/IViewChartShortcut.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Content/IViewChartShortcut.cs	(revision 15142)
+++ 	(revision )
@@ -1,26 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-
-namespace HeuristicLab.DataPreprocessing {
-  public interface IViewChartShortcut : IViewShortcut {
-  }
-}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Content/LineChartContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Content/LineChartContent.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Content/LineChartContent.cs	(revision 15242)
@@ -26,6 +26,7 @@
 namespace HeuristicLab.DataPreprocessing {
 
-  [Item("LineChart", "Represents the line chart grid.")]
+  [Item("Line Chart", "Represents the line chart grid.")]
   public class LineChartContent : PreprocessingChartContent {
+    public bool AllInOneMode { get; set; }
 
     public static new Image StaticItemImage {
@@ -35,8 +36,10 @@
     public LineChartContent(IFilteredPreprocessingData preprocessingData)
       : base(preprocessingData) {
+      AllInOneMode = true;
     }
 
     public LineChartContent(LineChartContent content, Cloner cloner)
       : base(content, cloner) {
+      this.AllInOneMode = content.AllInOneMode;
     }
     public override IDeepCloneable Clone(Cloner cloner) {
Index: stable/HeuristicLab.DataPreprocessing/3.4/Content/ManipulationContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Content/ManipulationContent.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Content/ManipulationContent.cs	(revision 15242)
@@ -28,21 +28,16 @@
   [Item("Manipulation", "Represents the available manipulations on a data set.")]
   public class ManipulationContent : Item, IViewShortcut {
-
-    private ManipulationLogic manipulationLogic;
-    private SearchLogic searchLogic;
-    private FilterLogic filterLogic;
-
-    public ManipulationLogic ManipulationLogic { get { return manipulationLogic; } }
-    public SearchLogic SearchLogic { get { return searchLogic; } }
-    public FilterLogic FilterLogic { get { return filterLogic; } }
-
     public static new Image StaticItemImage {
       get { return HeuristicLab.Common.Resources.VSImageLibrary.Method; }
     }
 
-    public ManipulationContent(ManipulationLogic theManipulationLogic, SearchLogic theSearchLogic, FilterLogic theFilterLogic) {
-      manipulationLogic = theManipulationLogic;
-      searchLogic = theSearchLogic;
-      filterLogic = theFilterLogic;
+    public ManipulationLogic ManipulationLogic { get; private set; }
+    public SearchLogic SearchLogic { get; private set; }
+    public FilterLogic FilterLogic { get; private set; }
+
+    public ManipulationContent(ManipulationLogic manipulationLogic, SearchLogic searchLogic, FilterLogic filterLogic) {
+      ManipulationLogic = manipulationLogic;
+      SearchLogic = searchLogic;
+      FilterLogic = filterLogic;
     }
 
@@ -52,6 +47,4 @@
       return new ManipulationContent(this, cloner);
     }
-
-
   }
 }
Index: stable/HeuristicLab.DataPreprocessing/3.4/Content/MultiScatterPlotContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Content/MultiScatterPlotContent.cs	(revision 15242)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Content/MultiScatterPlotContent.cs	(revision 15242)
@@ -0,0 +1,46 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.DataPreprocessing {
+
+  [Item("Multi Scatter Plot", "Represents a multi scatter plot.")]
+  public class MultiScatterPlotContent : ScatterPlotContent {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Performance; }
+    }
+
+    public MultiScatterPlotContent(IFilteredPreprocessingData preprocessingData)
+      : base(preprocessingData) {
+    }
+
+    public MultiScatterPlotContent(MultiScatterPlotContent content, Cloner cloner)
+      : base(content, cloner) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MultiScatterPlotContent(this, cloner);
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Content/PreprocessingChartContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Content/PreprocessingChartContent.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Content/PreprocessingChartContent.cs	(revision 15242)
@@ -23,6 +23,8 @@
 using System.Collections.Generic;
 using System.Drawing;
+using System.Linq;
 using HeuristicLab.Analysis;
 using HeuristicLab.Common;
+using HeuristicLab.Common.Resources;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
@@ -30,22 +32,28 @@
 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; }
+  public class PreprocessingChartContent : Item, IViewShortcut {
+    public enum LegendOrder {
+      Alphabetically,
+      Appearance
     }
 
-    private bool allInOneMode = true;
-    public bool AllInOneMode {
-      get { return this.allInOneMode; }
-      set { this.allInOneMode = value; }
+    public static new Image StaticItemImage {
+      get { return VSImageLibrary.PieChart; }
     }
 
     private ICheckedItemList<StringValue> variableItemList = null;
     public ICheckedItemList<StringValue> VariableItemList {
-      get { return this.variableItemList; }
-      set { this.variableItemList = value; }
+      get {
+        if (variableItemList == null)
+          variableItemList = CreateVariableItemList(PreprocessingData);
+        return this.variableItemList;
+      }
     }
 
     public IFilteredPreprocessingData PreprocessingData { get; private set; }
+    public event DataPreprocessingChangedEventHandler Changed {
+      add { PreprocessingData.Changed += value; }
+      remove { PreprocessingData.Changed -= value; }
+    }
 
     public PreprocessingChartContent(IFilteredPreprocessingData preprocessingData) {
@@ -55,5 +63,4 @@
     public PreprocessingChartContent(PreprocessingChartContent content, Cloner cloner)
       : base(content, cloner) {
-      this.allInOneMode = content.allInOneMode;
       this.PreprocessingData = content.PreprocessingData;
       this.variableItemList = cloner.Clone<ICheckedItemList<StringValue>>(variableItemList);
@@ -63,7 +70,10 @@
     }
 
+    public DataRow CreateDataRow(string variableName, DataRowVisualProperties.DataRowChartType chartType) {
+      return CreateDataRow(PreprocessingData, variableName, chartType);
+    }
 
-    public DataRow CreateDataRow(string variableName, DataRowVisualProperties.DataRowChartType chartType) {
-      IList<double> values = PreprocessingData.GetValues<double>(PreprocessingData.GetColumnIndex(variableName));
+    public static DataRow CreateDataRow(IFilteredPreprocessingData preprocessingData, string variableName, DataRowVisualProperties.DataRowChartType chartType) {
+      IList<double> values = preprocessingData.GetValues<double>(preprocessingData.GetColumnIndex(variableName));
       DataRow row = new DataRow(variableName, "", values);
       row.VisualProperties.ChartType = chartType;
@@ -71,73 +81,31 @@
     }
 
-    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(IList<string> checkedItems = null) {
-      if (checkedItems == null) checkedItems = new string[0];
+    private static ICheckedItemList<StringValue> CreateVariableItemList(IPreprocessingData preprocessingData) {
       ICheckedItemList<StringValue> itemList = new CheckedItemList<StringValue>();
-      foreach (string name in PreprocessingData.GetDoubleVariableNames()) {
+      foreach (string name in preprocessingData.GetDoubleVariableNames()) {
         var n = new StringValue(name);
-        itemList.Add(n, checkedItems.Contains(name));
+        bool isInputTarget = preprocessingData.InputVariables.Contains(name) || preprocessingData.TargetVariable == name;
+        itemList.Add(n, isInputTarget);
       }
       return new ReadOnlyCheckedItemList<StringValue>(itemList);
     }
 
-    public event DataPreprocessingChangedEventHandler Changed {
-      add { PreprocessingData.Changed += value; }
-      remove { PreprocessingData.Changed -= value; }
+    public static IEnumerable<string> GetVariableNamesForGrouping(IPreprocessingData preprocessingData, int maxDistinctValues = 20) {
+      var variableNames = new List<string>();
+
+      for (int i = 0; i < preprocessingData.Columns; ++i) {
+        int distinctValues = Int32.MaxValue;
+        if (preprocessingData.VariableHasType<double>(i))
+          distinctValues = preprocessingData.GetValues<double>(i).GroupBy(x => x).Count();
+        else if (preprocessingData.VariableHasType<string>(i))
+          distinctValues = preprocessingData.GetValues<string>(i).GroupBy(x => x).Count();
+        else if (preprocessingData.VariableHasType<DateTime>(i))
+          distinctValues = preprocessingData.GetValues<DateTime>(i).GroupBy(x => x).Count();
+
+        if (distinctValues <= maxDistinctValues)
+          variableNames.Add(preprocessingData.GetVariableName(i));
+      }
+      return variableNames;
     }
-
   }
 }
Index: stable/HeuristicLab.DataPreprocessing/3.4/Content/PreprocessingDataTable.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Content/PreprocessingDataTable.cs	(revision 15142)
+++ 	(revision )
@@ -1,58 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using HeuristicLab.Analysis;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-
-namespace HeuristicLab.DataPreprocessing {
-  [Item("PreprossingDataTable", "A table of data values.")]
-  public class PreprocessingDataTable : DataTable {
-
-    public PreprocessingDataTable()
-      : base() {
-      SelectedRows = new NamedItemCollection<DataRow>();
-    }
-    public PreprocessingDataTable(string name)
-      : base(name) {
-      SelectedRows = new NamedItemCollection<DataRow>();
-    }
-
-    protected PreprocessingDataTable(PreprocessingDataTable original, Cloner cloner)
-      : base(original, cloner) {
-      this.selectedRows = cloner.Clone(original.selectedRows);
-    }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new PreprocessingDataTable(this, cloner);
-    }
-
-    private NamedItemCollection<DataRow> selectedRows;
-    public NamedItemCollection<DataRow> SelectedRows {
-      get { return selectedRows; }
-      private set {
-        if (selectedRows != null) throw new InvalidOperationException("Rows already set");
-        selectedRows = value;
-      }
-    }
-
-  }
-}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Content/ScatterPlotContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Content/ScatterPlotContent.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Content/ScatterPlotContent.cs	(revision 15242)
@@ -20,71 +20,86 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
-using System.Drawing;
 using System.Linq;
 using HeuristicLab.Analysis;
 using HeuristicLab.Common;
-using HeuristicLab.Core;
+using HeuristicLab.Visualization.ChartControlsExtensions;
 
 namespace HeuristicLab.DataPreprocessing {
 
-  [Item("ScatterPlot", "Represents a scatter plot.")]
-  public class ScatterPlotContent : PreprocessingChartContent {
+  public abstract class ScatterPlotContent : PreprocessingChartContent {
+    public string GroupingVariable { get; set; }
 
-    public string SelectedXVariable { get; set; }
-    public string SelectedYVariable { get; set; }
-    public string SelectedColorVariable { get; set; }
-
-    public ScatterPlotContent(IFilteredPreprocessingData preprocessingData)
+    protected ScatterPlotContent(IFilteredPreprocessingData preprocessingData)
       : base(preprocessingData) {
     }
 
-    public ScatterPlotContent(ScatterPlotContent content, Cloner cloner)
+    protected ScatterPlotContent(ScatterPlotContent content, Cloner cloner)
       : base(content, cloner) {
-      this.SelectedXVariable = content.SelectedXVariable;
-      this.SelectedYVariable = content.SelectedYVariable;
-      this.SelectedColorVariable = content.SelectedColorVariable;
     }
 
-    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, string variableNameColor = "-") {
+    public static ScatterPlot CreateScatterPlot(IFilteredPreprocessingData preprocessingData, string variableNameX, string variableNameY, string variableNameGroup = "-", LegendOrder legendOrder = LegendOrder.Alphabetically) {
       ScatterPlot scatterPlot = new ScatterPlot();
 
-      IList<double> xValues = PreprocessingData.GetValues<double>(PreprocessingData.GetColumnIndex(variableNameX));
-      IList<double> yValues = PreprocessingData.GetValues<double>(PreprocessingData.GetColumnIndex(variableNameY));
-      if (variableNameColor == null || variableNameColor == "-") {
-        List<Point2D<double>> points = new List<Point2D<double>>();
+      IList<double> xValues = preprocessingData.GetValues<double>(preprocessingData.GetColumnIndex(variableNameX));
+      IList<double> yValues = preprocessingData.GetValues<double>(preprocessingData.GetColumnIndex(variableNameY));
 
-        for (int i = 0; i < xValues.Count; i++) {
-          Point2D<double> point = new Point2D<double>(xValues[i], yValues[i]);
-          points.Add(point);
-        }
+      var points = xValues.Zip(yValues, (x, y) => new Point2D<double>(x, y)).ToList();
+      var validPoints = points.Where(p => !double.IsNaN(p.X) && !double.IsNaN(p.Y) && !double.IsInfinity(p.X) && !double.IsInfinity(p.Y)).ToList();
+      if (validPoints.Any()) {
+        try {
+          double axisMin, axisMax, axisInterval;
+          ChartUtil.CalculateOptimalAxisInterval(validPoints.Min(p => p.X), validPoints.Max(p => p.X), out axisMin, out axisMax, out axisInterval);
+          scatterPlot.VisualProperties.XAxisMinimumAuto = false;
+          scatterPlot.VisualProperties.XAxisMaximumAuto = false;
+          scatterPlot.VisualProperties.XAxisMinimumFixedValue = axisMin;
+          scatterPlot.VisualProperties.XAxisMaximumFixedValue = axisMax;
+        } catch (ArgumentOutOfRangeException) { } // error during CalculateOptimalAxisInterval 
+        try {
+          double axisMin, axisMax, axisInterval;
+          ChartUtil.CalculateOptimalAxisInterval(validPoints.Min(p => p.Y), validPoints.Max(p => p.Y), out axisMin, out axisMax, out axisInterval);
+          scatterPlot.VisualProperties.YAxisMinimumAuto = false;
+          scatterPlot.VisualProperties.YAxisMaximumAuto = false;
+          scatterPlot.VisualProperties.YAxisMinimumFixedValue = axisMin;
+          scatterPlot.VisualProperties.YAxisMaximumFixedValue = axisMax;
+        } catch (ArgumentOutOfRangeException) { } // error during CalculateOptimalAxisInterval 
+      }
 
-        ScatterPlotDataRow scdr = new ScatterPlotDataRow(variableNameX + " - " + variableNameY, "", points);
+
+      //No Grouping
+      if (string.IsNullOrEmpty(variableNameGroup) || variableNameGroup == "-") {
+        ScatterPlotDataRow scdr = new ScatterPlotDataRow(variableNameX + " - " + variableNameY, "", validPoints);
+        scdr.VisualProperties.IsVisibleInLegend = false;
         scatterPlot.Rows.Add(scdr);
+        return scatterPlot;
+      }
 
-      } else {
-        var colorValues = PreprocessingData.GetValues<double>(PreprocessingData.GetColumnIndex(variableNameColor));
-        var data = xValues.Zip(yValues, (x, y) => new { x, y }).Zip(colorValues, (v, c) => new { v.x, v.y, c }).ToList();
-        var gradients = ColorGradient.Colors;
-        int curGradient = 0;
-        int numColors = colorValues.Distinct().Count();
-        foreach (var colorValue in colorValues.Distinct()) {
-          var values = data.Where(x => x.c == colorValue);
-          var row = new ScatterPlotDataRow(
-            variableNameX + " - " + variableNameY + " (" + colorValue + ")",
-            "",
-            values.Select(v => new Point2D<double>(v.x, v.y)),
-            new ScatterPlotDataRowVisualProperties() { Color = gradients[curGradient] });
-          curGradient += gradients.Count / numColors;
-          scatterPlot.Rows.Add(row);
-        }
+      //Grouping
+      int groupVariableIndex = preprocessingData.GetColumnIndex(variableNameGroup);
+      var groupingValues = Enumerable.Empty<string>();
+
+      if (preprocessingData.VariableHasType<double>(groupVariableIndex)) {
+        groupingValues = preprocessingData.GetValues<double>(groupVariableIndex).Select(x => x.ToString());
+      } else if (preprocessingData.VariableHasType<string>(groupVariableIndex)) {
+        groupingValues = preprocessingData.GetValues<string>(groupVariableIndex);
+      } else if (preprocessingData.VariableHasType<DateTime>(groupVariableIndex)) {
+        groupingValues = preprocessingData.GetValues<DateTime>(groupVariableIndex).Select(x => x.ToString());
+      }
+      var groups = groupingValues.Zip(validPoints, Tuple.Create).GroupBy(t => t.Item1, t => t.Item2);
+
+      if (legendOrder == LegendOrder.Alphabetically)
+        groups = groups.OrderBy(x => x.Key, new NaturalStringComparer());
+
+      foreach (var group in groups) {
+        var scdr = new ScatterPlotDataRow {
+          Name = group.Key,
+          VisualProperties = {
+            IsVisibleInLegend = true,
+            PointSize = 6
+          }
+        };
+        scdr.Points.AddRange(group);
+        scatterPlot.Rows.Add(scdr);
       }
       return scatterPlot;
Index: stable/HeuristicLab.DataPreprocessing/3.4/Content/SingleScatterPlotContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Content/SingleScatterPlotContent.cs	(revision 15242)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Content/SingleScatterPlotContent.cs	(revision 15242)
@@ -0,0 +1,52 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.DataPreprocessing {
+
+  [Item("Scatter Plot", "Represents a scatter plot.")]
+  public class SingleScatterPlotContent : ScatterPlotContent {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Performance; }
+    }
+
+    public string SelectedXVariable { get; set; }
+    public string SelectedYVariable { get; set; }
+
+    public SingleScatterPlotContent(IFilteredPreprocessingData preprocessingData)
+      : base(preprocessingData) {
+    }
+
+    public SingleScatterPlotContent(SingleScatterPlotContent content, Cloner cloner)
+      : base(content, cloner) {
+      this.SelectedXVariable = content.SelectedXVariable;
+      this.SelectedYVariable = content.SelectedYVariable;
+      this.GroupingVariable = content.GroupingVariable;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SingleScatterPlotContent(this, cloner);
+    }
+  }
+}
Index: stable/HeuristicLab.DataPreprocessing/3.4/Content/StatisticsContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Content/StatisticsContent.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Content/StatisticsContent.cs	(revision 15242)
@@ -27,21 +27,18 @@
   [Item("Statistics", "Represents the statistics grid.")]
   public class StatisticsContent : Item, IViewShortcut {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Object; }
+    }
 
-    private readonly StatisticsLogic statisticsLogic;
-    public StatisticsContent(StatisticsLogic theStatisticsLogic) {
-      statisticsLogic = theStatisticsLogic;
+    public ITransactionalPreprocessingData PreprocessingData { get; private set; }
+    public StatisticsLogic StatisticsLogic { get; private set; }
+
+    public StatisticsContent(ITransactionalPreprocessingData preProcessingData, StatisticsLogic statisticsLogic) {
+      PreprocessingData = preProcessingData;
+      StatisticsLogic = statisticsLogic;
     }
 
     public StatisticsContent(StatisticsContent content, Cloner cloner)
       : base(content, cloner) {
-
-    }
-
-    public StatisticsLogic StatisticsLogic {
-      get { return statisticsLogic; }
-    }
-
-    public static new Image StaticItemImage {
-      get { return HeuristicLab.Common.Resources.VSImageLibrary.Object; }
     }
 
@@ -51,8 +48,7 @@
 
     public event DataPreprocessingChangedEventHandler Changed {
-      add { statisticsLogic.Changed += value; }
-      remove { statisticsLogic.Changed -= value; }
+      add { StatisticsLogic.Changed += value; }
+      remove { StatisticsLogic.Changed -= value; }
     }
-
   }
 }
Index: stable/HeuristicLab.DataPreprocessing/3.4/Content/TransformationContent.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Content/TransformationContent.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Content/TransformationContent.cs	(revision 15242)
@@ -28,4 +28,7 @@
   [Item("Transformation", "Represents the transformation grid.")]
   public class TransformationContent : Item, IViewShortcut {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Method; }
+    }
 
     public IPreprocessingData Data { get; private set; }
@@ -33,8 +36,4 @@
 
     public ICheckedItemList<ITransformation> CheckedTransformationList { get; private set; }
-
-    public static new Image StaticItemImage {
-      get { return HeuristicLab.Common.Resources.VSImageLibrary.Method; }
-    }
 
     public TransformationContent(IPreprocessingData data, FilterLogic filterLogic) {
Index: stable/HeuristicLab.DataPreprocessing/3.4/Data/FilteredPreprocessingData.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Data/FilteredPreprocessingData.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Data/FilteredPreprocessingData.cs	(revision 15242)
@@ -271,5 +271,4 @@
 
     #region IPreprocessingData Members
-
     public bool Validate(string value, out string errorMessage, int columnIndex) {
       return originalData.Validate(value, out errorMessage, columnIndex);
Index: stable/HeuristicLab.DataPreprocessing/3.4/Data/IPreprocessingData.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Data/IPreprocessingData.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Data/IPreprocessingData.cs	(revision 15242)
@@ -27,5 +27,4 @@
 
 namespace HeuristicLab.DataPreprocessing {
-
   public interface IPreprocessingData : INamedItem {
     T GetCell<T>(int columnIndex, int rowIndex);
Index: stable/HeuristicLab.DataPreprocessing/3.4/Data/ITransactionalPreprocessingData.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Data/ITransactionalPreprocessingData.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Data/ITransactionalPreprocessingData.cs	(revision 15242)
@@ -24,5 +24,4 @@
 namespace HeuristicLab.DataPreprocessing {
   public interface ITransactionalPreprocessingData : IPreprocessingData {
-
     event DataPreprocessingChangedEventHandler Changed;
 
Index: stable/HeuristicLab.DataPreprocessing/3.4/Data/PreprocessingData.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Data/PreprocessingData.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Data/PreprocessingData.cs	(revision 15242)
@@ -33,12 +33,8 @@
   [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; }
-    }
+    public IList<ITransformation> Transformations { get; protected set; }
 
     protected IList<IList> variableValues;
@@ -85,5 +81,5 @@
       TrainingPartition = (IntRange)original.TrainingPartition.Clone(cloner);
       TestPartition = (IntRange)original.TestPartition.Clone(cloner);
-      transformations = new List<ITransformation>(original.transformations.Select(cloner.Clone));
+      Transformations = new List<ITransformation>(original.Transformations.Select(cloner.Clone));
 
       InputVariables = new List<string>(original.InputVariables);
@@ -97,5 +93,5 @@
       Name = "Preprocessing Data";
 
-      transformations = new List<ITransformation>();
+      Transformations = new List<ITransformation>();
       selection = new Dictionary<int, IList<int>>();
 
@@ -166,5 +162,4 @@
 
     #region IPreprocessingData Members
-
     public abstract T GetCell<T>(int columnIndex, int rowIndex);
 
Index: stable/HeuristicLab.DataPreprocessing/3.4/Data/TransactionalPreprocessingData.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Data/TransactionalPreprocessingData.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Data/TransactionalPreprocessingData.cs	(revision 15242)
@@ -33,5 +33,4 @@
   [Item("PreprocessingData", "Represents data used for preprocessing.")]
   public class TransactionalPreprocessingData : PreprocessingData, ITransactionalPreprocessingData {
-
     private class Snapshot {
       public IList<IList> VariableValues { get; set; }
@@ -70,5 +69,5 @@
         TrainingPartition = new IntRange(TrainingPartition.Start, TrainingPartition.End),
         TestPartition = new IntRange(TestPartition.Start, TestPartition.End),
-        Transformations = new List<ITransformation>(transformations),
+        Transformations = new List<ITransformation>(Transformations),
         ChangedType = changedType,
         ChangedColumn = column,
@@ -83,13 +82,10 @@
 
     #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];
@@ -216,5 +212,4 @@
     }
 
-
     public override void InsertRow(int rowIndex) {
       SaveSnapshot(DataPreprocessingChangedEventType.DeleteRow, -1, rowIndex);
@@ -346,5 +341,4 @@
 
     #region TransactionalPreprocessingData members
-
     public bool IsUndoAvailable {
       get { return undoHistory.Count > 0; }
@@ -358,5 +352,5 @@
         TrainingPartition = previousSnapshot.TrainingPartition;
         TestPartition = previousSnapshot.TestPartition;
-        transformations = previousSnapshot.Transformations;
+        Transformations = previousSnapshot.Transformations;
         undoHistory.Remove(previousSnapshot);
         OnChanged(previousSnapshot.ChangedType,
@@ -384,5 +378,4 @@
       OnChanged(@event, -1, -1);
     }
-
     #endregion
   }
Index: stable/HeuristicLab.DataPreprocessing/3.4/HeuristicLab.DataPreprocessing-3.4.csproj
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/HeuristicLab.DataPreprocessing-3.4.csproj	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/HeuristicLab.DataPreprocessing-3.4.csproj	(revision 15242)
@@ -18,5 +18,5 @@
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
-    <OutputPath>..\..\bin\</OutputPath>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
@@ -28,5 +28,5 @@
     <DebugType>pdbonly</DebugType>
     <Optimize>true</Optimize>
-    <OutputPath>..\..\bin\</OutputPath>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
     <DefineConstants>TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
@@ -36,5 +36,5 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
     <PlatformTarget>x64</PlatformTarget>
-    <OutputPath>..\..\bin\</OutputPath>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <Prefer32Bit>false</Prefer32Bit>
@@ -42,5 +42,5 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
     <PlatformTarget>x64</PlatformTarget>
-    <OutputPath>..\..\bin\</OutputPath>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
     <Optimize>true</Optimize>
     <Prefer32Bit>false</Prefer32Bit>
@@ -48,5 +48,5 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
     <DebugSymbols>true</DebugSymbols>
-    <OutputPath>..\..\bin\</OutputPath>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <DebugType>full</DebugType>
@@ -57,5 +57,5 @@
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
-    <OutputPath>..\..\bin\</OutputPath>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
     <DefineConstants>TRACE</DefineConstants>
     <Optimize>true</Optimize>
@@ -78,4 +78,6 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Content\MultiScatterPlotContent.cs" />
+    <Compile Include="Content\SingleScatterPlotContent.cs" />
     <Compile Include="Content\ScatterPlotContent.cs" />
     <Compile Include="Content\DataCompletenessChartContent.cs" />
@@ -84,6 +86,4 @@
     <Compile Include="Content\PreprocessingChartContent.cs" />
     <Compile Include="Data\PreprocessingData.cs" />
-    <Compile Include="Content\PreprocessingDataTable.cs" />
-    <Compile Include="Content\IViewChartShortcut.cs" />
     <Compile Include="Data\IFilteredPreprocessingData.cs" />
     <Compile Include="Content\CorrelationMatrixContent.cs" />
@@ -118,35 +118,35 @@
   <ItemGroup>
     <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
-      <Project>{887425b4-4348-49ed-a457-b7d2c26ddbf9}</Project>
+      <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>
+      <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>
+      <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>
+      <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>
+      <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>
+      <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>
+      <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project>
       <Name>HeuristicLab.Optimization-3.3</Name>
       <Private>False</Private>
@@ -158,10 +158,10 @@
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.PluginInfrastructure\3.3\HeuristicLab.PluginInfrastructure-3.3.csproj">
-      <Project>{94186a6a-5176-4402-ae83-886557b53cca}</Project>
+      <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>
+      <Project>{DF87C13E-A889-46FF-8153-66DCAA8C5674}</Project>
       <Name>HeuristicLab.Problems.DataAnalysis-3.4</Name>
       <Private>False</Private>
@@ -170,4 +170,9 @@
       <Project>{F4539FB6-4708-40C9-BE64-0A1390AEA197}</Project>
       <Name>HeuristicLab.Random-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Visualization.ChartControlsExtensions\3.3\HeuristicLab.Visualization.ChartControlsExtensions-3.3.csproj">
+      <Project>{315BDA09-3F4F-49B3-9790-B37CFC1C5750}</Project>
+      <Name>HeuristicLab.Visualization.ChartControlsExtensions-3.3</Name>
       <Private>False</Private>
     </ProjectReference>
Index: stable/HeuristicLab.DataPreprocessing/3.4/Logic/Filter/ComparisonFilter.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Logic/Filter/ComparisonFilter.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Logic/Filter/ComparisonFilter.cs	(revision 15242)
@@ -30,5 +30,4 @@
   [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"; }
Index: stable/HeuristicLab.DataPreprocessing/3.4/Logic/FilterLogic.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Logic/FilterLogic.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Logic/FilterLogic.cs	(revision 15242)
@@ -27,11 +27,8 @@
 namespace HeuristicLab.DataPreprocessing {
   public class FilterLogic {
-
     public IFilteredPreprocessingData PreprocessingData { get; private set; }
 
     public bool IsFiltered {
-      get {
-        return PreprocessingData.IsFiltered;
-      }
+      get { return PreprocessingData.IsFiltered; }
     }
 
Index: stable/HeuristicLab.DataPreprocessing/3.4/Logic/ManipulationLogic.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Logic/ManipulationLogic.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Logic/ManipulationLogic.cs	(revision 15242)
@@ -40,6 +40,6 @@
     }
 
-    public ManipulationLogic(ITransactionalPreprocessingData _prepocessingData, SearchLogic theSearchLogic, StatisticsLogic theStatisticsLogic) {
-      preprocessingData = _prepocessingData;
+    public ManipulationLogic(ITransactionalPreprocessingData preprocessingData, SearchLogic theSearchLogic, StatisticsLogic theStatisticsLogic) {
+      this.preprocessingData = preprocessingData;
       searchLogic = theSearchLogic;
       statisticsLogic = theStatisticsLogic;
@@ -109,11 +109,4 @@
       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) {
@@ -291,5 +284,4 @@
 
     public List<int> RowsWithMissingValuesGreater(double percent) {
-
       List<int> rows = new List<int>();
 
@@ -305,5 +297,4 @@
 
     public List<int> ColumnsWithMissingValuesGreater(double percent) {
-
       List<int> columns = new List<int>();
       for (int i = 0; i < preprocessingData.Columns; ++i) {
@@ -318,5 +309,4 @@
 
     public List<int> ColumnsWithVarianceSmaller(double variance) {
-
       List<int> columns = new List<int>();
       for (int i = 0; i < preprocessingData.Columns; ++i) {
@@ -362,5 +352,4 @@
       });
     }
-
   }
 }
Index: stable/HeuristicLab.DataPreprocessing/3.4/Logic/StatisticsLogic.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Logic/StatisticsLogic.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Logic/StatisticsLogic.cs	(revision 15242)
@@ -27,5 +27,4 @@
 namespace HeuristicLab.DataPreprocessing {
   public class StatisticsLogic {
-
     private readonly ITransactionalPreprocessingData preprocessingData;
     private readonly SearchLogic searchLogic;
Index: stable/HeuristicLab.DataPreprocessing/3.4/Plugin.cs.frame
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/Plugin.cs.frame	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/Plugin.cs.frame	(revision 15242)
@@ -34,8 +34,9 @@
   [PluginDependency("HeuristicLab.Collections", "3.3")]
   [PluginDependency("HeuristicLab.Data","3.3")]
-  [PluginDependency("HeuristicLab.Optimization", "3.3")]  
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
   [PluginDependency("HeuristicLab.Persistence", "3.3")]
   [PluginDependency("HeuristicLab.Problems.DataAnalysis","3.4")]
   [PluginDependency("HeuristicLab.Random", "3.3")]
+  [PluginDependency("HeuristicLab.Visualization.ChartControlsExtensions", "3.3")]
   public class HeuristicLabDataPreprocessingPlugin : PluginBase {
   }
Index: stable/HeuristicLab.DataPreprocessing/3.4/PreprocessingContext.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/PreprocessingContext.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/PreprocessingContext.cs	(revision 15242)
@@ -32,5 +32,4 @@
   [StorableClass]
   public class PreprocessingContext : NamedItem, IStorableContent {
-
     public string Filename { get; set; }
 
Index: stable/HeuristicLab.DataPreprocessing/3.4/ProblemDataCreator.cs
===================================================================
--- stable/HeuristicLab.DataPreprocessing/3.4/ProblemDataCreator.cs	(revision 15142)
+++ stable/HeuristicLab.DataPreprocessing/3.4/ProblemDataCreator.cs	(revision 15242)
@@ -28,14 +28,13 @@
 namespace HeuristicLab.DataPreprocessing {
   public class ProblemDataCreator {
-
     private readonly PreprocessingContext context;
 
     private Dataset ExportedDataset {
-      get {
-        return context.Data.ExportToDataset();
-      }
+      get { return context.Data.ExportToDataset(); }
     }
 
-    private IList<ITransformation> Transformations { get { return context.Data.Transformations; } }
+    private IList<ITransformation> Transformations {
+      get { return context.Data.Transformations; }
+    }
 
     public ProblemDataCreator(PreprocessingContext context) {
