Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/DataBarSetView.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/DataBarSetView.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/DataBarSetView.cs	(revision 17980)
@@ -1,6 +1,5 @@
 ﻿#region License Information
-
 /* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -19,5 +18,4 @@
  * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
  */
-
 #endregion
 
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/DatastreamAnalysisOptimizerView.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/DatastreamAnalysisOptimizerView.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/DatastreamAnalysisOptimizerView.cs	(revision 17980)
@@ -1,6 +1,5 @@
 ﻿#region License Information
-
 /* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -19,5 +18,4 @@
  * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
  */
-
 #endregion
 
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/ExtendedDataTableView.Designer.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/ExtendedDataTableView.Designer.cs	(revision 17980)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/ExtendedDataTableView.Designer.cs	(revision 17980)
@@ -0,0 +1,134 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+
+namespace HeuristicLab.DatastreamAnalysis.Views {
+  partial class ExtendedDataTableView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+      System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
+      System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
+      System.Windows.Forms.DataVisualization.Charting.Title title1 = new System.Windows.Forms.DataVisualization.Charting.Title();
+      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      this.configureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      this.nameTextBox.Location = new System.Drawing.Point(55, 0);
+      this.nameTextBox.Size = new System.Drawing.Size(279, 20);
+      //
+      // infoLabel
+      //
+      this.infoLabel.Location = new System.Drawing.Point(340, 3);
+      // 
+      // chart
+      // 
+      this.chart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.chart.BorderlineColor = System.Drawing.Color.Black;
+      this.chart.BorderlineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;
+      chartArea1.AxisX.Minimum = 0D;
+      chartArea1.CursorX.IsUserEnabled = true;
+      chartArea1.CursorX.IsUserSelectionEnabled = true;
+      chartArea1.CursorY.IsUserEnabled = true;
+      chartArea1.CursorY.IsUserSelectionEnabled = true;
+      chartArea1.Name = "Default";
+      this.chart.ChartAreas.Add(chartArea1);
+      legend1.Alignment = System.Drawing.StringAlignment.Center;
+      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend1.LegendItemOrder = System.Windows.Forms.DataVisualization.Charting.LegendItemOrder.ReversedSeriesOrder;
+      legend1.Name = "Default";
+      this.chart.Legends.Add(legend1);
+      this.chart.Location = new System.Drawing.Point(0, 26);
+      this.chart.Name = "chart";
+      series1.ChartArea = "Default";
+      series1.Legend = "Default";
+      series1.Name = "Default";
+      this.chart.Series.Add(series1);
+      this.chart.Size = new System.Drawing.Size(359, 248);
+      this.chart.TabIndex = 3;
+      this.chart.Text = "chart";
+      title1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+      title1.Name = "Default";
+      title1.Text = "Title";
+      this.chart.Titles.Add(title1);
+      this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
+      this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
+      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
+      // 
+      // configureToolStripMenuItem
+      // 
+      this.configureToolStripMenuItem.Name = "configureToolStripMenuItem";
+      this.configureToolStripMenuItem.Size = new System.Drawing.Size(256, 22);
+      this.configureToolStripMenuItem.Text = "Configure Chart...";
+      this.configureToolStripMenuItem.Click += new System.EventHandler(this.configureToolStripMenuItem_Click);
+      // 
+      // DataTableView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.chart);
+      this.Name = "DataTableView";
+      this.Size = new System.Drawing.Size(359, 274);
+      this.Controls.SetChildIndex(this.chart, 0);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+    }
+
+    #endregion
+
+    protected HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
+    private System.Windows.Forms.ToolStripMenuItem configureToolStripMenuItem;
+  }
+}
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/ExtendedDataTableView.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/ExtendedDataTableView.cs	(revision 17980)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/ExtendedDataTableView.cs	(revision 17980)
@@ -0,0 +1,757 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 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.Analysis;
+using HeuristicLab.Analysis.Views;
+using HeuristicLab.Collections;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+
+namespace HeuristicLab.DatastreamAnalysis.Views {
+  [View("ExtendedDataTable View")]
+  [Content(typeof(ExtendedDataTable), true)]
+  public partial class ExtendedDataTableView : NamedItemView, IConfigureableView {
+    protected List<Series> invisibleSeries;
+    protected Dictionary<IObservableList<Tuple<double,double>>, RangeDataRow> valuesRowsTable;
+    protected bool showChartOnly = false;
+
+    public new ExtendedDataTable Content {
+      get { return (ExtendedDataTable)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public bool ShowChartOnly {
+      get { return showChartOnly; }
+      set {
+        if (showChartOnly != value) {
+          showChartOnly = value;
+          UpdateControlsVisibility();
+        }
+      }
+    }
+
+    public ExtendedDataTableView() {
+      InitializeComponent();
+      valuesRowsTable = new Dictionary<IObservableList<Tuple<double, double>>, RangeDataRow>();
+      invisibleSeries = new List<Series>();
+      chart.CustomizeAllChartAreas();
+      chart.ChartAreas[0].CursorX.Interval = 1;
+      chart.ContextMenuStrip.Items.Add(configureToolStripMenuItem);
+    }
+
+    #region Event Handler Registration
+    protected override void DeregisterContentEvents() {
+      foreach (RangeDataRow row in Content.Rows)
+        DeregisterDataRowEvents(row);
+      Content.VisualPropertiesChanged -= new EventHandler(Content_VisualPropertiesChanged);
+      Content.Rows.ItemsAdded -= new CollectionItemsChangedEventHandler<RangeDataRow>(Rows_ItemsAdded);
+      Content.Rows.ItemsRemoved -= new CollectionItemsChangedEventHandler<RangeDataRow>(Rows_ItemsRemoved);
+      Content.Rows.ItemsReplaced -= new CollectionItemsChangedEventHandler<RangeDataRow>(Rows_ItemsReplaced);
+      Content.Rows.CollectionReset -= new CollectionItemsChangedEventHandler<RangeDataRow>(Rows_CollectionReset);
+      base.DeregisterContentEvents();
+    }
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.VisualPropertiesChanged += new EventHandler(Content_VisualPropertiesChanged);
+      Content.Rows.ItemsAdded += new CollectionItemsChangedEventHandler<RangeDataRow>(Rows_ItemsAdded);
+      Content.Rows.ItemsRemoved += new CollectionItemsChangedEventHandler<RangeDataRow>(Rows_ItemsRemoved);
+      Content.Rows.ItemsReplaced += new CollectionItemsChangedEventHandler<RangeDataRow>(Rows_ItemsReplaced);
+      Content.Rows.CollectionReset += new CollectionItemsChangedEventHandler<RangeDataRow>(Rows_CollectionReset);
+    }
+
+    protected virtual void RegisterDataRowEvents(RangeDataRow row) {
+      row.NameChanged += new EventHandler(Row_NameChanged);
+      row.VisualPropertiesChanged += new EventHandler(Row_VisualPropertiesChanged);
+      valuesRowsTable.Add(row.Values, row);
+      row.Values.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double,double>>>(Values_ItemsAdded);
+      row.Values.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsRemoved);
+      row.Values.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsReplaced);
+      row.Values.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsMoved);
+      row.Values.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_CollectionReset);
+    }
+    protected virtual void DeregisterDataRowEvents(RangeDataRow row) {
+      row.Values.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsAdded);
+      row.Values.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsRemoved);
+      row.Values.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsReplaced);
+      row.Values.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsMoved);
+      row.Values.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_CollectionReset);
+      valuesRowsTable.Remove(row.Values);
+      row.VisualPropertiesChanged -= new EventHandler(Row_VisualPropertiesChanged);
+      row.NameChanged -= new EventHandler(Row_NameChanged);
+    }
+    #endregion
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      invisibleSeries.Clear();
+      chart.Titles[0].Text = string.Empty;
+      chart.ChartAreas[0].AxisX.Title = string.Empty;
+      chart.ChartAreas[0].AxisY.Title = string.Empty;
+      chart.ChartAreas[0].AxisY2.Title = string.Empty;
+      chart.Series.Clear();
+      if (Content != null) {
+        chart.Titles[0].Text = Content.Name;
+        chart.Titles[0].Visible = !string.IsNullOrEmpty(Content.Name);
+        AddDataRows(Content.Rows);
+        ConfigureChartArea(chart.ChartAreas[0]);
+        RecalculateAxesScale(chart.ChartAreas[0]);
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      chart.Enabled = Content != null;
+    }
+
+    public void ShowConfiguration() {
+      MessageBox.Show("Nothing to configure.");
+      //if (Content != null) {
+      //  using (var dialog = new DataTableVisualPropertiesDialog(Content)) {
+      //    dialog.ShowDialog(this);
+      //  }
+      //} else MessageBox.Show("Nothing to configure.");
+    }
+
+    protected void UpdateControlsVisibility() {
+      if (InvokeRequired)
+        Invoke(new Action(UpdateControlsVisibility));
+      else {
+        foreach (Control c in Controls) {
+          if (c == chart) continue;
+          c.Visible = !showChartOnly;
+        }
+        chart.Dock = showChartOnly ? DockStyle.Fill : DockStyle.None;
+      }
+    }
+
+    protected virtual void AddDataRows(IEnumerable<RangeDataRow> rows) {
+      foreach (var row in rows) {
+        RegisterDataRowEvents(row);
+        var series = new Series(row.Name) {
+          Tag = row
+        };
+        if (row.VisualProperties.DisplayName.Trim() != String.Empty) series.LegendText = row.VisualProperties.DisplayName;
+        else series.LegendText = row.Name;
+        ConfigureSeries(series, row);
+        FillSeriesWithRowValues(series, row);
+        chart.Series.Add(series);
+      }
+      ConfigureChartArea(chart.ChartAreas[0]);
+      RecalculateAxesScale(chart.ChartAreas[0]);
+      UpdateYCursorInterval();
+      UpdateHistogramTransparency();
+    }
+
+    protected virtual void RemoveDataRows(IEnumerable<RangeDataRow> rows) {
+      foreach (var row in rows) {
+        DeregisterDataRowEvents(row);
+        Series series = chart.Series[row.Name];
+        chart.Series.Remove(series);
+        if (invisibleSeries.Contains(series))
+          invisibleSeries.Remove(series);
+      }
+      RecalculateAxesScale(chart.ChartAreas[0]);
+    }
+
+    private void ConfigureSeries(Series series, RangeDataRow row) {
+      RemoveCustomPropertyIfExists(series, "PointWidth");
+      series.BorderWidth = 1;
+      series.BorderDashStyle = ChartDashStyle.Solid;
+      series.BorderColor = Color.Empty;
+
+      if (row.VisualProperties.Color != Color.Empty)
+        series.Color = row.VisualProperties.Color;
+      else series.Color = Color.Empty;
+      series.IsVisibleInLegend = row.VisualProperties.IsVisibleInLegend;
+
+      switch (row.VisualProperties.ChartType) {
+        case DataRowVisualProperties.DataRowChartType.Line:
+          //series.ChartType = SeriesChartType.FastLine;
+          series.ChartType = SeriesChartType.Range;
+          series.BorderWidth = row.VisualProperties.LineWidth;
+          series.BorderDashStyle = ConvertLineStyle(row.VisualProperties.LineStyle);
+          break;
+        case DataRowVisualProperties.DataRowChartType.Bars:
+          // Bar is incompatible with anything but Bar and StackedBar*
+          if (!chart.Series.Any(x => x.ChartType != SeriesChartType.Bar && x.ChartType != SeriesChartType.StackedBar && x.ChartType != SeriesChartType.StackedBar100))
+            series.ChartType = SeriesChartType.Bar;
+          else {
+            series.ChartType = SeriesChartType.FastPoint; //default
+            row.VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Points;
+          }
+          break;
+        case DataRowVisualProperties.DataRowChartType.Columns:
+          series.ChartType = SeriesChartType.Column;
+          break;
+        case DataRowVisualProperties.DataRowChartType.Points:
+          series.ChartType = SeriesChartType.FastPoint;
+          break;
+        case DataRowVisualProperties.DataRowChartType.Histogram:
+          bool stacked = Content.VisualProperties.HistogramAggregation == DataTableVisualProperties.DataTableHistogramAggregation.Stacked;
+          series.ChartType = stacked ? SeriesChartType.StackedColumn : SeriesChartType.Column;
+          bool sideBySide = Content.VisualProperties.HistogramAggregation == DataTableVisualProperties.DataTableHistogramAggregation.SideBySide;
+          series.SetCustomProperty("DrawSideBySide", sideBySide ? "True" : "False");
+          series.SetCustomProperty("PointWidth", "1");
+          if (!series.Color.IsEmpty && series.Color.GetBrightness() < 0.25)
+            series.BorderColor = Color.White;
+          else series.BorderColor = Color.Black;
+          break;
+        case DataRowVisualProperties.DataRowChartType.StepLine:
+          series.ChartType = SeriesChartType.StepLine;
+          series.BorderWidth = row.VisualProperties.LineWidth;
+          series.BorderDashStyle = ConvertLineStyle(row.VisualProperties.LineStyle);
+          break;
+        default:
+          series.ChartType = SeriesChartType.FastPoint;
+          break;
+      }
+      series.YAxisType = row.VisualProperties.SecondYAxis ? AxisType.Secondary : AxisType.Primary;
+      series.XAxisType = row.VisualProperties.SecondXAxis ? AxisType.Secondary : AxisType.Primary;
+      if (row.VisualProperties.DisplayName.Trim() != String.Empty) series.LegendText = row.VisualProperties.DisplayName;
+      else series.LegendText = row.Name;
+
+      string xAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.XAxisTitle)
+                      ? "X"
+                      : Content.VisualProperties.XAxisTitle;
+      string yAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.YAxisTitle)
+                            ? "Y"
+                            : Content.VisualProperties.YAxisTitle;
+      series.ToolTip =
+        series.LegendText + Environment.NewLine +
+        xAxisTitle + " = " + "#INDEX," + Environment.NewLine +
+        yAxisTitle + " = " + "#VAL";
+    }
+
+    private void ConfigureChartArea(ChartArea area) {
+      if (Content.VisualProperties.TitleFont != null) chart.Titles[0].Font = Content.VisualProperties.TitleFont;
+      if (!Content.VisualProperties.TitleColor.IsEmpty) chart.Titles[0].ForeColor = Content.VisualProperties.TitleColor;
+      chart.Titles[0].Text = Content.VisualProperties.Title;
+      chart.Titles[0].Visible = !string.IsNullOrEmpty(Content.VisualProperties.Title);
+
+      if (Content.VisualProperties.AxisTitleFont != null) area.AxisX.TitleFont = Content.VisualProperties.AxisTitleFont;
+      if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisX.TitleForeColor = Content.VisualProperties.AxisTitleColor;
+      area.AxisX.Title = Content.VisualProperties.XAxisTitle;
+
+      if (Content.VisualProperties.AxisTitleFont != null) area.AxisX2.TitleFont = Content.VisualProperties.AxisTitleFont;
+      if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisX2.TitleForeColor = Content.VisualProperties.AxisTitleColor;
+      area.AxisX2.Title = Content.VisualProperties.SecondXAxisTitle;
+
+      if (Content.VisualProperties.AxisTitleFont != null) area.AxisY.TitleFont = Content.VisualProperties.AxisTitleFont;
+      if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisY.TitleForeColor = Content.VisualProperties.AxisTitleColor;
+      area.AxisY.Title = Content.VisualProperties.YAxisTitle;
+
+      if (Content.VisualProperties.AxisTitleFont != null) area.AxisY2.TitleFont = Content.VisualProperties.AxisTitleFont;
+      if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisY2.TitleForeColor = Content.VisualProperties.AxisTitleColor;
+      area.AxisY2.Title = Content.VisualProperties.SecondYAxisTitle;
+
+      area.AxisX.IsLogarithmic = Content.VisualProperties.XAxisLogScale;
+      area.AxisX2.IsLogarithmic = Content.VisualProperties.SecondXAxisLogScale;
+      area.AxisY.IsLogarithmic = Content.VisualProperties.YAxisLogScale;
+      area.AxisY2.IsLogarithmic = Content.VisualProperties.SecondYAxisLogScale;
+    }
+
+    private void RecalculateAxesScale(ChartArea area) {
+      // Reset the axes bounds so that RecalculateAxesScale() will assign new bounds
+      foreach (Axis a in area.Axes) {
+        a.Minimum = double.NaN;
+        a.Maximum = double.NaN;
+      }
+      area.RecalculateAxesScale();
+      area.AxisX.IsMarginVisible = false;
+      area.AxisX2.IsMarginVisible = false;
+
+      if (!Content.VisualProperties.XAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.XAxisMinimumFixedValue)) area.AxisX.Minimum = Content.VisualProperties.XAxisMinimumFixedValue;
+      if (!Content.VisualProperties.XAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.XAxisMaximumFixedValue)) area.AxisX.Maximum = Content.VisualProperties.XAxisMaximumFixedValue;
+      if (!Content.VisualProperties.SecondXAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.SecondXAxisMinimumFixedValue)) area.AxisX2.Minimum = Content.VisualProperties.SecondXAxisMinimumFixedValue;
+      if (!Content.VisualProperties.SecondXAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.SecondXAxisMaximumFixedValue)) area.AxisX2.Maximum = Content.VisualProperties.SecondXAxisMaximumFixedValue;
+      if (!Content.VisualProperties.YAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.YAxisMinimumFixedValue)) area.AxisY.Minimum = Content.VisualProperties.YAxisMinimumFixedValue;
+      if (!Content.VisualProperties.YAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.YAxisMaximumFixedValue)) area.AxisY.Maximum = Content.VisualProperties.YAxisMaximumFixedValue;
+      if (!Content.VisualProperties.SecondYAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.SecondYAxisMinimumFixedValue)) area.AxisY2.Minimum = Content.VisualProperties.SecondYAxisMinimumFixedValue;
+      if (!Content.VisualProperties.SecondYAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.SecondYAxisMaximumFixedValue)) area.AxisY2.Maximum = Content.VisualProperties.SecondYAxisMaximumFixedValue;
+      if (area.AxisX.Minimum >= area.AxisX.Maximum) area.AxisX.Maximum = area.AxisX.Minimum + 1;
+      if (area.AxisX2.Minimum >= area.AxisX2.Maximum) area.AxisX2.Maximum = area.AxisX2.Minimum + 1;
+      if (area.AxisY.Minimum >= area.AxisY.Maximum) area.AxisY.Maximum = area.AxisY.Minimum + 1;
+      if (area.AxisY2.Minimum >= area.AxisY2.Maximum) area.AxisY2.Maximum = area.AxisY2.Minimum + 1;
+    }
+
+    protected virtual void UpdateYCursorInterval() {
+      double interestingValuesRange = (
+        from series in chart.Series
+        where series.Enabled
+        let values = (from point in series.Points
+                      where !point.IsEmpty
+                      select point.YValues[0]).DefaultIfEmpty(1.0)
+        let range = values.Max() - values.Min()
+        where range > 0.0
+        select range
+        ).DefaultIfEmpty(1.0).Min();
+
+      double digits = (int)Math.Log10(interestingValuesRange) - 3;
+      double yZoomInterval = Math.Pow(10, digits);
+      this.chart.ChartAreas[0].CursorY.Interval = yZoomInterval;
+    }
+
+    protected void UpdateHistogramTransparency() {
+      if (Content.Rows.Any(r => RequiresTransparency(r) && r.VisualProperties.Color.IsEmpty)) {
+        foreach (var series in chart.Series) // sync colors before applying palette colors
+          series.Color = ((RangeDataRow)series.Tag).VisualProperties.Color;
+        chart.ApplyPaletteColors();
+      }
+
+      var numTransparent = Content.Rows.Count(RequiresTransparency);
+      if (numTransparent <= 1) return;
+      foreach (var series in chart.Series) {
+        var row = (RangeDataRow)series.Tag;
+        if (!RequiresTransparency(row))
+          continue;
+        var baseColor = row.VisualProperties.Color;
+        if (baseColor.IsEmpty) baseColor = series.Color;
+        series.Color = Color.FromArgb(180, baseColor);
+      }
+    }
+    private bool RequiresTransparency(RangeDataRow row) {
+      return row.VisualProperties.ChartType == DataRowVisualProperties.DataRowChartType.Histogram
+             && Content.VisualProperties.HistogramAggregation == DataTableVisualProperties.DataTableHistogramAggregation.Overlapping;
+    }
+
+    private void ToggleSeriesVisible(Series series) {
+      if (!invisibleSeries.Contains(series)) {
+        ClearPoints(series.Points);
+        invisibleSeries.Add(series);
+      } else {
+        invisibleSeries.Remove(series);
+        if (Content != null) {
+
+          var row = (from r in Content.Rows
+                     where r.Name == series.Name
+                     select r).Single();
+          FillSeriesWithRowValues(series, row);
+          this.chart.Legends[series.Legend].ForeColor = Color.Black;
+          RecalculateAxesScale(chart.ChartAreas[0]);
+          UpdateYCursorInterval();
+        }
+      }
+    }
+
+    private void FillSeriesWithRowValues(Series series, RangeDataRow row) {
+      switch (row.VisualProperties.ChartType) {
+        case DataRowVisualProperties.DataRowChartType.Histogram:
+          // when a single histogram is updated, all histograms must be updated. otherwise the value ranges may not be equal.
+          var histograms = Content.Rows
+            .Where(r => r.VisualProperties.ChartType == DataRowVisualProperties.DataRowChartType.Histogram)
+            .ToList();
+          CalculateHistogram(series, row, histograms);
+          foreach (var h in from r in histograms
+                            where r != row
+                            let s = chart.Series.FindByName(r.Name)
+                            where s != null
+                            where !invisibleSeries.Contains(s)
+                            select new { row = r, series = s }) {
+            ClearPoints(h.series.Points);
+            CalculateHistogram(h.series, h.row, histograms);
+          }
+          break;
+        default: {
+            bool yLogarithmic = series.YAxisType == AxisType.Primary
+                                  ? Content.VisualProperties.YAxisLogScale
+                                  : Content.VisualProperties.SecondYAxisLogScale;
+            bool xLogarithmic = series.XAxisType == AxisType.Primary
+                                  ? Content.VisualProperties.XAxisLogScale
+                                  : Content.VisualProperties.SecondXAxisLogScale;
+            for (int i = 0; i < row.Values.Count; i++) {
+              var value = row.Values[i];
+              var point = new DataPoint();
+              point.XValue = row.VisualProperties.StartIndexZero && !xLogarithmic ? i : i + 1;
+              if (IsInvalidValue(value.Item1) || (yLogarithmic && value.Item1 <= 0) 
+                || IsInvalidValue(value.Item2) || (yLogarithmic && value.Item2 <= 0))
+                point.IsEmpty = true;
+              else
+                point.YValues = new double[] { value.Item1, value.Item2 };
+              series.Points.Add(point);
+            }
+          }
+          break;
+      }
+    }
+
+    protected virtual void CalculateHistogram(Series series, RangeDataRow row, IEnumerable<RangeDataRow> histogramRows) {
+      ClearPoints(series.Points);
+      if (!row.Values.Any()) return;
+
+      var validValues = histogramRows.SelectMany(r => r.Values).Where(x => !IsInvalidValue(x.Item1) && !IsInvalidValue(x.Item2)).ToList();
+      if (!validValues.Any()) return;
+
+      int bins = Content.VisualProperties.HistogramBins;
+      decimal minValue = (decimal)validValues.Min(x => x.Item1);
+      decimal maxValue = (decimal)validValues.Max(x => x.Item2);
+      decimal intervalWidth = (maxValue - minValue) / bins;
+      if (intervalWidth < 0) return;
+      if (intervalWidth == 0) {
+        series.Points.AddXY(minValue, row.Values.Count);
+        return;
+      }
+
+      if (!Content.VisualProperties.HistogramExactBins) {
+        intervalWidth = (decimal)HumanRoundRange((double)intervalWidth);
+        minValue = Math.Floor(minValue / intervalWidth) * intervalWidth;
+        maxValue = Math.Ceiling(maxValue / intervalWidth) * intervalWidth;
+      }
+
+      decimal intervalCenter = intervalWidth / 2;
+
+      decimal min = 0.0m, max = 0.0m;
+      if (!Double.IsNaN(Content.VisualProperties.XAxisMinimumFixedValue) && !Content.VisualProperties.XAxisMinimumAuto)
+        min = (decimal)Content.VisualProperties.XAxisMinimumFixedValue;
+      else min = minValue;
+      if (!Double.IsNaN(Content.VisualProperties.XAxisMaximumFixedValue) && !Content.VisualProperties.XAxisMaximumAuto)
+        max = (decimal)Content.VisualProperties.XAxisMaximumFixedValue;
+      else max = maxValue + intervalWidth;
+
+      double axisInterval = (double)intervalWidth / row.VisualProperties.ScaleFactor;
+
+      var area = chart.ChartAreas[0];
+      area.AxisX.Interval = axisInterval;
+
+      series.SetCustomProperty("PointWidth", "1"); // 0.8 is the default value
+
+      // get the range or intervals which define the grouping of the frequency values
+      var range = Range(min, max, intervalWidth).Skip(1).ToList();
+
+      // aggregate the row values by unique key and frequency value
+      var valueFrequencies = (from v in row.Values
+                              where !IsInvalidValue(v.Item1) && !IsInvalidValue(v.Item2)
+                              orderby v
+                              group v by v into g
+                              select new Tuple<Tuple<double,double>, double>(g.First(), g.Count())).ToList();
+
+      // ensure that each column is displayed completely on the chart by adding two dummy datapoints on the upper and lower range
+      series.Points.Add(new DataPoint((double)(min - intervalWidth), 0));
+      series.Points.Add(new DataPoint((double)(max + intervalWidth), 0));
+
+      // add data points
+      int j = 0;
+      int overallCount = row.Values.Count(x => !IsInvalidValue(x.Item1) && !IsInvalidValue(x.Item2));
+      foreach (var d in range) {
+        double sum = 0.0;
+        // sum the frequency values that fall within the same interval
+        while (j < valueFrequencies.Count && (decimal)valueFrequencies[j].Item1.Item2 < d) {
+          sum += valueFrequencies[j].Item2;
+          ++j;
+        }
+        string xAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.XAxisTitle)
+                              ? "X"
+                              : Content.VisualProperties.XAxisTitle;
+        string yAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.YAxisTitle)
+                              ? "Y"
+                              : Content.VisualProperties.YAxisTitle;
+        series.Points.Add(new DataPoint((double)(d - intervalCenter), sum) {
+          ToolTip =
+            string.Format("{0}: [{1} - {2})", xAxisTitle, (d - intervalWidth), d) + Environment.NewLine +
+            string.Format("{0}: {1} ({2:F2}%)", yAxisTitle, sum, sum / overallCount * 100)
+        });
+      }
+    }
+
+    #region Event Handlers
+    #region Content Event Handlers
+    protected override void Content_NameChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_NameChanged), sender, e);
+      else {
+        Content.VisualProperties.Title = Content.Name;
+        base.Content_NameChanged(sender, e);
+      }
+    }
+    private void Content_VisualPropertiesChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_VisualPropertiesChanged), sender, e);
+      else {
+        ConfigureChartArea(chart.ChartAreas[0]);
+        RecalculateAxesScale(chart.ChartAreas[0]); // axes min/max could have changed
+
+        chart.Update(); // side-by-side and stacked histograms are not always correctly displayed without an update
+        // (chart update is required before the series are updated, otherwise the widths of the bars are updated incorrectly)
+        foreach (var row in Content.Rows.Where(r => r.VisualProperties.ChartType == DataRowVisualProperties.DataRowChartType.Histogram))
+          Row_VisualPropertiesChanged(row, EventArgs.Empty); // Histogram properties could have changed
+      }
+    }
+    #endregion
+    #region Rows Event Handlers
+    private void Rows_ItemsAdded(object sender, CollectionItemsChangedEventArgs<RangeDataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<RangeDataRow>(Rows_ItemsAdded), sender, e);
+      else {
+        AddDataRows(e.Items);
+      }
+    }
+    private void Rows_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<RangeDataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<RangeDataRow>(Rows_ItemsRemoved), sender, e);
+      else {
+        RemoveDataRows(e.Items);
+      }
+    }
+    private void Rows_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<RangeDataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<RangeDataRow>(Rows_ItemsReplaced), sender, e);
+      else {
+        RemoveDataRows(e.OldItems);
+        AddDataRows(e.Items);
+      }
+    }
+    private void Rows_CollectionReset(object sender, CollectionItemsChangedEventArgs<RangeDataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<RangeDataRow>(Rows_CollectionReset), sender, e);
+      else {
+        RemoveDataRows(e.OldItems);
+        AddDataRows(e.Items);
+      }
+    }
+    #endregion
+    #region Row Event Handlers
+    private void Row_VisualPropertiesChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Row_VisualPropertiesChanged), sender, e);
+      else {
+        RangeDataRow row = (RangeDataRow)sender;
+        Series series = chart.Series[row.Name];
+        ClearPoints(series.Points);
+        ConfigureSeries(series, row);
+        if (!invisibleSeries.Contains(series)) {
+          FillSeriesWithRowValues(series, row);
+          RecalculateAxesScale(chart.ChartAreas[0]);
+          UpdateHistogramTransparency();
+        }
+      }
+    }
+    private void Row_NameChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Row_NameChanged), sender, e);
+      else {
+        RangeDataRow row = (RangeDataRow)sender;
+        chart.Series[row.Name].Name = row.Name;
+      }
+    }
+    #endregion
+    #region Values Event Handlers
+    private void Values_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<double,double>>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsAdded), sender, e);
+      else {
+        RangeDataRow row = null;
+        valuesRowsTable.TryGetValue((IObservableList<Tuple<double, double>>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            ClearPoints(rowSeries.Points);
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    private void Values_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<double, double>>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsRemoved), sender, e);
+      else {
+        RangeDataRow row = null;
+        valuesRowsTable.TryGetValue((IObservableList<Tuple<double, double>>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            ClearPoints(rowSeries.Points);
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    private void Values_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<double, double>>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsReplaced), sender, e);
+      else {
+        RangeDataRow row = null;
+        valuesRowsTable.TryGetValue((IObservableList<Tuple<double, double>>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            if (row.VisualProperties.ChartType == DataRowVisualProperties.DataRowChartType.Histogram) {
+              ClearPoints(rowSeries.Points);
+              FillSeriesWithRowValues(rowSeries, row);
+            } else {
+              foreach (IndexedItem<Tuple<double, double>> item in e.Items) {
+                if (IsInvalidValue(item.Value.Item1) || IsInvalidValue(item.Value.Item2))
+                  rowSeries.Points[item.Index].IsEmpty = true;
+                else {
+                  rowSeries.Points[item.Index].YValues = new double[] { item.Value.Item1, item.Value.Item2 };
+                  rowSeries.Points[item.Index].IsEmpty = false;
+                }
+              }
+            }
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    private void Values_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<double, double>>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsMoved), sender, e);
+      else {
+        RangeDataRow row = null;
+        valuesRowsTable.TryGetValue((IObservableList<Tuple<double, double>>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            ClearPoints(rowSeries.Points);
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+
+    private void Values_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<double, double>>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_CollectionReset), sender, e);
+      else {
+        RangeDataRow row = null;
+        valuesRowsTable.TryGetValue((IObservableList<Tuple<double, double>>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            ClearPoints(rowSeries.Points);
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    #endregion
+    private void configureToolStripMenuItem_Click(object sender, EventArgs e) {
+      ShowConfiguration();
+    }
+    #endregion
+
+    #region Chart Event Handlers
+    private void chart_MouseDown(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem) {
+        ToggleSeriesVisible(result.Series);
+      }
+    }
+    private void chart_MouseMove(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem)
+        this.Cursor = Cursors.Hand;
+      else
+        this.Cursor = Cursors.Default;
+    }
+    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
+      foreach (LegendItem legendItem in e.LegendItems) {
+        var series = chart.Series[legendItem.SeriesName];
+        if (series != null) {
+          bool seriesIsInvisible = invisibleSeries.Contains(series);
+          foreach (LegendCell cell in legendItem.Cells) {
+            cell.ForeColor = seriesIsInvisible ? Color.Gray : Color.Black;
+          }
+        }
+      }
+    }
+    #endregion
+
+    #region Helpers
+    public static IEnumerable<decimal> Range(decimal min, decimal max, decimal step) {
+      decimal i;
+      for (i = min; i <= max; i += step)
+        yield return i;
+
+      if (i != max + step)
+        yield return i;
+    }
+
+    protected void RemoveCustomPropertyIfExists(Series series, string property) {
+      if (series.IsCustomPropertySet(property)) series.DeleteCustomProperty(property);
+    }
+
+    private double HumanRoundRange(double range) {
+      double base10 = Math.Pow(10.0, Math.Floor(Math.Log10(range)));
+      double rounding = range / base10;
+      if (rounding <= 1.5) rounding = 1;
+      else if (rounding <= 2.25) rounding = 2;
+      else if (rounding <= 3.75) rounding = 2.5;
+      else if (rounding <= 7.5) rounding = 5;
+      else rounding = 10;
+      return rounding * base10;
+    }
+
+    private double HumanRoundMax(double max) {
+      double base10;
+      if (max > 0) base10 = Math.Pow(10.0, Math.Floor(Math.Log10(max)));
+      else base10 = Math.Pow(10.0, Math.Ceiling(Math.Log10(-max)));
+      double rounding = (max > 0) ? base10 : -base10;
+      while (rounding < max) rounding += base10;
+      return rounding;
+    }
+
+    private ChartDashStyle ConvertLineStyle(DataRowVisualProperties.DataRowLineStyle dataRowLineStyle) {
+      switch (dataRowLineStyle) {
+        case DataRowVisualProperties.DataRowLineStyle.Dash:
+          return ChartDashStyle.Dash;
+        case DataRowVisualProperties.DataRowLineStyle.DashDot:
+          return ChartDashStyle.DashDot;
+        case DataRowVisualProperties.DataRowLineStyle.DashDotDot:
+          return ChartDashStyle.DashDotDot;
+        case DataRowVisualProperties.DataRowLineStyle.Dot:
+          return ChartDashStyle.Dot;
+        case DataRowVisualProperties.DataRowLineStyle.NotSet:
+          return ChartDashStyle.NotSet;
+        case DataRowVisualProperties.DataRowLineStyle.Solid:
+          return ChartDashStyle.Solid;
+        default:
+          return ChartDashStyle.NotSet;
+      }
+    }
+
+    protected static bool IsInvalidValue(double x) {
+      return double.IsNaN(x) || x < (double)decimal.MinValue || x > (double)decimal.MaxValue;
+    }
+
+    // workaround for performance problem as described in https://stackoverflow.com/questions/5744930/datapointcollection-clear-performance
+    public static void ClearPoints(DataPointCollection points) {
+      points.SuspendUpdates();
+      while (points.Count > 0)
+        points.RemoveAt(points.Count - 1);
+      points.ResumeUpdates();
+    }
+    #endregion
+  }
+}
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/HeuristicLab.DatastreamAnalysis.Views.csproj
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/HeuristicLab.DatastreamAnalysis.Views.csproj	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/HeuristicLab.DatastreamAnalysis.Views.csproj	(revision 17980)
@@ -10,5 +10,5 @@
     <RootNamespace>HeuristicLab.DatastreamAnalysis.Views</RootNamespace>
     <AssemblyName>HeuristicLab.DatastreamAnalysis.Views-3.4</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
@@ -29,5 +29,5 @@
     <DebugType>pdbonly</DebugType>
     <Optimize>true</Optimize>
-    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <OutputPath>..\..\..\..\trunk\bin\</OutputPath>
     <DefineConstants>TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
@@ -44,44 +44,69 @@
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="HEAL.Attic, Version=1.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HEAL.Attic.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Analysis-3.3">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Analysis.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Analysis.Views-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
     <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Common-3.3">
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Core-3.3">
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Core.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core.Views-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Data-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.MainForm-3.3">
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.MainForm-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.MainForm.WindowsForms-3.3">
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.MainForm.WindowsForms-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Optimization-3.3">
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Optimization.Views-3.3">
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimization.Views-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="HeuristicLab.Visualization.ChartControlsExtensions-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Visualization.ChartControlsExtensions-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="System" />
@@ -111,4 +136,10 @@
       <DependentUpon>DatastreamAnalysisOptimizerView.cs</DependentUpon>
     </Compile>
+    <Compile Include="ExtendedDataTableView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ExtendedDataTableView.Designer.cs">
+      <DependentUpon>ExtendedDataTableView.cs</DependentUpon>
+    </Compile>
     <Compile Include="Plugin.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
@@ -119,4 +150,10 @@
       <DependentUpon>RegressionEnsembleModelView.cs</DependentUpon>
     </Compile>
+    <Compile Include="TopicSelectorDialog.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="TopicSelectorDialog.Designer.cs">
+      <DependentUpon>TopicSelectorDialog.cs</DependentUpon>
+    </Compile>
   </ItemGroup>
   <ItemGroup>
@@ -129,8 +166,10 @@
       <Project>{8ba00ca6-71f6-415b-b5b7-da3d64318750}</Project>
       <Name>HeuristicLab.DatastreamAnalysis</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>
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/Plugin.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/Plugin.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/Plugin.cs	(revision 17980)
@@ -23,5 +23,5 @@
 
 namespace HeuristicLab.DatastreamAnalysis.Views {
-  [Plugin("HeuristicLab.DatastreamAnalysis.Views", "3.4.14.15025")]
+  [Plugin("HeuristicLab.DatastreamAnalysis.Views", "3.4.14.15867")]
   [PluginFile("HeuristicLab.DatastreamAnalysis.Views-3.4.dll", PluginFileType.Assembly)]
   [PluginDependency("HeuristicLab.Collections", "3.3")]
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/Properties/AssemblyInfo.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/Properties/AssemblyInfo.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/Properties/AssemblyInfo.cs	(revision 17980)
@@ -54,3 +54,3 @@
 // [assembly: AssemblyVersion("1.0.*")]
 [assembly: AssemblyVersion("3.4.0.0")]
-[assembly: AssemblyFileVersion("3.4.14.15025")]
+[assembly: AssemblyFileVersion("3.4.14.15867")]
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/RegressionEnsembleModelView.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/RegressionEnsembleModelView.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/RegressionEnsembleModelView.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -20,12 +20,7 @@
 #endregion
 
-using System;
-using System.Linq;
-using System.Windows.Forms;
-using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Core.Views;
 using HeuristicLab.MainForm;
-using HeuristicLab.MainForm.WindowsForms;
 using HeuristicLab.Problems.DataAnalysis;
 
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/TopicSelectorDialog.Designer.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/TopicSelectorDialog.Designer.cs	(revision 17980)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/TopicSelectorDialog.Designer.cs	(revision 17980)
@@ -0,0 +1,93 @@
+﻿namespace HeuristicLab.DatastreamAnalysis.Views {
+  partial class TopicSelectorDialog {
+    /// <summary>
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary>
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Windows Form Designer generated code
+
+    /// <summary>
+    /// Required method for Designer support - do not modify
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      this.okButton = new System.Windows.Forms.Button();
+      this.cancelButton = new System.Windows.Forms.Button();
+      this.toolTip = new System.Windows.Forms.ToolTip(this.components);
+      this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      this.SuspendLayout();
+      //
+      // okButton
+      //
+      this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
+      this.okButton.Enabled = false;
+      this.okButton.Location = new System.Drawing.Point(429, 365);
+      this.okButton.Name = "okButton";
+      this.okButton.Size = new System.Drawing.Size(75, 23);
+      this.okButton.TabIndex = 1;
+      this.okButton.Text = "&OK";
+      this.okButton.UseVisualStyleBackColor = true;
+      this.errorProvider.SetIconAlignment(this.okButton, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.okButton, 2);
+      // 
+      // cancelButton
+      // 
+      this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+      this.cancelButton.Location = new System.Drawing.Point(510, 365);
+      this.cancelButton.Name = "cancelButton";
+      this.cancelButton.Size = new System.Drawing.Size(75, 23);
+      this.cancelButton.TabIndex = 2;
+      this.cancelButton.Text = "&Cancel";
+      this.cancelButton.UseVisualStyleBackColor = true;
+      // 
+      // errorProvider
+      // 
+      this.errorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
+      this.errorProvider.ContainerControl = this;
+      // 
+      // TopicSelectorDialog
+      // 
+      this.AcceptButton = this.okButton;
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.CancelButton = this.cancelButton;
+      this.ClientSize = new System.Drawing.Size(600, 400);
+      //this.Controls.Add(this.refreshButton);
+      //this.Controls.Add(this.hiveResourceSelector);
+      this.Controls.Add(this.cancelButton);
+      this.Controls.Add(this.okButton);
+      this.MaximizeBox = false;
+      this.MinimizeBox = false;
+      this.Name = "TopicSelectorDialog";
+      this.ShowIcon = false;
+      this.ShowInTaskbar = false;
+      this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+      this.Text = "Select Topics";
+      //this.Load += new System.EventHandler(this.HiveResourceSelectorDialog_Load);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+    }
+
+    #endregion
+
+
+    protected System.Windows.Forms.Button okButton;
+    protected System.Windows.Forms.Button cancelButton;    
+    protected System.Windows.Forms.ToolTip toolTip;
+    protected System.Windows.Forms.ErrorProvider errorProvider;
+  }
+}
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/TopicSelectorDialog.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/TopicSelectorDialog.cs	(revision 17980)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis.Views/3.4/TopicSelectorDialog.cs	(revision 17980)
@@ -0,0 +1,17 @@
+﻿using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace HeuristicLab.DatastreamAnalysis.Views {
+  public partial class TopicSelectorDialog : Form {
+    public TopicSelectorDialog() {
+      InitializeComponent();
+    }
+  }
+}
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/AnalysisBase.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/AnalysisBase.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/AnalysisBase.cs	(revision 17980)
@@ -1,15 +1,30 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using HeuristicLab.Common;
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 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;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Problems.DataAnalysis;
+using HEAL.Attic;
 
 namespace HeuristicLab.DatastreamAnalysis {
-  [StorableClass]
+  [StorableType("3567EF3B-B71F-4DD7-B9FB-2FEF9208DA4E")]
   [Item("Analysis Base", "Represents trained models, grouped in ensembles and additional parameters for subsequent analysis purposes")]
   [Creatable(CreatableAttribute.Categories.DataAnalysisEnsembles, Priority = 100)]
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/DataBar.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/DataBar.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/DataBar.cs	(revision 17980)
@@ -1,5 +1,6 @@
 ﻿#region License Information
+
 /* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -18,16 +19,14 @@
  * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
  */
+
 #endregion
 
 using System;
-using System.Collections.Generic;
 using System.ComponentModel;
 using System.Drawing;
 using System.Runtime.CompilerServices;
-using HeuristicLab.Collections;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.DatastreamAnalysis {
@@ -36,5 +35,5 @@
   /// </summary>
   [Item("DataBar", "Bar representation for a single value")]
-  [StorableClass]
+  [StorableType("57864A6E-CCC6-4D36-8504-729E149DBB60")]
   public class DataBar : NamedItem, INotifyPropertyChanged {
     private double value;
@@ -127,5 +126,5 @@
     #region constructors, cloner ...
     [StorableConstructor]
-    protected DataBar(bool deserializing) : base(deserializing) { }
+    protected DataBar(StorableConstructorFlag _) : base(_) { }
 
     protected DataBar(DataBar original, Cloner cloner) : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/DataBarSet.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/DataBarSet.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/DataBarSet.cs	(revision 17980)
@@ -1,15 +1,31 @@
-﻿using System;
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Drawing;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using HeuristicLab.Analysis;
 using HeuristicLab.Collections;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.DatastreamAnalysis {
@@ -18,5 +34,5 @@
   /// </summary>
   [Item("DataBarSet", "A set of bars, each having name and value.")]
-  [StorableClass]
+  [StorableType("B07EF3A9-8500-4140-AF73-9C225A5AC2B5")]
   public class DataBarSet : NamedItem {
     public static new Image StaticItemImage {
@@ -45,5 +61,5 @@
     #region constructors, cloner,...
     [StorableConstructor]
-    protected DataBarSet(bool deserializing) : base(deserializing) { }
+    protected DataBarSet(StorableConstructorFlag _) : base(_) { }
 
     public DataBarSet() : base() {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/Datastream.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/Datastream.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/Datastream.cs	(revision 17980)
@@ -1,5 +1,6 @@
 ﻿#region License Information
+
 /* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -18,21 +19,19 @@
  * 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.Collections;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 using HeuristicLab.Problems.DataAnalysis;
 
 namespace HeuristicLab.DatastreamAnalysis {
-  [StorableClass]
   [Item("Datastream", "Represents an item containing a data source and reading options for a certain data stream.")]
+  [StorableType("91B9B2A6-D043-4FA0-9402-DF382B4B4D77")]
   [Creatable(CreatableAttribute.Categories.Problems)]
   public class Datastream : ParameterizedNamedItem, IDatastream {
@@ -47,4 +46,6 @@
     protected const string SlidingWindowSonarRatioParameterName = "SlidingWindowSonarRatio";
     protected const string SlidingWindowEvaluationSchemeParameterName = "SlidingWindowEvaluationScheme";
+    protected const string EvaluationHorizonParameterName = "EvaluationHorizon";
+    protected const string RollingEvaluationHorizonParameterName = "RollingEvaluationHorizon";
 
     #region parameter properites
@@ -93,4 +94,14 @@
         return (IValueParameter<EnumValue<EvaluationScheme>>)Parameters[SlidingWindowEvaluationSchemeParameterName];
       }
+    }
+
+    public IValueParameter<IntValue> EvaluationHorizonParameter 
+    {
+      get { return (IValueParameter<IntValue>)Parameters[EvaluationHorizonParameterName]; }
+    }
+
+    public IValueParameter<BoolValue> RollingEvaluationHorizonParameter 
+    {
+      get { return (IValueParameter<BoolValue>)Parameters[RollingEvaluationHorizonParameterName]; }
     }
 
@@ -154,4 +165,16 @@
       get { return SlidingWindowEvaluationSchemeParameter.Value; }
       set { SlidingWindowEvaluationSchemeParameter.Value = value; }
+    }
+
+    public IntValue EvaluationHorizon 
+    {
+      get { return EvaluationHorizonParameter.Value; }
+      set { EvaluationHorizonParameter.Value = value; }
+    }
+
+    public BoolValue RollingEvaluationHorizon 
+    {
+      get { return RollingEvaluationHorizonParameter.Value; }
+      set { RollingEvaluationHorizonParameter.Value = value; }
     }
 
@@ -185,5 +208,5 @@
       {
         //return ProblemData != null && ProblemData.Dataset != null && ProblemData.Dataset.Rows > 0 && FitnessPartition.Size > 0;
-        return FitnessPartition.Size > 0;
+        return FitnessPartition.Size >= 0;
       }
     }
@@ -219,5 +242,5 @@
     #region constructors
     [StorableConstructor]
-    protected Datastream(bool deserializing) : base(deserializing) { }
+    protected Datastream(StorableConstructorFlag _) : base(_) { }
 
     [StorableHook(HookType.AfterDeserialization)]
@@ -239,10 +262,12 @@
       Parameters.Add(new ValueParameter<RegressionProblemData>(ProblemDataParameterName, "ProblemData for analysis with selected ensembles.", null));
       Parameters.Add(new FixedValueParameter<StringValue>(DataSourceAddressParameterName, "Source address of data stream", new StringValue("")));
-      Parameters.Add(new FixedValueParameter<IntRange>(InitialSlidingWindowParameterName, "Initial sliding window boundaries", new IntRange(0, 100)));
-      Parameters.Add(new FixedValueParameter<IntValue>(SlidingWindowSizeParameterName, "Sliding window size", new IntValue(100)));
+      Parameters.Add(new FixedValueParameter<IntRange>(InitialSlidingWindowParameterName, "Initial sliding window boundaries", new IntRange(0, 10)));
+      Parameters.Add(new FixedValueParameter<IntValue>(SlidingWindowSizeParameterName, "Sliding window size", new IntValue(10)));
       Parameters.Add(new FixedValueParameter<IntValue>(SlidingWindowStepWidthParameterName, "Sliding window step width", new IntValue(1)));
       Parameters.Add(new FixedValueParameter<IntValue>(SlidingWindowMovementDelayParameterName, "Sliding window movement delay interval (milliseconds)", new IntValue(0)));
-      Parameters.Add(new FixedValueParameter<DoubleValue>(SlidingWindowSonarRatioParameterName, "Sliding window sonar ratio", new DoubleValue(0.25)));
+      Parameters.Add(new FixedValueParameter<DoubleValue>(SlidingWindowSonarRatioParameterName, "Sliding window sonar ratio", new DoubleValue(0.0)));
       Parameters.Add(new FixedValueParameter<EnumValue<EvaluationScheme>>(SlidingWindowEvaluationSchemeParameterName, "Sliding window evaluation scheme", new EnumValue<EvaluationScheme>(EvaluationScheme.none)));
+      Parameters.Add(new FixedValueParameter<IntValue>(EvaluationHorizonParameterName, "Evaluation Horizon", new IntValue(1)));
+      Parameters.Add(new ValueParameter<BoolValue>(RollingEvaluationHorizonParameterName, "Rolling Evalution Horizon", new BoolValue(false)));
       RegisterParameterEvents();
       InitializeState();
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/DatastreamAnalysisOptimizer.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/DatastreamAnalysisOptimizer.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/DatastreamAnalysisOptimizer.cs	(revision 17980)
@@ -1,6 +1,5 @@
 ﻿#region License Information
-
 /* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -19,11 +18,8 @@
  * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
  */
-
 #endregion
 
 using System;
 using System.Collections.Generic;
-using System.ComponentModel;
-using System.Diagnostics;
 using System.Drawing;
 using System.Linq;
@@ -36,6 +32,6 @@
 using HeuristicLab.Data;
 using HeuristicLab.Optimization;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 using HeuristicLab.Problems.DataAnalysis;
+using HEAL.Attic;
 
 namespace HeuristicLab.DatastreamAnalysis {
@@ -48,8 +44,8 @@
   }
 
-  [StorableClass]
   [Item("DatastreamAnalysis Optimizer",
      "The main loop for evaluating ensemble models against a incoming datastream of time series fashion.")]
   [Creatable(CreatableAttribute.Categories.Algorithms)]
+  [StorableType("C2743DA1-081A-4475-8C2C-BFFEACB44134")]
   public class DatastreamAnalysisOptimizer : Executable, IOptimizer, IStorableContent {
     #region properties
@@ -60,4 +56,21 @@
     public IEnumerable<IOptimizer> NestedOptimizers { get; }
 
+    private static Color[] _colorsBrightPastel = {
+                           Color.FromArgb(65, 140, 240),
+                           Color.FromArgb(252, 180, 65),
+                           Color.FromArgb(224, 64, 10),
+                           Color.FromArgb(5, 100, 146),
+                           Color.FromArgb(191, 191, 191),
+                           Color.FromArgb(26, 59, 105),
+                           Color.FromArgb(255, 227, 130),
+                           Color.FromArgb(18, 156, 221),
+                           Color.FromArgb(202, 107, 75),
+                           Color.FromArgb(0, 92, 219),
+                           Color.FromArgb(243, 210, 136),
+                           Color.FromArgb(80, 99, 129),
+                           Color.FromArgb(241, 185, 168),
+                           Color.FromArgb(224, 131, 10),
+                           Color.FromArgb(120, 147, 190)
+                         };
 
     [Storable]
@@ -75,9 +88,9 @@
 
     //private double lastStateValue;
-    private double pR2Sum;
-    private int detectionCount;
-    private int evaluationCount;
-    private double exclusivitySum;
-    private double accuracySum;
+    //private double pR2Sum;
+    //private int detectionCount;
+    //private int evaluationCount;
+    //private double exclusivitySum;
+    //private double accuracySum;
 
     private CancellationTokenSource cancellationTokenSource;
@@ -115,5 +128,5 @@
         if (value == null || value == ensembles)
           return;
-        if (!(value is IProxyEnsembleModel)) throw new ArgumentException("Invaid ensemble model type");
+        if (!(value is IProxyEnsembleModel)) throw new ArgumentException("Invalid ensemble model type");
         DeregisterEnsembleEvents();
         ensembles = value;
@@ -154,15 +167,31 @@
     }
 
-    private DataTable ResultsPeakQualities {
-      get { return ((DataTable) Results["Qualities 2"].Value); }
-    }
+    private DataTable ResultsHorizonQualities {
+      get { return ((DataTable)Results["Qualities 2"].Value); }
+    }
+
+    //private DataTable ResultsPeakQualities {
+    //  get { return ((DataTable) Results["Qualities 2"].Value); }
+    //}
 
     private const string ResultsQualitiesMSE = "Mean squared error";
     private const string ResultsQualitiesPR2 = "Pearson R²";
 
+    private ExtendedDataTable ResultsConfidenceTargets {
+      get { return ((ExtendedDataTable)Results["ConfidenceTargets"].Value); }
+    }
+
+    private ExtendedDataTable ResultsErrorRangeTargets {
+      get { return ((ExtendedDataTable)Results["ErrorRangeTargets"].Value); }
+    }
+
     private DataTable ResultsTargets {
       get { return ((DataTable) Results["Targets"].Value); }
     }
 
+    private DataTable ResultsHorizonTargets {
+      get { return ((DataTable) Results["Horizon Targets"].Value); }
+    }
+
     private DataTable ResultsStateDetection {
       get { return ((DataTable) Results["State Detection"].Value);}
@@ -170,71 +199,75 @@
 
     private const string ResultsTargetsReal = "Real";
+    private const string ResultsTargetRange = "[..]";
 
     private DataBarSet ResultsSWQualitiesBars {
-      get { return (DataBarSet) Results["Ensemble Comparison [SW-Quality]"].Value; }
-    }
-
-    private DataBarSet ResultsSWVotingBars {
-      get { return (DataBarSet) Results["Ensemble Comparison [SW-Voting]"].Value; }
-    }
-
-    private DataBarSet ResultsSonarQualitiesBars {
-      get { return (DataBarSet)Results["Ensemble Comparison [Sonar-Quality]"].Value; }
-    }
-
-    private DataBarSet ResultsSWPeakQualitiesBars {
-      get { return (DataBarSet)Results["Ensemble Comparison [SW-PeakQuality]"].Value; }
-    }
-
-    private double ResultsMeanPR2 {
-      get { return ((DoubleValue) Results["Mean PR2"].Value).Value; }
-      set { ((DoubleValue)Results["Mean PR2"].Value).Value = value; }
-    }
-
-    private double ResultsDetectionAccuracy {
-      get { return ((DoubleValue)Results["Detection Accuracy"].Value).Value; }
-      set { ((DoubleValue)Results["Detection Accuracy"].Value).Value = value; }
-    }
-
-    private double ResultsDetectionExclusivity {
-      get { return ((DoubleValue)Results["Detection Exclusivity"].Value).Value; }
-      set { ((DoubleValue)Results["Detection Exclusivity"].Value).Value = value; }
-    }
-
-    //private int ResultsTrueDetectionCount {
-    //  get { return ((IntValue)Results["True Detection Count"].Value).Value; }
-    //  set { ((IntValue)Results["True Detection Count"].Value).Value = value; }
+      get { return (DataBarSet)Results["Ensemble Comparison [SW-Quality]"].Value; }
+    }
+
+    //private DataBarSet ResultsSWVotingBars {
+    //  get { return (DataBarSet) Results["Ensemble Comparison [SW-Voting]"].Value; }
     //}
 
-    //private int ResultsFalseDetectionCount {
-    //  get { return ((IntValue)Results["False Detection Count"].Value).Value; }
-    //  set { ((IntValue)Results["False Detection Count"].Value).Value = value; }
+    //private DataBarSet ResultsSonarQualitiesBars {
+    //  get { return (DataBarSet)Results["Ensemble Comparison [Sonar-Quality]"].Value; }
     //}
 
+    //private DataBarSet ResultsSWPeakQualitiesBars {
+    //  get { return (DataBarSet)Results["Ensemble Comparison [SW-PeakQuality]"].Value; }
+    //}
+
+    //private double ResultsMeanPR2 {
+    //  get { return ((DoubleValue) Results["Mean PR2"].Value).Value; }
+    //  set { ((DoubleValue)Results["Mean PR2"].Value).Value = value; }
+    //}
+
+    //private double ResultsDetectionAccuracy {
+    //  get { return ((DoubleValue)Results["Detection Accuracy"].Value).Value; }
+    //  set { ((DoubleValue)Results["Detection Accuracy"].Value).Value = value; }
+    //}
+
+    //private double ResultsDetectionExclusivity {
+    //  get { return ((DoubleValue)Results["Detection Exclusivity"].Value).Value; }
+    //  set { ((DoubleValue)Results["Detection Exclusivity"].Value).Value = value; }
+    //}
+
     protected void SetupResults() {
-      evaluationCount = 0;
-      //lastStateValue = 0.0;
-      pR2Sum = 0.0;
-      exclusivitySum = 0.0;
-      accuracySum = 0.0;
-      detectionCount = 0;
+      //evaluationCount = 0;
+      //pR2Sum = 0.0;
+      //exclusivitySum = 0.0;
+      //accuracySum = 0.0;
+      //detectionCount = 0;
       Results.Clear();
       Results.Add(new Result("Sliding Window Movements", new IntValue(0)));
       Results.Add(new Result("Qualities 1", new DataTable("Average Pearson R²")));
-      Results.Add(new Result("Qualities 2", new DataTable("Peak Pearson R²")));
+      Results.Add(new Result("Qualities 2", new DataTable("Average Horizon Pearson R²")));
+      //Results.Add(new Result("Qualities 2", new DataTable("Peak Pearson R²")));
+      Results.Add(new Result("ConfidenceTargets", new ExtendedDataTable("ConfidenceTargets")));
+      Results.Add(new Result("ErrorRangeTargets", new ExtendedDataTable("ErrorRangeTargets")));
       Results.Add(new Result("Targets", new DataTable("Targets")));
+      Results.Add(new Result("Horizon Targets", new DataTable("Horizon Targets")));
       Results.Add(new Result("State Detection", new DataTable("State Detection")));
       Results.Add(new Result("Ensemble Comparison [SW-Quality]", new DataBarSet("Ensemble Comparison [SW-Quality]")));
-      Results.Add(new Result("Ensemble Comparison [SW-Voting]", new DataBarSet("Ensemble Comparison [SW-Voting]")));
-      Results.Add(new Result("Ensemble Comparison [Sonar-Quality]", new DataBarSet("Ensemble Comparison [Sonar-Quality]")));
-      Results.Add(new Result("Ensemble Comparison [SW-PeakQuality]", new DataBarSet("Ensemble Comparison [SW-PeakQuality]")));
-      Results.Add(new Result("Mean PR2", new DoubleValue()));
-      Results.Add(new Result("Detection Accuracy", new DoubleValue()));
-      Results.Add(new Result("Detection Exclusivity", new DoubleValue()));
+      //Results.Add(new Result("Ensemble Comparison [SW-Voting]", new DataBarSet("Ensemble Comparison [SW-Voting]")));
+      //Results.Add(new Result("Ensemble Comparison [Sonar-Quality]", new DataBarSet("Ensemble Comparison [Sonar-Quality]")));
+      //Results.Add(new Result("Ensemble Comparison [SW-PeakQuality]", new DataBarSet("Ensemble Comparison [SW-PeakQuality]")));
+      //Results.Add(new Result("Mean PR2", new DoubleValue()));
+      //Results.Add(new Result("Detection Accuracy", new DoubleValue()));
+      //Results.Add(new Result("Detection Exclusivity", new DoubleValue()));
 
       ResultsTargets.Rows.Add(new DataRow(ResultsTargetsReal));
+      ResultsHorizonTargets.Rows.Add(new DataRow(ResultsTargetsReal));
+      ResultsConfidenceTargets.Rows.Add(new RangeDataRow(ResultsTargetsReal));
+      ResultsErrorRangeTargets.Rows.Add(new RangeDataRow(ResultsTargetsReal));
+      int i = 1;
       foreach (var ensemble in Ensembles) {
         // targets table
         ResultsTargets.Rows.Add(new DataRow(ensemble.Name));
+        ResultsHorizonTargets.Rows.Add(new DataRow(ensemble.Name));
+        ResultsErrorRangeTargets.Rows.Add(new RangeDataRow(ensemble.Name));
+        ResultsErrorRangeTargets.Rows[ensemble.Name].VisualProperties.Color = _colorsBrightPastel[i];
+        ResultsConfidenceTargets.Rows.Add(new RangeDataRow(ensemble.Name));
+        ResultsConfidenceTargets.Rows[ensemble.Name].VisualProperties.Color = _colorsBrightPastel[i];
+        i++;
 
         ResultsStateDetection.Rows.Add(new DataRow(ensemble.Name));
@@ -243,6 +276,7 @@
         //ResultsQualities.Rows.Add(new DataRow(ensemble.Name + " - " + ResultsQualitiesMSE));
         ResultsQualities.Rows.Add(new DataRow(ensemble.Name));
-
-        ResultsPeakQualities.Rows.Add(new DataRow(ensemble.Name));
+        ResultsHorizonQualities.Rows.Add(new DataRow(ensemble.Name));
+
+        //ResultsPeakQualities.Rows.Add(new DataRow(ensemble.Name));
 
         // qualities (bars)
@@ -250,11 +284,21 @@
 
         // voting (bars)
-        ResultsSWVotingBars.Bars.Add(new DataBar(ensemble.Name, ensemble.ConfidenceThreshold.Start, ensemble.ConfidenceThreshold.End));
+        //ResultsSWVotingBars.Bars.Add(new DataBar(ensemble.Name, ensemble.ConfidenceThreshold.Start, ensemble.ConfidenceThreshold.End));
 
         // sonar quality (bars)
-        ResultsSonarQualitiesBars.Bars.Add(new DataBar(ensemble.Name, ensemble.QualityThreshold.Start, ensemble.QualityThreshold.End));
+        //ResultsSonarQualitiesBars.Bars.Add(new DataBar(ensemble.Name, ensemble.QualityThreshold.Start, ensemble.QualityThreshold.End));
 
         // quality peaks (bars)
-        ResultsSWPeakQualitiesBars.Bars.Add(new DataBar(ensemble.Name, ensemble.QualityThreshold.Start, ensemble.QualityThreshold.End));
+        //ResultsSWPeakQualitiesBars.Bars.Add(new DataBar(ensemble.Name, ensemble.QualityThreshold.Start, ensemble.QualityThreshold.End));
+      }
+
+      foreach (var ensemble in Ensembles) {
+        Color color = ResultsErrorRangeTargets.Rows[ensemble.Name].VisualProperties.Color;
+        color = Color.FromArgb(150, (int)(color.R * 1.0), (int)(color.G * 1.0), (int)(color.B * 1.0));
+        string rowName = ensemble.Name + " " + ResultsTargetRange;
+        ResultsErrorRangeTargets.Rows.Add(new RangeDataRow(rowName));
+        ResultsErrorRangeTargets.Rows[rowName].VisualProperties.Color = color;
+        ResultsConfidenceTargets.Rows.Add(new RangeDataRow(rowName));
+        ResultsConfidenceTargets.Rows[rowName].VisualProperties.Color = color;
       }
     }
@@ -275,5 +319,5 @@
 
     [StorableConstructor]
-    protected DatastreamAnalysisOptimizer(bool deserializing) : base(deserializing) {
+    protected DatastreamAnalysisOptimizer(StorableConstructorFlag _) : base(_) {
     }
 
@@ -302,4 +346,5 @@
       if (datastream != null) RegisterDatastreamEvents();
       if (ensembles != null) RegisterEnsembleEvents();
+      Prepare();
     }
     #endregion
@@ -309,5 +354,4 @@
     public override void Prepare() {
       if (ensembles == null || ensembles.Count == 0 || datastream == null || !datastream.SlidingWindowEvaluationPossible) return;
-      //if (ensembles.SelectMany(x => x.Models).Count() == 0) return;
       base.Prepare();
       OnPrepared();
@@ -428,4 +472,7 @@
       try {
         Run(cancellationToken);
+      } catch(Exception ex) {
+        if (ex is ArgumentOutOfRangeException) throw ex;
+        if (ex is OperationCanceledException) throw ex;
       }
       finally {
@@ -445,17 +492,26 @@
         replayedIndex = 0;
         prepared = false;
-      }
-
-      try {
+
+
+        Setup();
 
         // play and evaluate initial window
         PlayDatastream();
+
+        for (int i = 1; i < Datastream.EvaluationHorizon.Value; i++) {
+          foreach (var ensemble in Ensembles) {
+            ResultsHorizonTargets.Rows[ensemble.Name].Values.Add(double.NaN);
+          }
+        }
+
         //lastStateValue = Datastream.ProblemData.Dataset.GetDoubleValue("h", replayedIndex);
         if (Datastream.SlidingWindowEvaluationPossible) Evaluate();
         replayedIndex = Datastream.FitnessPartition.End;
-
+      }
+
+      try {
         do {
           while(Datastream.SlidingWindowMovementPossible) {
-            cancellationToken.ThrowIfCancellationRequested();
+           cancellationToken.ThrowIfCancellationRequested();
 
             // perform (delayed) window movement
@@ -489,18 +545,31 @@
         var realValue = problemData.Dataset.GetDoubleValue(targetVarName, i);
         ResultsTargets.Rows[ResultsTargetsReal].Values.Add(realValue);
-      }
-    }
-
-    private void Smoothen(double[] estimatedValuesPerRow) {
-      if (Datastream.SlidingWindowEvaluationScheme.Value == Datastream.EvaluationScheme.equal) {
-        var avg = estimatedValuesPerRow.Average();
-        for (int i = 0; i < estimatedValuesPerRow.Length; i++) {
-          estimatedValuesPerRow[i] = avg;
-        }
+        ResultsHorizonTargets.Rows[ResultsTargetsReal].Values.Add(realValue);
+        ResultsErrorRangeTargets.Rows[ResultsTargetsReal].Values.Add(new Tuple<double, double>(realValue, realValue));
+        ResultsConfidenceTargets.Rows[ResultsTargetsReal].Values.Add(new Tuple<double, double>(realValue, realValue));
+      }
+    }
+
+    //private void Smoothen(double[] estimatedValuesPerRow) {
+    //  if (Datastream.SlidingWindowEvaluationScheme.Value == Datastream.EvaluationScheme.equal) {
+    //    var avg = estimatedValuesPerRow.Average();
+    //    for (int i = 0; i < estimatedValuesPerRow.Length; i++) {
+    //      estimatedValuesPerRow[i] = avg;
+    //    }
+    //  }
+    //}
+
+    Dictionary<string, List<double>> estimates;
+
+    private void Setup() {
+      estimates = new Dictionary<string, List<double>>();
+      foreach(var ensemble in Ensembles) {
+        estimates.Add(ensemble.Name, new List<double>());
       }
     }
 
     private void Evaluate() {
-      evaluationCount++;
+
+      //evaluationCount++;
       var problemData = Datastream.ProblemData;
       var dataset = problemData.Dataset;
@@ -510,8 +579,8 @@
       var realValues = dataset.GetDoubleValues(targetVarName, rows);
 
-      int sonarSize = (int)(Datastream.FitnessPartition.Size * Datastream.SlidingWindowSonarRatio.Value);
-      var sonarStart = Datastream.FitnessPartition.End - sonarSize;
-      var sonarRows = Enumerable.Range(sonarStart, sonarSize);
-      var sonarRealValues = dataset.GetDoubleValues(targetVarName, sonarRows);
+      //int sonarSize = (int)(Datastream.FitnessPartition.Size * Datastream.SlidingWindowSonarRatio.Value);
+      //var sonarStart = Datastream.FitnessPartition.End - sonarSize;
+      //var sonarRows = Enumerable.Range(sonarStart, sonarSize);
+      //var sonarRealValues = dataset.GetDoubleValues(targetVarName, sonarRows);
 
       var winningEnsembleName = ensembles[0].Name;
@@ -519,20 +588,24 @@
       var winningEnsembleIdx = 0;
       var ec = 0;
-      bool stateChangeInStep = false;
+      //bool stateChangeInStep = false;
       var curDetectionCount = 0;
-      var changeDetectionCount = 0;
+      //var changeDetectionCount = 0;
       //double curStateValue = 0.0;
 
       foreach (var ensemble in Ensembles) {
 
-        var sonarEstimatedValuesPerModelPerRow = ensemble.Model.Models.Select(x => x.GetEstimatedValues(datastream.ProblemData.Dataset, sonarRows).ToArray());
-        var sonarEstimatedValuesPerRow = Enumerable.Range(0, sonarSize).Select(r => sonarEstimatedValuesPerModelPerRow.Select(m => m[r]).Average()).ToArray();
+        //var sonarEstimatedValuesPerModelPerRow = ensemble.Model.Models.Select(x => x.GetEstimatedValues(datastream.ProblemData.Dataset, sonarRows).ToArray());
+        //var sonarEstimatedValuesPerRow = Enumerable.Range(0, sonarSize).Select(r => sonarEstimatedValuesPerModelPerRow.Select(m => m[r]).Average()).ToArray();
         
-        var estimatedValuesPerModelPerRow = ensemble.Model.Models.Select(x => x.GetEstimatedValues(datastream.ProblemData.Dataset, rows).ToArray());
-        var estimatedValuesPerRow = Enumerable.Range(0, Datastream.FitnessPartition.Size).Select(r => estimatedValuesPerModelPerRow.Select(e => e[r]).Average()).ToArray(); // per row
-        var averageEstimatedValuesPerModel = estimatedValuesPerModelPerRow.Select(x => x.Average()); // per model
-        var averageEstimatedValue = averageEstimatedValuesPerModel.Average();
-
-        // calulate quality
+        var estimatedValuesPerModelPerRow = ensemble.Model.Models.Select(x => x.GetEstimatedValues(datastream.ProblemData.Dataset, rows).ToArray());        
+        double[] estimatedValuesPerRow = Enumerable.Range(0, Datastream.FitnessPartition.Size).Select(r => estimatedValuesPerModelPerRow.Select(e => e[r]).Average()).ToArray(); // per row        
+        
+        //var averageEstimatedValuesPerModel = estimatedValuesPerModelPerRow.Select(x => x.Average()); // per model
+        //var averageEstimatedValue = averageEstimatedValuesPerModel.Average();
+
+
+
+
+        // calulate PR
         //var mse = Math.Pow(averageEstimatedValue - realValues.Average(), 2);
         OnlineCalculatorError error;
@@ -540,35 +613,55 @@
         var pR2 = error == OnlineCalculatorError.None ? pR * pR : 0.0;
 
-        var sonarPR = OnlinePearsonsRCalculator.Calculate(sonarEstimatedValuesPerRow, sonarRealValues, out error);
-        var sonarPR2 = error == OnlineCalculatorError.None ? sonarPR * sonarPR : 0.0;
+        //var sonarPR = OnlinePearsonsRCalculator.Calculate(sonarEstimatedValuesPerRow, sonarRealValues, out error);
+        //var sonarPR2 = error == OnlineCalculatorError.None ? sonarPR * sonarPR : 0.0;
    
         var estimatedValuesPerModelPerRowArr = estimatedValuesPerModelPerRow.ToArray();
         var curPR = 0.0;
         
-        var peakPR = OnlinePearsonsRCalculator.Calculate(estimatedValuesPerModelPerRowArr[0], realValues, out error);
-        for (int i = 1; i < estimatedValuesPerModelPerRow.Count(); i++) {
-          curPR = OnlinePearsonsRCalculator.Calculate(estimatedValuesPerModelPerRowArr[i], realValues, out error);
-          if (curPR > peakPR && error == OnlineCalculatorError.None) {
-            peakPR = curPR;
-          }
-        }
-        var peakPR2 = peakPR * peakPR;
+        //var peakPR = OnlinePearsonsRCalculator.Calculate(estimatedValuesPerModelPerRowArr[0], realValues, out error);
+        //for (int i = 1; i < estimatedValuesPerModelPerRow.Count(); i++) {
+        //  curPR = OnlinePearsonsRCalculator.Calculate(estimatedValuesPerModelPerRowArr[i], realValues, out error);
+        //  if (curPR > peakPR && error == OnlineCalculatorError.None) {
+        //    peakPR = curPR;
+        //  }
+        //}
+        //var peakPR2 = peakPR * peakPR;
+
+        // calculate
+        double mae = OnlineMeanAbsoluteErrorCalculator.Calculate(realValues, estimatedValuesPerRow, out error);
+        //double mse = OnlineMeanSquaredErrorCalculator.Calculate(realValues, estimatedValuesPerRow, out error);
 
         // calculate confidence
-        var cm1 = CalulateEnsembleConfidenceCM1(ensemble, estimatedValuesPerModelPerRow, realValues);
+        //var cm1 = CalulateEnsembleConfidenceCM1(ensemble, estimatedValuesPerModelPerRow, realValues);
 
         int replayAmount = Datastream.FitnessPartition.End - replayedIndex;
         int replayCount = estimatedValuesPerRow.Length - replayAmount;
 
-        Smoothen(estimatedValuesPerRow);
+        //Smoothen(estimatedValuesPerRow);
 
         for (int i = replayedIndex; i < Datastream.FitnessPartition.End; i++) {
           //ResultsTargets.Rows[ensemble.Name].Values.Add(averageEstimatedValue);
+          
+          var estVal = estimatedValuesPerRow[replayCount];
+          var estStdDev = ComputeStdDev(estimatedValuesPerModelPerRow.Select(x => x[replayCount]).ToList());
+
           ResultsTargets.Rows[ensemble.Name].Values.Add(estimatedValuesPerRow[replayCount]);
+          if(Datastream.RollingEvaluationHorizon.Value) {
+            var rollingPrediction = RollingEvaluate(ensemble, i);
+            ResultsHorizonTargets.Rows[ensemble.Name].Values.Add(rollingPrediction);
+          } else {
+            ResultsHorizonTargets.Rows[ensemble.Name].Values.Add(estimatedValuesPerRow[replayCount]);
+          }
+
+
+          ResultsErrorRangeTargets.Rows[ensemble.Name].Values.Add(new Tuple<double, double>(estVal, estVal));
+          ResultsErrorRangeTargets.Rows[ensemble.Name + " " + ResultsTargetRange].Values.Add(new Tuple<double, double>(estVal - mae, estVal + mae));
+          ResultsConfidenceTargets.Rows[ensemble.Name].Values.Add(new Tuple<double, double>(estVal, estVal));
+          ResultsConfidenceTargets.Rows[ensemble.Name + " " + ResultsTargetRange].Values.Add(new Tuple<double, double>(estVal - 1.96*estStdDev, estVal + 1.96*estStdDev));
           replayCount++;
 
           //ResultsQualities.Rows[ensemble.Name + " - " + ResultsQualitiesMSE].Values.Add(mse);
           ResultsQualities.Rows[ensemble.Name].Values.Add(pR2);
-          ResultsPeakQualities.Rows[ensemble.Name].Values.Add(peakPR2);
+          //ResultsPeakQualities.Rows[ensemble.Name].Values.Add(peakPR2);
 
           double amp = (pR2 > ensemble.QualityThreshold.Start) ? 1.0 : 0.0;
@@ -576,7 +669,7 @@
         }
         ResultsSWQualitiesBars.Bars[ensemble.Name].Value = pR2;
-        ResultsSonarQualitiesBars.Bars[ensemble.Name].Value = sonarPR2;
-        ResultsSWVotingBars.Bars[ensemble.Name].Value = cm1;
-        ResultsSWPeakQualitiesBars.Bars[ensemble.Name].Value = peakPR2;
+        //ResultsSonarQualitiesBars.Bars[ensemble.Name].Value = sonarPR2;
+        //ResultsSWVotingBars.Bars[ensemble.Name].Value = cm1;
+        //ResultsSWPeakQualitiesBars.Bars[ensemble.Name].Value = peakPR2;
 
         if (pR2 > ensemble.QualityThreshold.Start)
@@ -594,74 +687,73 @@
       // =================================================
 
-      if (winningEnsemblePR2 > ensembles[winningEnsembleIdx].QualityThreshold.Start) {
-        // Mean PR2
-        pR2Sum += winningEnsemblePR2;
-        detectionCount++;
-        ResultsMeanPR2 = pR2Sum/detectionCount;
-
-        // detection exclusivity --> 1.0 - (x - 1) * (1.0 / n)
-        var fraction = 1.0 / ensembles.Count;
-        var curExclusivity = 1.0 - (curDetectionCount - 1) * fraction;
-        exclusivitySum += curExclusivity;
-        ResultsDetectionExclusivity = exclusivitySum / detectionCount;
-      }
-
-      //double replCount = 0.0;
-      //double accCount = 0.0;
-      //for (int i = replayedIndex; i < Datastream.FitnessPartition.End; i++) {
-      //  replCount++;
-      //  //curStateValue = problemData.Dataset.GetDoubleValue("h", i);
-      //  if (curStateValue <= 0.5 && winningEnsembleIdx == 0 && winningEnsemblePR2 > ensembles[winningEnsembleIdx].QualityThreshold.Start) {
-      //    accCount++;
-      //  } else if (curStateValue > 0.5 && winningEnsembleIdx == 1 && winningEnsemblePR2 > ensembles[winningEnsembleIdx].QualityThreshold.Start) {
-      //    accCount++;
-      //  }
+      //if (winningEnsemblePR2 > ensembles[winningEnsembleIdx].QualityThreshold.Start) {
+      //  // Mean PR2
+      //  pR2Sum += winningEnsemblePR2;
+      //  detectionCount++;
+      //  ResultsMeanPR2 = pR2Sum/detectionCount;
+
+      //  // detection exclusivity --> 1.0 - (x - 1) * (1.0 / n)
+      //  var fraction = 1.0 / ensembles.Count;
+      //  var curExclusivity = 1.0 - (curDetectionCount - 1) * fraction;
+      //  exclusivitySum += curExclusivity;
+      //  ResultsDetectionExclusivity = exclusivitySum / detectionCount;
       //}
-      //accuracySum += accCount / replCount;
-      //ResultsDetectionAccuracy = accuracySum / evaluationCount;
-
-
-
-
-      //if (accCount / replCount > 1.0) {
-      //  Console.WriteLine();
-      //}
-
-      //if(accuracySum / evaluationCount > 1.0) {
-      //  Console.WriteLine();
-      //}
-
-      //if (accCount < replCount && !accDiscount) accDiscount = true;
-      //if (accDiscount && accuracySum/evaluationCount >= 1.0) {
-      //  Console.WriteLine();
-      //}
-
-      //lastStateValue = curStateValue;
-
-      // detection of state change
-      //for (int i = replayedIndex; i < Datastream.FitnessPartition.End; i++) {
-      //  curStateValue = problemData.Dataset.GetDoubleValue("h", i);
-      //  if (lastStateValue > curStateValue || lastStateValue < curStateValue) {
-      //    stateChangeInStep = true;
-      //    changeDetectionCount++;
-      //  }
-      //}
-      //lastStateValue = curStateValue;
-
-      // detection accuracy
-      //if (!stateChangeInStep && winningEnsemblePR2 > ensembles[winningEnsembleIdx].QualityThreshold.Start) {
-      //  // (stable) state - detected
-      //  accuracySum++;
-      //} else if(!stateChangeInStep && winningEnsemblePR2 < ensembles[winningEnsembleIdx].QualityThreshold.Start) {
-      //  // (stable) state - not detected
-      //  // no accuracy points (or penalty)
-      //} else if (stateChangeInStep && winningEnsemblePR2 < ensembles[winningEnsembleIdx].QualityThreshold.Start) {
-      //  // change - detected
-      //  accuracySum++;
-      //} else if (stateChangeInStep && winningEnsemblePR2 > ensembles[winningEnsembleIdx].QualityThreshold.Start) {
-      //  // change - not detected
-      //  // no accuracy points (or penalty)
-      //}
-    }
+
+      OnlineCalculatorError err;
+
+      int size = Datastream.FitnessPartition.Size;
+      int horizon = Datastream.EvaluationHorizon.Value;
+      int start = replayedIndex - size;
+      int end = start + size;
+
+      var realVals = ResultsHorizonTargets.Rows[ResultsTargetsReal].Values;
+      if (replayedIndex >= (size - 1)+horizon && realVals.Count >= end) {
+        
+        var reals = Enumerable.Range(start, size).Select(r => realVals[r]).ToArray();
+
+        foreach (var ensemble in Ensembles) {
+          var estimatedVals = ResultsHorizonTargets.Rows[ensemble.Name].Values;
+
+          if (estimatedVals.Count >= end) {
+            var vals = Enumerable.Range(start, size).Select(r => estimatedVals[r]).ToArray();
+            var pR = OnlinePearsonsRCalculator.Calculate(vals, reals, out err);
+            var pR2 = err == OnlineCalculatorError.None ? pR * pR : 0.0;
+            ResultsHorizonQualities.Rows[ensemble.Name].Values.Add(pR2);
+          }
+        }
+      }
+
+
+    }
+
+    private double RollingEvaluate(ProxyEnsembleModel ensemble, int index) {
+      
+      var variables = datastream.ProblemData.InputVariables
+        .Select(x => x.Value)
+        .Where(x => x != datastream.ProblemData.TargetVariable)
+        .ToList();
+      var ods = datastream.ProblemData.Dataset;
+      var values = new double[1,variables.Count];
+      var rows = Enumerable.Range(0, 1);
+
+      for(int i = 0; i < variables.Count; i++) {
+        values[0,i] = ods.GetDoubleValue(variables[i], index);
+      }
+
+      Dataset ds = new Dataset(variables, values);
+      double estimate = ensemble.Model.GetEstimatedValues(ds, rows).ToArray()[0];
+
+      for(int i = 1; i < datastream.EvaluationHorizon.Value; i++) {
+        values[0, 0] = estimate;
+        for(int v = 0; v < variables.Count-1; v++) {
+          values[0, v + 1] = ds.GetDoubleValue(variables[v], 0);
+        }
+        ds = new Dataset(variables, values);
+        estimate = ensemble.Model.GetEstimatedValues(ds, rows).ToArray()[0];
+      }
+      
+      return estimate;
+    }
+
     private bool accDiscount = false;
 
@@ -879,4 +971,12 @@
 
     #endregion nameditem
+
+    #region Helpers
+    private double ComputeStdDev(List<double> series) {
+      double avg = series.Average();
+      double sumOfSquaredDeviations = series.Sum(val => (val - avg) * (val - avg));
+      return Math.Sqrt(sumOfSquaredDeviations / (series.Count - 1));
+    }
+    #endregion
   }
 }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/DatastreamAnalysisUtil.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/DatastreamAnalysisUtil.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/DatastreamAnalysisUtil.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,6 +21,4 @@
 
 using System;
-using HeuristicLab.Collections;
-using HeuristicLab.Core;
 
 namespace HeuristicLab.DatastreamAnalysis {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/ExtendedDataTable.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/ExtendedDataTable.cs	(revision 17980)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/ExtendedDataTable.cs	(revision 17980)
@@ -0,0 +1,318 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+ #endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Analysis;
+using HeuristicLab.Collections;
+using HEAL.Attic;
+
+namespace HeuristicLab.DatastreamAnalysis {
+  /// <summary>
+  /// A table of data values or intervals.
+  /// </summary>
+  [Item("ExtendedDataTable", "A data table where the points are either double values or ranges")]
+  [StorableType("8E716B16-5B9C-441D-97BB-8C362E8D5BC4")]
+  public class ExtendedDataTable : NamedItem, IStringConvertibleMatrix, IContent {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Performance; }
+    }
+
+    private DataTableVisualProperties visualProperties;
+    public DataTableVisualProperties VisualProperties {
+      get { return visualProperties; }
+      set {
+        if (visualProperties != value) {
+          if (value == null) throw new ArgumentNullException("VisualProperties");
+          if (visualProperties != null) visualProperties.PropertyChanged -= new PropertyChangedEventHandler(VisualProperties_PropertyChanged);
+          visualProperties = value;
+          visualProperties.PropertyChanged += new PropertyChangedEventHandler(VisualProperties_PropertyChanged);
+          OnVisualPropertiesChanged();
+        }
+      }
+    }
+
+    private NamedItemCollection<RangeDataRow> rows;
+    public NamedItemCollection<RangeDataRow> Rows {
+      get { return rows; }
+      private set {
+        if (rows != null) throw new InvalidOperationException("Rows already set.");
+        rows = value;
+        if (rows != null) RegisterRowsEvents();
+      }
+    }
+
+    #region Persistence Properties
+    [Storable(Name = "VisualProperties")]
+    private DataTableVisualProperties StorableVisualProperties {
+      get { return visualProperties; }
+      set {
+        visualProperties = value;
+        visualProperties.PropertyChanged += new PropertyChangedEventHandler(VisualProperties_PropertyChanged);
+      }
+    }
+    [Storable(Name = "rows")]
+    private IEnumerable<RangeDataRow> StorableRows {
+      get { return rows; }
+      set { rows = new NamedItemCollection<RangeDataRow>(value); }
+    }
+    #endregion
+
+    #region constructors, cloner,...
+    [StorableConstructor]
+    protected ExtendedDataTable(StorableConstructorFlag _) : base(_) { }
+    protected ExtendedDataTable(ExtendedDataTable original, Cloner cloner) : base(original, cloner) {
+      VisualProperties = (DataTableVisualProperties)cloner.Clone(original.visualProperties);
+      rows = cloner.Clone(original.rows);
+      this.RegisterRowsEvents();
+    }
+    public ExtendedDataTable() : base() {
+      Name = "ExtendedDataTable";
+      VisualProperties = new DataTableVisualProperties();
+      rows = new NamedItemCollection<RangeDataRow>();
+      this.RegisterRowsEvents();
+    }
+    public ExtendedDataTable(string name) : base(name) {
+      VisualProperties = new DataTableVisualProperties();
+      rows = new NamedItemCollection<RangeDataRow>();
+      this.RegisterRowsEvents();
+    }
+    public ExtendedDataTable(string name, string description) : base(name, description) {
+      VisualProperties = new DataTableVisualProperties();
+      rows = new NamedItemCollection<RangeDataRow>();
+      this.RegisterRowsEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ExtendedDataTable(this, cloner);
+    }
+    #endregion constructors, cloner,...
+
+    #region events
+    public event EventHandler VisualPropertiesChanged;
+    protected virtual void OnVisualPropertiesChanged() {
+      var handler = VisualPropertiesChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    private void VisualProperties_PropertyChanged(object sender, PropertyChangedEventArgs e) {
+      OnVisualPropertiesChanged();
+    }
+
+    private void RegisterRowsEvents() {
+      rows.ItemsAdded += new CollectionItemsChangedEventHandler<RangeDataRow>(Rows_ItemsAdded);
+      rows.ItemsRemoved += new CollectionItemsChangedEventHandler<RangeDataRow>(Rows_ItemsRemoved);
+      rows.ItemsReplaced += new CollectionItemsChangedEventHandler<RangeDataRow>(Rows_ItemsReplaced);
+      rows.CollectionReset += new CollectionItemsChangedEventHandler<RangeDataRow>(Rows_CollectionReset);
+      foreach (var row in Rows) RegisterRowEvents(row);
+    }
+
+    protected virtual void Rows_ItemsAdded(object sender, CollectionItemsChangedEventArgs<RangeDataRow> e) {
+      foreach (var row in e.Items)
+        this.RegisterRowEvents(row);
+
+      this.OnColumnsChanged();
+      this.OnColumnNamesChanged();
+      this.OnReset();
+    }
+    protected virtual void Rows_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<RangeDataRow> e) {
+      foreach (var row in e.Items)
+        this.DeregisterRowEvents(row);
+
+      this.OnColumnsChanged();
+      this.OnColumnNamesChanged();
+      this.OnReset();
+    }
+    protected virtual void Rows_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<RangeDataRow> e) {
+      foreach (var row in e.OldItems)
+        this.DeregisterRowEvents(row);
+      foreach (var row in e.Items)
+        this.RegisterRowEvents(row);
+
+      this.OnColumnsChanged();
+      this.OnColumnNamesChanged();
+      this.OnReset();
+    }
+    protected virtual void Rows_CollectionReset(object sender, CollectionItemsChangedEventArgs<RangeDataRow> e) {
+      foreach (var row in e.OldItems)
+        this.DeregisterRowEvents(row);
+      foreach (var row in e.Items)
+        this.RegisterRowEvents(row);
+
+      if (e.OldItems.Count() != e.Items.Count())
+        this.OnColumnsChanged();
+      this.OnColumnNamesChanged();
+      this.OnReset();
+    }
+
+    private void RegisterRowEvents(RangeDataRow row) {
+      row.Values.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsAdded);
+      row.Values.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsMoved);
+      row.Values.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsRemoved);
+      row.Values.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsReplaced);
+      row.Values.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_CollectionReset);
+      //if (row is DataRow) {
+      //  DataRow _row = row as DataRow;
+      //  _row.Values.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsAdded);
+      //  _row.Values.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsMoved);
+      //  _row.Values.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsRemoved);
+      //  _row.Values.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsReplaced);
+      //  _row.Values.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_CollectionReset);
+      //} else if(row is RangeDataRow) {
+      //  RangeDataRow _row = row as RangeDataRow;
+      //  _row.Values.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsAdded);
+      //  _row.Values.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsMoved);
+      //  _row.Values.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsRemoved);
+      //  _row.Values.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsReplaced);
+      //  _row.Values.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_CollectionReset);
+      //}
+    }
+    private void DeregisterRowEvents(RangeDataRow row) {
+      row.Values.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsAdded);
+      row.Values.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsMoved);
+      row.Values.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsRemoved);
+      row.Values.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_ItemsReplaced);
+      row.Values.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<double, double>>>(Values_CollectionReset);
+    }
+    #endregion events
+
+    #region RangeDataRow Value Events
+    private void Values_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<double, double>>> e) {
+      this.OnReset();
+    }
+    private void Values_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<double, double>>> e) {
+      this.OnReset();
+    }
+    private void Values_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<double, double>>> e) {
+      this.OnReset();
+    }
+    private void Values_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<double, double>>> e) {
+      this.OnReset();
+    }
+    private void Values_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<double, double>>> e) {
+      this.OnReset();
+    }
+    #endregion
+
+    #region IStringConvertibleMatrix Members
+
+    int IStringConvertibleMatrix.Rows {
+      get {
+        //int maxDR = rows.OfType<DataRow>().Max(r => r.Values.Count);
+        //int maxIDR = rows.OfType<RangeDataRow>().Max(r => r.Values.Count);
+        //return rows.Count == 0 ? 0 : maxDR >= maxIDR ? maxDR : maxIDR;
+        return rows.Count == 0 ? 0 : rows.Max(r => r.Values.Count);
+      }
+      set { throw new NotSupportedException(); }
+    }
+    int IStringConvertibleMatrix.Columns {
+      get { return rows.Count; }
+      set { throw new NotSupportedException(); }
+    }
+    IEnumerable<string> IStringConvertibleMatrix.ColumnNames {
+      get { return rows.Select(r => r.Name); }
+      set { throw new NotSupportedException(); }
+    }
+    IEnumerable<string> IStringConvertibleMatrix.RowNames {
+      get { return Enumerable.Empty<string>(); }
+      set { throw new NotSupportedException(); }
+    }
+
+    bool IStringConvertibleMatrix.SortableView {
+      get { return true; }
+      set { throw new NotSupportedException(); }
+    }
+    bool IStringConvertibleMatrix.ReadOnly {
+      get { return true; }
+    }
+
+    string IStringConvertibleMatrix.GetValue(int rowIndex, int columnIndex) {
+      if (columnIndex < rows.Count) {
+        string columnName = ((IStringConvertibleMatrix)this).ColumnNames.ElementAt(columnIndex);
+        if(rows.ContainsKey(columnName)) {
+          RangeDataRow row = rows[columnName];
+          if(rowIndex < row.Values.Count) return "[" + row.Values[rowIndex].Item1 + "," + row.Values[rowIndex].Item1 + "]";
+        }
+        //if(rows.ContainsKey(columnName)) {
+        //  if(rows[columnName] is DataRow) {
+        //    DataRow row = rows[columnName] as DataRow;
+        //    if (rowIndex < row.Values.Count) return row.Values[rowIndex].ToString();
+        //  } else if(rows[columnName] is RangeDataRow) {
+        //    RangeDataRow row = rows[columnName] as RangeDataRow;
+        //    if (rowIndex < row.Values.Count) return "[" + row.Values[rowIndex].Item1 + "," + row.Values[rowIndex].Item1 + "]";
+        //  }
+        //}
+      }
+      return string.Empty;
+    }
+
+    bool IStringConvertibleMatrix.Validate(string value, out string errorMessage) {
+      throw new NotSupportedException();
+    }
+    bool IStringConvertibleMatrix.SetValue(string value, int rowIndex, int columnIndex) {
+      throw new NotSupportedException();
+    }
+
+    public event EventHandler<EventArgs<int, int>> ItemChanged;
+    protected virtual void OnItemChanged(int rowIndex, int columnIndex) {
+      var handler = ItemChanged;
+      if (handler != null) handler(this, new EventArgs<int, int>(rowIndex, columnIndex));
+      OnToStringChanged();
+    }
+    public event EventHandler Reset;
+    protected virtual void OnReset() {
+      var handler = Reset;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ColumnsChanged;
+    protected virtual void OnColumnsChanged() {
+      var handler = ColumnsChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler RowsChanged;
+    protected virtual void OnRowsChanged() {
+      var handler = RowsChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ColumnNamesChanged;
+    protected virtual void OnColumnNamesChanged() {
+      var handler = ColumnNamesChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler RowNamesChanged;
+    protected virtual void OnRowNamesChanged() {
+      var handler = RowNamesChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler SortableViewChanged;
+    protected virtual void OnSortableViewChanged() {
+      var handler = SortableViewChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    #endregion
+  }
+}
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/HeuristicLab.DatastreamAnalysis.csproj
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/HeuristicLab.DatastreamAnalysis.csproj	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/HeuristicLab.DatastreamAnalysis.csproj	(revision 17980)
@@ -10,5 +10,5 @@
     <RootNamespace>HeuristicLab.DatastreamAnalysis</RootNamespace>
     <AssemblyName>HeuristicLab.DatastreamAnalysis-3.4</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <TargetFrameworkProfile />
@@ -26,5 +26,5 @@
     <DebugType>pdbonly</DebugType>
     <Optimize>true</Optimize>
-    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <OutputPath>..\..\..\..\trunk\bin\</OutputPath>
     <DefineConstants>TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
@@ -38,6 +38,12 @@
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="HeuristicLab.Analysis-3.3">
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Analysis-3.3.dll</HintPath>
+    <Reference Include="HEAL.Attic, Version=1.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HEAL.Attic.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Analysis-3.3.dll</HintPath>
       <Private>False</Private>
     </Reference>
@@ -94,4 +100,5 @@
     <Reference Include="System.Drawing" />
     <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Windows.Forms.DataVisualization" />
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
@@ -103,4 +110,5 @@
   <ItemGroup>
     <Compile Include="AnalysisBase.cs" />
+    <Compile Include="ExtendedDataTable.cs" />
     <Compile Include="DataBar.cs" />
     <Compile Include="DataBarSet.cs" />
@@ -110,4 +118,5 @@
     <Compile Include="IAnalysisBase.cs" />
     <Compile Include="IDatastream.cs" />
+    <Compile Include="RangeDataRow.cs" />
     <Compile Include="IProxyEnsembleModel.cs" />
     <Compile Include="Plugin.cs" />
@@ -124,4 +133,5 @@
       <Project>{df87c13e-a889-46ff-8153-66dcaa8c5674}</Project>
       <Name>HeuristicLab.Problems.DataAnalysis-3.4</Name>
+      <Private>False</Private>
     </ProjectReference>
   </ItemGroup>
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/IAnalysisBase.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/IAnalysisBase.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/IAnalysisBase.cs	(revision 17980)
@@ -1,7 +1,24 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+ #endregion
+
+using System;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/IDatastream.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/IDatastream.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/IDatastream.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -22,5 +22,4 @@
 using System;
 using System.Collections.Generic;
-using HeuristicLab.Common;
 using HeuristicLab.Core;
 
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/IProxyEnsembleModel.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/IProxyEnsembleModel.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/IProxyEnsembleModel.cs	(revision 17980)
@@ -1,7 +1,25 @@
-﻿using System;
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 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 System.Threading.Tasks;
 using HeuristicLab.Core;
 
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/Plugin.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/Plugin.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/Plugin.cs	(revision 17980)
@@ -23,5 +23,5 @@
 
 namespace HeuristicLab.DatastreamAnalysis {
-  [Plugin("HeuristicLab.DatastreamAnalysis", "3.4.14.15025")]
+  [Plugin("HeuristicLab.DatastreamAnalysis", "3.4.14.15867")]
   [PluginFile("HeuristicLab.DatastreamAnalysis-3.4.dll", PluginFileType.Assembly)]
   [PluginDependency("HeuristicLab.Collections", "3.3")]
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/Properties/AssemblyInfo.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/Properties/AssemblyInfo.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/Properties/AssemblyInfo.cs	(revision 17980)
@@ -54,3 +54,3 @@
 // [assembly: AssemblyVersion("1.0.*")]
 [assembly: AssemblyVersion("3.4.0.0")]
-[assembly: AssemblyFileVersion("3.4.14.15025")]
+[assembly: AssemblyFileVersion("3.4.14.15867")]
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/ProxyEnsembleModel.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/ProxyEnsembleModel.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/ProxyEnsembleModel.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -18,21 +18,19 @@
  * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
  */
-#endregion
+ #endregion
 
 using System;
 using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using HeuristicLab.Collections;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 using HeuristicLab.Problems.DataAnalysis;
+using HEAL.Attic;
+
 namespace HeuristicLab.DatastreamAnalysis {
-  [StorableClass]
-  [Item("Proxy Ensemble Model", "Represents a named and rated collection of models which acts as a model yet again.")]
+  [Item("Proxy Ensemble Model", "Represents a named and rated collection of models which acts as a model yet again.")]  
   [Creatable(CreatableAttribute.Categories.DataAnalysis)]
+  [StorableType("F3794605-3D02-4482-8919-2FC29EBDB6F4")]
   public class ProxyEnsembleModel : ParameterizedNamedItem, IProxyEnsembleModel {
     protected const string ModelParameterName = "Model";
@@ -76,5 +74,5 @@
     #region constructors, clone ...
     [StorableConstructor]
-    protected ProxyEnsembleModel(bool deserializing) : base(deserializing) { }
+    protected ProxyEnsembleModel(StorableConstructorFlag _) : base(_) { }
     protected ProxyEnsembleModel(ProxyEnsembleModel original, Cloner cloner) : base(original, cloner) {
       RegisterParameterEvents();
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/RangeDataRow.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/RangeDataRow.cs	(revision 17980)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/RangeDataRow.cs	(revision 17980)
@@ -0,0 +1,117 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Analysis;
+using HEAL.Attic;
+
+namespace HeuristicLab.DatastreamAnalysis {
+  /// <summary>
+  /// A row of data ranges.
+  /// </summary>
+  [Item("RangeDataRow", "A DataRow with double tuples")]
+  [StorableType("38367CFE-AEE7-44C2-BF10-CB42F25BB533")]
+  public class RangeDataRow : NamedItem {
+    private DataRowVisualProperties visualProperties;
+    public DataRowVisualProperties VisualProperties {
+      get { return visualProperties; }
+      set {
+        if (visualProperties != value) {
+          if (value == null) throw new ArgumentNullException("VisualProperties");
+          if (visualProperties != null) visualProperties.PropertyChanged -= new PropertyChangedEventHandler(VisualProperties_PropertyChanged);
+          visualProperties = value;
+          visualProperties.PropertyChanged += new PropertyChangedEventHandler(VisualProperties_PropertyChanged);
+          OnVisualPropertiesChanged();
+        }
+      }
+    }
+    private ObservableList<Tuple<double,double>> values;
+    public ObservableList<Tuple<double, double>> Values {
+      get { return values; }
+    }
+
+    #region Persistence Properties
+    [Storable(Name = "VisualProperties")]
+    private DataRowVisualProperties StorableVisualProperties {
+      get { return visualProperties; }
+      set {
+        visualProperties = value;
+        visualProperties.PropertyChanged += new PropertyChangedEventHandler(VisualProperties_PropertyChanged);
+      }
+    }
+    [Storable(Name ="values")]
+    private IEnumerable<Tuple<double, double>> StorableValues {
+      get { return values; }
+      set { values = new ObservableList<Tuple<double, double>>(value); }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected RangeDataRow(StorableConstructorFlag _) : base(_) { }
+    protected RangeDataRow(RangeDataRow original, Cloner cloner)
+      : base(original, cloner) {
+      this.VisualProperties = (DataRowVisualProperties)cloner.Clone(original.visualProperties);
+      this.values = new ObservableList<Tuple<double, double>>(original.values);
+    }
+    public RangeDataRow() : this("RangeDataRow") { }
+    public RangeDataRow(string name)
+      : base(name) {
+      if (string.IsNullOrEmpty(name)) throw new ArgumentException("Name of a RangeDataRow cannot be empty", name);
+      VisualProperties = new DataRowVisualProperties(name);
+      values = new ObservableList<Tuple<double,double>>();
+    }
+    public RangeDataRow(string name, string description)
+      : base(name, description) {
+      if (string.IsNullOrEmpty(name)) throw new ArgumentException("Name of a RangeDataRow cannot be empty", name);
+      VisualProperties = new DataRowVisualProperties(name);
+      values = new ObservableList<Tuple<double, double>>();
+    }
+    public RangeDataRow(string name, string description, IEnumerable<Tuple<double, double>> values)
+      : base(name, description) {
+      if (string.IsNullOrEmpty(name)) throw new ArgumentException("Name of a RangeDataRow cannot be empty", name);
+      VisualProperties = new DataRowVisualProperties(name);
+      this.values = new ObservableList<Tuple<double, double>>(values);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RangeDataRow(this, cloner);
+    }
+
+    public event EventHandler VisualPropertiesChanged;
+    protected virtual void OnVisualPropertiesChanged() {
+      EventHandler handler = VisualPropertiesChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    private void VisualProperties_PropertyChanged(object sender, PropertyChangedEventArgs e) {
+      OnVisualPropertiesChanged();
+    }
+    protected override void OnNameChanged() {
+      base.OnNameChanged();
+      VisualProperties.DisplayName = Name;
+    }
+  }
+}
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -25,15 +25,15 @@
 using System.Collections.ObjectModel;
 using System.Linq;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
 namespace HeuristicLab.Problems.DataAnalysis {
   [Item("Dataset", "Represents a dataset containing data that should be analyzed.")]
-  [StorableClass]
+  [StorableType("49F4D145-50D7-4497-8D8A-D190CD556CC8")]
   public class Dataset : NamedItem, IDataset {
     [StorableConstructor]
-    protected Dataset(bool deserializing) : base(deserializing) { }
+    protected Dataset(StorableConstructorFlag _) : base(_) { }
     protected Dataset(Dataset original, Cloner cloner)
       : base(original, cloner) {
@@ -115,18 +115,44 @@
     }
 
+    public static Dataset FromRowData(IEnumerable<string> variableNames, double[,] data) {
+      var colWise = new List<IList>(data.GetLength(1));
+      for (var col = 0; col < data.GetLength(1); col++) {
+        var column = new List<double>(data.GetLength(0));
+        for (var row = 0; row < data.GetLength(0); row++) {
+          column.Add(data[row, col]);
+        }
+        colWise.Add(column);
+      }
+      return new Dataset(variableNames, colWise);
+    }
+
+    public static Dataset FromRowData(IEnumerable<string> variableNames, IEnumerable<IList> data) {
+      var vnames = variableNames.ToList();
+      var transposed = new List<IList>();
+      var iter = data.GetEnumerator();
+      if (!iter.MoveNext()) throw new ArgumentException("Data does not contain any rows", nameof(data));
+      for (var i = 0; i < iter.Current.Count; i++) {
+        if (i >= vnames.Count) throw new ArgumentException("There are more variables in data, than variable names.", nameof(variableNames));
+        if (iter.Current[i] == null) throw new ArgumentException("Null values are not supported.", nameof(data));
+        if (!IsAllowedType(iter.Current[i].GetType())) throw new ArgumentException("Data contains types that are not allowed.", nameof(data));
+        if (iter.Current[i] is double d)
+          transposed.Add(new List<double>() { d });
+        else if (iter.Current[i] is DateTime dt)
+          transposed.Add(new List<DateTime>() { dt });
+        else if (iter.Current[i] is string s)
+          transposed.Add(new List<string>() { s });
+        else throw new NotSupportedException(string.Format("Variable {0} has type {1}. This is not supported when converting from row-wise data.", vnames[i], iter.Current[i].GetType()));
+      }
+      if (transposed.Count < vnames.Count) throw new ArgumentException("There are less variables in data, than variable names.", nameof(variableNames));
+      while (iter.MoveNext()) {
+        for (var i = 0; i < iter.Current.Count; i++)
+          if (transposed[i].Add(iter.Current[i]) < 0)
+            throw new ArgumentException(string.Format("Variable {0} has invalid value ({1})", vnames[i], iter.Current[i]), nameof(data));
+      }
+      return new Dataset(vnames, transposed);
+    }
+
     public ModifiableDataset ToModifiable() {
-      var values = new List<IList>();
-      foreach (var v in variableNames) {
-        if (VariableHasType<double>(v)) {
-          values.Add(new List<double>((IList<double>)variableValues[v]));
-        } else if (VariableHasType<string>(v)) {
-          values.Add(new List<string>((IList<string>)variableValues[v]));
-        } else if (VariableHasType<DateTime>(v)) {
-          values.Add(new List<DateTime>((IList<DateTime>)variableValues[v]));
-        } else {
-          throw new ArgumentException("Unknown variable type.");
-        }
-      }
-      return new ModifiableDataset(variableNames, values);
+      return new ModifiableDataset(variableNames, variableNames.Select(v => variableValues[v]), true);
     }
 
@@ -141,10 +167,10 @@
     }
 
-    protected Dataset(Dataset dataset) : this(dataset.variableNames, dataset.variableValues.Values) { }
+
 
     #region Backwards compatible code, remove with 3.5
     private double[,] storableData;
-    //name alias used to suppport backwards compatibility
-    [Storable(Name = "data", AllowOneWay = true)]
+    //name alias used to support backwards compatibility
+    [Storable(OldName = "data")]
     private double[,] StorableData { set { storableData = value; } }
 
@@ -179,4 +205,8 @@
       }
     }
+
+    public bool ContainsVariable(string variableName) {
+      return variableValues.ContainsKey(variableName);
+    }
     public IEnumerable<string> DoubleVariables {
       get { return variableValues.Where(p => p.Value is IList<double>).Select(p => p.Key); }
@@ -318,7 +348,8 @@
     #region IStringConvertibleMatrix Members
     [Storable]
-    protected int rows;
+    private int rows;
     public int Rows {
       get { return rows; }
+      protected set { rows = value; }
     }
     int IStringConvertibleMatrix.Rows {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/DatasetExtensions.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/DatasetExtensions.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/DatasetExtensions.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/DatasetUtil.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/DatasetUtil.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/DatasetUtil.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -93,4 +93,20 @@
     }
 
+    public static Dictionary<string, Interval> GetVariableRanges(IDataset dataset, IEnumerable<int> rows = null) {
+      Dictionary<string, Interval> variableRanges = new Dictionary<string, Interval>();
+
+      foreach (var variable in dataset.VariableNames) {
+        IEnumerable<double> values = null;
+
+        if (rows == null) values = dataset.GetDoubleValues(variable);
+        else values = dataset.GetDoubleValues(variable, rows);
+
+        var range = Interval.GetInterval(values);
+        variableRanges.Add(variable, range);
+      }
+
+      return variableRanges;
+    }
+
     private static bool GetEqualValues(this Dictionary<ValuesType, ValuesType> variableValuesMapping, ValuesType originalValues, out ValuesType matchingValues) {
       if (variableValuesMapping.ContainsKey(originalValues)) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/DoubleLimit.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/DoubleLimit.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/DoubleLimit.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -24,8 +24,8 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("EB663E63-5F5B-4BD9-9A18-1A164D6E3045")]
   [Item("DoubleLimit", "Represents a lower and a upper bound for double values.")]
   public class DoubleLimit : StringConvertibleValueTuple<DoubleValue, DoubleValue> {
@@ -41,5 +41,5 @@
 
     [StorableConstructor]
-    protected DoubleLimit(bool deserializing) : base(deserializing) { }
+    protected DoubleLimit(StorableConstructorFlag _) : base(_) { }
     protected DoubleLimit(DoubleLimit original, Cloner cloner)
       : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 17980)
@@ -11,5 +11,5 @@
     <RootNamespace>HeuristicLab.Problems.DataAnalysis</RootNamespace>
     <AssemblyName>HeuristicLab.Problems.DataAnalysis-3.4</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
     <TargetFrameworkProfile>
     </TargetFrameworkProfile>
@@ -51,5 +51,5 @@
     <DebugType>pdbonly</DebugType>
     <Optimize>true</Optimize>
-    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <OutputPath>..\..\..\..\trunk\bin\</OutputPath>
     <DefineConstants>TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
@@ -99,39 +99,62 @@
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="ALGLIB-3.7.0">
-      <HintPath>..\..\..\..\trunk\bin\ALGLIB-3.7.0.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Collections-3.3">
+    <Reference Include="ALGLIB-3.7.0, Version=3.7.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <HintPath>..\..\bin\ALGLIB-3.7.0.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Collections-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Common-3.3">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Common-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Common.Resources-3.3">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Core-3.3">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Core-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Data-3.3">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Data-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Optimization-3.3">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Parameters-3.3">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Parameters-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Persistence-3.3">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\trunk\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Problems.Instances-3.3">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.Instances-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
-    </Reference>
-    <Reference Include="HeuristicLab.Random-3.3">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Random-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
       <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Random-3.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="System" />
@@ -163,4 +186,5 @@
     <Compile Include="Implementation\Classification\ClassificationEnsembleProblemData.cs" />
     <Compile Include="Implementation\Classification\ClassificationSolutionBase.cs" />
+    <Compile Include="Implementation\Classification\ClassificationSolutionVariableImpactsCalculator.cs" />
     <Compile Include="Implementation\Classification\ConstantClassificationSolution.cs" />
     <Compile Include="Implementation\Classification\DiscriminantFunctionClassificationSolutionBase.cs" />
@@ -171,8 +195,8 @@
     <Compile Include="Implementation\ConstantModel.cs" />
     <Compile Include="Implementation\DataAnalysisModel.cs" />
+    <Compile Include="Implementation\Interval.cs" />
     <Compile Include="Implementation\Regression\ConfidenceBoundRegressionSolution.cs" />
     <Compile Include="Implementation\Regression\ConstantRegressionModel.cs" />
     <Compile Include="Implementation\Regression\ConstantRegressionSolution.cs" />
-    <Compile Include="Implementation\Regression\RatedRegressionEnsembleModel.cs" />
     <Compile Include="Implementation\Regression\RegressionEnsembleProblemData.cs" />
     <Compile Include="Implementation\Regression\RegressionEnsembleModel.cs">
@@ -275,4 +299,5 @@
     <Compile Include="OnlineCalculators\OnlineTheilsUStatisticCalculator.cs" />
     <Compile Include="OnlineCalculators\OnlineWeightedDirectionalSymmetryCalculator.cs" />
+    <Compile Include="OnlineCalculators\OnlineWeightedClassificationMeanSquaredErrorCalculator.cs" />
     <Compile Include="Plugin.cs" />
     <Compile Include="Implementation\Classification\ThresholdCalculators\AccuracyMaximizationThresholdCalculator.cs" />
@@ -303,5 +328,11 @@
     </BootstrapperPackage>
   </ItemGroup>
-  <ItemGroup />
+  <ItemGroup>
+    <Reference Include="HEAL.Attic, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\bin\HEAL.Attic.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleModel.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleModel.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleModel.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -24,5 +24,5 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
@@ -30,5 +30,5 @@
   /// Represents classification solutions that contain an ensemble of multiple classification models
   /// </summary>
-  [StorableClass]
+  [StorableType("0F720A40-5CC2-4E2B-8D4E-CCAD8EB56E43")]
   [Item("ClassificationEnsembleModel", "A classification model that contains an ensemble of multiple classification models")]
   public class ClassificationEnsembleModel : ClassificationModel, IClassificationEnsembleModel {
@@ -44,5 +44,5 @@
 
     [StorableConstructor]
-    protected ClassificationEnsembleModel(bool deserializing) : base(deserializing) { }
+    protected ClassificationEnsembleModel(StorableConstructorFlag _) : base(_) { }
     protected ClassificationEnsembleModel(ClassificationEnsembleModel original, Cloner cloner)
       : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleProblemData.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleProblemData.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleProblemData.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -25,8 +25,8 @@
 using HeuristicLab.Data;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("58768587-0920-4B52-95E4-66B54E8E837C")]
   [Item("ClassificationEnsembleProblemData", "Represents an item containing all data defining a classification problem.")]
   public class ClassificationEnsembleProblemData : ClassificationProblemData {
@@ -65,5 +65,5 @@
 
     [StorableConstructor]
-    protected ClassificationEnsembleProblemData(bool deserializing) : base(deserializing) { }
+    protected ClassificationEnsembleProblemData(StorableConstructorFlag _) : base(_) { }
     protected ClassificationEnsembleProblemData(ClassificationEnsembleProblemData original, Cloner cloner) : base(original, cloner) { }
     public override IDeepCloneable Clone(Cloner cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -27,5 +27,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
@@ -33,5 +33,5 @@
   /// Represents classification solutions that contain an ensemble of multiple classification models
   /// </summary>
-  [StorableClass]
+  [StorableType("4CDD22EE-B53D-4899-A77E-C503FF9EBC8E")]
   [Item("Classification Ensemble Solution", "A classification solution that contains an ensemble of multiple classification models")]
   [Creatable(CreatableAttribute.Categories.DataAnalysisEnsembles, Priority = 110)]
@@ -61,6 +61,5 @@
 
     [StorableConstructor]
-    private ClassificationEnsembleSolution(bool deserializing)
-      : base(deserializing) {
+    private ClassificationEnsembleSolution(StorableConstructorFlag _) : base(_) {
       classificationSolutions = new ItemCollection<IClassificationSolution>();
     }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationModel.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationModel.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationModel.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -24,8 +24,8 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("7E6091F9-86FD-4C47-8935-9C35CAB4261B")]
   [Item("Classification Model", "Base class for all classification models.")]
   public abstract class ClassificationModel : DataAnalysisModel, IClassificationModel {
@@ -41,6 +41,7 @@
     }
 
-    protected ClassificationModel(bool deserializing)
-      : base(deserializing) {
+    [StorableConstructor]
+    protected ClassificationModel(StorableConstructorFlag _)
+      : base(_) {
       targetVariable = string.Empty;
     }
@@ -66,4 +67,32 @@
     public abstract IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData);
 
+    public virtual bool IsProblemDataCompatible(IClassificationProblemData problemData, out string errorMessage) {
+      return IsProblemDataCompatible(this, problemData, out errorMessage);
+    }
+
+    public override bool IsProblemDataCompatible(IDataAnalysisProblemData problemData, out string errorMessage) {
+      if (problemData == null) throw new ArgumentNullException("problemData", "The provided problemData is null.");
+      var classificationProblemData = problemData as IClassificationProblemData;
+      if (classificationProblemData == null)
+        throw new ArgumentException("The problem data is not compatible with this classification model. Instead a " + problemData.GetType().GetPrettyName() + " was provided.", "problemData");
+      return IsProblemDataCompatible(classificationProblemData, out errorMessage);
+    }
+
+    public static bool IsProblemDataCompatible(IClassificationModel model, IClassificationProblemData problemData, out string errorMessage) {
+      if (model == null) throw new ArgumentNullException("model", "The provided model is null.");
+      if (problemData == null) throw new ArgumentNullException("problemData", "The provided problemData is null.");
+      errorMessage = string.Empty;
+
+      if (model.TargetVariable != problemData.TargetVariable)
+        errorMessage = string.Format("The target variable of the model {0} does not match the target variable of the problemData {1}.", model.TargetVariable, problemData.TargetVariable);
+
+      var evaluationErrorMessage = string.Empty;
+      var datasetCompatible = model.IsDatasetCompatible(problemData.Dataset, out evaluationErrorMessage);
+      if (!datasetCompatible)
+        errorMessage += evaluationErrorMessage;
+
+      return string.IsNullOrEmpty(errorMessage);
+    }
+
     #region events
     public event EventHandler TargetVariableChanged;
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationPerformanceMeasures.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationPerformanceMeasures.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationPerformanceMeasures.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -24,8 +24,8 @@
 using HeuristicLab.Data;
 using HeuristicLab.Optimization;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("6F44E140-22CF-48D3-B100-B6013F2B6608")]
   public class ClassificationPerformanceMeasuresResultCollection : ResultCollection {
     #region result names
@@ -54,6 +54,5 @@
     }
     [StorableConstructor]
-    protected ClassificationPerformanceMeasuresResultCollection(bool deserializing)
-      : base(deserializing) {
+    protected ClassificationPerformanceMeasuresResultCollection(StorableConstructorFlag _) : base(_) {
     }
 
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblem.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblem.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblem.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -22,8 +22,8 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("93696570-A410-4885-A210-7220771B6050")]
   [Item("Classification Problem", "A general classification problem.")]
   public class ClassificationProblem : DataAnalysisProblem<IClassificationProblemData>, IClassificationProblem, IStorableContent {
@@ -31,5 +31,5 @@
 
     [StorableConstructor]
-    protected ClassificationProblem(bool deserializing) : base(deserializing) { }
+    protected ClassificationProblem(StorableConstructorFlag _) : base(_) { }
     protected ClassificationProblem(ClassificationProblem original, Cloner cloner) : base(original, cloner) { }
     public override IDeepCloneable Clone(Cloner cloner) { return new ClassificationProblem(this, cloner); }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -27,8 +27,8 @@
 using HeuristicLab.Data;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("1C8DCCCF-4E2A-421D-9C61-7C017D584054")]
   [Item("ClassificationProblemData", "Represents an item containing all data defining a classification problem.")]
   public class ClassificationProblemData : DataAnalysisProblemData, IClassificationProblemData, IStorableContent {
@@ -279,5 +279,5 @@
 
     [StorableConstructor]
-    protected ClassificationProblemData(bool deserializing) : base(deserializing) { }
+    protected ClassificationProblemData(StorableConstructorFlag _) : base(_) { }
     [StorableHook(HookType.AfterDeserialization)]
     private void AfterDeserialization() {
@@ -467,53 +467,4 @@
     }
     #endregion
-
-    protected override bool IsProblemDataCompatible(IDataAnalysisProblemData problemData, out string errorMessage) {
-      if (problemData == null) throw new ArgumentNullException("problemData", "The provided problemData is null.");
-      IClassificationProblemData classificationProblemData = problemData as IClassificationProblemData;
-      if (classificationProblemData == null)
-        throw new ArgumentException("The problem data is no classification problem data. Instead a " + problemData.GetType().GetPrettyName() + " was provided.", "problemData");
-
-      var returnValue = base.IsProblemDataCompatible(classificationProblemData, out errorMessage);
-      //check targetVariable
-      if (classificationProblemData.InputVariables.All(var => var.Value != TargetVariable)) {
-        errorMessage = string.Format("The target variable {0} is not present in the new problem data.", TargetVariable)
-                       + Environment.NewLine + errorMessage;
-        return false;
-      }
-
-      var newClassValues = classificationProblemData.Dataset.GetDoubleValues(TargetVariable).Distinct().OrderBy(x => x);
-      if (!newClassValues.SequenceEqual(ClassValues)) {
-        errorMessage = errorMessage + string.Format("The class values differ in the provided classification problem data.");
-        returnValue = false;
-      }
-
-      var newPositivieClassName = classificationProblemData.PositiveClass;
-      if (newPositivieClassName != PositiveClass) {
-        errorMessage = errorMessage + string.Format("The positive class differs in the provided classification problem data.");
-        returnValue = false;
-      }
-
-      return returnValue;
-    }
-
-    public override void AdjustProblemDataProperties(IDataAnalysisProblemData problemData) {
-      if (problemData == null) throw new ArgumentNullException("problemData", "The provided problemData is null.");
-      ClassificationProblemData classificationProblemData = problemData as ClassificationProblemData;
-      if (classificationProblemData == null)
-        throw new ArgumentException("The problem data is not a classification problem data. Instead a " + problemData.GetType().GetPrettyName() + " was provided.", "problemData");
-
-      base.AdjustProblemDataProperties(problemData);
-      TargetVariable = classificationProblemData.TargetVariable;
-      for (int i = 0; i < classificationProblemData.ClassNames.Count(); i++)
-        ClassNamesParameter.Value[i, 0] = classificationProblemData.ClassNames.ElementAt(i);
-
-      PositiveClass = classificationProblemData.PositiveClass;
-
-      for (int i = 0; i < Classes; i++) {
-        for (int j = 0; j < Classes; j++) {
-          ClassificationPenaltiesParameter.Value[i, j] = classificationProblemData.GetClassificationPenalty(ClassValuesCache[i], ClassValuesCache[j]);
-        }
-      }
-    }
   }
 }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -23,5 +23,5 @@
 using System.Linq;
 using HeuristicLab.Common;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
@@ -29,11 +29,10 @@
   /// Represents a classification data analysis solution
   /// </summary>
-  [StorableClass]
+  [StorableType("A240D831-23D6-4432-A105-12D02D2EA75A")]
   public class ClassificationSolution : ClassificationSolutionBase {
     protected readonly Dictionary<int, double> evaluationCache;
 
     [StorableConstructor]
-    protected ClassificationSolution(bool deserializing)
-      : base(deserializing) {
+    protected ClassificationSolution(StorableConstructorFlag _) : base(_) {
       evaluationCache = new Dictionary<int, double>();
     }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionBase.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionBase.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionBase.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -25,9 +26,9 @@
 using HeuristicLab.Data;
 using HeuristicLab.Optimization;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 using HeuristicLab.Problems.DataAnalysis.OnlineCalculators;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("60599497-EAF0-4DB0-B2E4-D58F34458D8F")]
   public abstract class ClassificationSolutionBase : DataAnalysisSolution, IClassificationSolution {
     private const string TrainingAccuracyResultName = "Accuracy (training)";
@@ -44,5 +45,11 @@
     public new IClassificationProblemData ProblemData {
       get { return (IClassificationProblemData)base.ProblemData; }
-      set { base.ProblemData = value; }
+      set {
+        if (value == null) throw new ArgumentNullException("The problemData must not be null.");
+        string errorMessage = string.Empty;
+        if (!Model.IsProblemDataCompatible(value, out errorMessage)) throw new ArgumentException(errorMessage);
+
+        base.ProblemData = value;
+      }
     }
 
@@ -71,5 +78,5 @@
 
     [StorableConstructor]
-    protected ClassificationSolutionBase(bool deserializing) : base(deserializing) { }
+    protected ClassificationSolutionBase(StorableConstructorFlag _) : base(_) { }
     protected ClassificationSolutionBase(ClassificationSolutionBase original, Cloner cloner)
       : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionVariableImpactsCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionVariableImpactsCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionVariableImpactsCalculator.cs	(revision 17980)
@@ -2,5 +2,5 @@
 
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -23,4 +23,5 @@
 
 using System;
+using System.Collections;
 using System.Collections.Generic;
 using System.Linq;
@@ -29,11 +30,13 @@
 using HeuristicLab.Data;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 using HeuristicLab.Random;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("768AFEDB-5641-429E-85A1-A0BE8DFDD56F")]
   [Item("ClassificationSolution Impacts Calculator", "Calculation of the impacts of input variables for any classification solution")]
   public sealed class ClassificationSolutionVariableImpactsCalculator : ParameterizedNamedItem {
+    #region Parameters/Properties
+    [StorableType("e6cd2226-10cd-4765-ae1a-924e316b6aac")]
     public enum ReplacementMethodEnum {
       Median,
@@ -42,4 +45,6 @@
       Noise
     }
+
+    [StorableType("84d84ccf-5d6d-432f-a946-eb499935e5c8")]
     public enum FactorReplacementMethodEnum {
       Best,
@@ -47,4 +52,6 @@
       Shuffle
     }
+
+    [StorableType("70f30113-df01-41b4-9e3b-2982035de498")]
     public enum DataPartitionEnum {
       Training,
@@ -54,8 +61,12 @@
 
     private const string ReplacementParameterName = "Replacement Method";
+    private const string FactorReplacementParameterName = "Factor Replacement Method";
     private const string DataPartitionParameterName = "DataPartition";
 
     public IFixedValueParameter<EnumValue<ReplacementMethodEnum>> ReplacementParameter {
       get { return (IFixedValueParameter<EnumValue<ReplacementMethodEnum>>)Parameters[ReplacementParameterName]; }
+    }
+    public IFixedValueParameter<EnumValue<FactorReplacementMethodEnum>> FactorReplacementParameter {
+      get { return (IFixedValueParameter<EnumValue<FactorReplacementMethodEnum>>)Parameters[FactorReplacementParameterName]; }
     }
     public IFixedValueParameter<EnumValue<DataPartitionEnum>> DataPartitionParameter {
@@ -67,135 +78,154 @@
       set { ReplacementParameter.Value.Value = value; }
     }
+    public FactorReplacementMethodEnum FactorReplacementMethod {
+      get { return FactorReplacementParameter.Value.Value; }
+      set { FactorReplacementParameter.Value.Value = value; }
+    }
     public DataPartitionEnum DataPartition {
       get { return DataPartitionParameter.Value.Value; }
       set { DataPartitionParameter.Value.Value = value; }
     }
-
-
+    #endregion
+
+    #region Ctor/Cloner
     [StorableConstructor]
-    private ClassificationSolutionVariableImpactsCalculator(bool deserializing) : base(deserializing) { }
+    private ClassificationSolutionVariableImpactsCalculator(StorableConstructorFlag _) : base(_) { }
     private ClassificationSolutionVariableImpactsCalculator(ClassificationSolutionVariableImpactsCalculator original, Cloner cloner)
       : base(original, cloner) { }
+    public ClassificationSolutionVariableImpactsCalculator()
+      : base() {
+      Parameters.Add(new FixedValueParameter<EnumValue<ReplacementMethodEnum>>(ReplacementParameterName, "The replacement method for variables during impact calculation.", new EnumValue<ReplacementMethodEnum>(ReplacementMethodEnum.Shuffle)));
+      Parameters.Add(new FixedValueParameter<EnumValue<FactorReplacementMethodEnum>>(FactorReplacementParameterName, "The replacement method for factor variables during impact calculation.", new EnumValue<FactorReplacementMethodEnum>(FactorReplacementMethodEnum.Best)));
+      Parameters.Add(new FixedValueParameter<EnumValue<DataPartitionEnum>>(DataPartitionParameterName, "The data partition on which the impacts are calculated.", new EnumValue<DataPartitionEnum>(DataPartitionEnum.Training)));
+    }
+
     public override IDeepCloneable Clone(Cloner cloner) {
       return new ClassificationSolutionVariableImpactsCalculator(this, cloner);
     }
-
-    public ClassificationSolutionVariableImpactsCalculator()
-      : base() {
-      Parameters.Add(new FixedValueParameter<EnumValue<ReplacementMethodEnum>>(ReplacementParameterName, "The replacement method for variables during impact calculation.", new EnumValue<ReplacementMethodEnum>(ReplacementMethodEnum.Median)));
-      Parameters.Add(new FixedValueParameter<EnumValue<DataPartitionEnum>>(DataPartitionParameterName, "The data partition on which the impacts are calculated.", new EnumValue<DataPartitionEnum>(DataPartitionEnum.Training)));
-    }
+    #endregion
 
     //mkommend: annoying name clash with static method, open to better naming suggestions
     public IEnumerable<Tuple<string, double>> Calculate(IClassificationSolution solution) {
-      return CalculateImpacts(solution, DataPartition, ReplacementMethod);
+      return CalculateImpacts(solution, ReplacementMethod, FactorReplacementMethod, DataPartition);
     }
 
     public static IEnumerable<Tuple<string, double>> CalculateImpacts(
       IClassificationSolution solution,
-      DataPartitionEnum data = DataPartitionEnum.Training,
-      ReplacementMethodEnum replacementMethod = ReplacementMethodEnum.Median,
+      ReplacementMethodEnum replacementMethod = ReplacementMethodEnum.Shuffle,
+      FactorReplacementMethodEnum factorReplacementMethod = FactorReplacementMethodEnum.Best,
+      DataPartitionEnum dataPartition = DataPartitionEnum.Training) {
+
+      IEnumerable<int> rows = GetPartitionRows(dataPartition, solution.ProblemData);
+      IEnumerable<double> estimatedClassValues = solution.GetEstimatedClassValues(rows);
+      var model = (IClassificationModel)solution.Model.Clone(); //mkommend: clone of model is necessary, because the thresholds for IDiscriminantClassificationModels are updated
+
+      return CalculateImpacts(model, solution.ProblemData, estimatedClassValues, rows, replacementMethod, factorReplacementMethod);
+    }
+
+    public static IEnumerable<Tuple<string, double>> CalculateImpacts(
+     IClassificationModel model,
+     IClassificationProblemData problemData,
+     IEnumerable<double> estimatedClassValues,
+     IEnumerable<int> rows,
+     ReplacementMethodEnum replacementMethod = ReplacementMethodEnum.Shuffle,
+     FactorReplacementMethodEnum factorReplacementMethod = FactorReplacementMethodEnum.Best) {
+
+      //fholzing: try and catch in case a different dataset is loaded, otherwise statement is neglectable
+      var missingVariables = model.VariablesUsedForPrediction.Except(problemData.Dataset.VariableNames);
+      if (missingVariables.Any()) {
+        throw new InvalidOperationException(string.Format("Can not calculate variable impacts, because the model uses inputs missing in the dataset ({0})", string.Join(", ", missingVariables)));
+      }
+      IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+      var originalQuality = CalculateQuality(targetValues, estimatedClassValues);
+
+      var impacts = new Dictionary<string, double>();
+      var inputvariables = new HashSet<string>(problemData.AllowedInputVariables.Union(model.VariablesUsedForPrediction));
+      var modifiableDataset = ((Dataset)(problemData.Dataset).Clone()).ToModifiable();
+
+      foreach (var inputVariable in inputvariables) {
+        impacts[inputVariable] = CalculateImpact(inputVariable, model, problemData, modifiableDataset, rows, replacementMethod, factorReplacementMethod, targetValues, originalQuality);
+      }
+
+      return impacts.Select(i => Tuple.Create(i.Key, i.Value));
+    }
+
+    public static double CalculateImpact(string variableName,
+      IClassificationModel model,
+      IClassificationProblemData problemData,
+      ModifiableDataset modifiableDataset,
+      IEnumerable<int> rows,
+      ReplacementMethodEnum replacementMethod = ReplacementMethodEnum.Shuffle,
+      FactorReplacementMethodEnum factorReplacementMethod = FactorReplacementMethodEnum.Best,
+      IEnumerable<double> targetValues = null,
+      double quality = double.NaN) {
+
+      if (!model.VariablesUsedForPrediction.Contains(variableName)) { return 0.0; }
+      if (!problemData.Dataset.VariableNames.Contains(variableName)) {
+        throw new InvalidOperationException(string.Format("Can not calculate variable impact, because the model uses inputs missing in the dataset ({0})", variableName));
+      }
+
+      if (targetValues == null) {
+        targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+      }
+      if (quality == double.NaN) {
+        quality = CalculateQuality(model.GetEstimatedClassValues(modifiableDataset, rows), targetValues);
+      }
+
+      IList originalValues = null;
+      IList replacementValues = GetReplacementValues(modifiableDataset, variableName, model, rows, targetValues, out originalValues, replacementMethod, factorReplacementMethod);
+
+      double newValue = CalculateQualityForReplacement(model, modifiableDataset, variableName, originalValues, rows, replacementValues, targetValues);
+      double impact = quality - newValue;
+
+      return impact;
+    }
+
+    private static IList GetReplacementValues(ModifiableDataset modifiableDataset,
+      string variableName,
+      IClassificationModel model,
+      IEnumerable<int> rows,
+      IEnumerable<double> targetValues,
+      out IList originalValues,
+      ReplacementMethodEnum replacementMethod = ReplacementMethodEnum.Shuffle,
       FactorReplacementMethodEnum factorReplacementMethod = FactorReplacementMethodEnum.Best) {
 
-      var problemData = solution.ProblemData;
-      var dataset = problemData.Dataset;
-
-      IEnumerable<int> rows;
-      IEnumerable<double> targetValues;
-      double originalAccuracy;
-
-      OnlineCalculatorError error;
-
-      switch (data) {
-        case DataPartitionEnum.All:
-          rows = problemData.AllIndices;
-          targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.AllIndices).ToList();
-          originalAccuracy = OnlineAccuracyCalculator.Calculate(targetValues, solution.EstimatedClassValues, out error);
-          if (error != OnlineCalculatorError.None) throw new InvalidOperationException("Error during accuracy calculation.");
-          break;
-        case DataPartitionEnum.Training:
-          rows = problemData.TrainingIndices;
-          targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices).ToList();
-          originalAccuracy = OnlineAccuracyCalculator.Calculate(targetValues, solution.EstimatedTrainingClassValues, out error);
-          if (error != OnlineCalculatorError.None) throw new InvalidOperationException("Error during accuracy calculation.");
-          break;
-        case DataPartitionEnum.Test:
-          rows = problemData.TestIndices;
-          targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TestIndices).ToList();
-          originalAccuracy = OnlineAccuracyCalculator.Calculate(targetValues, solution.EstimatedTestClassValues, out error);
-          if (error != OnlineCalculatorError.None) throw new InvalidOperationException("Error during accuracy calculation.");
-          break;
-        default: throw new ArgumentException(string.Format("DataPartition {0} cannot be handled.", data));
-      }
-
-      var impacts = new Dictionary<string, double>();
-      var modifiableDataset = ((Dataset)dataset).ToModifiable();
-
-      var inputvariables = new HashSet<string>(problemData.AllowedInputVariables.Union(solution.Model.VariablesUsedForPrediction));
-      var allowedInputVariables = dataset.VariableNames.Where(v => inputvariables.Contains(v)).ToList();
-
-      // calculate impacts for double variables
-      foreach (var inputVariable in allowedInputVariables.Where(problemData.Dataset.VariableHasType<double>)) {
-        var newEstimates = EvaluateModelWithReplacedVariable(solution.Model, inputVariable, modifiableDataset, rows, replacementMethod);
-        var newAccuracy = OnlineAccuracyCalculator.Calculate(targetValues, newEstimates, out error);
-        if (error != OnlineCalculatorError.None) throw new InvalidOperationException("Error during R² calculation with replaced inputs.");
-
-        impacts[inputVariable] = originalAccuracy - newAccuracy;
-      }
-
-      // calculate impacts for string variables
-      foreach (var inputVariable in allowedInputVariables.Where(problemData.Dataset.VariableHasType<string>)) {
-        if (factorReplacementMethod == FactorReplacementMethodEnum.Best) {
-          // try replacing with all possible values and find the best replacement value
-          var smallestImpact = double.PositiveInfinity;
-          foreach (var repl in problemData.Dataset.GetStringValues(inputVariable, rows).Distinct()) {
-            var newEstimates = EvaluateModelWithReplacedVariable(solution.Model, inputVariable, modifiableDataset, rows,
-              Enumerable.Repeat(repl, dataset.Rows));
-            var newAccuracy = OnlineAccuracyCalculator.Calculate(targetValues, newEstimates, out error);
-            if (error != OnlineCalculatorError.None)
-              throw new InvalidOperationException("Error during accuracy calculation with replaced inputs.");
-
-            var impact = originalAccuracy - newAccuracy;
-            if (impact < smallestImpact) smallestImpact = impact;
-          }
-          impacts[inputVariable] = smallestImpact;
-        } else {
-          // for replacement methods shuffle and mode
-          // calculate impacts for factor variables
-
-          var newEstimates = EvaluateModelWithReplacedVariable(solution.Model, inputVariable, modifiableDataset, rows,
-            factorReplacementMethod);
-          var newAccuracy = OnlineAccuracyCalculator.Calculate(targetValues, newEstimates, out error);
-          if (error != OnlineCalculatorError.None)
-            throw new InvalidOperationException("Error during accuracy calculation with replaced inputs.");
-
-          impacts[inputVariable] = originalAccuracy - newAccuracy;
-        }
-      } // foreach
-      return impacts.OrderByDescending(i => i.Value).Select(i => Tuple.Create(i.Key, i.Value));
-    }
-
-    private static IEnumerable<double> EvaluateModelWithReplacedVariable(IClassificationModel model, string variable, ModifiableDataset dataset, IEnumerable<int> rows, ReplacementMethodEnum replacement = ReplacementMethodEnum.Median) {
-      var originalValues = dataset.GetReadOnlyDoubleValues(variable).ToList();
+      IList replacementValues = null;
+      if (modifiableDataset.VariableHasType<double>(variableName)) {
+        originalValues = modifiableDataset.GetReadOnlyDoubleValues(variableName).ToList();
+        replacementValues = GetReplacementValuesForDouble(modifiableDataset, rows, (List<double>)originalValues, replacementMethod);
+      } else if (modifiableDataset.VariableHasType<string>(variableName)) {
+        originalValues = modifiableDataset.GetReadOnlyStringValues(variableName).ToList();
+        replacementValues = GetReplacementValuesForString(model, modifiableDataset, variableName, rows, (List<string>)originalValues, targetValues, factorReplacementMethod);
+      } else {
+        throw new NotSupportedException("Variable not supported");
+      }
+
+      return replacementValues;
+    }
+
+    private static IList GetReplacementValuesForDouble(ModifiableDataset modifiableDataset,
+      IEnumerable<int> rows,
+      List<double> originalValues,
+      ReplacementMethodEnum replacementMethod = ReplacementMethodEnum.Shuffle) {
+
+      IRandom random = new FastRandom(31415);
+      List<double> replacementValues;
       double replacementValue;
-      List<double> replacementValues;
-      IRandom rand;
-
-      switch (replacement) {
+
+      switch (replacementMethod) {
         case ReplacementMethodEnum.Median:
           replacementValue = rows.Select(r => originalValues[r]).Median();
-          replacementValues = Enumerable.Repeat(replacementValue, dataset.Rows).ToList();
+          replacementValues = Enumerable.Repeat(replacementValue, modifiableDataset.Rows).ToList();
           break;
         case ReplacementMethodEnum.Average:
           replacementValue = rows.Select(r => originalValues[r]).Average();
-          replacementValues = Enumerable.Repeat(replacementValue, dataset.Rows).ToList();
+          replacementValues = Enumerable.Repeat(replacementValue, modifiableDataset.Rows).ToList();
           break;
         case ReplacementMethodEnum.Shuffle:
           // new var has same empirical distribution but the relation to y is broken
-          rand = new FastRandom(31415);
           // prepare a complete column for the dataset
-          replacementValues = Enumerable.Repeat(double.NaN, dataset.Rows).ToList();
+          replacementValues = Enumerable.Repeat(double.NaN, modifiableDataset.Rows).ToList();
           // shuffle only the selected rows
-          var shuffledValues = rows.Select(r => originalValues[r]).Shuffle(rand).ToList();
+          var shuffledValues = rows.Select(r => originalValues[r]).Shuffle(random).ToList();
           int i = 0;
           // update column values 
@@ -207,29 +237,46 @@
           var avg = rows.Select(r => originalValues[r]).Average();
           var stdDev = rows.Select(r => originalValues[r]).StandardDeviation();
-          rand = new FastRandom(31415);
           // prepare a complete column for the dataset
-          replacementValues = Enumerable.Repeat(double.NaN, dataset.Rows).ToList();
+          replacementValues = Enumerable.Repeat(double.NaN, modifiableDataset.Rows).ToList();
           // update column values 
           foreach (var r in rows) {
-            replacementValues[r] = NormalDistributedRandom.NextDouble(rand, avg, stdDev);
+            replacementValues[r] = NormalDistributedRandom.NextDouble(random, avg, stdDev);
           }
           break;
 
         default:
-          throw new ArgumentException(string.Format("ReplacementMethod {0} cannot be handled.", replacement));
-      }
-
-      return EvaluateModelWithReplacedVariable(model, variable, dataset, rows, replacementValues);
-    }
-
-    private static IEnumerable<double> EvaluateModelWithReplacedVariable(
-      IClassificationModel model, string variable, ModifiableDataset dataset,
-      IEnumerable<int> rows,
-      FactorReplacementMethodEnum replacement = FactorReplacementMethodEnum.Shuffle) {
-      var originalValues = dataset.GetReadOnlyStringValues(variable).ToList();
-      List<string> replacementValues;
-      IRandom rand;
-
-      switch (replacement) {
+          throw new ArgumentException(string.Format("ReplacementMethod {0} cannot be handled.", replacementMethod));
+      }
+
+      return replacementValues;
+    }
+
+    private static IList GetReplacementValuesForString(IClassificationModel model,
+      ModifiableDataset modifiableDataset,
+      string variableName,
+      IEnumerable<int> rows,
+      List<string> originalValues,
+      IEnumerable<double> targetValues,
+      FactorReplacementMethodEnum factorReplacementMethod = FactorReplacementMethodEnum.Shuffle) {
+
+      List<string> replacementValues = null;
+      IRandom random = new FastRandom(31415);
+
+      switch (factorReplacementMethod) {
+        case FactorReplacementMethodEnum.Best:
+          // try replacing with all possible values and find the best replacement value
+          var bestQuality = double.NegativeInfinity;
+          foreach (var repl in modifiableDataset.GetStringValues(variableName, rows).Distinct()) {
+            List<string> curReplacementValues = Enumerable.Repeat(repl, modifiableDataset.Rows).ToList();
+            //fholzing: this result could be used later on (theoretically), but is neglected for better readability/method consistency 
+            var newValue = CalculateQualityForReplacement(model, modifiableDataset, variableName, originalValues, rows, curReplacementValues, targetValues);
+            var curQuality = newValue;
+
+            if (curQuality > bestQuality) {
+              bestQuality = curQuality;
+              replacementValues = curReplacementValues;
+            }
+          }
+          break;
         case FactorReplacementMethodEnum.Mode:
           var mostCommonValue = rows.Select(r => originalValues[r])
@@ -237,13 +284,12 @@
             .OrderByDescending(g => g.Count())
             .First().Key;
-          replacementValues = Enumerable.Repeat(mostCommonValue, dataset.Rows).ToList();
+          replacementValues = Enumerable.Repeat(mostCommonValue, modifiableDataset.Rows).ToList();
           break;
         case FactorReplacementMethodEnum.Shuffle:
           // new var has same empirical distribution but the relation to y is broken
-          rand = new FastRandom(31415);
           // prepare a complete column for the dataset
-          replacementValues = Enumerable.Repeat(string.Empty, dataset.Rows).ToList();
+          replacementValues = Enumerable.Repeat(string.Empty, modifiableDataset.Rows).ToList();
           // shuffle only the selected rows
-          var shuffledValues = rows.Select(r => originalValues[r]).Shuffle(rand).ToList();
+          var shuffledValues = rows.Select(r => originalValues[r]).Shuffle(random).ToList();
           int i = 0;
           // update column values 
@@ -253,29 +299,59 @@
           break;
         default:
-          throw new ArgumentException(string.Format("FactorReplacementMethod {0} cannot be handled.", replacement));
-      }
-
-      return EvaluateModelWithReplacedVariable(model, variable, dataset, rows, replacementValues);
-    }
-
-    private static IEnumerable<double> EvaluateModelWithReplacedVariable(IClassificationModel model, string variable,
-      ModifiableDataset dataset, IEnumerable<int> rows, IEnumerable<double> replacementValues) {
-      var originalValues = dataset.GetReadOnlyDoubleValues(variable).ToList();
-      dataset.ReplaceVariable(variable, replacementValues.ToList());
+          throw new ArgumentException(string.Format("FactorReplacementMethod {0} cannot be handled.", factorReplacementMethod));
+      }
+
+      return replacementValues;
+    }
+
+    private static double CalculateQualityForReplacement(
+      IClassificationModel model,
+      ModifiableDataset modifiableDataset,
+      string variableName,
+      IList originalValues,
+      IEnumerable<int> rows,
+      IList replacementValues,
+      IEnumerable<double> targetValues) {
+
+      modifiableDataset.ReplaceVariable(variableName, replacementValues);
+      var discModel = model as IDiscriminantFunctionClassificationModel;
+      if (discModel != null) {
+        var problemData = new ClassificationProblemData(modifiableDataset, modifiableDataset.VariableNames, model.TargetVariable);
+        discModel.RecalculateModelParameters(problemData, rows);
+      }
+
       //mkommend: ToList is used on purpose to avoid lazy evaluation that could result in wrong estimates due to variable replacements
-      var estimates = model.GetEstimatedClassValues(dataset, rows).ToList();
-      dataset.ReplaceVariable(variable, originalValues);
-
-      return estimates;
-    }
-    private static IEnumerable<double> EvaluateModelWithReplacedVariable(IClassificationModel model, string variable,
-      ModifiableDataset dataset, IEnumerable<int> rows, IEnumerable<string> replacementValues) {
-      var originalValues = dataset.GetReadOnlyStringValues(variable).ToList();
-      dataset.ReplaceVariable(variable, replacementValues.ToList());
-      //mkommend: ToList is used on purpose to avoid lazy evaluation that could result in wrong estimates due to variable replacements
-      var estimates = model.GetEstimatedClassValues(dataset, rows).ToList();
-      dataset.ReplaceVariable(variable, originalValues);
-
-      return estimates;
+      var estimates = model.GetEstimatedClassValues(modifiableDataset, rows).ToList();
+      var ret = CalculateQuality(targetValues, estimates);
+      modifiableDataset.ReplaceVariable(variableName, originalValues);
+
+      return ret;
+    }
+
+    public static double CalculateQuality(IEnumerable<double> targetValues, IEnumerable<double> estimatedClassValues) {
+      OnlineCalculatorError errorState;
+      var ret = OnlineAccuracyCalculator.Calculate(targetValues, estimatedClassValues, out errorState);
+      if (errorState != OnlineCalculatorError.None) { throw new InvalidOperationException("Error during calculation with replaced inputs."); }
+      return ret;
+    }
+
+    public static IEnumerable<int> GetPartitionRows(DataPartitionEnum dataPartition, IClassificationProblemData problemData) {
+      IEnumerable<int> rows;
+
+      switch (dataPartition) {
+        case DataPartitionEnum.All:
+          rows = problemData.AllIndices;
+          break;
+        case DataPartitionEnum.Test:
+          rows = problemData.TestIndices;
+          break;
+        case DataPartitionEnum.Training:
+          rows = problemData.TrainingIndices;
+          break;
+        default:
+          throw new NotSupportedException("DataPartition not supported");
+      }
+
+      return rows;
     }
   }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ConstantClassificationSolution.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ConstantClassificationSolution.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ConstantClassificationSolution.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -22,8 +22,8 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("D5A42FE7-D21B-48F7-A812-FE69724D0098")]
   [Item(Name = "Constant Classification Solution", Description = "Represents a constant classification solution (model + data).")]
   public class ConstantClassificationSolution : ClassificationSolution {
@@ -34,5 +34,5 @@
 
     [StorableConstructor]
-    protected ConstantClassificationSolution(bool deserializing) : base(deserializing) { }
+    protected ConstantClassificationSolution(StorableConstructorFlag _) : base(_) { }
     protected ConstantClassificationSolution(ConstantClassificationSolution original, Cloner cloner) : base(original, cloner) { }
     public ConstantClassificationSolution(ConstantModel model, IClassificationProblemData problemData)
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationModel.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationModel.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationModel.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -23,7 +23,7 @@
 using System.Collections.Generic;
 using System.Linq;
+using HEAL.Attic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
 namespace HeuristicLab.Problems.DataAnalysis {
@@ -31,5 +31,5 @@
   /// Represents discriminant function classification data analysis models.
   /// </summary>
-  [StorableClass]
+  [StorableType("E7A8648D-C938-499F-A712-185542095708")]
   [Item("DiscriminantFunctionClassificationModel", "Represents a classification model that uses a discriminant function and classification thresholds.")]
   public class DiscriminantFunctionClassificationModel : ClassificationModel, IDiscriminantFunctionClassificationModel {
@@ -68,5 +68,5 @@
 
     [StorableConstructor]
-    protected DiscriminantFunctionClassificationModel(bool deserializing) : base(deserializing) { }
+    protected DiscriminantFunctionClassificationModel(StorableConstructorFlag _) : base(_) { }
     protected DiscriminantFunctionClassificationModel(DiscriminantFunctionClassificationModel original, Cloner cloner)
       : base(original, cloner) {
@@ -121,6 +121,11 @@
 
     public override IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
+      var estimatedValues = GetEstimatedValues(dataset, rows);
+      return GetEstimatedClassValues(estimatedValues);
+    }
+
+    public virtual IEnumerable<double> GetEstimatedClassValues(IEnumerable<double> estimatedValues) {
       if (!Thresholds.Any() && !ClassValues.Any()) throw new ArgumentException("No thresholds and class values were set for the current classification model.");
-      foreach (var x in GetEstimatedValues(dataset, rows)) {
+      foreach (var x in estimatedValues) {
         int classIndex = 0;
         // find first threshold value which is larger than x => class index = threshold index + 1
@@ -132,4 +137,5 @@
       }
     }
+
     #region events
     public event EventHandler ThresholdsChanged;
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolution.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolution.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolution.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -24,5 +24,5 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
@@ -30,5 +30,5 @@
   /// Represents a classification solution that uses a discriminant function and classification thresholds.
   /// </summary>
-  [StorableClass]
+  [StorableType("A3480DF9-49E7-4329-AD23-57B4441033C1")]
   [Item("DiscriminantFunctionClassificationSolution", "Represents a classification solution that uses a discriminant function and classification thresholds.")]
   public class DiscriminantFunctionClassificationSolution : DiscriminantFunctionClassificationSolutionBase {
@@ -37,6 +37,5 @@
 
     [StorableConstructor]
-    protected DiscriminantFunctionClassificationSolution(bool deserializing)
-      : base(deserializing) {
+    protected DiscriminantFunctionClassificationSolution(StorableConstructorFlag _) : base(_) {
       valueEvaluationCache = new Dictionary<int, double>();
       classValueEvaluationCache = new Dictionary<int, double>();
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolutionBase.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolutionBase.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolutionBase.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -27,5 +27,5 @@
 using HeuristicLab.Data;
 using HeuristicLab.Optimization;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
@@ -33,5 +33,5 @@
   /// Represents a classification solution that uses a discriminant function and classification thresholds.
   /// </summary>
-  [StorableClass]
+  [StorableType("3668EBE0-128C-4BC4-902C-161670F98FAD")]
   [Item("DiscriminantFunctionClassificationSolution", "Represents a classification solution that uses a discriminant function and classification thresholds.")]
   public abstract class DiscriminantFunctionClassificationSolutionBase : ClassificationSolutionBase, IDiscriminantFunctionClassificationSolution {
@@ -74,5 +74,5 @@
 
     [StorableConstructor]
-    protected DiscriminantFunctionClassificationSolutionBase(bool deserializing) : base(deserializing) { }
+    protected DiscriminantFunctionClassificationSolutionBase(StorableConstructorFlag _) : base(_) { }
     protected DiscriminantFunctionClassificationSolutionBase(DiscriminantFunctionClassificationSolutionBase original, Cloner cloner)
       : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/AccuracyMaximizationThresholdCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/AccuracyMaximizationThresholdCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/AccuracyMaximizationThresholdCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -25,5 +25,5 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
@@ -31,10 +31,10 @@
   /// Represents a threshold calculator that maximizes the weighted accuracy of the classifcation model.
   /// </summary>
-  [StorableClass]
+  [StorableType("30BB9513-542D-4CB8-931B-9767C9CB2EFB")]
   [Item("AccuracyMaximizationThresholdCalculator", "Represents a threshold calculator that maximizes the weighted accuracy of the classifcation model.")]
   public class AccuracyMaximizationThresholdCalculator : ThresholdCalculator {
 
     [StorableConstructor]
-    protected AccuracyMaximizationThresholdCalculator(bool deserializing) : base(deserializing) { }
+    protected AccuracyMaximizationThresholdCalculator(StorableConstructorFlag _) : base(_) { }
     protected AccuracyMaximizationThresholdCalculator(AccuracyMaximizationThresholdCalculator original, Cloner cloner)
       : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/NormalDistributionCutPointsThresholdCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/NormalDistributionCutPointsThresholdCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/NormalDistributionCutPointsThresholdCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -25,5 +25,5 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
@@ -31,10 +31,10 @@
   /// Represents a threshold calculator that calculates thresholds as the cutting points between the estimated class distributions (assuming normally distributed class values).
   /// </summary>
-  [StorableClass]
+  [StorableType("D01CB5DC-606B-4CE9-B293-2D4D80A70BB8")]
   [Item("NormalDistributionCutPointsThresholdCalculator", "Represents a threshold calculator that calculates thresholds as the cutting points between the estimated class distributions (assuming normally distributed class values).")]
   public class NormalDistributionCutPointsThresholdCalculator : ThresholdCalculator {
 
     [StorableConstructor]
-    protected NormalDistributionCutPointsThresholdCalculator(bool deserializing) : base(deserializing) { }
+    protected NormalDistributionCutPointsThresholdCalculator(StorableConstructorFlag _) : base(_) { }
     protected NormalDistributionCutPointsThresholdCalculator(NormalDistributionCutPointsThresholdCalculator original, Cloner cloner)
       : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/ThresholdCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/ThresholdCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/ThresholdCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -23,5 +23,5 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
@@ -29,9 +29,9 @@
   /// Base class for threshold calculators for discriminant function classification models.
   /// </summary>
-  [StorableClass]
+  [StorableType("F56CDC6C-D4F5-4B2D-A7C4-04E0D2255699")]
   public abstract class ThresholdCalculator : NamedItem, IDiscriminantFunctionThresholdCalculator {
 
     [StorableConstructor]
-    protected ThresholdCalculator(bool deserializing) : base(deserializing) { }
+    protected ThresholdCalculator(StorableConstructorFlag _) : base(_) { }
     protected ThresholdCalculator(ThresholdCalculator original, Cloner cloner)
       : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblem.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblem.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblem.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -22,12 +22,12 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("CB64B930-3C95-4663-B583-712B42E33712")]
   [Item("Clustering Problem", "A general clustering problem.")]
   public class ClusteringProblem : DataAnalysisProblem<IClusteringProblemData>, IClusteringProblem {
     [StorableConstructor]
-    protected ClusteringProblem(bool deserializing) : base(deserializing) { }
+    protected ClusteringProblem(StorableConstructorFlag _) : base(_) { }
     protected ClusteringProblem(ClusteringProblem original, Cloner cloner) : base(original, cloner) { }
     public override IDeepCloneable Clone(Cloner cloner) { return new ClusteringProblem(this, cloner); }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblemData.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblemData.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblemData.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -24,8 +24,8 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("B74A767A-86ED-4B0E-BC01-82A4509CB81B")]
   [Item("ClusteringProblemData", "Represents an item containing all data defining a clustering problem.")]
   public sealed class ClusteringProblemData : DataAnalysisProblemData, IClusteringProblemData, IStorableContent {
@@ -72,5 +72,5 @@
 
     [StorableConstructor]
-    private ClusteringProblemData(bool deserializing) : base(deserializing) { }
+    private ClusteringProblemData(StorableConstructorFlag _) : base(_) { }
     [StorableHook(HookType.AfterDeserialization)]
     private void AfterDeserialization() {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -23,5 +23,5 @@
 using System.Linq;
 using HeuristicLab.Common;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
@@ -29,9 +29,9 @@
   /// Represents a clustering data analysis solution
   /// </summary>
-  [StorableClass]
+  [StorableType("51241A39-F5C6-4DC8-A27A-83875FFCB51B")]
   public class ClusteringSolution : DataAnalysisSolution, IClusteringSolution {
 
     [StorableConstructor]
-    protected ClusteringSolution(bool deserializing) : base(deserializing) { }
+    protected ClusteringSolution(StorableConstructorFlag _) : base(_) { }
     protected ClusteringSolution(ClusteringSolution original, Cloner cloner)
       : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/ConstantModel.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/ConstantModel.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/ConstantModel.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -26,8 +26,8 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("CAE567A8-86A4-4554-BF89-79FFFB4204D1")]
   [Item("Constant Model", "A model that always returns the same constant value regardless of the presented input data.")]
   public class ConstantModel : RegressionModel, IClassificationModel, ITimeSeriesPrognosisModel, IStringConvertibleValue {
@@ -43,5 +43,5 @@
 
     [StorableConstructor]
-    protected ConstantModel(bool deserializing) : base(deserializing) { }
+    protected ConstantModel(StorableConstructorFlag _) : base(_) { }
     protected ConstantModel(ConstantModel original, Cloner cloner)
       : base(original, cloner) {
@@ -83,4 +83,22 @@
     }
 
+    public virtual bool IsProblemDataCompatible(IClassificationProblemData problemData, out string errorMessage) {
+      return ClassificationModel.IsProblemDataCompatible(this, problemData, out errorMessage);
+    }
+
+    public override bool IsProblemDataCompatible(IDataAnalysisProblemData problemData, out string errorMessage) {
+      if (problemData == null) throw new ArgumentNullException("problemData", "The provided problemData is null.");
+
+      var regressionProblemData = problemData as IRegressionProblemData;
+      if (regressionProblemData != null)
+        return IsProblemDataCompatible(regressionProblemData, out errorMessage);
+
+      var classificationProblemData = problemData as IClassificationProblemData;
+      if (classificationProblemData != null)
+        return IsProblemDataCompatible(classificationProblemData, out errorMessage);
+
+      throw new ArgumentException("The problem data is compatible with this model. Instead a " + problemData.GetType().GetPrettyName() + " was provided.", "problemData");
+    }
+
     #region IStringConvertibleValue
     public bool ReadOnly { get; private set; }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisModel.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisModel.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisModel.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -20,15 +20,16 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("EF0EF64F-392A-448A-B30F-1AE113C6CC88")]
   [Item("DataAnalysisModel", "Base class for data analysis models.")]
   public abstract class DataAnalysisModel : NamedItem, IDataAnalysisModel {
     [StorableConstructor]
-    protected DataAnalysisModel(bool deserializing) : base(deserializing) { }
+    protected DataAnalysisModel(StorableConstructorFlag _) : base(_) { }
     protected DataAnalysisModel(DataAnalysisModel original, Cloner cloner)
       : base(original, cloner) { }
@@ -38,4 +39,28 @@
 
     public abstract IEnumerable<string> VariablesUsedForPrediction { get; }
+
+    public virtual bool IsDatasetCompatible(IDataset dataset, out string errorMessage) {
+      if (dataset == null) throw new ArgumentNullException("dataset", "The provided dataset is null.");
+      return IsDatasetCompatible(this, dataset, out errorMessage);
+    }
+
+    public abstract bool IsProblemDataCompatible(IDataAnalysisProblemData problemData, out string errorMessage);
+
+    public static bool IsDatasetCompatible(IDataAnalysisModel model, IDataset dataset, out string errorMessage) {
+      if(model == null) throw new ArgumentNullException("model", "The provided model is null.");
+      if (dataset == null) throw new ArgumentNullException("dataset", "The provided dataset is null.");
+      errorMessage = string.Empty;
+
+      foreach (var variable in model.VariablesUsedForPrediction) {
+        if (!dataset.ContainsVariable(variable)) {
+          if (string.IsNullOrEmpty(errorMessage)) {
+            errorMessage = "The following variables must be present in the dataset for model evaluation:";
+          }
+          errorMessage += System.Environment.NewLine + " " + variable;
+        }
+      }
+
+      return string.IsNullOrEmpty(errorMessage);
+    }
   }
 }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblem.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblem.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblem.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -25,9 +25,9 @@
 using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 using HeuristicLab.Problems.Instances;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("67267E9F-8A34-4CB6-9776-DD1483131987")]
   public abstract class DataAnalysisProblem<T> : Problem, IDataAnalysisProblem<T>,
     IProblemInstanceConsumer<T>, IProblemInstanceExporter<T>
@@ -57,5 +57,5 @@
     }
     [StorableConstructor]
-    protected DataAnalysisProblem(bool deserializing) : base(deserializing) { }
+    protected DataAnalysisProblem(StorableConstructorFlag _) : base(_) { }
 
     protected DataAnalysisProblem(T problemData)
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -23,5 +23,4 @@
 using System.Collections.Generic;
 using System.Linq;
-using System.Text;
 using HeuristicLab.Collections;
 using HeuristicLab.Common;
@@ -29,8 +28,8 @@
 using HeuristicLab.Data;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("85AE1542-D563-434F-A760-1D181EFC2101")]
   public abstract class DataAnalysisProblemData : ParameterizedNamedItem, IDataAnalysisProblemData {
     protected const string DatasetParameterName = "Dataset";
@@ -144,5 +143,5 @@
     }
     [StorableConstructor]
-    protected DataAnalysisProblemData(bool deserializing) : base(deserializing) { }
+    protected DataAnalysisProblemData(StorableConstructorFlag _) : base(_) { }
 
     [StorableHook(HookType.AfterDeserialization)]
@@ -163,5 +162,5 @@
 
       var variables = dataset.VariableNames.Where(variable => dataset.VariableHasType<double>(variable) || dataset.VariableHasType<string>(variable));
-      var inputVariables = new CheckedItemList<StringValue>(variables.Select(x => new StringValue(x)));
+      var inputVariables = new CheckedItemList<StringValue>(variables.Select(x => new StringValue(x).AsReadOnly()));
       foreach (StringValue x in inputVariables)
         inputVariables.SetItemCheckedState(x, allowedInputVariables.Contains(x.Value));
@@ -207,39 +206,4 @@
       if (listeners != null) listeners(this, EventArgs.Empty);
     }
-
-    protected virtual bool IsProblemDataCompatible(IDataAnalysisProblemData problemData, out string errorMessage) {
-      errorMessage = string.Empty;
-      if (problemData == null) throw new ArgumentNullException("problemData", "The provided problemData is null.");
-
-      //check allowed input variables
-      StringBuilder message = new StringBuilder();
-      var variables = new HashSet<string>(problemData.InputVariables.Select(x => x.Value));
-      foreach (var item in AllowedInputVariables) {
-        if (!variables.Contains(item))
-          message.AppendLine("Input variable '" + item + "' is not present in the new problem data.");
-      }
-
-      if (message.Length != 0) {
-        errorMessage = message.ToString();
-        return false;
-      }
-      return true;
-
-    }
-
-    public virtual void AdjustProblemDataProperties(IDataAnalysisProblemData problemData) {
-      DataAnalysisProblemData data = problemData as DataAnalysisProblemData;
-      if (data == null) throw new ArgumentException("The problem data is not a data analysis problem data. Instead a " + problemData.GetType().GetPrettyName() + " was provided.", "problemData");
-
-      string errorMessage;
-      if (!data.IsProblemDataCompatible(this, out errorMessage)) {
-        throw new InvalidOperationException(errorMessage);
-      }
-
-      foreach (var inputVariable in InputVariables) {
-        var variable = data.InputVariables.FirstOrDefault(i => i.Value == inputVariable.Value);
-        InputVariables.SetItemCheckedState(inputVariable, variable != null && data.InputVariables.ItemChecked(variable));
-      }
-    }
   }
 }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisSolution.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisSolution.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisSolution.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -25,5 +25,5 @@
 using HeuristicLab.Common;
 using HeuristicLab.Optimization;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
@@ -31,5 +31,5 @@
   /// Abstract base class for data analysis solutions
   /// </summary>
-  [StorableClass]
+  [StorableType("339E0EAD-07D7-44C5-8E1D-AE9B2AA9A67D")]
   public abstract class DataAnalysisSolution : ResultCollection, IDataAnalysisSolution {
     private const string ModelResultName = "Model";
@@ -58,12 +58,13 @@
       get { return (IDataAnalysisProblemData)this[ProblemDataResultName].Value; }
       set {
-        if (this[ProblemDataResultName].Value != value) {
-          if (value != null) {
-            ProblemData.Changed -= new EventHandler(ProblemData_Changed);
-            this[ProblemDataResultName].Value = value;
-            ProblemData.Changed += new EventHandler(ProblemData_Changed);
-            OnProblemDataChanged();
-          }
-        }
+        if (value == null) throw new ArgumentNullException("The problemData must not be null.");
+        if (this[ProblemDataResultName].Value == value) return;
+        string errorMessage = string.Empty;
+        if (!Model.IsProblemDataCompatible(value, out errorMessage)) throw new ArgumentException(errorMessage);
+
+        ProblemData.Changed -= new EventHandler(ProblemData_Changed);
+        this[ProblemDataResultName].Value = value;
+        ProblemData.Changed += new EventHandler(ProblemData_Changed);
+        OnProblemDataChanged();
       }
     }
@@ -71,5 +72,5 @@
 
     [StorableConstructor]
-    protected DataAnalysisSolution(bool deserializing) : base(deserializing) { }
+    protected DataAnalysisSolution(StorableConstructorFlag _) : base(_) { }
     protected DataAnalysisSolution(DataAnalysisSolution original, Cloner cloner)
       : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval.cs	(revision 17980)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Interval.cs	(revision 17980)
@@ -0,0 +1,293 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 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 HEAL.Attic;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("849e42d3-8934-419d-9aff-64ad81c06b67")]
+  public class Interval : IEquatable<Interval> {
+    [Storable]
+    public double LowerBound { get; private set; }
+    [Storable]
+    public double UpperBound { get; private set; }
+
+    [StorableConstructor]
+    protected Interval(StorableConstructorFlag _) { }
+
+    /// <summary>
+    /// Creates an interval with given bounds, where lower bound must be smaller than
+    /// the upper bound. Floating point precision errors trough calculations are fixed by,
+    /// checking if the intervals are almost the same (E-12). If this is the case, the bounds 
+    /// will be set to the bound closer to zero.
+    /// </summary>
+    /// <param name="lowerBound">Lower bound of the interval</param>
+    /// <param name="upperBound">Upper bound of the interval</param>
+    public Interval(double lowerBound, double upperBound) {
+      if (lowerBound.IsAlmost(upperBound)) {
+        //If the bounds go over zero
+        if (lowerBound <= 0 && upperBound >= 0) {
+          lowerBound = 0.0;
+          upperBound = 0.0;
+          //Interval is negative
+        } else if (upperBound < 0) {
+          lowerBound = upperBound;
+          //Interval is positive
+        } else {
+          upperBound = lowerBound;
+        }
+      }
+
+      if (lowerBound > upperBound)
+        throw new ArgumentException("LowerBound must be smaller than UpperBound.");
+
+      this.LowerBound = lowerBound;
+      this.UpperBound = upperBound;
+    }
+
+    public bool Contains(double value) {
+      return LowerBound <= value && value <= UpperBound;
+    }
+
+    public override string ToString() {
+      return "Interval: [" + LowerBound + ", " + UpperBound + "]";
+    }
+
+    public bool IsInfiniteOrUndefined {
+      get {
+        return double.IsInfinity(LowerBound) || double.IsInfinity(UpperBound) ||
+                double.IsNaN(LowerBound) || double.IsNaN(UpperBound);
+      }
+    }
+
+    /// <summary>
+    /// True if the interval is positive without zero
+    /// </summary>
+    public bool IsPositive {
+      get => LowerBound > 0.0; 
+    }
+
+    /// <summary>
+    /// True if the interval is negative without zero
+    /// </summary>
+    public bool IsNegative {
+      get => UpperBound < 0.0;
+    }
+
+    public static Interval GetInterval(IEnumerable<double> values) {
+      if (values == null) throw new ArgumentNullException("values");
+      if (!values.Any()) throw new ArgumentException($"No values are present.");
+
+      var min = double.MaxValue;
+      var max = double.MinValue;
+
+      foreach (var value in values) {
+        //If an value is NaN return an interval [NaN, NaN]
+        if (double.IsNaN(value)) return new Interval(double.NaN, double.NaN);
+
+        if (value < min) min = value;
+        if (value > max) max = value;
+      }
+
+      return new Interval(min, max);
+    }
+
+    #region Equals, GetHashCode, == , !=
+    public bool Equals(Interval other) {
+      if (other == null)
+        return false;
+
+      return (UpperBound.IsAlmost(other.UpperBound) || (double.IsNaN(UpperBound) && double.IsNaN(other.UpperBound)))
+        && (LowerBound.IsAlmost(other.LowerBound) || (double.IsNaN(LowerBound) && double.IsNaN(other.LowerBound)));
+    }
+
+    public override bool Equals(object obj) {
+      return Equals(obj as Interval);
+    }
+
+    public override int GetHashCode() {
+      return LowerBound.GetHashCode() ^ UpperBound.GetHashCode();
+    }
+
+    public static bool operator ==(Interval interval1, Interval interval2) {
+      if (ReferenceEquals(interval1, null)) return ReferenceEquals(interval2, null);
+      return interval1.Equals(interval2);
+    }
+    public static bool operator !=(Interval interval1, Interval interval2) {
+      return !(interval1 == interval2);
+    }
+    #endregion
+
+    #region operations
+
+    // [x1,x2] + [y1,y2] = [x1 + y1,x2 + y2]
+    public static Interval Add(Interval a, Interval b) {
+      return new Interval(a.LowerBound + b.LowerBound, a.UpperBound + b.UpperBound);
+    }
+
+    // [x1,x2] − [y1,y2] = [x1 − y2,x2 − y1]
+    public static Interval Subtract(Interval a, Interval b) {
+      return new Interval(a.LowerBound - b.UpperBound, a.UpperBound - b.LowerBound);
+    }
+
+    // [x1,x2] * [y1,y2] = [min(x1*y1,x1*y2,x2*y1,x2*y2),max(x1*y1,x1*y2,x2*y1,x2*y2)]
+    public static Interval Multiply(Interval a, Interval b) {
+      double v1 = a.LowerBound * b.LowerBound;
+      double v2 = a.LowerBound * b.UpperBound;
+      double v3 = a.UpperBound * b.LowerBound;
+      double v4 = a.UpperBound * b.UpperBound;
+
+      double min = Math.Min(Math.Min(v1, v2), Math.Min(v3, v4));
+      double max = Math.Max(Math.Max(v1, v2), Math.Max(v3, v4));
+      return new Interval(min, max);
+    }
+
+    //Division by intervals containing 0 is implemented as defined in
+    //http://en.wikipedia.org/wiki/Interval_arithmetic
+    public static Interval Divide(Interval a, Interval b) {
+      if (b.Contains(0.0)) {
+        if (b.LowerBound.IsAlmost(0.0)) return Interval.Multiply(a, new Interval(1.0 / b.UpperBound, double.PositiveInfinity));
+        else if (b.UpperBound.IsAlmost(0.0)) return Interval.Multiply(a, new Interval(double.NegativeInfinity, 1.0 / b.LowerBound));
+        else return new Interval(double.NegativeInfinity, double.PositiveInfinity);
+      }
+      return Interval.Multiply(a, new Interval(1.0 / b.UpperBound, 1.0 / b.LowerBound));
+    }
+
+    public static Interval Sine(Interval a) {
+      if (Math.Abs(a.UpperBound - a.LowerBound) >= Math.PI * 2) return new Interval(-1, 1);
+
+      //divide the interval by PI/2 so that the optima lie at x element of N (0,1,2,3,4,...)
+      double Pihalf = Math.PI / 2;
+      Interval scaled = Interval.Divide(a, new Interval(Pihalf, Pihalf));
+      //move to positive scale
+      if (scaled.LowerBound < 0) {
+        int periodsToMove = Math.Abs((int)scaled.LowerBound / 4) + 1;
+        scaled = Interval.Add(scaled, new Interval(periodsToMove * 4, periodsToMove * 4));
+      }
+
+      double scaledLowerBound = scaled.LowerBound % 4.0;
+      double scaledUpperBound = scaled.UpperBound % 4.0;
+      if (scaledUpperBound < scaledLowerBound) scaledUpperBound += 4.0;
+      List<double> sinValues = new List<double>();
+      sinValues.Add(Math.Sin(scaledLowerBound * Pihalf));
+      sinValues.Add(Math.Sin(scaledUpperBound * Pihalf));
+
+      int startValue = (int)Math.Ceiling(scaledLowerBound);
+      while (startValue < scaledUpperBound) {
+        sinValues.Add(Math.Sin(startValue * Pihalf));
+        startValue += 1;
+      }
+
+      return new Interval(sinValues.Min(), sinValues.Max());
+    }
+    public static Interval Cosine(Interval a) {
+      return Interval.Sine(Interval.Add(a, new Interval(Math.PI / 2, Math.PI / 2)));
+    }
+    public static Interval Tangens(Interval a) {
+      return Interval.Divide(Interval.Sine(a), Interval.Cosine(a));
+    }
+    public static Interval HyperbolicTangent(Interval a) {
+      return new Interval(Math.Tanh(a.LowerBound), Math.Tanh(a.UpperBound));
+    }
+
+    public static Interval Logarithm(Interval a) {
+      return new Interval(Math.Log(a.LowerBound), Math.Log(a.UpperBound));
+    }
+    public static Interval Exponential(Interval a) {
+      return new Interval(Math.Exp(a.LowerBound), Math.Exp(a.UpperBound));
+    }
+
+    public static Interval Power(Interval a, Interval b) {
+      if (a.Contains(0.0) && b.LowerBound < 0) return new Interval(double.NaN, double.NaN);
+
+      int bLower = (int)Math.Round(b.LowerBound);
+      int bUpper = (int)Math.Round(b.UpperBound);
+
+      List<double> powerValues = new List<double>();
+      powerValues.Add(Math.Pow(a.UpperBound, bUpper));
+      powerValues.Add(Math.Pow(a.UpperBound, bUpper - 1));
+      powerValues.Add(Math.Pow(a.UpperBound, bLower));
+      powerValues.Add(Math.Pow(a.UpperBound, bLower + 1));
+
+      powerValues.Add(Math.Pow(a.LowerBound, bUpper));
+      powerValues.Add(Math.Pow(a.LowerBound, bUpper - 1));
+      powerValues.Add(Math.Pow(a.LowerBound, bLower));
+      powerValues.Add(Math.Pow(a.LowerBound, bLower + 1));
+
+      return new Interval(powerValues.Min(), powerValues.Max());
+    }
+
+    public static Interval Square(Interval a) {
+      if (a.UpperBound <= 0) return new Interval(a.UpperBound * a.UpperBound, a.LowerBound * a.LowerBound);     // interval is negative
+      else if (a.LowerBound >= 0) return new Interval(a.LowerBound * a.LowerBound, a.UpperBound * a.UpperBound); // interval is positive
+      else return new Interval(0, Math.Max(a.LowerBound * a.LowerBound, a.UpperBound * a.UpperBound)); // interval goes over zero
+    }
+
+    public static Interval Cube(Interval a) {
+      return new Interval(Math.Pow(a.LowerBound, 3), Math.Pow(a.UpperBound, 3));
+    }
+
+    public static Interval Root(Interval a, Interval b) {
+      int lower = (int)Math.Round(b.LowerBound);
+      int higher = (int)Math.Round(b.UpperBound);
+
+      return new Interval(Math.Pow(a.LowerBound, 1.0 / higher), Math.Pow(a.UpperBound, 1.0 / lower));
+    }
+
+    public static Interval SquareRoot(Interval a) {
+      if (a.LowerBound < 0) return new Interval(double.NaN, double.NaN);
+      return new Interval(Math.Sqrt(a.LowerBound), Math.Sqrt(a.UpperBound));
+    }
+
+    public static Interval CubicRoot(Interval a) {
+      var lower = (a.LowerBound < 0) ? -Math.Pow(-a.LowerBound, 1d / 3d) : Math.Pow(a.LowerBound, 1d / 3d);
+      var upper = (a.UpperBound < 0) ? -Math.Pow(-a.UpperBound, 1d / 3d) : Math.Pow(a.UpperBound, 1d / 3d);
+
+      return new Interval(lower, upper);
+    }
+
+    public static Interval Absolute(Interval a) {
+      var absLower = Math.Abs(a.LowerBound);
+      var absUpper = Math.Abs(a.UpperBound);
+      var min = Math.Min(absLower, absUpper);
+      var max = Math.Max(absLower, absUpper);
+
+      if (a.Contains(0.0)) {
+        min = 0.0;
+      }
+
+      return new Interval(min, max);
+    }
+
+    public static Interval AnalyticalQuotient(Interval a, Interval b) {
+      var dividend = a;
+      var divisor = Add(Square(b), new Interval(1.0, 1.0));
+      divisor = SquareRoot(divisor);
+
+      var quotient = Divide(dividend, divisor);
+      return quotient;
+    }
+    #endregion
+  }
+}
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConfidenceBoundRegressionSolution.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConfidenceBoundRegressionSolution.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConfidenceBoundRegressionSolution.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -23,5 +23,5 @@
 using System.Linq;
 using HeuristicLab.Common;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
@@ -29,5 +29,5 @@
   /// Represents a regression data analysis solution that supports confidence estimates
   /// </summary>
-  [StorableClass]
+  [StorableType("C2D0DE07-E8F0-4850-AAF3-E2885EC1DDB6")]
   public class ConfidenceRegressionSolution : RegressionSolution, IConfidenceRegressionSolution {
     protected readonly Dictionary<int, double> varianceEvaluationCache;
@@ -39,6 +39,5 @@
 
     [StorableConstructor]
-    protected ConfidenceRegressionSolution(bool deserializing)
-      : base(deserializing) {
+    protected ConfidenceRegressionSolution(StorableConstructorFlag _) : base(_) {
       varianceEvaluationCache = new Dictionary<int, double>();
     }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionModel.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionModel.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionModel.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -26,8 +26,8 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("E4C0D707-F668-428F-951C-F82A475177BE")]
   [Item("Constant Regression Model", "A model that always returns the same constant value regardless of the presented input data.")]
   [Obsolete]
@@ -43,5 +43,5 @@
 
     [StorableConstructor]
-    protected ConstantRegressionModel(bool deserializing) : base(deserializing) { }
+    protected ConstantRegressionModel(StorableConstructorFlag _) : base(_) { }
     protected ConstantRegressionModel(ConstantRegressionModel original, Cloner cloner)
       : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionSolution.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionSolution.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionSolution.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -22,8 +22,8 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("4DDDFDFA-3AF5-468F-971F-26B8AB014338")]
   [Item(Name = "Constant Regression Solution", Description = "Represents a constant regression solution (model + data).")]
   public class ConstantRegressionSolution : RegressionSolution {
@@ -34,5 +34,5 @@
 
     [StorableConstructor]
-    protected ConstantRegressionSolution(bool deserializing) : base(deserializing) { }
+    protected ConstantRegressionSolution(StorableConstructorFlag _) : base(_) { }
     protected ConstantRegressionSolution(ConstantRegressionSolution original, Cloner cloner) : base(original, cloner) { }
     public ConstantRegressionSolution(ConstantModel model, IRegressionProblemData problemData)
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleModel.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleModel.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleModel.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -25,5 +25,5 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
@@ -31,6 +31,6 @@
   /// Represents regression solutions that contain an ensemble of multiple regression models
   /// </summary>
-  [StorableClass]
-  [Item("Regression Ensemble Model", "A regression model that contains an ensemble of multiple regression models")]
+  [StorableType("202C33A2-2B7A-42E2-B3F3-BE1C9A9B5B84")]
+  [Item("RegressionEnsembleModel", "A regression model that contains an ensemble of multiple regression models")]
   public sealed class RegressionEnsembleModel : RegressionModel, IRegressionEnsembleModel {
     public override IEnumerable<string> VariablesUsedForPrediction {
@@ -73,5 +73,5 @@
 
     #region backwards compatiblity 3.3.5
-    [Storable(Name = "models", AllowOneWay = true)]
+    [Storable(OldName = "models")]
     private List<IRegressionModel> OldStorableModels {
       set { models = value; }
@@ -89,5 +89,5 @@
 
     [StorableConstructor]
-    private RegressionEnsembleModel(bool deserializing) : base(deserializing) { }
+    private RegressionEnsembleModel(StorableConstructorFlag _) : base(_) { }
     private RegressionEnsembleModel(RegressionEnsembleModel original, Cloner cloner)
       : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleProblemData.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleProblemData.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleProblemData.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -25,8 +25,8 @@
 using HeuristicLab.Data;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("CB105C71-FA47-4FFC-BF56-57B6BB2E0BC7")]
   [Item("RegressionEnsembleProblemData", "Represents an item containing all data defining a regression problem.")]
   public sealed class RegressionEnsembleProblemData : RegressionProblemData {
@@ -62,5 +62,5 @@
 
     [StorableConstructor]
-    private RegressionEnsembleProblemData(bool deserializing) : base(deserializing) { }
+    private RegressionEnsembleProblemData(StorableConstructorFlag _) : base(_) { }
     private RegressionEnsembleProblemData(RegressionEnsembleProblemData original, Cloner cloner) : base(original, cloner) { }
     public override IDeepCloneable Clone(Cloner cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -27,5 +27,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
@@ -33,5 +33,5 @@
   /// Represents regression solutions that contain an ensemble of multiple regression models
   /// </summary>
-  [StorableClass]
+  [StorableType("C5B38C31-4307-48E4-9BCD-6797C329E018")]
   [Item("Regression Ensemble Solution", "A regression solution that contains an ensemble of multiple regression models")]
   [Creatable(CreatableAttribute.Categories.DataAnalysisEnsembles, Priority = 100)]
@@ -62,6 +62,5 @@
 
     [StorableConstructor]
-    private RegressionEnsembleSolution(bool deserializing)
-      : base(deserializing) {
+    private RegressionEnsembleSolution(StorableConstructorFlag _) : base(_) {
       regressionSolutions = new ItemCollection<IRegressionSolution>();
     }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionModel.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionModel.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionModel.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -24,8 +24,8 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("2998B895-4724-489C-A4CA-9ADD10C7CA49")]
   [Item("Regression Model", "Base class for all regression models.")]
   public abstract class RegressionModel : DataAnalysisModel, IRegressionModel {
@@ -41,6 +41,7 @@
     }
 
-    protected RegressionModel(bool deserializing)
-      : base(deserializing) {
+    [StorableConstructor]
+    protected RegressionModel(StorableConstructorFlag _)
+      : base(_) {
       targetVariable = string.Empty;
     }
@@ -67,4 +68,32 @@
     public abstract IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData);
 
+    public virtual bool IsProblemDataCompatible(IRegressionProblemData problemData, out string errorMessage) {
+      return IsProblemDataCompatible(this, problemData, out errorMessage);
+    }
+
+    public override bool IsProblemDataCompatible(IDataAnalysisProblemData problemData, out string errorMessage) {
+      if (problemData == null) throw new ArgumentNullException("problemData", "The provided problemData is null.");
+      var regressionProblemData = problemData as IRegressionProblemData;
+      if (regressionProblemData == null)
+        throw new ArgumentException("The problem data is not compatible with this regression model. Instead a " + problemData.GetType().GetPrettyName() + " was provided.", "problemData");
+      return IsProblemDataCompatible(regressionProblemData, out errorMessage);
+    }
+
+    public static bool IsProblemDataCompatible(IRegressionModel model, IRegressionProblemData problemData, out string errorMessage) {
+      if (model == null) throw new ArgumentNullException("model", "The provided model is null.");
+      if (problemData == null) throw new ArgumentNullException("problemData", "The provided problemData is null.");
+      errorMessage = string.Empty;
+
+      if (model.TargetVariable != problemData.TargetVariable)
+        errorMessage = string.Format("The target variable of the model {0} does not match the target variable of the problemData {1}.", model.TargetVariable, problemData.TargetVariable);
+
+      var evaluationErrorMessage = string.Empty;
+      var datasetCompatible = model.IsDatasetCompatible(problemData.Dataset, out evaluationErrorMessage);
+      if (!datasetCompatible)
+        errorMessage += evaluationErrorMessage;
+
+      return string.IsNullOrEmpty(errorMessage);
+    }
+
     #region events
     public event EventHandler TargetVariableChanged;
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblem.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblem.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblem.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -22,8 +22,8 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("BD8AFF60-E8BE-4325-B1AC-08B7BDF37865")]
   [Item("Regression Problem", "A general regression problem.")]
   public class RegressionProblem : DataAnalysisProblem<IRegressionProblemData>, IRegressionProblem, IStorableContent {
@@ -31,5 +31,5 @@
 
     [StorableConstructor]
-    protected RegressionProblem(bool deserializing) : base(deserializing) { }
+    protected RegressionProblem(StorableConstructorFlag _) : base(_) { }
     protected RegressionProblem(RegressionProblem original, Cloner cloner) : base(original, cloner) { }
     public override IDeepCloneable Clone(Cloner cloner) { return new RegressionProblem(this, cloner); }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -27,8 +27,8 @@
 using HeuristicLab.Data;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("EE612297-B1AF-42D2-BF21-AF9A2D42791C")]
   [Item("RegressionProblemData", "Represents an item containing all data defining a regression problem.")]
   public class RegressionProblemData : DataAnalysisProblemData, IRegressionProblemData, IStorableContent {
@@ -122,5 +122,5 @@
 
     [StorableConstructor]
-    protected RegressionProblemData(bool deserializing) : base(deserializing) { }
+    protected RegressionProblemData(StorableConstructorFlag _) : base(_) { }
     [StorableHook(HookType.AfterDeserialization)]
     private void AfterDeserialization() {
@@ -161,23 +161,4 @@
       OnChanged();
     }
-
-    protected override bool IsProblemDataCompatible(IDataAnalysisProblemData problemData, out string errorMessage) {
-      if (problemData == null) throw new ArgumentNullException("problemData", "The provided problemData is null.");
-      IRegressionProblemData regressionProblemData = problemData as IRegressionProblemData;
-      if (regressionProblemData == null)
-        throw new ArgumentException("The problem data is not a regression problem data. Instead a " + problemData.GetType().GetPrettyName() + " was provided.", "problemData");
-
-      var returnValue = base.IsProblemDataCompatible(problemData, out errorMessage);
-      return returnValue;
-    }
-
-    public override void AdjustProblemDataProperties(IDataAnalysisProblemData problemData) {
-      if (problemData == null) throw new ArgumentNullException("problemData", "The provided problemData is null.");
-      RegressionProblemData regressionProblemData = problemData as RegressionProblemData;
-      if (regressionProblemData == null)
-        throw new ArgumentException("The problem data is not a regression problem data. Instead a " + problemData.GetType().GetPrettyName() + " was provided.", "problemData");
-
-      base.AdjustProblemDataProperties(problemData);
-    }
   }
 }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -23,5 +23,5 @@
 using System.Linq;
 using HeuristicLab.Common;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
@@ -29,11 +29,10 @@
   /// Represents a regression data analysis solution
   /// </summary>
-  [StorableClass]
+  [StorableType("00A95897-4AA4-406B-B304-5D19AA30C4B1")]
   public class RegressionSolution : RegressionSolutionBase {
     protected readonly Dictionary<int, double> evaluationCache;
 
     [StorableConstructor]
-    protected RegressionSolution(bool deserializing)
-      : base(deserializing) {
+    protected RegressionSolution(StorableConstructorFlag _) : base(_) {
       evaluationCache = new Dictionary<int, double>();
     }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -25,8 +25,8 @@
 using HeuristicLab.Data;
 using HeuristicLab.Optimization;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("03116F5E-ABBF-4966-9428-E3DC67D1D03D")]
   public abstract class RegressionSolutionBase : DataAnalysisSolution, IRegressionSolution {
     protected const string TrainingMeanSquaredErrorResultName = "Mean squared error (training)";
@@ -70,5 +70,11 @@
     public new IRegressionProblemData ProblemData {
       get { return (IRegressionProblemData)base.ProblemData; }
-      set { base.ProblemData = value; }
+      set {
+        if (value == null) throw new ArgumentNullException("The problemData must not be null.");
+        string errorMessage = string.Empty;
+        if (!Model.IsProblemDataCompatible(value, out errorMessage)) throw new ArgumentException(errorMessage);
+
+        base.ProblemData = value;
+      }
     }
 
@@ -154,5 +160,5 @@
 
     [StorableConstructor]
-    protected RegressionSolutionBase(bool deserializing) : base(deserializing) { }
+    protected RegressionSolutionBase(StorableConstructorFlag _) : base(_) { }
     protected RegressionSolutionBase(RegressionSolutionBase original, Cloner cloner)
       : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionVariableImpactsCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionVariableImpactsCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionVariableImpactsCalculator.cs	(revision 17980)
@@ -2,5 +2,5 @@
 
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -23,4 +23,5 @@
 
 using System;
+using System.Collections;
 using System.Collections.Generic;
 using System.Linq;
@@ -29,11 +30,13 @@
 using HeuristicLab.Data;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 using HeuristicLab.Random;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("414B25CD-6643-4E42-9EB2-B9A24F5E1528")]
   [Item("RegressionSolution Impacts Calculator", "Calculation of the impacts of input variables for any regression solution")]
   public sealed class RegressionSolutionVariableImpactsCalculator : ParameterizedNamedItem {
+    #region Parameters/Properties
+    [StorableType("45a48ef7-e1e6-44b7-95b1-ae9d01aa5de4")]
     public enum ReplacementMethodEnum {
       Median,
@@ -42,4 +45,6 @@
       Noise
     }
+
+    [StorableType("78df33f8-4715-4d25-a69a-f2bc1277fa3b")]
     public enum FactorReplacementMethodEnum {
       Best,
@@ -47,4 +52,6 @@
       Shuffle
     }
+
+    [StorableType("946646da-1c0b-435e-88f9-38d649fc5194")]
     public enum DataPartitionEnum {
       Training,
@@ -54,8 +61,12 @@
 
     private const string ReplacementParameterName = "Replacement Method";
+    private const string FactorReplacementParameterName = "Factor Replacement Method";
     private const string DataPartitionParameterName = "DataPartition";
 
     public IFixedValueParameter<EnumValue<ReplacementMethodEnum>> ReplacementParameter {
       get { return (IFixedValueParameter<EnumValue<ReplacementMethodEnum>>)Parameters[ReplacementParameterName]; }
+    }
+    public IFixedValueParameter<EnumValue<FactorReplacementMethodEnum>> FactorReplacementParameter {
+      get { return (IFixedValueParameter<EnumValue<FactorReplacementMethodEnum>>)Parameters[FactorReplacementParameterName]; }
     }
     public IFixedValueParameter<EnumValue<DataPartitionEnum>> DataPartitionParameter {
@@ -67,148 +78,152 @@
       set { ReplacementParameter.Value.Value = value; }
     }
+    public FactorReplacementMethodEnum FactorReplacementMethod {
+      get { return FactorReplacementParameter.Value.Value; }
+      set { FactorReplacementParameter.Value.Value = value; }
+    }
     public DataPartitionEnum DataPartition {
       get { return DataPartitionParameter.Value.Value; }
       set { DataPartitionParameter.Value.Value = value; }
     }
-
-
+    #endregion
+
+    #region Ctor/Cloner
     [StorableConstructor]
-    private RegressionSolutionVariableImpactsCalculator(bool deserializing) : base(deserializing) { }
+    private RegressionSolutionVariableImpactsCalculator(StorableConstructorFlag _) : base(_) { }
     private RegressionSolutionVariableImpactsCalculator(RegressionSolutionVariableImpactsCalculator original, Cloner cloner)
       : base(original, cloner) { }
+    public RegressionSolutionVariableImpactsCalculator()
+      : base() {
+      Parameters.Add(new FixedValueParameter<EnumValue<ReplacementMethodEnum>>(ReplacementParameterName, "The replacement method for variables during impact calculation.", new EnumValue<ReplacementMethodEnum>(ReplacementMethodEnum.Shuffle)));
+      Parameters.Add(new FixedValueParameter<EnumValue<FactorReplacementMethodEnum>>(FactorReplacementParameterName, "The replacement method for factor variables during impact calculation.", new EnumValue<FactorReplacementMethodEnum>(FactorReplacementMethodEnum.Best)));
+      Parameters.Add(new FixedValueParameter<EnumValue<DataPartitionEnum>>(DataPartitionParameterName, "The data partition on which the impacts are calculated.", new EnumValue<DataPartitionEnum>(DataPartitionEnum.Training)));
+    }
+
     public override IDeepCloneable Clone(Cloner cloner) {
       return new RegressionSolutionVariableImpactsCalculator(this, cloner);
     }
-
-    public RegressionSolutionVariableImpactsCalculator()
-      : base() {
-      Parameters.Add(new FixedValueParameter<EnumValue<ReplacementMethodEnum>>(ReplacementParameterName, "The replacement method for variables during impact calculation.", new EnumValue<ReplacementMethodEnum>(ReplacementMethodEnum.Median)));
-      Parameters.Add(new FixedValueParameter<EnumValue<DataPartitionEnum>>(DataPartitionParameterName, "The data partition on which the impacts are calculated.", new EnumValue<DataPartitionEnum>(DataPartitionEnum.Training)));
-    }
+    #endregion
 
     //mkommend: annoying name clash with static method, open to better naming suggestions
     public IEnumerable<Tuple<string, double>> Calculate(IRegressionSolution solution) {
-      return CalculateImpacts(solution, DataPartition, ReplacementMethod);
+      return CalculateImpacts(solution, ReplacementMethod, FactorReplacementMethod, DataPartition);
     }
 
     public static IEnumerable<Tuple<string, double>> CalculateImpacts(
       IRegressionSolution solution,
-      DataPartitionEnum data = DataPartitionEnum.Training,
-      ReplacementMethodEnum replacementMethod = ReplacementMethodEnum.Median,
+      ReplacementMethodEnum replacementMethod = ReplacementMethodEnum.Shuffle,
       FactorReplacementMethodEnum factorReplacementMethod = FactorReplacementMethodEnum.Best,
-      Func<double, string, bool> progressCallback = null) {
-
-      var problemData = solution.ProblemData;
-      var dataset = problemData.Dataset;
-
-      IEnumerable<int> rows;
-      IEnumerable<double> targetValues;
-      double originalR2 = -1;
-
-      OnlineCalculatorError error;
-
-      switch (data) {
-        case DataPartitionEnum.All:
-          rows = solution.ProblemData.AllIndices;
-          targetValues = problemData.TargetVariableValues.ToList();
-          originalR2 = OnlinePearsonsRCalculator.Calculate(problemData.TargetVariableValues, solution.EstimatedValues, out error);
-          if (error != OnlineCalculatorError.None) throw new InvalidOperationException("Error during R² calculation.");
-          originalR2 = originalR2 * originalR2;
-          break;
-        case DataPartitionEnum.Training:
-          rows = problemData.TrainingIndices;
-          targetValues = problemData.TargetVariableTrainingValues.ToList();
-          originalR2 = solution.TrainingRSquared;
-          break;
-        case DataPartitionEnum.Test:
-          rows = problemData.TestIndices;
-          targetValues = problemData.TargetVariableTestValues.ToList();
-          originalR2 = solution.TestRSquared;
-          break;
-        default: throw new ArgumentException(string.Format("DataPartition {0} cannot be handled.", data));
-      }
+      DataPartitionEnum dataPartition = DataPartitionEnum.Training) {
+
+      IEnumerable<int> rows = GetPartitionRows(dataPartition, solution.ProblemData);
+      IEnumerable<double> estimatedValues = solution.GetEstimatedValues(rows);
+      return CalculateImpacts(solution.Model, solution.ProblemData, estimatedValues, rows, replacementMethod, factorReplacementMethod);
+    }
+
+    public static IEnumerable<Tuple<string, double>> CalculateImpacts(
+     IRegressionModel model,
+     IRegressionProblemData problemData,
+     IEnumerable<double> estimatedValues,
+     IEnumerable<int> rows,
+     ReplacementMethodEnum replacementMethod = ReplacementMethodEnum.Shuffle,
+     FactorReplacementMethodEnum factorReplacementMethod = FactorReplacementMethodEnum.Best) {
+
+      //fholzing: try and catch in case a different dataset is loaded, otherwise statement is neglectable
+      var missingVariables = model.VariablesUsedForPrediction.Except(problemData.Dataset.VariableNames);
+      if (missingVariables.Any()) {
+        throw new InvalidOperationException(string.Format("Can not calculate variable impacts, because the model uses inputs missing in the dataset ({0})", string.Join(", ", missingVariables)));
+      }
+      IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+      var originalQuality = CalculateQuality(targetValues, estimatedValues);
 
       var impacts = new Dictionary<string, double>();
-      var modifiableDataset = ((Dataset)dataset).ToModifiable();
-
-      var inputvariables = new HashSet<string>(problemData.AllowedInputVariables.Union(solution.Model.VariablesUsedForPrediction));
-      var allowedInputVariables = dataset.VariableNames.Where(v => inputvariables.Contains(v)).ToList();
-
-      int curIdx = 0;
-      int count = allowedInputVariables.Where(problemData.Dataset.VariableHasType<double>).Count();
-      // calculate impacts for double variables
-      foreach (var inputVariable in allowedInputVariables.Where(problemData.Dataset.VariableHasType<double>)) {
-        //Report the current progress in percent. If the callback returns true, it means the execution shall be stopped
-        if (progressCallback != null) {
-          curIdx++;
-          if (progressCallback((double)curIdx / count, string.Format("Calculating impact for variable {0} ({1} of {2})", inputVariable, curIdx, count))) { return null; }
-        }
-        var newEstimates = EvaluateModelWithReplacedVariable(solution.Model, inputVariable, modifiableDataset, rows, replacementMethod);
-        var newR2 = OnlinePearsonsRCalculator.Calculate(targetValues, newEstimates, out error);
-        if (error != OnlineCalculatorError.None) throw new InvalidOperationException("Error during R² calculation with replaced inputs.");
-
-        newR2 = newR2 * newR2;
-        var impact = originalR2 - newR2;
-        impacts[inputVariable] = impact;
-      }
-
-      // calculate impacts for string variables
-      foreach (var inputVariable in allowedInputVariables.Where(problemData.Dataset.VariableHasType<string>)) {
-        if (factorReplacementMethod == FactorReplacementMethodEnum.Best) {
-          // try replacing with all possible values and find the best replacement value
-          var smallestImpact = double.PositiveInfinity;
-          foreach (var repl in problemData.Dataset.GetStringValues(inputVariable, rows).Distinct()) {
-            var newEstimates = EvaluateModelWithReplacedVariable(solution.Model, inputVariable, modifiableDataset, rows,
-              Enumerable.Repeat(repl, dataset.Rows));
-            var newR2 = OnlinePearsonsRCalculator.Calculate(targetValues, newEstimates, out error);
-            if (error != OnlineCalculatorError.None)
-              throw new InvalidOperationException("Error during R² calculation with replaced inputs.");
-
-            newR2 = newR2 * newR2;
-            var impact = originalR2 - newR2;
-            if (impact < smallestImpact) smallestImpact = impact;
-          }
-          impacts[inputVariable] = smallestImpact;
-        } else {
-          // for replacement methods shuffle and mode
-          // calculate impacts for factor variables
-
-          var newEstimates = EvaluateModelWithReplacedVariable(solution.Model, inputVariable, modifiableDataset, rows,
-            factorReplacementMethod);
-          var newR2 = OnlinePearsonsRCalculator.Calculate(targetValues, newEstimates, out error);
-          if (error != OnlineCalculatorError.None)
-            throw new InvalidOperationException("Error during R² calculation with replaced inputs.");
-
-          newR2 = newR2 * newR2;
-          var impact = originalR2 - newR2;
-          impacts[inputVariable] = impact;
-        }
-      } // foreach
-      return impacts.OrderByDescending(i => i.Value).Select(i => Tuple.Create(i.Key, i.Value));
-    }
-
-
-    private static IEnumerable<double> EvaluateModelWithReplacedVariable(IRegressionModel model, string variable, ModifiableDataset dataset, IEnumerable<int> rows, ReplacementMethodEnum replacement = ReplacementMethodEnum.Median) {
-      var originalValues = dataset.GetReadOnlyDoubleValues(variable).ToList();
+      var inputvariables = new HashSet<string>(problemData.AllowedInputVariables.Union(model.VariablesUsedForPrediction));
+      var modifiableDataset = ((Dataset)(problemData.Dataset).Clone()).ToModifiable();
+
+      foreach (var inputVariable in inputvariables) {
+        impacts[inputVariable] = CalculateImpact(inputVariable, model, problemData, modifiableDataset, rows, replacementMethod, factorReplacementMethod, targetValues, originalQuality);
+      }
+
+      return impacts.Select(i => Tuple.Create(i.Key, i.Value));
+    }
+
+    public static double CalculateImpact(string variableName,
+      IRegressionModel model,
+      IRegressionProblemData problemData,
+      ModifiableDataset modifiableDataset,
+      IEnumerable<int> rows,
+      ReplacementMethodEnum replacementMethod = ReplacementMethodEnum.Shuffle,
+      FactorReplacementMethodEnum factorReplacementMethod = FactorReplacementMethodEnum.Best,
+      IEnumerable<double> targetValues = null,
+      double quality = double.NaN) {
+
+      if (!model.VariablesUsedForPrediction.Contains(variableName)) { return 0.0; }
+      if (!problemData.Dataset.VariableNames.Contains(variableName)) {
+        throw new InvalidOperationException(string.Format("Can not calculate variable impact, because the model uses inputs missing in the dataset ({0})", variableName));
+      }
+
+      if (targetValues == null) {
+        targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+      }
+      if (quality == double.NaN) {
+        quality = CalculateQuality(model.GetEstimatedValues(modifiableDataset, rows), targetValues);
+      }
+
+      IList originalValues = null;
+      IList replacementValues = GetReplacementValues(modifiableDataset, variableName, model, rows, targetValues, out originalValues, replacementMethod, factorReplacementMethod);
+
+      double newValue = CalculateQualityForReplacement(model, modifiableDataset, variableName, originalValues, rows, replacementValues, targetValues);
+      double impact = quality - newValue;
+
+      return impact;
+    }
+
+    private static IList GetReplacementValues(ModifiableDataset modifiableDataset,
+      string variableName,
+      IRegressionModel model,
+      IEnumerable<int> rows,
+      IEnumerable<double> targetValues,
+      out IList originalValues,
+      ReplacementMethodEnum replacementMethod = ReplacementMethodEnum.Shuffle,
+      FactorReplacementMethodEnum factorReplacementMethod = FactorReplacementMethodEnum.Best) {
+
+      IList replacementValues = null;
+      if (modifiableDataset.VariableHasType<double>(variableName)) {
+        originalValues = modifiableDataset.GetReadOnlyDoubleValues(variableName).ToList();
+        replacementValues = GetReplacementValuesForDouble(modifiableDataset, rows, (List<double>)originalValues, replacementMethod);
+      } else if (modifiableDataset.VariableHasType<string>(variableName)) {
+        originalValues = modifiableDataset.GetReadOnlyStringValues(variableName).ToList();
+        replacementValues = GetReplacementValuesForString(model, modifiableDataset, variableName, rows, (List<string>)originalValues, targetValues, factorReplacementMethod);
+      } else {
+        throw new NotSupportedException("Variable not supported");
+      }
+
+      return replacementValues;
+    }
+
+    private static IList GetReplacementValuesForDouble(ModifiableDataset modifiableDataset,
+      IEnumerable<int> rows,
+      List<double> originalValues,
+      ReplacementMethodEnum replacementMethod = ReplacementMethodEnum.Shuffle) {
+
+      IRandom random = new FastRandom(31415);
+      List<double> replacementValues;
       double replacementValue;
-      List<double> replacementValues;
-      IRandom rand;
-
-      switch (replacement) {
+
+      switch (replacementMethod) {
         case ReplacementMethodEnum.Median:
           replacementValue = rows.Select(r => originalValues[r]).Median();
-          replacementValues = Enumerable.Repeat(replacementValue, dataset.Rows).ToList();
+          replacementValues = Enumerable.Repeat(replacementValue, modifiableDataset.Rows).ToList();
           break;
         case ReplacementMethodEnum.Average:
           replacementValue = rows.Select(r => originalValues[r]).Average();
-          replacementValues = Enumerable.Repeat(replacementValue, dataset.Rows).ToList();
+          replacementValues = Enumerable.Repeat(replacementValue, modifiableDataset.Rows).ToList();
           break;
         case ReplacementMethodEnum.Shuffle:
           // new var has same empirical distribution but the relation to y is broken
-          rand = new FastRandom(31415);
           // prepare a complete column for the dataset
-          replacementValues = Enumerable.Repeat(double.NaN, dataset.Rows).ToList();
+          replacementValues = Enumerable.Repeat(double.NaN, modifiableDataset.Rows).ToList();
           // shuffle only the selected rows
-          var shuffledValues = rows.Select(r => originalValues[r]).Shuffle(rand).ToList();
+          var shuffledValues = rows.Select(r => originalValues[r]).Shuffle(random).ToList();
           int i = 0;
           // update column values 
@@ -220,29 +235,46 @@
           var avg = rows.Select(r => originalValues[r]).Average();
           var stdDev = rows.Select(r => originalValues[r]).StandardDeviation();
-          rand = new FastRandom(31415);
           // prepare a complete column for the dataset
-          replacementValues = Enumerable.Repeat(double.NaN, dataset.Rows).ToList();
+          replacementValues = Enumerable.Repeat(double.NaN, modifiableDataset.Rows).ToList();
           // update column values 
           foreach (var r in rows) {
-            replacementValues[r] = NormalDistributedRandom.NextDouble(rand, avg, stdDev);
+            replacementValues[r] = NormalDistributedRandom.NextDouble(random, avg, stdDev);
           }
           break;
 
         default:
-          throw new ArgumentException(string.Format("ReplacementMethod {0} cannot be handled.", replacement));
-      }
-
-      return EvaluateModelWithReplacedVariable(model, variable, dataset, rows, replacementValues);
-    }
-
-    private static IEnumerable<double> EvaluateModelWithReplacedVariable(
-      IRegressionModel model, string variable, ModifiableDataset dataset,
-      IEnumerable<int> rows,
-      FactorReplacementMethodEnum replacement = FactorReplacementMethodEnum.Shuffle) {
-      var originalValues = dataset.GetReadOnlyStringValues(variable).ToList();
-      List<string> replacementValues;
-      IRandom rand;
-
-      switch (replacement) {
+          throw new ArgumentException(string.Format("ReplacementMethod {0} cannot be handled.", replacementMethod));
+      }
+
+      return replacementValues;
+    }
+
+    private static IList GetReplacementValuesForString(IRegressionModel model,
+      ModifiableDataset modifiableDataset,
+      string variableName,
+      IEnumerable<int> rows,
+      List<string> originalValues,
+      IEnumerable<double> targetValues,
+      FactorReplacementMethodEnum factorReplacementMethod = FactorReplacementMethodEnum.Shuffle) {
+
+      List<string> replacementValues = null;
+      IRandom random = new FastRandom(31415);
+
+      switch (factorReplacementMethod) {
+        case FactorReplacementMethodEnum.Best:
+          // try replacing with all possible values and find the best replacement value
+          var bestQuality = double.NegativeInfinity;
+          foreach (var repl in modifiableDataset.GetStringValues(variableName, rows).Distinct()) {
+            List<string> curReplacementValues = Enumerable.Repeat(repl, modifiableDataset.Rows).ToList();
+            //fholzing: this result could be used later on (theoretically), but is neglected for better readability/method consistency 
+            var newValue = CalculateQualityForReplacement(model, modifiableDataset, variableName, originalValues, rows, curReplacementValues, targetValues);
+            var curQuality = newValue;
+
+            if (curQuality > bestQuality) {
+              bestQuality = curQuality;
+              replacementValues = curReplacementValues;
+            }
+          }
+          break;
         case FactorReplacementMethodEnum.Mode:
           var mostCommonValue = rows.Select(r => originalValues[r])
@@ -250,13 +282,12 @@
             .OrderByDescending(g => g.Count())
             .First().Key;
-          replacementValues = Enumerable.Repeat(mostCommonValue, dataset.Rows).ToList();
+          replacementValues = Enumerable.Repeat(mostCommonValue, modifiableDataset.Rows).ToList();
           break;
         case FactorReplacementMethodEnum.Shuffle:
           // new var has same empirical distribution but the relation to y is broken
-          rand = new FastRandom(31415);
           // prepare a complete column for the dataset
-          replacementValues = Enumerable.Repeat(string.Empty, dataset.Rows).ToList();
+          replacementValues = Enumerable.Repeat(string.Empty, modifiableDataset.Rows).ToList();
           // shuffle only the selected rows
-          var shuffledValues = rows.Select(r => originalValues[r]).Shuffle(rand).ToList();
+          var shuffledValues = rows.Select(r => originalValues[r]).Shuffle(random).ToList();
           int i = 0;
           // update column values 
@@ -266,29 +297,53 @@
           break;
         default:
-          throw new ArgumentException(string.Format("FactorReplacementMethod {0} cannot be handled.", replacement));
-      }
-
-      return EvaluateModelWithReplacedVariable(model, variable, dataset, rows, replacementValues);
-    }
-
-    private static IEnumerable<double> EvaluateModelWithReplacedVariable(IRegressionModel model, string variable,
-      ModifiableDataset dataset, IEnumerable<int> rows, IEnumerable<double> replacementValues) {
-      var originalValues = dataset.GetReadOnlyDoubleValues(variable).ToList();
-      dataset.ReplaceVariable(variable, replacementValues.ToList());
+          throw new ArgumentException(string.Format("FactorReplacementMethod {0} cannot be handled.", factorReplacementMethod));
+      }
+
+      return replacementValues;
+    }
+
+    private static double CalculateQualityForReplacement(
+      IRegressionModel model,
+      ModifiableDataset modifiableDataset,
+      string variableName,
+      IList originalValues,
+      IEnumerable<int> rows,
+      IList replacementValues,
+      IEnumerable<double> targetValues) {
+
+      modifiableDataset.ReplaceVariable(variableName, replacementValues);
       //mkommend: ToList is used on purpose to avoid lazy evaluation that could result in wrong estimates due to variable replacements
-      var estimates = model.GetEstimatedValues(dataset, rows).ToList();
-      dataset.ReplaceVariable(variable, originalValues);
-
-      return estimates;
-    }
-    private static IEnumerable<double> EvaluateModelWithReplacedVariable(IRegressionModel model, string variable,
-      ModifiableDataset dataset, IEnumerable<int> rows, IEnumerable<string> replacementValues) {
-      var originalValues = dataset.GetReadOnlyStringValues(variable).ToList();
-      dataset.ReplaceVariable(variable, replacementValues.ToList());
-      //mkommend: ToList is used on purpose to avoid lazy evaluation that could result in wrong estimates due to variable replacements
-      var estimates = model.GetEstimatedValues(dataset, rows).ToList();
-      dataset.ReplaceVariable(variable, originalValues);
-
-      return estimates;
+      var estimates = model.GetEstimatedValues(modifiableDataset, rows).ToList();
+      var ret = CalculateQuality(targetValues, estimates);
+      modifiableDataset.ReplaceVariable(variableName, originalValues);
+
+      return ret;
+    }
+
+    public static double CalculateQuality(IEnumerable<double> targetValues, IEnumerable<double> estimatedValues) {
+      OnlineCalculatorError errorState;
+      var ret = OnlinePearsonsRCalculator.Calculate(targetValues, estimatedValues, out errorState);
+      if (errorState != OnlineCalculatorError.None) { throw new InvalidOperationException("Error during calculation with replaced inputs."); }
+      return ret * ret;
+    }
+
+    public static IEnumerable<int> GetPartitionRows(DataPartitionEnum dataPartition, IRegressionProblemData problemData) {
+      IEnumerable<int> rows;
+
+      switch (dataPartition) {
+        case DataPartitionEnum.All:
+          rows = problemData.AllIndices;
+          break;
+        case DataPartitionEnum.Test:
+          rows = problemData.TestIndices;
+          break;
+        case DataPartitionEnum.Training:
+          rows = problemData.TrainingIndices;
+          break;
+        default:
+          throw new NotSupportedException("DataPartition not supported");
+      }
+
+      return rows;
     }
   }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/ConstantTimeSeriesPrognosisModel.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/ConstantTimeSeriesPrognosisModel.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/ConstantTimeSeriesPrognosisModel.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -25,13 +25,13 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("A69BF8CC-2A57-4FBE-A468-8D38F3B6BBA6")]
   [Item("Constant TimeSeries Model", "A time series model that returns for all prediciton the same constant value.")]
   [Obsolete]
   public class ConstantTimeSeriesPrognosisModel : ConstantRegressionModel, ITimeSeriesPrognosisModel {
     [StorableConstructor]
-    protected ConstantTimeSeriesPrognosisModel(bool deserializing) : base(deserializing) { }
+    protected ConstantTimeSeriesPrognosisModel(StorableConstructorFlag _) : base(_) { }
     protected ConstantTimeSeriesPrognosisModel(ConstantTimeSeriesPrognosisModel original, Cloner cloner) : base(original, cloner) { }
     public override IDeepCloneable Clone(Cloner cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisAutoRegressiveModel.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisAutoRegressiveModel.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisAutoRegressiveModel.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -25,8 +25,8 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("9C44E097-50F8-4EC1-BE1B-6A0246EC020E")]
   [Item("Autoregressive TimeSeries Model", "A linear autoregressive time series model used to predict future values.")]
   public class TimeSeriesPrognosisAutoRegressiveModel : RegressionModel, ITimeSeriesPrognosisModel {
@@ -43,5 +43,5 @@
 
     [StorableConstructor]
-    protected TimeSeriesPrognosisAutoRegressiveModel(bool deserializing) : base(deserializing) { }
+    protected TimeSeriesPrognosisAutoRegressiveModel(StorableConstructorFlag _) : base(_) { }
     protected TimeSeriesPrognosisAutoRegressiveModel(TimeSeriesPrognosisAutoRegressiveModel original, Cloner cloner)
       : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblem.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblem.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblem.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -22,12 +22,12 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("F6680708-9368-4A96-AE2F-B4B7F4C3FE52")]
   [Item("Time-series Prognosis Problem", "A general time-series prognosis problem.")]
   public class TimeSeriesPrognosisProblem : DataAnalysisProblem<ITimeSeriesPrognosisProblemData>, ITimeSeriesPrognosisProblem {
     [StorableConstructor]
-    protected TimeSeriesPrognosisProblem(bool deserializing) : base(deserializing) { }
+    protected TimeSeriesPrognosisProblem(StorableConstructorFlag _) : base(_) { }
     protected TimeSeriesPrognosisProblem(TimeSeriesPrognosisProblem original, Cloner cloner) : base(original, cloner) { }
     public override IDeepCloneable Clone(Cloner cloner) { return new TimeSeriesPrognosisProblem(this, cloner); }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblemData.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblemData.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblemData.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -27,8 +27,8 @@
 using HeuristicLab.Data;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("68E790CA-24B3-4127-B06B-24E5D3078E52")]
   [Item("TimeSeriesPrognosisProblemData", "Represents an item containing all data defining a time series prognosis problem.")]
   public class TimeSeriesPrognosisProblemData : RegressionProblemData, ITimeSeriesPrognosisProblemData {
@@ -1571,5 +1571,5 @@
 
     [StorableConstructor]
-    protected TimeSeriesPrognosisProblemData(bool deserializing) : base(deserializing) { }
+    protected TimeSeriesPrognosisProblemData(StorableConstructorFlag _) : base(_) { }
 
     protected TimeSeriesPrognosisProblemData(TimeSeriesPrognosisProblemData original, Cloner cloner) : base(original, cloner) { }
@@ -1620,36 +1620,4 @@
       OnChanged();
     }
-
-    protected override bool IsProblemDataCompatible(IDataAnalysisProblemData problemData, out string errorMessage) {
-      if (problemData == null) throw new ArgumentNullException("problemData", "The provided problemData is null.");
-      ITimeSeriesPrognosisProblemData timeseriesProblemData = problemData as ITimeSeriesPrognosisProblemData;
-      if (timeseriesProblemData == null)
-        throw new ArgumentException("The problem data is not a time-series problem data. Instead a " + problemData.GetType().GetPrettyName() + " was provided.", "problemData");
-
-      var returnValue = base.IsProblemDataCompatible(problemData, out errorMessage);
-      //check targetVariable
-      if (problemData.InputVariables.All(var => var.Value != TargetVariable)) {
-        errorMessage = string.Format("The target variable {0} is not present in the new problem data.", TargetVariable)
-                       + Environment.NewLine + errorMessage;
-        return false;
-      }
-      return returnValue;
-    }
-
-    public override void AdjustProblemDataProperties(IDataAnalysisProblemData problemData) {
-      TimeSeriesPrognosisProblemData timeSeriesProblemData = problemData as TimeSeriesPrognosisProblemData;
-      if (timeSeriesProblemData == null)
-        throw new ArgumentException("The problem data is not a timeseries problem data. Instead a " + problemData.GetType().GetPrettyName() + " was provided.", "problemData");
-
-      var trainingDataStart = TrainingIndices.First();
-
-      base.AdjustProblemDataProperties(problemData);
-
-      TestPartition.Start = trainingDataStart;
-
-      TrainingHorizon = timeSeriesProblemData.TrainingHorizon;
-      TestHorizon = timeSeriesProblemData.TestHorizon;
-    }
-
   }
 }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisResults.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisResults.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisResults.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -27,8 +27,8 @@
 using HeuristicLab.Data;
 using HeuristicLab.Optimization;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("E3F334B4-9980-473C-B77F-128AFAFD1DD1")]
   [Item("Prognosis Results", "Represents a collection of time series prognosis results.")]
   public class TimeSeriesPrognosisResults : ResultCollection {
@@ -330,5 +330,5 @@
 
     [StorableConstructor]
-    public TimeSeriesPrognosisResults(bool deserializing) : base(deserializing) { }
+    public TimeSeriesPrognosisResults(StorableConstructorFlag _) : base(_) { }
     protected TimeSeriesPrognosisResults(TimeSeriesPrognosisResults original, Cloner cloner)
       : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolution.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolution.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolution.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -23,5 +23,5 @@
 using System.Linq;
 using HeuristicLab.Common;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
@@ -29,8 +29,8 @@
   /// Represents a time series prognosis data analysis solution
   /// </summary>
-  [StorableClass]
+  [StorableType("42CF9704-DCB2-4159-89B3-A30645399B86")]
   public class TimeSeriesPrognosisSolution : TimeSeriesPrognosisSolutionBase {
     [StorableConstructor]
-    protected TimeSeriesPrognosisSolution(bool deserializing) : base(deserializing) { }
+    protected TimeSeriesPrognosisSolution(StorableConstructorFlag _) : base(_) { }
     protected TimeSeriesPrognosisSolution(TimeSeriesPrognosisSolution original, Cloner cloner) : base(original, cloner) { }
     protected internal TimeSeriesPrognosisSolution(ITimeSeriesPrognosisModel model, ITimeSeriesPrognosisProblemData problemData)
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -25,8 +25,8 @@
 using HeuristicLab.Data;
 using HeuristicLab.Optimization;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("DF08D8C4-90F8-456E-855B-C8F487FF7B51")]
   public abstract class TimeSeriesPrognosisSolutionBase : RegressionSolutionBase, ITimeSeriesPrognosisSolution {
     #region result names
@@ -128,5 +128,5 @@
 
     [StorableConstructor]
-    protected TimeSeriesPrognosisSolutionBase(bool deserializing) : base(deserializing) { }
+    protected TimeSeriesPrognosisSolutionBase(StorableConstructorFlag _) : base(_) { }
     protected TimeSeriesPrognosisSolutionBase(TimeSeriesPrognosisSolutionBase original, Cloner cloner) : base(original, cloner) { }
     protected TimeSeriesPrognosisSolutionBase(ITimeSeriesPrognosisModel model, ITimeSeriesPrognosisProblemData problemData)
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/CopyColumnTransformation.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/CopyColumnTransformation.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/CopyColumnTransformation.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -26,8 +26,8 @@
 using HeuristicLab.Data;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("DF78A485-8B71-46A4-8A2C-68642084D201")]
   [Item("CopyColumnTransformation", "Represents a transformation which represents a copied Column.")]
   public class CopyColumnTransformation : Transformation {
@@ -50,5 +50,5 @@
 
     [StorableConstructor]
-    protected CopyColumnTransformation(bool deserializing) : base(deserializing) { }
+    protected CopyColumnTransformation(StorableConstructorFlag _) : base(_) { }
     protected CopyColumnTransformation(CopyColumnTransformation original, Cloner cloner)
       : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ExponentialTransformation.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ExponentialTransformation.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ExponentialTransformation.cs	(revision 17980)
@@ -6,8 +6,8 @@
 using HeuristicLab.Data;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("AAB32034-FA4A-4D70-937F-EF026C1D508A")]
   [Item("Exponential Transformation", "f(x) = b ^ x | Represents a exponential transformation.")]
   public class ExponentialTransformation : Transformation<double> {
@@ -30,5 +30,5 @@
 
     [StorableConstructor]
-    protected ExponentialTransformation(bool deserializing) : base(deserializing) { }
+    protected ExponentialTransformation(StorableConstructorFlag _) : base(_) { }
 
     protected ExponentialTransformation(ExponentialTransformation original, Cloner cloner)
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LinearTransformation.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LinearTransformation.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LinearTransformation.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -28,8 +28,8 @@
 using HeuristicLab.Data;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("203E6A27-4430-4A9E-825A-22C1B254F5E8")]
   [Item("Linear Transformation", "f(x) = k * x + d | Represents a linear transformation with multiplication and addition.")]
   public class LinearTransformation : Transformation<double> {
@@ -66,5 +66,5 @@
 
     [StorableConstructor]
-    protected LinearTransformation(bool deserializing) : base(deserializing) { }
+    protected LinearTransformation(StorableConstructorFlag _) : base(_) { }
     protected LinearTransformation(LinearTransformation original, Cloner cloner)
       : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LogarithmicTransformation.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LogarithmicTransformation.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/LogarithmicTransformation.cs	(revision 17980)
@@ -6,8 +6,8 @@
 using HeuristicLab.Data;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("D3330C77-060A-4F75-A0C5-47AC81C5F2DF")]
   [Item("Logarithmic Transformation", "f(x) = log(x, b) | Represents a logarithmic transformation.")]
   public class LogarithmicTransformation : Transformation<double> {
@@ -30,5 +30,5 @@
 
     [StorableConstructor]
-    protected LogarithmicTransformation(bool deserializing) : base(deserializing) { }
+    protected LogarithmicTransformation(StorableConstructorFlag _) : base(_) { }
     protected LogarithmicTransformation(LogarithmicTransformation original, Cloner cloner)
       : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/PowerTransformation.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/PowerTransformation.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/PowerTransformation.cs	(revision 17980)
@@ -6,8 +6,8 @@
 using HeuristicLab.Data;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("D5A6860A-AEE5-47BE-A4D2-0107AB0A90E3")]
   [Item("Power Transformation", "f(x) = x ^ exp | Represents a power transformation.")]
   public class PowerTransformation : Transformation<double> {
@@ -30,5 +30,5 @@
 
     [StorableConstructor]
-    protected PowerTransformation(bool deserializing) : base(deserializing) { }
+    protected PowerTransformation(StorableConstructorFlag _) : base(_) { }
     protected PowerTransformation(PowerTransformation original, Cloner cloner)
       : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ReciprocalTransformation.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ReciprocalTransformation.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ReciprocalTransformation.cs	(revision 17980)
@@ -5,7 +5,7 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("8D242A5A-5EBB-4618-958E-A7EF34151508")]
   [Item("Reciprocal Transformation", "f(x) = 1 / x | Represents a reciprocal transformation.")]
   public class ReciprocalTransformation : Transformation<double> {
@@ -18,5 +18,5 @@
 
     [StorableConstructor]
-    protected ReciprocalTransformation(bool deserializing) : base(deserializing) { }
+    protected ReciprocalTransformation(StorableConstructorFlag _) : base(_) { }
     protected ReciprocalTransformation(ReciprocalTransformation original, Cloner cloner)
       : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftStandardDistributionTransformation.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftStandardDistributionTransformation.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftStandardDistributionTransformation.cs	(revision 17980)
@@ -5,8 +5,8 @@
 using HeuristicLab.Data;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("F0DC4951-64DF-4058-8E87-748D0FA1AA21")]
   [Item("Shift Standard Distribution Transformation", "f(x) = ((x - m_org) / s_org ) * s_tar + m_tar | Represents Transformation to unit standard deviation and additional linear transformation to a target Mean and Standard deviation")]
   public class ShiftStandardDistributionTransformation : Transformation<double> {
@@ -52,5 +52,5 @@
 
     [StorableConstructor]
-    protected ShiftStandardDistributionTransformation(bool deserializing) : base(deserializing) { }
+    protected ShiftStandardDistributionTransformation(StorableConstructorFlag _) : base(_) { }
     protected ShiftStandardDistributionTransformation(ShiftStandardDistributionTransformation original, Cloner cloner)
       : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftToRangeTransformation.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftToRangeTransformation.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/ShiftToRangeTransformation.cs	(revision 17980)
@@ -5,8 +5,8 @@
 using HeuristicLab.Data;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [StorableClass]
+  [StorableType("4A91E704-927C-4278-AA11-79C16BD8E4F2")]
   [Item("Shift to Range Transformation", "f(x) = k * x + d, start <= f(x) <= end | Represents a linear Transformation using Parameters defining a target range")]
   public class ShiftToRangeTransformation : LinearTransformation {
@@ -29,5 +29,5 @@
 
     [StorableConstructor]
-    protected ShiftToRangeTransformation(bool deserializing) : base(deserializing) { }
+    protected ShiftToRangeTransformation(StorableConstructorFlag _) : base(_) { }
     protected ShiftToRangeTransformation(ShiftToRangeTransformation original, Cloner cloner)
       : base(original, cloner) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/Transformation.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/Transformation.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Transformations/Transformation.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -26,10 +26,10 @@
 using HeuristicLab.Data;
 using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
 
   [Item("Transformation", "Represents the base class for a transformation.")]
-  [StorableClass]
+  [StorableType("46B380CC-6CDE-40FC-9BB4-E3FF82BA35EA")]
   public abstract class Transformation : ParameterizedNamedItem, ITransformation {
     protected const string ColumnParameterName = "Column";
@@ -49,5 +49,5 @@
 
     [StorableConstructor]
-    protected Transformation(bool deserializing) : base(deserializing) { }
+    protected Transformation(StorableConstructorFlag _) : base(_) { }
     protected Transformation(Transformation original, Cloner cloner) : base(original, cloner) { }
     protected Transformation(IEnumerable<string> allowedColumns) {
@@ -58,9 +58,9 @@
 
   [Item("Transformation", "Represents the base class for a transformation.")]
-  [StorableClass]
+  [StorableType("F244DB89-72EA-4B41-89FA-C2E14F30AD29")]
   public abstract class Transformation<T> : Transformation, ITransformation<T> {
 
     [StorableConstructor]
-    protected Transformation(bool deserializing) : base(deserializing) { }
+    protected Transformation(StorableConstructorFlag _) : base(_) { }
     protected Transformation(Transformation<T> original, Cloner cloner) : base(original, cloner) { }
     protected Transformation(IEnumerable<string> allowedColumns) : base(allowedColumns) { }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationEnsembleModel.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationEnsembleModel.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationEnsembleModel.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,5 +21,8 @@
 
 using System.Collections.Generic;
+using HEAL.Attic;
+
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("4bd3a1b0-6371-418e-9fd7-f9be9e3b2928")]
   public interface IClassificationEnsembleModel : IClassificationModel {
     void Add(IClassificationModel model);
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationEnsembleSolution.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationEnsembleSolution.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationEnsembleSolution.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -22,5 +22,8 @@
 using System.Collections.Generic;
 using HeuristicLab.Core;
+using HEAL.Attic;
+
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("b966443d-a221-46df-83d1-49adaae1adbe")]
   public interface IClassificationEnsembleSolution : IClassificationSolution {
     new IClassificationEnsembleModel Model { get; }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationModel.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationModel.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationModel.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -22,6 +22,8 @@
 using System;
 using System.Collections.Generic;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("ff091491-c895-41cb-9c45-f3b1a11637d4")]
   /// <summary>
   /// Interface for all classification models.
@@ -31,4 +33,5 @@
     IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows);
     IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData);
+    bool IsProblemDataCompatible(IClassificationProblemData problemData, out string errorMessage);
     string TargetVariable { get; set; }
     event EventHandler TargetVariableChanged;
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationProblem.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationProblem.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationProblem.cs	(revision 17980)
@@ -1,5 +1,6 @@
-﻿#region License Information
+﻿using HEAL.Attic;
+#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,4 +22,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("fd15f587-2a68-4180-86c4-82410e3f22e2")]
   public interface IClassificationProblem : IDataAnalysisProblem<IClassificationProblemData> {
   }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationProblemData.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationProblemData.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationProblemData.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,5 +21,8 @@
 
 using System.Collections.Generic;
+using HEAL.Attic;
+
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("8cd26df9-aed7-4378-9516-04322b6f9d2e")]
   public interface IClassificationProblemData : IDataAnalysisProblemData {
     string TargetVariable { get; set; }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationSolution.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationSolution.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationSolution.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,5 +21,8 @@
 
 using System.Collections.Generic;
+using HEAL.Attic;
+
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("7aef6b19-899c-4510-a3d1-9d5056ee204e")]
   public interface IClassificationSolution : IDataAnalysisSolution {
     new IClassificationModel Model { get; }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionClassificationModel.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionClassificationModel.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionClassificationModel.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -22,5 +22,8 @@
 using System;
 using System.Collections.Generic;
+using HEAL.Attic;
+
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("ea474735-61d0-4ada-8970-ac1d78ce4d15")]
   public interface IDiscriminantFunctionClassificationModel : IClassificationModel {
     IEnumerable<double> Thresholds { get; }
@@ -31,4 +34,5 @@
     void SetThresholdsAndClassValues(IEnumerable<double> thresholds, IEnumerable<double> classValues);
     IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows);
+    IEnumerable<double> GetEstimatedClassValues(IEnumerable<double> estimatedValues);
 
     event EventHandler ThresholdsChanged;
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionClassificationSolution.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionClassificationSolution.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionClassificationSolution.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -20,7 +20,9 @@
 #endregion
 
-using System;
 using System.Collections.Generic;
+using HEAL.Attic;
+
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("ecb5d2f6-8041-4d07-aeff-e7fc0b5c355e")]
   public interface IDiscriminantFunctionClassificationSolution : IClassificationSolution {
     new IDiscriminantFunctionClassificationModel Model { get; }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionThresholdCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionThresholdCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionThresholdCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -22,5 +22,8 @@
 using System.Collections.Generic;
 using HeuristicLab.Core;
+using HEAL.Attic;
+
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("f12cfcbe-8473-49c3-8c43-bddce2d7b772")]
   public interface IDiscriminantFunctionThresholdCalculator : INamedItem {
     void Calculate(IClassificationProblemData problemData, IEnumerable<double> estimatedValues, IEnumerable<double> targetClassValues, out double[] classValues, out double[] thresholds);
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringModel.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringModel.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringModel.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,5 +21,8 @@
 
 using System.Collections.Generic;
+using HEAL.Attic;
+
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("1aab7e19-317f-47e0-acc7-b0538e572d8e")]
   public interface IClusteringModel : IDataAnalysisModel {
     IEnumerable<int> GetClusterValues(IDataset dataset, IEnumerable<int> rows);
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringProblem.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringProblem.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringProblem.cs	(revision 17980)
@@ -1,5 +1,6 @@
-﻿#region License Information
+﻿using HEAL.Attic;
+#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,4 +22,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("fc7456d2-3892-4a7b-a77a-b7a0828d2530")]
   public interface IClusteringProblem : IDataAnalysisProblem<IClusteringProblemData> {
   }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringProblemData.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringProblemData.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringProblemData.cs	(revision 17980)
@@ -1,5 +1,6 @@
-﻿#region License Information
+﻿using HEAL.Attic;
+#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,4 +22,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("e39aa6c0-d6c6-491d-88cc-de05c6503314")]
   public interface IClusteringProblemData : IDataAnalysisProblemData {
   }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringSolution.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringSolution.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringSolution.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,5 +21,8 @@
 
 using System.Collections.Generic;
+using HEAL.Attic;
+
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("dbb9226f-312d-4ee2-a6cc-b74cc6ab5cc0")]
   public interface IClusteringSolution : IDataAnalysisSolution {
     new IClusteringModel Model { get; }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisModel.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisModel.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisModel.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -22,6 +22,8 @@
 using System.Collections.Generic;
 using HeuristicLab.Core;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("f85ccf7a-7df5-431e-bc4d-be6f3c4c2338")]
   /// <summary>
   /// Interface for all data-analysis models (regression/classification/clustering).
@@ -30,4 +32,6 @@
   public interface IDataAnalysisModel : INamedItem {
     IEnumerable<string> VariablesUsedForPrediction { get; }
+    bool IsDatasetCompatible(IDataset dataset, out string errorMessage);
+    bool IsProblemDataCompatible(IDataAnalysisProblemData problemData, out string errorMessage);
   }
 }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblem.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblem.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblem.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -23,6 +23,8 @@
 using HeuristicLab.Core;
 using HeuristicLab.Optimization;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("74e4c570-3881-4bfa-a5bb-2bb71cdee2b3")]
   public interface IDataAnalysisProblem : IProblem {
     IParameter ProblemDataParameter { get; }
@@ -31,4 +33,5 @@
   }
 
+  [StorableType("c2f6fcdd-ab62-4423-be75-01aa694df411")]
   public interface IDataAnalysisProblem<T> : IDataAnalysisProblem
   where T : class, IDataAnalysisProblemData {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblemData.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblemData.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblemData.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -24,6 +24,8 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("3f50defe-1f79-4122-a96b-11ca90202210")]
   public interface IDataAnalysisProblemData : INamedItem {
     bool IsEmpty { get; }
@@ -49,6 +51,4 @@
 
     event EventHandler Changed;
-
-    void AdjustProblemDataProperties(IDataAnalysisProblemData problemData);
   }
 }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisSolution.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisSolution.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisSolution.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -23,6 +23,8 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("f8f940b8-7888-401b-8382-51face79d703")]
   public interface IDataAnalysisSolution : INamedItem, IStorableContent {
     IDataAnalysisModel Model { get; }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisSolutionExporter.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisSolutionExporter.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisSolutionExporter.cs	(revision 17980)
@@ -1,5 +1,6 @@
-﻿#region License Information
+﻿using HEAL.Attic;
+#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -20,9 +21,7 @@
 #endregion
 
-using System;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
 
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("87fc237a-8478-429a-b276-6c7e09a86137")]
   public interface IDataAnalysisSolutionExporter {
     string FileTypeFilter { get; }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataset.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataset.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataset.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -25,6 +25,8 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("55cc9211-2136-41a0-a5bc-0d51e915d1b4")]
   public interface IDataset : IItem, IStringConvertibleMatrix {
     IEnumerable<string> VariableNames { get; }
@@ -33,4 +35,5 @@
     IEnumerable<string> DateTimeVariables { get; }
 
+    bool ContainsVariable(string variablename);
     bool VariableHasType<T>(string variableName);
 
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDependencyCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDependencyCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDependencyCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IOnlineCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IOnlineCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IOnlineCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/ITransformation.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/ITransformation.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/ITransformation.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -22,6 +22,8 @@
 using System.Collections.Generic;
 using HeuristicLab.Core;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("6d791015-1439-40e6-a0ba-a8c49c0ddba9")]
   public interface ITransformation : IParameterizedItem {
     string ShortName { get; }
@@ -29,4 +31,5 @@
   }
 
+  [StorableType("a200b865-5010-46ae-9070-094ac272f3a8")]
   public interface ITransformation<T> : ITransformation {
     void ConfigureParameters(IEnumerable<T> data);
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/ITransformationMapper.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/ITransformationMapper.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/ITransformationMapper.cs	(revision 17980)
@@ -1,5 +1,6 @@
-﻿#region License Information
+﻿using HEAL.Attic;
+#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -22,4 +23,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("a5bda2a6-0f93-4f44-8992-af0cd3582527")]
   public interface ITransformationMapper<out T> {
     T GenerateModel(ITransformation transformation);
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IConfidenceRegressionModel.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IConfidenceRegressionModel.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IConfidenceRegressionModel.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,6 +21,8 @@
 
 using System.Collections.Generic;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("35261615-3840-49ba-90a5-0e15806c1bc4")]
   public interface IConfidenceRegressionModel : IRegressionModel {
     IEnumerable<double> GetEstimatedVariances(IDataset dataset, IEnumerable<int> rows);
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IConfidenceRegressionSolution.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IConfidenceRegressionSolution.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IConfidenceRegressionSolution.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,6 +21,8 @@
 
 using System.Collections.Generic;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("710d4059-2512-415d-b4bc-8cd995d5b9fc")]
   public interface IConfidenceRegressionSolution : IRegressionSolution {
     new IConfidenceRegressionModel Model { get; }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionEnsembleModel.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionEnsembleModel.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionEnsembleModel.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -22,5 +22,8 @@
 using System;
 using System.Collections.Generic;
+using HEAL.Attic;
+
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("50848b49-340b-460a-981c-b3eb436c5bcf")]
   public interface IRegressionEnsembleModel : IRegressionModel {
     void Add(IRegressionModel model);
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionEnsembleSolution.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionEnsembleSolution.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionEnsembleSolution.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -22,5 +22,8 @@
 using System.Collections.Generic;
 using HeuristicLab.Core;
+using HEAL.Attic;
+
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("287c5f55-cc5c-488a-a5e7-17a41a087981")]
   public interface IRegressionEnsembleSolution : IRegressionSolution {
     new IRegressionEnsembleModel Model { get; }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionModel.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionModel.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionModel.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -22,6 +22,8 @@
 using System;
 using System.Collections.Generic;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("56c31bd6-dc0d-4478-b121-ea1817eae301")]
   /// <summary>
   /// Interface for all regression models.
@@ -31,4 +33,5 @@
     IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows);
     IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData);
+    bool IsProblemDataCompatible(IRegressionProblemData problemData, out string errorMessage);
     string TargetVariable { get; set; }
     event EventHandler TargetVariableChanged;
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionProblem.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionProblem.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionProblem.cs	(revision 17980)
@@ -1,5 +1,6 @@
-﻿#region License Information
+﻿using HEAL.Attic;
+#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,4 +22,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("4541dcea-2a97-451f-b3bd-84a1342e2b1d")]
   public interface IRegressionProblem : IDataAnalysisProblem<IRegressionProblemData> {
   }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionProblemData.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionProblemData.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionProblemData.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,6 +21,8 @@
 
 using System.Collections.Generic;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("1ef22b8b-f3b4-494b-8cdd-f08e84e316e0")]
   public interface IRegressionProblemData : IDataAnalysisProblemData {
     string TargetVariable { get; set; }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionSolution.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionSolution.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionSolution.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,5 +21,8 @@
 
 using System.Collections.Generic;
+using HEAL.Attic;
+
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("b9d7d1f7-c603-45ef-b372-71b82446fa72")]
   public interface IRegressionSolution : IDataAnalysisSolution {
     new IRegressionModel Model { get; }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/IOnlineTimeSeriesCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/IOnlineTimeSeriesCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/IOnlineTimeSeriesCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,5 +21,4 @@
 
 
-using System;
 using System.Collections.Generic;
 
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisModel.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisModel.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisModel.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,5 +21,8 @@
 
 using System.Collections.Generic;
+using HEAL.Attic;
+
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("c238682c-af0b-449e-aecf-8cf61418f425")]
   /// <summary>
   /// Interface for all time series prognosis models.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisProblem.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisProblem.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisProblem.cs	(revision 17980)
@@ -1,5 +1,6 @@
-﻿#region License Information
+﻿using HEAL.Attic;
+#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,4 +22,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("5823dd3a-37a0-4b7c-b9d4-07994084188f")]
   public interface ITimeSeriesPrognosisProblem : IDataAnalysisProblem<ITimeSeriesPrognosisProblemData> {
   }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisProblemData.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisProblemData.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisProblemData.cs	(revision 17980)
@@ -1,5 +1,6 @@
-﻿#region License Information
+﻿using HEAL.Attic;
+#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,4 +22,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("9f05ada5-f1b1-44fd-84ad-2f7b427e94c3")]
   public interface ITimeSeriesPrognosisProblemData : IRegressionProblemData {
     int TrainingHorizon { get; set; }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisSolution.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisSolution.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisSolution.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,5 +21,8 @@
 
 using System.Collections.Generic;
+using HEAL.Attic;
+
 namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableType("2793d8c7-6f34-4d9d-970c-a705f6c47b5c")]
   public interface ITimeSeriesPrognosisSolution : IRegressionSolution {
     new ITimeSeriesPrognosisModel Model { get; }
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/ModifiableDataset.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/ModifiableDataset.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/ModifiableDataset.cs	(revision 17980)
@@ -2,5 +2,5 @@
 
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -29,12 +29,12 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HEAL.Attic;
 
 namespace HeuristicLab.Problems.DataAnalysis {
   [Item("ModifiableDataset", "Represents a dataset containing data that should be analyzed, which can be modified by adding or replacing variables and values.")]
-  [StorableClass]
+  [StorableType("4B9DA9DD-10C4-4609-8F87-B35ECD7A7487")]
   public sealed class ModifiableDataset : Dataset, IStringConvertibleMatrix {
     [StorableConstructor]
-    private ModifiableDataset(bool deserializing) : base(deserializing) { }
+    private ModifiableDataset(StorableConstructorFlag _) : base(_) { }
 
     private ModifiableDataset(ModifiableDataset original, Cloner cloner) : base(original, cloner) {
@@ -47,6 +47,37 @@
     public ModifiableDataset() { }
 
-    public ModifiableDataset(IEnumerable<string> variableNames, IEnumerable<IList> variableValues) :
-      base(variableNames, variableValues, cloneValues: false) { }
+    public ModifiableDataset(IEnumerable<string> variableNames, IEnumerable<IList> variableValues, bool cloneValues = false) :
+      base(variableNames, variableValues, cloneValues) { }
+
+    public Dataset ToDataset() {
+      return new Dataset(variableNames, variableNames.Select(v => variableValues[v]));
+    }
+
+
+    public IEnumerable<object> GetRow(int row) {
+      if (row < 0 || row >= Rows)
+        throw new ArgumentException(string.Format("Invalid row {0} specified. The dataset contains {1} row(s).", row, Rows));
+
+      return variableValues.Select(x => x.Value[row]);
+    }
+
+    public void AddRow(IEnumerable<object> values) {
+      var list = values.ToList();
+      if (list.Count != variableNames.Count)
+        throw new ArgumentException("The number of values must be equal to the number of variable names.");
+      // check if all the values are of the correct type
+      for (int i = 0; i < list.Count; ++i) {
+        if (list[i].GetType() != GetVariableType(variableNames[i])) {
+          throw new ArgumentException("The type of the provided value does not match the variable type.");
+        }
+      }
+      // add values
+      for (int i = 0; i < list.Count; ++i) {
+        variableValues[variableNames[i]].Add(list[i]);
+      }
+      Rows++;
+      OnRowsChanged();
+      OnReset();
+    }
 
     public void ReplaceRow(int row, IEnumerable<object> values) {
@@ -64,4 +95,42 @@
         variableValues[variableNames[i]][row] = list[i];
       }
+      OnReset();
+    }
+
+    // slow, avoid using this
+    public void RemoveRow(int row) {
+      foreach (var list in variableValues.Values)
+        list.RemoveAt(row);
+      Rows--;
+      OnRowsChanged();
+      OnReset();
+    }
+
+    // adds a new variable to the dataset
+    public void AddVariable(string variableName, IList values) {
+      InsertVariable(variableName, Columns, values);
+    }
+
+    public void InsertVariable(string variableName, int position, IList values) {
+      if (variableValues.ContainsKey(variableName))
+        throw new ArgumentException(string.Format("Variable {0} is already present in the dataset.", variableName));
+
+      if (position < 0 || position > Columns)
+        throw new ArgumentException(string.Format("Incorrect position {0} specified. The position must be between 0 and {1}.", position, Columns));
+
+      if (values == null)
+        throw new ArgumentNullException("values", "Values must not be null. At least an empty list of values has to be provided.");
+
+      if (values.Count != Rows)
+        throw new ArgumentException(string.Format("{0} values are provided, but {1} rows are present in the dataset.", values.Count, Rows));
+
+      if (!IsAllowedType(values))
+        throw new ArgumentException(string.Format("Unsupported type {0} for variable {1}.", GetElementType(values), variableName));
+
+      variableNames.Insert(position, variableName);
+      variableValues[variableName] = values;
+
+      OnColumnsChanged();
+      OnColumnNamesChanged();
       OnReset();
     }
@@ -77,41 +146,4 @@
     }
 
-    public void AddRow(IEnumerable<object> values) {
-      var list = values.ToList();
-      if (list.Count != variableNames.Count)
-        throw new ArgumentException("The number of values must be equal to the number of variable names.");
-      // check if all the values are of the correct type
-      for (int i = 0; i < list.Count; ++i) {
-        if (list[i].GetType() != GetVariableType(variableNames[i])) {
-          throw new ArgumentException("The type of the provided value does not match the variable type.");
-        }
-      }
-      // add values
-      for (int i = 0; i < list.Count; ++i) {
-        variableValues[variableNames[i]].Add(list[i]);
-      }
-      rows++;
-      OnRowsChanged();
-      OnReset();
-    }
-
-    // adds a new variable to the dataset
-    public void AddVariable(string variableName, IList values) {
-      if (variableValues.ContainsKey(variableName))
-        throw new ArgumentException(string.Format("Variable {0} is already present in the dataset.", variableName));
-
-      if (values == null || values.Count == 0)
-        throw new ArgumentException("Cannot add variable with no values.");
-
-      if (!IsAllowedType(values))
-        throw new ArgumentException(string.Format("Unsupported type {0} for variable {1}.", GetElementType(values), variableName));
-
-      variableValues[variableName] = values;
-      variableNames.Add(variableName);
-
-      OnColumnsChanged();
-      OnColumnNamesChanged();
-      OnReset();
-    }
 
     public void RemoveVariable(string variableName) {
@@ -125,12 +157,13 @@
     }
 
-    // slow, avoid using this
-    public void RemoveRow(int row) {
-      foreach (var list in variableValues.Values)
-        list.RemoveAt(row);
-      rows--;
+    public void ClearValues() {
+      foreach (var list in variableValues.Values) {
+        list.Clear();
+      }
+      Rows = 0;
       OnRowsChanged();
       OnReset();
     }
+
 
     public void SetVariableValue(object value, string variableName, int row) {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/AutoCorrelationCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/AutoCorrelationCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/AutoCorrelationCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/ClassificationPerformanceMeasuresCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/ClassificationPerformanceMeasuresCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/ClassificationPerformanceMeasuresCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/ConfusionMatrixCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/ConfusionMatrixCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/ConfusionMatrixCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/HoeffdingsDependenceCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/HoeffdingsDependenceCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/HoeffdingsDependenceCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/PearsonsRDependenceCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/PearsonsRDependenceCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/PearsonsRDependenceCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/PearsonsRSquaredDependenceCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/PearsonsRSquaredDependenceCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/PearsonsRSquaredDependenceCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/SpearmansRankCorrelationCoefficientCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/SpearmansRankCorrelationCoefficientCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/SpearmansRankCorrelationCoefficientCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/FOneScoreCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/FOneScoreCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/FOneScoreCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/MatthewsCorrelationCoefficientCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/MatthewsCorrelationCoefficientCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/MatthewsCorrelationCoefficientCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/NormalizedGiniCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/NormalizedGiniCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/NormalizedGiniCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -23,5 +23,4 @@
 using System.Collections.Generic;
 using System.Linq;
-using HeuristicLab.Common;
 
 namespace HeuristicLab.Problems.DataAnalysis {
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineAccuracyCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineAccuracyCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineAccuracyCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineBoundedMeanSquaredErrorCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineBoundedMeanSquaredErrorCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineBoundedMeanSquaredErrorCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineCovarianceCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineCovarianceCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineCovarianceCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineDirectionalSymmetryCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineDirectionalSymmetryCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineDirectionalSymmetryCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineLinearScalingParameterCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineLinearScalingParameterCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineLinearScalingParameterCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMaxAbsoluteErrorCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMaxAbsoluteErrorCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMaxAbsoluteErrorCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsoluteErrorCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsoluteErrorCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsoluteErrorCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsolutePercentageErrorCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsolutePercentageErrorCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsolutePercentageErrorCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAndVarianceCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAndVarianceCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAndVarianceCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanErrorCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanErrorCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanErrorCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanSquaredErrorCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanSquaredErrorCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanSquaredErrorCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineNormalizedMeanSquaredErrorCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineNormalizedMeanSquaredErrorCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineNormalizedMeanSquaredErrorCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlinePearsonsRCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlinePearsonsRCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlinePearsonsRCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlinePearsonsRSquaredCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlinePearsonsRSquaredCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlinePearsonsRSquaredCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineWeightedClassificationMeanSquaredErrorCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineWeightedClassificationMeanSquaredErrorCalculator.cs	(revision 17980)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineWeightedClassificationMeanSquaredErrorCalculator.cs	(revision 17980)
@@ -0,0 +1,115 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class OnlineWeightedClassificationMeanSquaredErrorCalculator : IOnlineCalculator {
+
+    private double sse;
+    private int n;
+    public double WeightedResidualsMeanSquaredError {
+      get {
+        return n > 0 ? sse / n : 0.0;
+      }
+    }
+
+    public double PositiveClassValue { get; private set; }
+    public double ClassValuesMax { get; private set; }
+    public double ClassValuesMin { get; private set; }
+    public double DefiniteResidualsWeight { get; private set; }
+    public double PositiveClassResidualsWeight { get; private set; }
+    public double NegativeClassesResidualsWeight { get; private set; }
+
+    public OnlineWeightedClassificationMeanSquaredErrorCalculator(double positiveClassValue, double classValuesMax, double classValuesMin,
+                                                                double definiteResidualsWeight, double positiveClassResidualsWeight, double negativeClassesResidualsWeight) {
+      PositiveClassValue = positiveClassValue;
+      ClassValuesMax = classValuesMax;
+      ClassValuesMin = classValuesMin;
+      DefiniteResidualsWeight = definiteResidualsWeight;
+      PositiveClassResidualsWeight = positiveClassResidualsWeight;
+      NegativeClassesResidualsWeight = negativeClassesResidualsWeight;
+      Reset();
+    }
+
+    #region IOnlineCalculator Members
+    private OnlineCalculatorError errorState;
+    public OnlineCalculatorError ErrorState {
+      get { return errorState; }
+    }
+    public double Value {
+      get { return WeightedResidualsMeanSquaredError; }
+    }
+    public void Reset() {
+      n = 0;
+      sse = 0.0;
+      errorState = OnlineCalculatorError.InsufficientElementsAdded;
+    }
+
+    public void Add(double original, double estimated) {
+      if (double.IsNaN(estimated) || double.IsInfinity(estimated) ||
+          double.IsNaN(original) || double.IsInfinity(original) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
+        errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+      } else {
+        double error = estimated - original;
+        double weight;
+        //apply weight
+        if (estimated > ClassValuesMax || estimated < ClassValuesMin) {
+          weight = DefiniteResidualsWeight;
+        } else if (original.IsAlmost(PositiveClassValue)) {
+          weight = PositiveClassResidualsWeight;
+        } else {
+          weight = NegativeClassesResidualsWeight;
+        }
+        sse += error * error * weight;
+        n++;
+        errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded);        // n >= 1
+      }
+    }
+    #endregion
+
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, double positiveClassValue, double classValuesMax, double classValuesMin,
+                                                                double definiteResidualsWeight, double positiveClassResidualsWeight, double negativeClassesResidualsWeight, out OnlineCalculatorError errorState) {
+      IEnumerator<double> originalEnumerator = originalValues.GetEnumerator();
+      IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator();
+      OnlineWeightedClassificationMeanSquaredErrorCalculator calculator = new OnlineWeightedClassificationMeanSquaredErrorCalculator(positiveClassValue, classValuesMax, classValuesMin, definiteResidualsWeight, positiveClassResidualsWeight, negativeClassesResidualsWeight);
+
+      // always move forward both enumerators (do not use short-circuit evaluation!)
+      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
+        double original = originalEnumerator.Current;
+        double estimated = estimatedEnumerator.Current;
+        calculator.Add(original, estimated);
+        if (calculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+
+      // check if both enumerators are at the end to make sure both enumerations have the same length
+      if (calculator.ErrorState == OnlineCalculatorError.None &&
+         (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in originalValues and estimatedValues enumerations doesn't match.");
+      } else {
+        errorState = calculator.ErrorState;
+        return calculator.WeightedResidualsMeanSquaredError;
+      }
+    }
+  }
+}
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineWeightedDirectionalSymmetryCalculator.cs
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineWeightedDirectionalSymmetryCalculator.cs	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineWeightedDirectionalSymmetryCalculator.cs	(revision 17980)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Plugin.cs.frame
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Plugin.cs.frame	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Plugin.cs.frame	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -26,5 +26,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  [Plugin("HeuristicLab.Problems.DataAnalysis","Provides base classes for data analysis tasks.", "3.4.11.$WCREV$")]
+  [Plugin("HeuristicLab.Problems.DataAnalysis","Provides base classes for data analysis tasks.", "3.4.12.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.DataAnalysis-3.4.dll", PluginFileType.Assembly)]
   [PluginDependency("HeuristicLab.ALGLIB","3.7.0")]
@@ -36,5 +36,5 @@
   [PluginDependency("HeuristicLab.Optimization","3.3")]
   [PluginDependency("HeuristicLab.Parameters", "3.3")]
-  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  [PluginDependency("HeuristicLab.Attic", "1.0")]
   [PluginDependency("HeuristicLab.Problems.Instances", "3.3")]  
   [PluginDependency("HeuristicLab.Random", "3.3")]
Index: branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Properties/AssemblyInfo.cs.frame
===================================================================
--- branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Properties/AssemblyInfo.cs.frame	(revision 15868)
+++ branches/2719_HeuristicLab.DatastreamAnalysis/HeuristicLab.Problems.DataAnalysis/3.4/Properties/AssemblyInfo.cs.frame	(revision 17980)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -31,5 +31,5 @@
 [assembly: AssemblyCompany("")]
 [assembly: AssemblyProduct("HeuristicLab")]
-[assembly: AssemblyCopyright("(c) 2002-2018 HEAL")]
+[assembly: AssemblyCopyright("(c) HEAL")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
@@ -53,3 +53,3 @@
 // by using the '*' as shown below:
 [assembly: AssemblyVersion("3.4.0.0")]
-[assembly: AssemblyFileVersion("3.4.11.$WCREV$")]
+[assembly: AssemblyFileVersion("3.4.12.$WCREV$")]
