Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/Allele.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/Allele.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/Allele.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequency.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequency.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequency.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyAnalyzer.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyAnalyzer.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyAnalyzer.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyCollection.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyCollection.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyCollection.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyCollectionHistory.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyCollectionHistory.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyCollectionHistory.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/BestScopeSolutionAnalyzer.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/BestScopeSolutionAnalyzer.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/BestScopeSolutionAnalyzer.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/DataRow.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/DataRow.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/DataRow.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/DataRowVisualProperties.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/DataRowVisualProperties.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/DataRowVisualProperties.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -123,24 +123,5 @@
       }
     }
-    private int bins;
-    public int Bins {
-      get { return bins; }
-      set {
-        if (bins != value) {
-          bins = value;
-          OnPropertyChanged("Bins");
-        }
-      }
-    }
-    private bool exactBins;
-    public bool ExactBins {
-      get { return exactBins; }
-      set {
-        if (exactBins != value) {
-          exactBins = value;
-          OnPropertyChanged("ExactBins");
-        }
-      }
-    }
+
     private double scaleFactor;
     public double ScaleFactor {
@@ -215,14 +196,4 @@
       set { lineWidth = value; }
     }
-    [Storable(Name = "Bins")]
-    private int StorableBins {
-      get { return bins; }
-      set { bins = value; }
-    }
-    [Storable(Name = "ExactBins")]
-    private bool StorableExactBins {
-      get { return exactBins; }
-      set { exactBins = value; }
-    }
     [Storable(Name = "ScaleFactor")]
     private double StorableScaleFactor {
@@ -240,4 +211,23 @@
       set { displayName = value; }
     }
+    #endregion
+
+    #region Histogram Properties - Backwards Compatability
+    internal enum DataRowHistogramAggregation {
+      Overlapping,
+      SideBySide,
+      Stacked
+    }
+
+    internal int? Bins { get; private set; }
+    internal bool? ExactBins { get; private set; }
+    internal DataRowHistogramAggregation? Aggregation { get; private set; }
+
+    [Storable(Name = "Bins", AllowOneWay = true)]
+    private int StorableBins { set { Bins = value; } }
+    [Storable(Name = "ExactBins", AllowOneWay = true)]
+    private bool StorableExactBins { set { ExactBins = value; } }
+    [Storable(Name = "Aggregation", AllowOneWay = true)]
+    private DataRowHistogramAggregation StorableAggregation { set { Aggregation = value; } }
     #endregion
 
@@ -253,6 +243,4 @@
       this.startIndexZero = original.startIndexZero;
       this.lineWidth = original.lineWidth;
-      this.bins = original.bins;
-      this.exactBins = original.exactBins;
       this.scaleFactor = original.scaleFactor;
       this.displayName = original.displayName;
@@ -267,6 +255,4 @@
       startIndexZero = false;
       lineWidth = 1;
-      bins = 10;
-      exactBins = false;
       scaleFactor = 1.0;
       displayName = String.Empty;
@@ -294,11 +280,8 @@
       if (secondXAxis == default(bool)
         && lineStyle == default(DataRowLineStyle)
-        && lineWidth == default(int) && bins == default(int) && exactBins == default(bool)
         && displayName == default(string)) {
         secondXAxis = false;
         lineStyle = DataRowLineStyle.Solid;
         lineWidth = 1;
-        bins = 10;
-        exactBins = false;
         displayName = String.Empty;
       }
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/DataTable.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/DataTable.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/DataTable.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -112,4 +112,19 @@
       if (VisualProperties == null) VisualProperties = new DataTableVisualProperties(name);
       if (VisualProperties.Title == null) VisualProperties.Title = name;
+
+      #region Backwards Compatability Histogram Visual Properties 
+      var rowProperties = Rows.Select(r => r.VisualProperties).ToList();
+      if (rowProperties.Any(r => r.Bins.HasValue))
+        VisualProperties.HistogramBins = rowProperties.Where(r => r.Bins.HasValue).Max(r => r.Bins.Value);
+      if (rowProperties.Any(r => r.ExactBins.HasValue))
+        VisualProperties.HistogramExactBins = rowProperties.Where(r => r.ExactBins.HasValue).Any(r => r.ExactBins.Value);
+      if (rowProperties.Any(r => r.Aggregation.HasValue)) {
+        var maxOccurrence = rowProperties
+          .Where(r => r.Aggregation.HasValue).Select(r => r.Aggregation.Value)
+          .GroupBy(x => x).OrderByDescending(x => x.Count())
+          .First().Key;
+        VisualProperties.HistogramAggregation = (DataTableVisualProperties.DataTableHistogramAggregation)maxOccurrence;
+      }
+      #endregion
     }
     #endregion
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/DataTableHistory.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/DataTableHistory.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/DataTableHistory.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/DataTableValuesCollector.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/DataTableValuesCollector.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/DataTableValuesCollector.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/DataTableVisualProperties.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/DataTableVisualProperties.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/DataTableVisualProperties.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -20,8 +20,9 @@
 #endregion
 
+using System;
+using System.ComponentModel;
+using System.Drawing;
 using HeuristicLab.Common;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using System.ComponentModel;
-using System.Drawing;
 
 namespace HeuristicLab.Analysis {
@@ -31,4 +32,13 @@
   [StorableClass]
   public class DataTableVisualProperties : DeepCloneable, INotifyPropertyChanged {
+
+    #region Histogram Aggregation
+    public enum DataTableHistogramAggregation {
+      Overlapping,
+      SideBySide,
+      Stacked
+    }
+    #endregion
+
     private Font titleFont;
     public Font TitleFont {
@@ -352,4 +362,37 @@
         secondYAxisLogScale = value;
         OnPropertyChanged("SecondYAxisLogScale");
+      }
+    }
+
+    private int histogramBins;
+    public int HistogramBins {
+      get { return histogramBins; }
+      set {
+        if (histogramBins != value) {
+          histogramBins = value;
+          OnPropertyChanged("HistogramBins");
+        }
+      }
+    }
+
+    private bool histogramExactBins;
+    public bool HistogramExactBins {
+      get { return histogramExactBins; }
+      set {
+        if (histogramExactBins != value) {
+          histogramExactBins = value;
+          OnPropertyChanged("HistogramExactBins");
+        }
+      }
+    }
+
+    private DataTableHistogramAggregation histogramAggregation;
+    public DataTableHistogramAggregation HistogramAggregation {
+      get { return histogramAggregation; }
+      set {
+        if (histogramAggregation != value) {
+          histogramAggregation = value;
+          OnPropertyChanged("HistogramAggregation");
+        }
       }
     }
@@ -500,4 +543,19 @@
       get { return secondYAxisLogScale; }
       set { secondYAxisLogScale = value; }
+    }
+    [Storable(Name = "HistogramBins", DefaultValue = 10)]
+    private int StorableHistogramBins {
+      get { return histogramBins; }
+      set { histogramBins = value; }
+    }
+    [Storable(Name = "HistogramExactBins", DefaultValue = false)]
+    private bool StorableHistogramExactBins {
+      get { return histogramExactBins; }
+      set { histogramExactBins = value; }
+    }
+    [Storable(Name = "HistogramAggregation", DefaultValue = DataTableHistogramAggregation.Overlapping)]
+    private DataTableHistogramAggregation StorableHistogramAggregation {
+      get { return histogramAggregation; }
+      set { histogramAggregation = value; }
     }
     #endregion
@@ -536,4 +594,7 @@
       this.yAxisLogScale = original.yAxisLogScale;
       this.secondYAxisLogScale = original.secondYAxisLogScale;
+      this.histogramBins = original.histogramBins;
+      this.histogramExactBins = original.histogramExactBins;
+      this.histogramAggregation = original.histogramAggregation;
     }
     public DataTableVisualProperties() {
@@ -565,4 +626,7 @@
       this.yAxisLogScale = false;
       this.secondYAxisLogScale = false;
+      histogramBins = 10;
+      histogramExactBins = false;
+      histogramAggregation = DataTableHistogramAggregation.Overlapping;
     }
     public DataTableVisualProperties(string title)
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/GanttData.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/GanttData.cs	(revision 15973)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/GanttData.cs	(revision 15973)
@@ -0,0 +1,188 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  [Item("Gantt Data", "Data of a Gantt visualization")]
+  [StorableClass]
+  public class GanttData : NamedItem {
+
+    [Storable]
+    private NamedItemCollection<GanttRow> rows;
+    public NamedItemCollection<GanttRow> Rows { get { return rows; } }
+
+    [Storable]
+    private ObservableDictionary<string, Color> categoryColors;
+    public ObservableDictionary<string, Color> CategoryColors { get { return categoryColors; } }
+
+    [StorableConstructor]
+    protected GanttData(bool deserializing) : base(deserializing) {}
+    protected GanttData(GanttData original, Cloner cloner)
+      : base(original, cloner) {
+      rows = cloner.Clone(original.rows);
+      categoryColors = new ObservableDictionary<string, Color>(original.categoryColors);
+    }
+    public GanttData() : this("Gantt Data", "Data of a Gantt visualization") { }
+    public GanttData(string name) : this(name, string.Empty) { }
+    public GanttData(string name, string description) : base(name, description) {
+      rows = new NamedItemCollection<GanttRow>();
+      categoryColors = new ObservableDictionary<string, Color>();
+    }
+    public GanttData(IEnumerable<GanttRow> rows) : this("Gantt Data", rows) { }
+    public GanttData(string name, IEnumerable<GanttRow> rows) : this(name, string.Empty, rows) { }
+    public GanttData(string name, string description, IEnumerable<GanttRow> rows) : base(name, description) {
+      this.rows = new NamedItemCollection<GanttRow>(rows);
+      categoryColors = new ObservableDictionary<string, Color>();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GanttData(this, cloner);
+    }
+  }
+
+  [Item("Gantt Row", "Row of a Gantt chart")]
+  [StorableClass]
+  public class GanttRow : NamedItem {
+    [Storable]
+    private ItemList<GanttItem> items;
+    public ItemList<GanttItem> Items { get { return items; } }
+
+    [StorableConstructor]
+    protected GanttRow(bool deserializing) : base(deserializing) {}
+    protected GanttRow(GanttRow original, Cloner cloner)
+      : base(original, cloner) {
+      items = cloner.Clone(original.items);
+    }
+    public GanttRow() : this("Gantt Row", "Row of a Gantt chart") { }
+    public GanttRow(string name) : this(name, string.Empty) { }
+    public GanttRow(string name, string description) : base(name, description) {
+      items = new ItemList<GanttItem>();
+    }
+    public GanttRow(IEnumerable<GanttItem> items) : this("Gantt Row", items) { }
+    public GanttRow(string name, IEnumerable<GanttItem> items) : this(name, string.Empty, items) { }
+    public GanttRow(string name, string description, IEnumerable<GanttItem> items) : base(name, description) {
+      this.items = new ItemList<GanttItem>(items);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GanttRow(this, cloner);
+    }
+  }
+
+  [Item("Gantt Item", "Item of a Gantt chart row")]
+  [StorableClass]
+  public class GanttItem : Item, INotifyPropertyChanged {
+
+    [Storable]
+    private DateTime startDate;
+    public DateTime StartDate {
+      get { return startDate; }
+      set {
+        if (startDate == value) return;
+        startDate = value;
+        OnPropertyChanged("StartDate");
+      }
+    }
+
+    [Storable]
+    private DateTime endDate;
+    public DateTime EndDate {
+      get { return endDate; }
+      set {
+        if (endDate == value) return;
+        endDate = value;
+        OnPropertyChanged("EndDate");
+      }
+    }
+
+    [Storable]
+    private string toolTip;
+    public string ToolTip {
+      get { return toolTip; }
+      set {
+        if (toolTip == value) return;
+        toolTip = value;
+        OnPropertyChanged("ToolTip");
+      }
+    }
+
+    [Storable]
+    private string category;
+    public string Category {
+      get { return category; }
+      set {
+        if (category == value) return;
+        category = value;
+        OnPropertyChanged("Category");
+      }
+    }
+
+    [Storable]
+    private bool showLabel;
+    public bool ShowLabel {
+      get { return showLabel; }
+      set {
+        if (showLabel == value) return;
+        showLabel = value;
+        OnPropertyChanged("ShowLabel");
+      }
+    }
+
+    [StorableConstructor]
+    protected GanttItem(bool deserializing) : base(deserializing) { }
+    protected GanttItem(GanttItem original, Cloner cloner)
+      : base(original, cloner) {
+      startDate = original.startDate;
+      endDate = original.endDate;
+      toolTip = original.toolTip;
+      category = original.category;
+      showLabel = original.showLabel;
+    }
+    public GanttItem() : this(DateTime.Now, DateTime.Now) { }
+    public GanttItem(DateTime start, DateTime end) {
+      startDate = start;
+      endDate = end;
+      toolTip = string.Empty;
+      category = string.Empty;
+      showLabel = false;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GanttItem(this, cloner);
+    }
+
+    public event PropertyChangedEventHandler PropertyChanged;
+    protected virtual void OnPropertyChanged(string propertyName) {
+      var handler = PropertyChanged;
+      if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
+    }
+  }
+}
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/HeatMap.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/HeatMap.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/HeatMap.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/HeatMapHistory.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/HeatMapHistory.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/HeatMapHistory.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/IndexedDataRow.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/IndexedDataRow.cs	(revision 15973)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/IndexedDataRow.cs	(revision 15973)
@@ -0,0 +1,112 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+
+namespace HeuristicLab.Analysis {
+  [Item("IndexedDataRow", "A data row that contains a series of points.")]
+  [StorableClass]
+  public class IndexedDataRow<T> : 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<T, double>> values;
+    public ObservableList<Tuple<T, double>> Values {
+      get { return values; }
+    }
+
+    #region Persistence Properties
+    [Storable(Name = "visualProperties")]
+    private DataRowVisualProperties StorableVisualProperties {
+      get { return visualProperties; }
+      set { visualProperties = value; }
+    }
+    [Storable(Name = "values")]
+    private IEnumerable<Tuple<T, double>> StorableValues {
+      get { return values; }
+      set { values = new ObservableList<Tuple<T, double>>(value); }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected IndexedDataRow(bool deserializing) : base(deserializing) { }
+    protected IndexedDataRow(IndexedDataRow<T> original, Cloner cloner)
+      : base(original, cloner) {
+      values = new ObservableList<Tuple<T, double>>(original.values.Select(x => Tuple.Create<T, double>(x.Item1, x.Item2)).ToList());
+      VisualProperties = cloner.Clone(original.visualProperties);
+    }
+    public IndexedDataRow() {
+      values = new ObservableList<Tuple<T, double>>();
+      VisualProperties = new DataRowVisualProperties();
+    }
+    public IndexedDataRow(string name)
+      : base(name) {
+      values = new ObservableList<Tuple<T, double>>();
+      VisualProperties = new DataRowVisualProperties(name);
+    }
+    public IndexedDataRow(string name, string description)
+      : base(name, description) {
+      values = new ObservableList<Tuple<T, double>>();
+      VisualProperties = new DataRowVisualProperties(name);
+    }
+    public IndexedDataRow(string name, string description, IEnumerable<Tuple<T, double>> values)
+      : base(name, description) {
+      this.values = new ObservableList<Tuple<T, double>>(values);
+      VisualProperties = new DataRowVisualProperties(name);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new IndexedDataRow<T>(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/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/IndexedDataTable.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/IndexedDataTable.cs	(revision 15973)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/IndexedDataTable.cs	(revision 15973)
@@ -0,0 +1,279 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  [Item("IndexedDataTable", "A data table where the points are also given with a certain index.")]
+  [StorableClass]
+  public class IndexedDataTable<T> : NamedItem, IStringConvertibleMatrix {
+    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<IndexedDataRow<T>> rows;
+    public NamedItemCollection<IndexedDataRow<T>> Rows {
+      get { return rows; }
+    }
+
+    #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<IndexedDataRow<T>> StorableRows {
+      get { return rows; }
+      set { rows = new NamedItemCollection<IndexedDataRow<T>>(value); }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected IndexedDataTable(bool deserializing) : base(deserializing) { }
+    protected IndexedDataTable(IndexedDataTable<T> original, Cloner cloner)
+      : base(original, cloner) {
+      VisualProperties = (DataTableVisualProperties)cloner.Clone(original.visualProperties);
+      rows = cloner.Clone(original.rows);
+      this.RegisterRowsEvents();
+    }
+    public IndexedDataTable()
+      : base() {
+      VisualProperties = new DataTableVisualProperties();
+      rows = new NamedItemCollection<IndexedDataRow<T>>();
+      this.RegisterRowsEvents();
+    }
+    public IndexedDataTable(string name)
+      : base(name) {
+      VisualProperties = new DataTableVisualProperties();
+      rows = new NamedItemCollection<IndexedDataRow<T>>();
+      this.RegisterRowsEvents();
+    }
+    public IndexedDataTable(string name, string description)
+      : base(name, description) {
+      VisualProperties = new DataTableVisualProperties();
+      rows = new NamedItemCollection<IndexedDataRow<T>>();
+      this.RegisterRowsEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new IndexedDataTable<T>(this, cloner);
+    }
+
+    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<IndexedDataRow<T>>(RowsOnItemsAdded);
+      rows.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(RowsOnItemsRemoved);
+      rows.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(RowsOnItemsReplaced);
+      rows.CollectionReset += new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(RowsOnCollectionReset);
+      foreach (var row in Rows) RegisterRowEvents(row);
+    }
+    protected virtual void RowsOnItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedDataRow<T>> e) {
+      foreach (var row in e.Items)
+        this.RegisterRowEvents(row);
+
+      this.OnColumnsChanged();
+      this.OnColumnNamesChanged();
+      this.OnReset();
+    }
+    protected virtual void RowsOnItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedDataRow<T>> e) {
+      foreach (var row in e.Items)
+        this.DeregisterRowEvents(row);
+
+      this.OnColumnsChanged();
+      this.OnColumnNamesChanged();
+      this.OnReset();
+    }
+    protected virtual void RowsOnItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedDataRow<T>> 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 RowsOnCollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedDataRow<T>> 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(IndexedDataRow<T> row) {
+      row.Values.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(ValuesOnItemsAdded);
+      row.Values.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(ValuesOnItemsMoved);
+      row.Values.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(ValuesOnItemsRemoved);
+      row.Values.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(ValuesOnItemsReplaced);
+      row.Values.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(ValuesOnCollectionReset);
+    }
+    private void DeregisterRowEvents(IndexedDataRow<T> row) {
+      row.Values.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(ValuesOnItemsAdded);
+      row.Values.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(ValuesOnItemsMoved);
+      row.Values.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(ValuesOnItemsRemoved);
+      row.Values.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(ValuesOnItemsReplaced);
+      row.Values.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(ValuesOnCollectionReset);
+    }
+
+    protected virtual void ValuesOnItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<T, double>>> e) {
+      this.OnReset();
+    }
+    protected virtual void ValuesOnItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<T, double>>> e) {
+      this.OnReset();
+    }
+    protected virtual void ValuesOnItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<T, double>>> e) {
+      this.OnReset();
+    }
+    protected virtual void ValuesOnItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<T, double>>> e) {
+      this.OnReset();
+    }
+    protected virtual void ValuesOnCollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<T, double>>> e) {
+      this.OnReset();
+    }
+
+    #region IStringConvertibleMatrix Members
+
+    int IStringConvertibleMatrix.Rows {
+      get { return rows.Count == 0 ? 0 : rows.Max(r => r.Values.Count); }
+      set { throw new NotSupportedException(); }
+    }
+    int IStringConvertibleMatrix.Columns {
+      get { return rows.Count * 2; }
+      set { throw new NotSupportedException(); }
+    }
+    IEnumerable<string> IStringConvertibleMatrix.ColumnNames {
+      get { return rows.Select(r => new string[] { r.Name + " Index", r.Name }).SelectMany(x => x); }
+      set { throw new NotSupportedException(); }
+    }
+    IEnumerable<string> IStringConvertibleMatrix.RowNames {
+      get { return new List<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 * 2) {
+        string columnName = ((IStringConvertibleMatrix)this).ColumnNames.ElementAt(columnIndex);
+        if (!rows.ContainsKey(columnName) && columnName.Length > " Index".Length) {
+          columnName = columnName.Substring(0, columnName.Length - " Index".Length);
+          if (rows.ContainsKey(columnName) && rowIndex < rows[columnName].Values.Count)
+            return rows[columnName].Values[rowIndex].Item1.ToString();
+          else return string.Empty;
+        } else if (rows.ContainsKey(columnName) && rowIndex < rows[columnName].Values.Count)
+          return rows[columnName].Values[rowIndex].Item2.ToString();
+      }
+      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/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlot.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlot.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlot.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotDataRow.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotDataRow.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotDataRow.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotDataRowVisualProperties.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotDataRowVisualProperties.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotDataRowVisualProperties.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -45,4 +45,14 @@
     }
     #endregion
+    #region
+    public enum ScatterPlotDataRowRegressionType {
+      None,
+      Linear,
+      Polynomial,
+      Exponential,
+      Logarithmic,
+      Power
+    }
+    #endregion
 
     private Color color;
@@ -101,4 +111,49 @@
       }
     }
+    private ScatterPlotDataRowRegressionType regressionType;
+    public ScatterPlotDataRowRegressionType RegressionType {
+      get { return regressionType; }
+      set {
+        if (regressionType != value) {
+          regressionType = value;
+          OnPropertyChanged("RegressionType");
+        }
+      }
+    }
+    private int polynomialRegressionOrder;
+    public int PolynomialRegressionOrder {
+      get { return polynomialRegressionOrder; }
+      set {
+        if (polynomialRegressionOrder != value) {
+          polynomialRegressionOrder = value;
+          OnPropertyChanged("PolynomialRegressionOrder");
+        }
+      }
+    }
+    private bool isRegressionVisibleInLegend;
+    public bool IsRegressionVisibleInLegend {
+      get { return isRegressionVisibleInLegend; }
+      set {
+        if (isRegressionVisibleInLegend != value) {
+          isRegressionVisibleInLegend = value;
+          OnPropertyChanged("IsRegressionVisibleInLegend");
+        }
+      }
+    }
+    private string regressionDisplayName;
+    public string RegressionDisplayName {
+      get { return regressionDisplayName ?? string.Empty; }
+      set {
+        if (regressionDisplayName != value) {
+          if (value == null && regressionDisplayName != string.Empty) {
+            regressionDisplayName = string.Empty;
+            OnPropertyChanged("RegressionDisplayName");
+          } else if (value != null) {
+            regressionDisplayName = value;
+            OnPropertyChanged("RegressionDisplayName");
+          }
+        }
+      }
+    }
 
     #region Persistence Properties
@@ -127,4 +182,24 @@
       get { return displayName; }
       set { displayName = value; }
+    }
+    [Storable(Name = "RegressionType")]
+    private ScatterPlotDataRowRegressionType StorableRegressionType {
+      get { return regressionType; }
+      set { regressionType = value; }
+    }
+    [Storable(Name = "PolynomialRegressionOrder", DefaultValue = 2)]
+    private int StorablePolynomialRegressionOrder {
+      get { return polynomialRegressionOrder; }
+      set { polynomialRegressionOrder = value; }
+    }
+    [Storable(Name = "IsRegressionVisibleInLegend", DefaultValue = true)]
+    private bool StorableIsRegressionVisibleInLegend {
+      get { return isRegressionVisibleInLegend; }
+      set { isRegressionVisibleInLegend = value; }
+    }
+    [Storable(Name = "RegressionDisplayName")]
+    private string StorableRegressionDisplayName {
+      get { return regressionDisplayName; }
+      set { regressionDisplayName = value; }
     }
     #endregion
@@ -139,4 +214,8 @@
       this.displayName = original.displayName;
       this.isVisibleInLegend = original.isVisibleInLegend;
+      this.regressionType = original.regressionType;
+      this.polynomialRegressionOrder = original.polynomialRegressionOrder;
+      this.isRegressionVisibleInLegend = original.isRegressionVisibleInLegend;
+      this.regressionDisplayName = original.regressionDisplayName;
     }
     public ScatterPlotDataRowVisualProperties() {
@@ -146,4 +225,8 @@
       displayName = String.Empty;
       isVisibleInLegend = true;
+      regressionType = ScatterPlotDataRowRegressionType.None;
+      polynomialRegressionOrder = 2;
+      isRegressionVisibleInLegend = true;
+      regressionDisplayName = string.Empty;
     }
     public ScatterPlotDataRowVisualProperties(string displayName)
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotHistory.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotHistory.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotHistory.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotVisualProperties.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotVisualProperties.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotVisualProperties.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 15973)
@@ -131,4 +131,7 @@
     <Compile Include="AlleleFrequencyAnalysis\AlleleFrequencyCollectionHistory.cs" />
     <Compile Include="BestScopeSolutionAnalyzer.cs" />
+    <Compile Include="DataVisualization\GanttData.cs" />
+    <Compile Include="DataVisualization\IndexedDataRow.cs" />
+    <Compile Include="DataVisualization\IndexedDataTable.cs" />
     <Compile Include="DataVisualization\ScatterPlotDataRowVisualProperties.cs" />
     <Compile Include="DataVisualization\ScatterPlotDataRow.cs" />
@@ -154,4 +157,5 @@
     <Compile Include="QualityAnalysis\BestAverageWorstQualityCalculator.cs" />
     <Compile Include="QualityAnalysis\BestQualityMemorizer.cs" />
+    <Compile Include="QualityAnalysis\ExpectedRuntimeHelper.cs" />
     <Compile Include="QualityAnalysis\QualityAnalyzer.cs" />
     <Compile Include="QualityAnalysis\QualityDifferenceCalculator.cs" />
@@ -159,4 +163,6 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="QualityAnalysis\QualityDistributionAnalyzer.cs" />
+    <Compile Include="QualityAnalysis\QualityPerClockAnalyzer.cs" />
+    <Compile Include="QualityAnalysis\QualityPerEvaluationsAnalyzer.cs" />
     <Compile Include="QualityAnalysis\ScaledQualityDifferenceAnalyzer.cs" />
     <Compile Include="Statistics\BonferroniHolm.cs" />
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/MultiAnalyzer.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/MultiAnalyzer.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/MultiAnalyzer.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/MultiObjective/ParetoFrontAnalyzer.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/MultiObjective/ParetoFrontAnalyzer.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/MultiObjective/ParetoFrontAnalyzer.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/MultiObjective/RankBasedParetoFrontAnalyzer.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/MultiObjective/RankBasedParetoFrontAnalyzer.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/MultiObjective/RankBasedParetoFrontAnalyzer.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/MultidimensionalScaling/MultidimensionalScaling.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/MultidimensionalScaling/MultidimensionalScaling.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/MultidimensionalScaling/MultidimensionalScaling.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Plugin.cs.frame
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Plugin.cs.frame	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Plugin.cs.frame	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -26,5 +26,5 @@
   /// Plugin class for HeuristicLab.Analysis plugin.
   /// </summary>
-  [Plugin("HeuristicLab.Analysis", "3.3.13.$WCREV$")]
+  [Plugin("HeuristicLab.Analysis", "3.3.15.$WCREV$")]
   [PluginFile("HeuristicLab.Analysis-3.3.dll", PluginFileType.Assembly)]
   [PluginDependency("HeuristicLab.ALGLIB", "3.7.0")]
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/PopulationDiversityAnalyzer.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/PopulationDiversityAnalyzer.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/PopulationDiversityAnalyzer.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/PopulationSimilarityAnalyzer.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/PopulationSimilarityAnalyzer.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/PopulationSimilarityAnalyzer.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/SingleObjectivePopulationDiversityAnalyzer.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/SingleObjectivePopulationDiversityAnalyzer.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/SingleObjectivePopulationDiversityAnalyzer.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Properties/AssemblyInfo.cs.frame	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Properties/AssemblyInfo.cs.frame	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -32,5 +32,5 @@
 [assembly: AssemblyCompany("")]
 [assembly: AssemblyProduct("HeuristicLab")]
-[assembly: AssemblyCopyright("(c) 2002-2015 HEAL")]
+[assembly: AssemblyCopyright("(c) 2002-2018 HEAL")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
@@ -54,3 +54,3 @@
 // by using the '*' as shown below:
 [assembly: AssemblyVersion("3.3.0.0")]
-[assembly: AssemblyFileVersion("3.3.13.$WCREV$")]
+[assembly: AssemblyFileVersion("3.3.15.$WCREV$")]
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/BestAverageWorstQualityAnalyzer.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/BestAverageWorstQualityAnalyzer.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/BestAverageWorstQualityAnalyzer.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/BestAverageWorstQualityCalculator.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/BestAverageWorstQualityCalculator.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/BestAverageWorstQualityCalculator.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/BestQualityMemorizer.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/BestQualityMemorizer.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/BestQualityMemorizer.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/ExpectedRuntimeHelper.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/ExpectedRuntimeHelper.cs	(revision 15973)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/ExpectedRuntimeHelper.cs	(revision 15973)
@@ -0,0 +1,62 @@
+﻿using HeuristicLab.Common;
+using HeuristicLab.Optimization;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+
+namespace HeuristicLab.Analysis {
+  public static class ExpectedRuntimeHelper {
+    public static ErtCalculationResult CalculateErt(IEnumerable<IEnumerable<Tuple<double, double>>> convGraphs, double target, bool maximization) {
+      var successful = new List<double>();
+      var unsuccessful = new List<double>();
+      foreach (var graph in convGraphs) {
+        var targetAchieved = false;
+        var lastEffort = double.MaxValue;
+        foreach (var v in graph) {
+          if (maximization && v.Item2 >= target || !maximization && v.Item2 <= target) {
+            successful.Add(v.Item1);
+            targetAchieved = true;
+            break;
+          }
+          lastEffort = v.Item1;
+        }
+        if (!targetAchieved) unsuccessful.Add(lastEffort);
+      }
+
+      var ert = double.PositiveInfinity;
+
+      var nRuns = successful.Count + unsuccessful.Count;
+      if (successful.Count > 0) {
+        var succAvg = successful.Average();
+        var succDev = successful.StandardDeviation() + 1e-7;
+        successful.RemoveAll(x => x < succAvg - 2 * succDev);
+        unsuccessful.RemoveAll(x => x < succAvg - 2 * succDev);
+        nRuns = successful.Count + unsuccessful.Count;
+
+        ert = successful.Average() / (successful.Count / (double)nRuns);
+      }
+      return new ErtCalculationResult(successful.Count, nRuns, ert);
+    }
+
+    public static ErtCalculationResult CalculateErt(List<IRun> runs, string indexedDataTableName, double target, bool maximization) {
+      return CalculateErt(runs.Select(r => ((IndexedDataTable<double>)r.Results[indexedDataTableName]).Rows.First().Values), target, maximization);
+    }
+  }
+
+  public struct ErtCalculationResult {
+    public readonly int SuccessfulRuns;
+    public readonly int TotalRuns;
+    public readonly double ExpectedRuntime;
+
+    public ErtCalculationResult(int successful, int total, double ert) {
+      SuccessfulRuns = successful;
+      TotalRuns = total;
+      ExpectedRuntime = ert;
+    }
+
+    public override string ToString() {
+      return ExpectedRuntime.ToString("##,0.0", CultureInfo.CurrentCulture.NumberFormat);
+    }
+  }
+}
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityAnalyzer.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityAnalyzer.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityAnalyzer.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityDifferenceCalculator.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityDifferenceCalculator.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityDifferenceCalculator.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityDistributionAnalyzer.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityDistributionAnalyzer.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityDistributionAnalyzer.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityPerClockAnalyzer.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityPerClockAnalyzer.cs	(revision 15973)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityPerClockAnalyzer.cs	(revision 15973)
@@ -0,0 +1,108 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  [Item("QualityPerClockAnalyzer", @"Creates a plot of the solution quality with respect to the elapsed wall-clock time.")]
+  [StorableClass]
+  public class QualityPerClockAnalyzer : SingleSuccessorOperator, IAnalyzer, ISingleObjectiveOperator {
+    public virtual bool EnabledByDefault {
+      get { return false; }
+    }
+
+    public ILookupParameter<DoubleValue> BestQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["BestQuality"]; }
+    }
+
+    public ILookupParameter<DateTimeValue> LastUpdateTimeParameter {
+      get { return (ILookupParameter<DateTimeValue>)Parameters["LastUpdateTime"]; }
+    }
+
+    public IResultParameter<IndexedDataTable<double>> QualityPerClockParameter {
+      get { return (IResultParameter<IndexedDataTable<double>>)Parameters["QualityPerClock"]; }
+    }
+
+    [StorableConstructor]
+    protected QualityPerClockAnalyzer(bool deserializing) : base(deserializing) { }
+    protected QualityPerClockAnalyzer(QualityPerClockAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public QualityPerClockAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleValue>("BestQuality", "The quality value that should be compared."));
+      Parameters.Add(new LookupParameter<DateTimeValue>("LastUpdateTime", "The time the analyzer was last run."));
+      Parameters.Add(new ResultParameter<IndexedDataTable<double>>("QualityPerClock", "Data table containing the first hitting graph with elapsed wall clock time (in seconds) as the x-axis."));
+      QualityPerClockParameter.DefaultValue = new IndexedDataTable<double>("Quality per Clock") {
+        VisualProperties = {
+          XAxisTitle = "Elapsed time [s]",
+          YAxisTitle = "Quality"
+        },
+        Rows = { new IndexedDataRow<double>("First-hit Graph") { VisualProperties = {
+          ChartType = DataRowVisualProperties.DataRowChartType.StepLine,
+          LineWidth = 2
+        } } }
+      };
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new QualityPerClockAnalyzer(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var bestQuality = BestQualityParameter.ActualValue.Value;
+      var dataTable = QualityPerClockParameter.ActualValue;
+      var values = dataTable.Rows["First-hit Graph"].Values;
+
+      var lastUpdateTime = LastUpdateTimeParameter.ActualValue;
+      if (lastUpdateTime == null) {
+        lastUpdateTime = new DateTimeValue(DateTime.UtcNow.AddMilliseconds(-1));
+        LastUpdateTimeParameter.ActualValue = lastUpdateTime;
+      }
+
+      var now = DateTime.UtcNow;
+      var runtimeSoFar = (now - lastUpdateTime.Value).TotalSeconds + (values.Count > 0 ? values.Last().Item1 : 0);
+      lastUpdateTime.Value = now;
+      var newEntry = Tuple.Create(runtimeSoFar, bestQuality);
+
+      if (values.Count == 0) {
+        values.Add(newEntry); // record the first data
+        values.Add(Tuple.Create(runtimeSoFar, bestQuality)); // last entry records max number of evaluations
+        return base.Apply();
+      }
+
+      var improvement = values.Last().Item2 != bestQuality;
+      if (improvement) {
+        values[values.Count - 1] = newEntry; // record the improvement
+        values.Add(Tuple.Create(runtimeSoFar, bestQuality)); // last entry records max number of evaluations
+      } else {
+        values[values.Count - 1] = Tuple.Create(runtimeSoFar, bestQuality);
+      }
+      return base.Apply();
+    }
+  }
+}
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityPerEvaluationsAnalyzer.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityPerEvaluationsAnalyzer.cs	(revision 15973)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityPerEvaluationsAnalyzer.cs	(revision 15973)
@@ -0,0 +1,113 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  [Item("QualityPerEvaluationsAnalyzer", @"Creates a plot of the solution quality with respect to the number of evaluated solutions.")]
+  [StorableClass]
+  public class QualityPerEvaluationsAnalyzer : SingleSuccessorOperator, IAnalyzer, ISingleObjectiveOperator {
+    public virtual bool EnabledByDefault {
+      get { return false; }
+    }
+
+    public ILookupParameter<DoubleValue> BestQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["BestQuality"]; }
+    }
+    public ILookupParameter<IntValue> EvaluatedSolutionsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
+    }
+    public ILookupParameter<IntValue> EvaluatedMovesParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["EvaluatedMoves"]; }
+    }
+    public IValueLookupParameter<DoubleValue> MoveCostPerSolutionParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["MoveCostPerSolution"]; }
+    }
+    public IResultParameter<IndexedDataTable<double>> QualityPerEvaluationsParameter {
+      get { return (IResultParameter<IndexedDataTable<double>>)Parameters["QualityPerEvaluations"]; }
+    }
+
+    [StorableConstructor]
+    protected QualityPerEvaluationsAnalyzer(bool deserializing) : base(deserializing) { }
+    protected QualityPerEvaluationsAnalyzer(QualityPerEvaluationsAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public QualityPerEvaluationsAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleValue>("BestQuality", "The quality value that should be compared."));
+      Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The number of evaluated solutions."));
+      Parameters.Add(new LookupParameter<IntValue>("EvaluatedMoves", "The number of evaluated moves."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("MoveCostPerSolution", "The cost to evaluate a move as a ratio to the cost of evaluating a solution.", new DoubleValue(1)));
+      Parameters.Add(new ResultParameter<IndexedDataTable<double>>("QualityPerEvaluations", "Data table containing the first hitting graph with evaluations as the x-axis."));
+      QualityPerEvaluationsParameter.DefaultValue = new IndexedDataTable<double>("Quality per Evaluations") {
+        VisualProperties = {
+          XAxisTitle = "Evaluations",
+          YAxisTitle = "Quality"
+        },
+        Rows = { new IndexedDataRow<double>("First-hit Graph") { VisualProperties = {
+          ChartType = DataRowVisualProperties.DataRowChartType.StepLine,
+          LineWidth = 2
+        } } }
+      };
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new QualityPerEvaluationsAnalyzer(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var bestQuality = BestQualityParameter.ActualValue.Value;
+      var evalSols = EvaluatedSolutionsParameter.ActualValue;
+      var evalMoves = EvaluatedMovesParameter.ActualValue;
+      var evaluations = 0.0;
+      if (evalSols != null) evaluations += evalSols.Value;
+      if (evalMoves != null) evaluations += evalMoves.Value * MoveCostPerSolutionParameter.ActualValue.Value;
+
+      if (evaluations > 0) {
+        var dataTable = QualityPerEvaluationsParameter.ActualValue;
+        var values = dataTable.Rows["First-hit Graph"].Values;
+
+        var newEntry = Tuple.Create(evaluations, bestQuality);
+
+        if (values.Count == 0) {
+          values.Add(newEntry); // record the first data
+          values.Add(Tuple.Create(evaluations, bestQuality)); // last entry records max number of evaluations
+          return base.Apply();
+        }
+
+        var improvement = values.Last().Item2 != bestQuality;
+        if (improvement) {
+          values[values.Count - 1] = newEntry; // record the improvement
+          values.Add(Tuple.Create(evaluations, bestQuality)); // last entry records max number of evaluations
+        } else {
+          values[values.Count - 1] = Tuple.Create(evaluations, bestQuality); // the last entry is updated
+        }
+      }
+      return base.Apply();
+    }
+  }
+}
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/ScaledQualityDifferenceAnalyzer.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/ScaledQualityDifferenceAnalyzer.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/QualityAnalysis/ScaledQualityDifferenceAnalyzer.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/BonferroniHolm.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/BonferroniHolm.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/BonferroniHolm.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/EnumerableStatisticsExtension.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/EnumerableStatisticsExtension.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/EnumerableStatisticsExtension.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/Fitting/ExpFitting.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/Fitting/ExpFitting.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/Fitting/ExpFitting.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/Fitting/IFitting.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/Fitting/IFitting.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/Fitting/IFitting.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/Fitting/LinearLeastSquaresFitting.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/Fitting/LinearLeastSquaresFitting.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/Fitting/LinearLeastSquaresFitting.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/Fitting/LogFitting.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/Fitting/LogFitting.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/Fitting/LogFitting.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/KernelDensityEstimator.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/KernelDensityEstimator.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/KernelDensityEstimator.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/KruskalWallisTest.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/KruskalWallisTest.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/KruskalWallisTest.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/PairwiseTest.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/PairwiseTest.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/PairwiseTest.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/SampleSizeDetermination.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/SampleSizeDetermination.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/Statistics/SampleSizeDetermination.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/ValueAnalysis/MinAverageMaxValueAnalyzer.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/ValueAnalysis/MinAverageMaxValueAnalyzer.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/ValueAnalysis/MinAverageMaxValueAnalyzer.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/ValueAnalysis/MinAverageMaxValueCalculator.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/ValueAnalysis/MinAverageMaxValueCalculator.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/ValueAnalysis/MinAverageMaxValueCalculator.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/ValueAnalysis/SingleValueAnalyzer.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/ValueAnalysis/SingleValueAnalyzer.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/ValueAnalysis/SingleValueAnalyzer.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/ValueAnalysis/ValueAnalyzer.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/ValueAnalysis/ValueAnalyzer.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Analysis/3.3/ValueAnalysis/ValueAnalyzer.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
