Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/AlleleFrequencyCollectionHistoryView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/AlleleFrequencyCollectionHistoryView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/AlleleFrequencyCollectionHistoryView.Designer.cs	(revision 12764)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Analysis.Views {
+  partial class AlleleFrequencyCollectionHistoryView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+    }
+
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/AlleleFrequencyCollectionHistoryView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/AlleleFrequencyCollectionHistoryView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/AlleleFrequencyCollectionHistoryView.cs	(revision 12764)
@@ -0,0 +1,35 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Windows.Forms;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Analysis.Views {
+  [View("AlleleFrequencyCollectionHistory View")]
+  [Content(typeof(AlleleFrequencyCollectionHistory), true)]
+  public partial class AlleleFrequencyCollectionHistoryView : MovieView<AlleleFrequencyCollection> {
+    public AlleleFrequencyCollectionHistoryView() {
+      InitializeComponent();
+      itemsGroupBox.Text = "Allele Frequencies";
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/AlleleFrequencyCollectionView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/AlleleFrequencyCollectionView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/AlleleFrequencyCollectionView.Designer.cs	(revision 12764)
@@ -0,0 +1,108 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Analysis.Views {
+  partial class AlleleFrequencyCollectionView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      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.Title title1 = new System.Windows.Forms.DataVisualization.Charting.Title();
+      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // chart
+      // 
+      this.chart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.chart.BorderlineColor = System.Drawing.Color.Black;
+      this.chart.BorderlineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;
+      chartArea1.AxisX.IntervalAutoMode = System.Windows.Forms.DataVisualization.Charting.IntervalAutoMode.VariableCount;
+      chartArea1.AxisX.LabelAutoFitStyle = ((System.Windows.Forms.DataVisualization.Charting.LabelAutoFitStyles)((System.Windows.Forms.DataVisualization.Charting.LabelAutoFitStyles.IncreaseFont | System.Windows.Forms.DataVisualization.Charting.LabelAutoFitStyles.DecreaseFont)));
+      chartArea1.AxisX.Title = "Allele Index";
+      chartArea1.AxisY.Maximum = 1D;
+      chartArea1.AxisY.Minimum = 0D;
+      chartArea1.AxisY.Title = "Relative Frequency";
+      chartArea1.AxisY2.Title = "Average Solution Quality";
+      chartArea1.CursorX.IsUserEnabled = true;
+      chartArea1.CursorX.IsUserSelectionEnabled = true;
+      chartArea1.CursorY.IsUserEnabled = true;
+      chartArea1.CursorY.IsUserSelectionEnabled = true;
+      chartArea1.Name = "Default";
+      this.chart.ChartAreas.Add(chartArea1);
+      legend1.Alignment = System.Drawing.StringAlignment.Center;
+      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend1.Name = "Default";
+      this.chart.Legends.Add(legend1);
+      this.chart.Location = new System.Drawing.Point(0, 0);
+      this.chart.Name = "chart";
+      this.chart.Size = new System.Drawing.Size(498, 359);
+      this.chart.TabIndex = 0;
+      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 = "Allele Frequencies";
+      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);
+      // 
+      // AlleleFrequencyCollectionView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.chart);
+      this.Name = "AlleleFrequencyCollectionView";
+      this.Size = new System.Drawing.Size(498, 359);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    protected HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
+
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/AlleleFrequencyCollectionView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/AlleleFrequencyCollectionView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/AlleleFrequencyCollectionView.cs	(revision 12764)
@@ -0,0 +1,182 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Analysis.Views {
+  [View("AlleleFrequencyCollection View")]
+  [Content(typeof(AlleleFrequencyCollection), true)]
+  public partial class AlleleFrequencyCollectionView : ItemView {
+    private List<Series> invisibleSeries;
+
+    public new AlleleFrequencyCollection Content {
+      get { return (AlleleFrequencyCollection)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public AlleleFrequencyCollectionView() {
+      InitializeComponent();
+      invisibleSeries = new List<Series>();
+      chart.CustomizeAllChartAreas();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        chart.Series.Clear();
+        invisibleSeries.Clear();
+      } else {
+        if (chart.Series.Count == 0) CreateSeries();
+        UpdateSeries();
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      chart.Enabled = Content != null;
+    }
+
+    protected virtual void CreateSeries() {
+      Series bestKnown = new Series("Alleles of Best Known Solution");
+      bestKnown.ChartType = SeriesChartType.Column;
+      bestKnown.XValueType = ChartValueType.String;
+      bestKnown.YValueType = ChartValueType.Double;
+      bestKnown.YAxisType = AxisType.Primary;
+      chart.Series.Add(bestKnown);
+
+      Series others = new Series("Other Alleles");
+      others.ChartType = SeriesChartType.Column;
+      others.XValueType = ChartValueType.String;
+      others.YValueType = ChartValueType.Double;
+      others.YAxisType = AxisType.Primary;
+      chart.Series.Add(others);
+      invisibleSeries.Add(others);
+
+      Series qualities = new Series("Average Solution Qualities");
+      qualities.ChartType = SeriesChartType.FastPoint;
+      qualities.XValueType = ChartValueType.String;
+      qualities.YValueType = ChartValueType.Double;
+      qualities.YAxisType = AxisType.Secondary;
+      chart.Series.Add(qualities);
+
+      Series impacts = new Series("Average Impact");
+      impacts.ChartType = SeriesChartType.FastPoint;
+      impacts.XValueType = ChartValueType.String;
+      impacts.YValueType = ChartValueType.Double;
+      impacts.YAxisType = AxisType.Secondary;
+      chart.Series.Add(impacts);
+    }
+
+    protected virtual void UpdateSeries() {
+      int index = 1;
+      Series bestKnown = chart.Series["Alleles of Best Known Solution"];
+      Series others = chart.Series["Other Alleles"];
+      Series qualities = chart.Series["Average Solution Qualities"];
+      Series impacts = chart.Series["Average Impact"];
+      bestKnown.Points.Clear();
+      others.Points.Clear();
+      qualities.Points.Clear();
+      impacts.Points.Clear();
+
+      if (!invisibleSeries.Contains(qualities) && !invisibleSeries.Contains(impacts))
+        chart.ChartAreas["Default"].AxisY2.Title = "Average Solution Quality / Average Impact";
+      else if (!invisibleSeries.Contains(qualities))
+        chart.ChartAreas["Default"].AxisY2.Title = "Average Solution Quality";
+      else if (!invisibleSeries.Contains(impacts))
+        chart.ChartAreas["Default"].AxisY2.Title = "Average Impact";
+
+      if (!invisibleSeries.Contains(bestKnown)) {
+        foreach (AlleleFrequency af in Content.Where(x => x.ContainedInBestKnownSolution).OrderBy(x => x.Id)) {
+          bestKnown.Points.Add(CreateDataPoint(index, af.Frequency, af));
+          if (!invisibleSeries.Contains(qualities)) qualities.Points.Add(CreateDataPoint(index, af.AverageSolutionQuality, af));
+          if (!invisibleSeries.Contains(impacts)) impacts.Points.Add(CreateDataPoint(index, af.AverageImpact, af));
+          index++;
+        }
+      }
+      if (!invisibleSeries.Contains(others)) {
+        foreach (AlleleFrequency af in Content.Where(x => !x.ContainedInBestKnownSolution).OrderBy(x => x.Id)) {
+          others.Points.Add(CreateDataPoint(index, af.Frequency, af));
+          if (!invisibleSeries.Contains(qualities)) qualities.Points.Add(CreateDataPoint(index, af.AverageSolutionQuality, af));
+          if (!invisibleSeries.Contains(impacts)) impacts.Points.Add(CreateDataPoint(index, af.AverageImpact, af));
+          index++;
+        }
+      }
+    }
+
+    protected virtual DataPoint CreateDataPoint(int index, double value, AlleleFrequency af) {
+      string nl = Environment.NewLine;
+      DataPoint p = new DataPoint(index, value);
+      p.ToolTip = string.Format("Id: {0}" + nl +
+                                "Relative Frequency: {1}" + nl +
+                                "Average Solution Quality: {2}" + nl +
+                                "Average Impact: {3}" + nl +
+                                "Contained in Best Known Solution: {4}" + nl +
+                                "Contained in Best Solution: {5}",
+                                af.Id, af.Frequency, af.AverageSolutionQuality, af.AverageImpact, af.ContainedInBestKnownSolution, af.ContainedInBestSolution);
+      p.IsEmpty = value == 0;
+      return p;
+    }
+
+    #region Chart Events
+    protected virtual void chart_MouseDown(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem) {
+        ToggleSeriesVisible(result.Series);
+      }
+    }
+
+    protected virtual void ToggleSeriesVisible(Series series) {
+      if (!invisibleSeries.Contains(series))
+        invisibleSeries.Add(series);
+      else
+        invisibleSeries.Remove(series);
+      UpdateSeries();
+    }
+
+    protected virtual 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;
+    }
+
+    protected virtual 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
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/AlleleFrequencyView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/AlleleFrequencyView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/AlleleFrequencyView.Designer.cs	(revision 12764)
@@ -0,0 +1,216 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Analysis.Views {
+  partial class AlleleFrequencyView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      this.toolTip = new System.Windows.Forms.ToolTip(this.components);
+      this.idLabel = new System.Windows.Forms.Label();
+      this.idTextBox = new System.Windows.Forms.TextBox();
+      this.frequencyTextBox = new System.Windows.Forms.TextBox();
+      this.averageImpactTextBox = new System.Windows.Forms.TextBox();
+      this.averageSolutionQualityTextBox = new System.Windows.Forms.TextBox();
+      this.frequencyLabel = new System.Windows.Forms.Label();
+      this.averageImpactLabel = new System.Windows.Forms.Label();
+      this.averageSolutionQualityLabel = new System.Windows.Forms.Label();
+      this.containedInBestKnownSolutionLabel = new System.Windows.Forms.Label();
+      this.containedInBestSolutionLabel = new System.Windows.Forms.Label();
+      this.containedInBestKnownSolutionCheckBox = new System.Windows.Forms.CheckBox();
+      this.containedInBestSolutionCheckBox = new System.Windows.Forms.CheckBox();
+      this.SuspendLayout();
+      // 
+      // idLabel
+      // 
+      this.idLabel.AutoSize = true;
+      this.idLabel.Location = new System.Drawing.Point(3, 3);
+      this.idLabel.Name = "idLabel";
+      this.idLabel.Size = new System.Drawing.Size(19, 13);
+      this.idLabel.TabIndex = 0;
+      this.idLabel.Text = "&Id:";
+      // 
+      // idTextBox
+      // 
+      this.idTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.idTextBox.Location = new System.Drawing.Point(179, 0);
+      this.idTextBox.Name = "idTextBox";
+      this.idTextBox.ReadOnly = true;
+      this.idTextBox.Size = new System.Drawing.Size(188, 20);
+      this.idTextBox.TabIndex = 1;
+      // 
+      // frequencyTextBox
+      // 
+      this.frequencyTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.frequencyTextBox.Location = new System.Drawing.Point(179, 26);
+      this.frequencyTextBox.Name = "frequencyTextBox";
+      this.frequencyTextBox.ReadOnly = true;
+      this.frequencyTextBox.Size = new System.Drawing.Size(188, 20);
+      this.frequencyTextBox.TabIndex = 3;
+      // 
+      // averageImpactTextBox
+      // 
+      this.averageImpactTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.averageImpactTextBox.Location = new System.Drawing.Point(179, 52);
+      this.averageImpactTextBox.Name = "averageImpactTextBox";
+      this.averageImpactTextBox.ReadOnly = true;
+      this.averageImpactTextBox.Size = new System.Drawing.Size(188, 20);
+      this.averageImpactTextBox.TabIndex = 5;
+      // 
+      // averageSolutionQualityTextBox
+      // 
+      this.averageSolutionQualityTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.averageSolutionQualityTextBox.Location = new System.Drawing.Point(179, 78);
+      this.averageSolutionQualityTextBox.Name = "averageSolutionQualityTextBox";
+      this.averageSolutionQualityTextBox.ReadOnly = true;
+      this.averageSolutionQualityTextBox.Size = new System.Drawing.Size(188, 20);
+      this.averageSolutionQualityTextBox.TabIndex = 7;
+      // 
+      // frequencyLabel
+      // 
+      this.frequencyLabel.AutoSize = true;
+      this.frequencyLabel.Location = new System.Drawing.Point(3, 29);
+      this.frequencyLabel.Name = "frequencyLabel";
+      this.frequencyLabel.Size = new System.Drawing.Size(60, 13);
+      this.frequencyLabel.TabIndex = 2;
+      this.frequencyLabel.Text = "&Frequency:";
+      // 
+      // averageImpactLabel
+      // 
+      this.averageImpactLabel.AutoSize = true;
+      this.averageImpactLabel.Location = new System.Drawing.Point(3, 55);
+      this.averageImpactLabel.Name = "averageImpactLabel";
+      this.averageImpactLabel.Size = new System.Drawing.Size(85, 13);
+      this.averageImpactLabel.TabIndex = 4;
+      this.averageImpactLabel.Text = "Average &Impact:";
+      // 
+      // averageSolutionQualityLabel
+      // 
+      this.averageSolutionQualityLabel.AutoSize = true;
+      this.averageSolutionQualityLabel.Location = new System.Drawing.Point(3, 81);
+      this.averageSolutionQualityLabel.Name = "averageSolutionQualityLabel";
+      this.averageSolutionQualityLabel.Size = new System.Drawing.Size(126, 13);
+      this.averageSolutionQualityLabel.TabIndex = 6;
+      this.averageSolutionQualityLabel.Text = "Average Solution &Quality:";
+      // 
+      // containedInBestKnownSolutionLabel
+      // 
+      this.containedInBestKnownSolutionLabel.AutoSize = true;
+      this.containedInBestKnownSolutionLabel.Location = new System.Drawing.Point(3, 104);
+      this.containedInBestKnownSolutionLabel.Name = "containedInBestKnownSolutionLabel";
+      this.containedInBestKnownSolutionLabel.Size = new System.Drawing.Size(170, 13);
+      this.containedInBestKnownSolutionLabel.TabIndex = 8;
+      this.containedInBestKnownSolutionLabel.Text = "Contained in Best &Known Solution:";
+      // 
+      // containedInBestSolutionLabel
+      // 
+      this.containedInBestSolutionLabel.AutoSize = true;
+      this.containedInBestSolutionLabel.Location = new System.Drawing.Point(3, 124);
+      this.containedInBestSolutionLabel.Name = "containedInBestSolutionLabel";
+      this.containedInBestSolutionLabel.Size = new System.Drawing.Size(134, 13);
+      this.containedInBestSolutionLabel.TabIndex = 10;
+      this.containedInBestSolutionLabel.Text = "Contained in &Best Solution:";
+      // 
+      // containedInBestKnownSolutionCheckBox
+      // 
+      this.containedInBestKnownSolutionCheckBox.AutoSize = true;
+      this.containedInBestKnownSolutionCheckBox.Enabled = false;
+      this.containedInBestKnownSolutionCheckBox.Location = new System.Drawing.Point(179, 104);
+      this.containedInBestKnownSolutionCheckBox.Name = "containedInBestKnownSolutionCheckBox";
+      this.containedInBestKnownSolutionCheckBox.Size = new System.Drawing.Size(15, 14);
+      this.containedInBestKnownSolutionCheckBox.TabIndex = 9;
+      this.containedInBestKnownSolutionCheckBox.UseVisualStyleBackColor = true;
+      // 
+      // containedInBestSolutionCheckBox
+      // 
+      this.containedInBestSolutionCheckBox.AutoSize = true;
+      this.containedInBestSolutionCheckBox.Enabled = false;
+      this.containedInBestSolutionCheckBox.Location = new System.Drawing.Point(179, 124);
+      this.containedInBestSolutionCheckBox.Name = "containedInBestSolutionCheckBox";
+      this.containedInBestSolutionCheckBox.Size = new System.Drawing.Size(15, 14);
+      this.containedInBestSolutionCheckBox.TabIndex = 11;
+      this.containedInBestSolutionCheckBox.UseVisualStyleBackColor = true;
+      // 
+      // AlleleFrequencyView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.containedInBestSolutionCheckBox);
+      this.Controls.Add(this.containedInBestKnownSolutionCheckBox);
+      this.Controls.Add(this.averageSolutionQualityTextBox);
+      this.Controls.Add(this.averageImpactTextBox);
+      this.Controls.Add(this.frequencyTextBox);
+      this.Controls.Add(this.idTextBox);
+      this.Controls.Add(this.containedInBestSolutionLabel);
+      this.Controls.Add(this.containedInBestKnownSolutionLabel);
+      this.Controls.Add(this.averageSolutionQualityLabel);
+      this.Controls.Add(this.averageImpactLabel);
+      this.Controls.Add(this.frequencyLabel);
+      this.Controls.Add(this.idLabel);
+      this.Name = "AlleleFrequencyView";
+      this.Size = new System.Drawing.Size(367, 151);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    protected System.Windows.Forms.ToolTip toolTip;
+    protected System.Windows.Forms.Label idLabel;
+    protected System.Windows.Forms.TextBox idTextBox;
+    protected System.Windows.Forms.TextBox frequencyTextBox;
+    protected System.Windows.Forms.TextBox averageImpactTextBox;
+    protected System.Windows.Forms.TextBox averageSolutionQualityTextBox;
+    protected System.Windows.Forms.Label frequencyLabel;
+    protected System.Windows.Forms.Label averageImpactLabel;
+    protected System.Windows.Forms.Label averageSolutionQualityLabel;
+    protected System.Windows.Forms.Label containedInBestKnownSolutionLabel;
+    protected System.Windows.Forms.Label containedInBestSolutionLabel;
+    protected System.Windows.Forms.CheckBox containedInBestKnownSolutionCheckBox;
+    protected System.Windows.Forms.CheckBox containedInBestSolutionCheckBox;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/AlleleFrequencyView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/AlleleFrequencyView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/AlleleFrequencyView.cs	(revision 12764)
@@ -0,0 +1,66 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Windows.Forms;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Analysis.Views {
+  [View("AlleleFrequency View")]
+  [Content(typeof(AlleleFrequency), true)]
+  public partial class AlleleFrequencyView : ItemView {
+    public new AlleleFrequency Content {
+      get { return (AlleleFrequency)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public AlleleFrequencyView() {
+      InitializeComponent();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        idTextBox.Text = string.Empty;
+        frequencyTextBox.Text = string.Empty;
+        averageImpactTextBox.Text = string.Empty;
+        averageSolutionQualityTextBox.Text = string.Empty;
+        containedInBestKnownSolutionCheckBox.Checked = false;
+        containedInBestSolutionCheckBox.Checked = false;
+      } else {
+        idTextBox.Text = Content.Id;
+        frequencyTextBox.Text = Content.Frequency.ToString();
+        averageImpactTextBox.Text = Content.AverageImpact.ToString();
+        averageSolutionQualityTextBox.Text = Content.AverageSolutionQuality.ToString();
+        containedInBestKnownSolutionCheckBox.Checked = Content.ContainedInBestKnownSolution;
+        containedInBestSolutionCheckBox.Checked = Content.ContainedInBestSolution;
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      idTextBox.Enabled = Content != null;
+      frequencyTextBox.Enabled = Content != null;
+      averageImpactTextBox.Enabled = Content != null;
+      averageSolutionQualityTextBox.Enabled = Content != null;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataRowVisualPropertiesControl.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataRowVisualPropertiesControl.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataRowVisualPropertiesControl.Designer.cs	(revision 12764)
@@ -0,0 +1,487 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Analysis.Views {
+  partial class DataRowVisualPropertiesControl {
+    /// <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.chartTypeComboBox = new System.Windows.Forms.ComboBox();
+      this.colorDialog = new System.Windows.Forms.ColorDialog();
+      this.colorButton = new System.Windows.Forms.Button();
+      this.startIndexZeroCheckBox = new System.Windows.Forms.CheckBox();
+      this.binsNumericUpDown = new System.Windows.Forms.NumericUpDown();
+      this.label1 = new System.Windows.Forms.Label();
+      this.label2 = new System.Windows.Forms.Label();
+      this.label3 = new System.Windows.Forms.Label();
+      this.commonGroupBox = new System.Windows.Forms.GroupBox();
+      this.displayNameTextBox = new System.Windows.Forms.TextBox();
+      this.axisGroupBox = new System.Windows.Forms.GroupBox();
+      this.yAxisSecondaryRadioButton = new System.Windows.Forms.RadioButton();
+      this.xAxisPrimaryRadioButton = new System.Windows.Forms.RadioButton();
+      this.yAxisPrimaryRadioButton = new System.Windows.Forms.RadioButton();
+      this.label5 = new System.Windows.Forms.Label();
+      this.xAxisSecondaryRadioButton = new System.Windows.Forms.RadioButton();
+      this.label6 = new System.Windows.Forms.Label();
+      this.label9 = new System.Windows.Forms.Label();
+      this.histoGramGroupBox = new System.Windows.Forms.GroupBox();
+      this.binsExactRadioButton = new System.Windows.Forms.RadioButton();
+      this.binsApproximatelyRadioButton = new System.Windows.Forms.RadioButton();
+      this.lineChartGroupBox = new System.Windows.Forms.GroupBox();
+      this.lineWidthNumericUpDown = new System.Windows.Forms.NumericUpDown();
+      this.label4 = new System.Windows.Forms.Label();
+      this.label7 = new System.Windows.Forms.Label();
+      this.lineStyleComboBox = new System.Windows.Forms.ComboBox();
+      this.label8 = new System.Windows.Forms.Label();
+      this.panel1 = new System.Windows.Forms.Panel();
+      this.panel2 = new System.Windows.Forms.Panel();
+      ((System.ComponentModel.ISupportInitialize)(this.binsNumericUpDown)).BeginInit();
+      this.commonGroupBox.SuspendLayout();
+      this.axisGroupBox.SuspendLayout();
+      this.histoGramGroupBox.SuspendLayout();
+      this.lineChartGroupBox.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.lineWidthNumericUpDown)).BeginInit();
+      this.panel1.SuspendLayout();
+      this.panel2.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // chartTypeComboBox
+      // 
+      this.chartTypeComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.chartTypeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.chartTypeComboBox.FormattingEnabled = true;
+      this.chartTypeComboBox.Location = new System.Drawing.Point(57, 45);
+      this.chartTypeComboBox.Name = "chartTypeComboBox";
+      this.chartTypeComboBox.Size = new System.Drawing.Size(264, 21);
+      this.chartTypeComboBox.TabIndex = 3;
+      this.chartTypeComboBox.SelectedValueChanged += new System.EventHandler(this.chartTypeComboBox_SelectedValueChanged);
+      // 
+      // colorDialog
+      // 
+      this.colorDialog.Color = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(128)))), ((int)(((byte)(255)))));
+      // 
+      // colorButton
+      // 
+      this.colorButton.BackColor = System.Drawing.SystemColors.Control;
+      this.colorButton.Location = new System.Drawing.Point(56, 72);
+      this.colorButton.Name = "colorButton";
+      this.colorButton.Size = new System.Drawing.Size(23, 23);
+      this.colorButton.TabIndex = 5;
+      this.colorButton.UseVisualStyleBackColor = false;
+      this.colorButton.Click += new System.EventHandler(this.colorButton_Click);
+      // 
+      // startIndexZeroCheckBox
+      // 
+      this.startIndexZeroCheckBox.AutoSize = true;
+      this.startIndexZeroCheckBox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
+      this.startIndexZeroCheckBox.Location = new System.Drawing.Point(81, 46);
+      this.startIndexZeroCheckBox.Name = "startIndexZeroCheckBox";
+      this.startIndexZeroCheckBox.Size = new System.Drawing.Size(15, 14);
+      this.startIndexZeroCheckBox.TabIndex = 3;
+      this.startIndexZeroCheckBox.UseVisualStyleBackColor = true;
+      this.startIndexZeroCheckBox.CheckedChanged += new System.EventHandler(this.startIndexZeroCheckBox_CheckedChanged);
+      // 
+      // binsNumericUpDown
+      // 
+      this.binsNumericUpDown.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.binsNumericUpDown.Location = new System.Drawing.Point(57, 19);
+      this.binsNumericUpDown.Minimum = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+      this.binsNumericUpDown.Name = "binsNumericUpDown";
+      this.binsNumericUpDown.Size = new System.Drawing.Size(97, 20);
+      this.binsNumericUpDown.TabIndex = 1;
+      this.binsNumericUpDown.Value = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+      this.binsNumericUpDown.ValueChanged += new System.EventHandler(this.binsNumericUpDown_ValueChanged);
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(6, 48);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(34, 13);
+      this.label1.TabIndex = 2;
+      this.label1.Text = "&Type:";
+      // 
+      // label2
+      // 
+      this.label2.AutoSize = true;
+      this.label2.Location = new System.Drawing.Point(6, 77);
+      this.label2.Name = "label2";
+      this.label2.Size = new System.Drawing.Size(34, 13);
+      this.label2.TabIndex = 4;
+      this.label2.Text = "&Color:";
+      // 
+      // label3
+      // 
+      this.label3.AutoSize = true;
+      this.label3.Location = new System.Drawing.Point(6, 21);
+      this.label3.Name = "label3";
+      this.label3.Size = new System.Drawing.Size(30, 13);
+      this.label3.TabIndex = 0;
+      this.label3.Text = "&Bins:";
+      // 
+      // commonGroupBox
+      // 
+      this.commonGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.commonGroupBox.Controls.Add(this.displayNameTextBox);
+      this.commonGroupBox.Controls.Add(this.axisGroupBox);
+      this.commonGroupBox.Controls.Add(this.colorButton);
+      this.commonGroupBox.Controls.Add(this.label9);
+      this.commonGroupBox.Controls.Add(this.label1);
+      this.commonGroupBox.Controls.Add(this.label2);
+      this.commonGroupBox.Controls.Add(this.chartTypeComboBox);
+      this.commonGroupBox.Location = new System.Drawing.Point(0, 0);
+      this.commonGroupBox.Name = "commonGroupBox";
+      this.commonGroupBox.Size = new System.Drawing.Size(327, 174);
+      this.commonGroupBox.TabIndex = 0;
+      this.commonGroupBox.TabStop = false;
+      this.commonGroupBox.Text = "Common";
+      // 
+      // displayNameTextBox
+      // 
+      this.displayNameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.displayNameTextBox.Location = new System.Drawing.Point(57, 19);
+      this.displayNameTextBox.Name = "displayNameTextBox";
+      this.displayNameTextBox.Size = new System.Drawing.Size(264, 20);
+      this.displayNameTextBox.TabIndex = 1;
+      this.displayNameTextBox.Validated += new System.EventHandler(this.displayNameTextBox_Validated);
+      // 
+      // axisGroupBox
+      // 
+      this.axisGroupBox.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.axisGroupBox.Controls.Add(this.panel2);
+      this.axisGroupBox.Controls.Add(this.panel1);
+      this.axisGroupBox.Controls.Add(this.label5);
+      this.axisGroupBox.Controls.Add(this.label6);
+      this.axisGroupBox.Location = new System.Drawing.Point(6, 101);
+      this.axisGroupBox.Name = "axisGroupBox";
+      this.axisGroupBox.Size = new System.Drawing.Size(315, 67);
+      this.axisGroupBox.TabIndex = 6;
+      this.axisGroupBox.TabStop = false;
+      this.axisGroupBox.Text = "Axes";
+      // 
+      // yAxisSecondaryRadioButton
+      // 
+      this.yAxisSecondaryRadioButton.AutoSize = true;
+      this.yAxisSecondaryRadioButton.Location = new System.Drawing.Point(65, 0);
+      this.yAxisSecondaryRadioButton.Name = "yAxisSecondaryRadioButton";
+      this.yAxisSecondaryRadioButton.Size = new System.Drawing.Size(76, 17);
+      this.yAxisSecondaryRadioButton.TabIndex = 5;
+      this.yAxisSecondaryRadioButton.TabStop = true;
+      this.yAxisSecondaryRadioButton.Text = "&Secondary";
+      this.yAxisSecondaryRadioButton.UseVisualStyleBackColor = true;
+      this.yAxisSecondaryRadioButton.CheckedChanged += new System.EventHandler(this.yAxisRadioButton_CheckedChanged);
+      // 
+      // xAxisPrimaryRadioButton
+      // 
+      this.xAxisPrimaryRadioButton.AutoSize = true;
+      this.xAxisPrimaryRadioButton.Location = new System.Drawing.Point(0, 0);
+      this.xAxisPrimaryRadioButton.Name = "xAxisPrimaryRadioButton";
+      this.xAxisPrimaryRadioButton.Size = new System.Drawing.Size(59, 17);
+      this.xAxisPrimaryRadioButton.TabIndex = 1;
+      this.xAxisPrimaryRadioButton.TabStop = true;
+      this.xAxisPrimaryRadioButton.Text = "&Primary";
+      this.xAxisPrimaryRadioButton.UseVisualStyleBackColor = true;
+      this.xAxisPrimaryRadioButton.CheckedChanged += new System.EventHandler(this.xAxisRadioButton_CheckedChanged);
+      // 
+      // yAxisPrimaryRadioButton
+      // 
+      this.yAxisPrimaryRadioButton.AutoSize = true;
+      this.yAxisPrimaryRadioButton.Location = new System.Drawing.Point(0, 0);
+      this.yAxisPrimaryRadioButton.Name = "yAxisPrimaryRadioButton";
+      this.yAxisPrimaryRadioButton.Size = new System.Drawing.Size(59, 17);
+      this.yAxisPrimaryRadioButton.TabIndex = 4;
+      this.yAxisPrimaryRadioButton.TabStop = true;
+      this.yAxisPrimaryRadioButton.Text = "&Primary";
+      this.yAxisPrimaryRadioButton.UseVisualStyleBackColor = true;
+      this.yAxisPrimaryRadioButton.CheckedChanged += new System.EventHandler(this.yAxisRadioButton_CheckedChanged);
+      // 
+      // label5
+      // 
+      this.label5.AutoSize = true;
+      this.label5.Location = new System.Drawing.Point(6, 44);
+      this.label5.Name = "label5";
+      this.label5.Size = new System.Drawing.Size(39, 13);
+      this.label5.TabIndex = 3;
+      this.label5.Text = "&Y-Axis:";
+      // 
+      // xAxisSecondaryRadioButton
+      // 
+      this.xAxisSecondaryRadioButton.AutoSize = true;
+      this.xAxisSecondaryRadioButton.Location = new System.Drawing.Point(65, 0);
+      this.xAxisSecondaryRadioButton.Name = "xAxisSecondaryRadioButton";
+      this.xAxisSecondaryRadioButton.Size = new System.Drawing.Size(76, 17);
+      this.xAxisSecondaryRadioButton.TabIndex = 2;
+      this.xAxisSecondaryRadioButton.TabStop = true;
+      this.xAxisSecondaryRadioButton.Text = "&Secondary";
+      this.xAxisSecondaryRadioButton.UseVisualStyleBackColor = true;
+      this.xAxisSecondaryRadioButton.CheckedChanged += new System.EventHandler(this.xAxisRadioButton_CheckedChanged);
+      // 
+      // label6
+      // 
+      this.label6.AutoSize = true;
+      this.label6.Location = new System.Drawing.Point(6, 21);
+      this.label6.Name = "label6";
+      this.label6.Size = new System.Drawing.Size(39, 13);
+      this.label6.TabIndex = 0;
+      this.label6.Text = "&X-Axis:";
+      // 
+      // label9
+      // 
+      this.label9.AutoSize = true;
+      this.label9.Location = new System.Drawing.Point(6, 22);
+      this.label9.Name = "label9";
+      this.label9.Size = new System.Drawing.Size(38, 13);
+      this.label9.TabIndex = 0;
+      this.label9.Text = "&Name:";
+      // 
+      // histoGramGroupBox
+      // 
+      this.histoGramGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.histoGramGroupBox.Controls.Add(this.binsExactRadioButton);
+      this.histoGramGroupBox.Controls.Add(this.binsApproximatelyRadioButton);
+      this.histoGramGroupBox.Controls.Add(this.binsNumericUpDown);
+      this.histoGramGroupBox.Controls.Add(this.label3);
+      this.histoGramGroupBox.Location = new System.Drawing.Point(0, 280);
+      this.histoGramGroupBox.Name = "histoGramGroupBox";
+      this.histoGramGroupBox.Size = new System.Drawing.Size(327, 47);
+      this.histoGramGroupBox.TabIndex = 2;
+      this.histoGramGroupBox.TabStop = false;
+      this.histoGramGroupBox.Text = "Histogram Properties";
+      // 
+      // binsExactRadioButton
+      // 
+      this.binsExactRadioButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.binsExactRadioButton.AutoSize = true;
+      this.binsExactRadioButton.Location = new System.Drawing.Point(269, 19);
+      this.binsExactRadioButton.Name = "binsExactRadioButton";
+      this.binsExactRadioButton.Size = new System.Drawing.Size(52, 17);
+      this.binsExactRadioButton.TabIndex = 3;
+      this.binsExactRadioButton.TabStop = true;
+      this.binsExactRadioButton.Text = "&Exact";
+      this.binsExactRadioButton.UseVisualStyleBackColor = true;
+      this.binsExactRadioButton.CheckedChanged += new System.EventHandler(this.binNumberRadioButton_CheckedChanged);
+      // 
+      // binsApproximatelyRadioButton
+      // 
+      this.binsApproximatelyRadioButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.binsApproximatelyRadioButton.AutoSize = true;
+      this.binsApproximatelyRadioButton.Location = new System.Drawing.Point(173, 19);
+      this.binsApproximatelyRadioButton.Name = "binsApproximatelyRadioButton";
+      this.binsApproximatelyRadioButton.Size = new System.Drawing.Size(90, 17);
+      this.binsApproximatelyRadioButton.TabIndex = 2;
+      this.binsApproximatelyRadioButton.TabStop = true;
+      this.binsApproximatelyRadioButton.Text = "&Approximately";
+      this.binsApproximatelyRadioButton.UseVisualStyleBackColor = true;
+      this.binsApproximatelyRadioButton.CheckedChanged += new System.EventHandler(this.binNumberRadioButton_CheckedChanged);
+      // 
+      // lineChartGroupBox
+      // 
+      this.lineChartGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.lineChartGroupBox.Controls.Add(this.lineWidthNumericUpDown);
+      this.lineChartGroupBox.Controls.Add(this.label4);
+      this.lineChartGroupBox.Controls.Add(this.startIndexZeroCheckBox);
+      this.lineChartGroupBox.Controls.Add(this.label7);
+      this.lineChartGroupBox.Controls.Add(this.lineStyleComboBox);
+      this.lineChartGroupBox.Controls.Add(this.label8);
+      this.lineChartGroupBox.Location = new System.Drawing.Point(0, 180);
+      this.lineChartGroupBox.Name = "lineChartGroupBox";
+      this.lineChartGroupBox.Size = new System.Drawing.Size(327, 94);
+      this.lineChartGroupBox.TabIndex = 1;
+      this.lineChartGroupBox.TabStop = false;
+      this.lineChartGroupBox.Text = "Line Properties";
+      // 
+      // lineWidthNumericUpDown
+      // 
+      this.lineWidthNumericUpDown.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.lineWidthNumericUpDown.Location = new System.Drawing.Point(82, 66);
+      this.lineWidthNumericUpDown.Minimum = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+      this.lineWidthNumericUpDown.Name = "lineWidthNumericUpDown";
+      this.lineWidthNumericUpDown.Size = new System.Drawing.Size(239, 20);
+      this.lineWidthNumericUpDown.TabIndex = 5;
+      this.lineWidthNumericUpDown.Value = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+      this.lineWidthNumericUpDown.ValueChanged += new System.EventHandler(this.lineWidthNumericUpDown_ValueChanged);
+      // 
+      // label4
+      // 
+      this.label4.AutoSize = true;
+      this.label4.Location = new System.Drawing.Point(6, 68);
+      this.label4.Name = "label4";
+      this.label4.Size = new System.Drawing.Size(38, 13);
+      this.label4.TabIndex = 4;
+      this.label4.Text = "&Width:";
+      // 
+      // label7
+      // 
+      this.label7.AutoSize = true;
+      this.label7.Location = new System.Drawing.Point(6, 46);
+      this.label7.Name = "label7";
+      this.label7.Size = new System.Drawing.Size(70, 13);
+      this.label7.TabIndex = 2;
+      this.label7.Text = "Start &Index 0:";
+      // 
+      // lineStyleComboBox
+      // 
+      this.lineStyleComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.lineStyleComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.lineStyleComboBox.FormattingEnabled = true;
+      this.lineStyleComboBox.Location = new System.Drawing.Point(82, 19);
+      this.lineStyleComboBox.Name = "lineStyleComboBox";
+      this.lineStyleComboBox.Size = new System.Drawing.Size(239, 21);
+      this.lineStyleComboBox.TabIndex = 1;
+      this.lineStyleComboBox.SelectedValueChanged += new System.EventHandler(this.lineStyleComboBox_SelectedValueChanged);
+      // 
+      // label8
+      // 
+      this.label8.AutoSize = true;
+      this.label8.Location = new System.Drawing.Point(6, 22);
+      this.label8.Name = "label8";
+      this.label8.Size = new System.Drawing.Size(33, 13);
+      this.label8.TabIndex = 0;
+      this.label8.Text = "&Style:";
+      // 
+      // panel1
+      // 
+      this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.panel1.Controls.Add(this.xAxisPrimaryRadioButton);
+      this.panel1.Controls.Add(this.xAxisSecondaryRadioButton);
+      this.panel1.Location = new System.Drawing.Point(51, 19);
+      this.panel1.Name = "panel1";
+      this.panel1.Size = new System.Drawing.Size(258, 17);
+      this.panel1.TabIndex = 6;
+      // 
+      // panel2
+      // 
+      this.panel2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.panel2.Controls.Add(this.yAxisSecondaryRadioButton);
+      this.panel2.Controls.Add(this.yAxisPrimaryRadioButton);
+      this.panel2.Location = new System.Drawing.Point(51, 42);
+      this.panel2.Name = "panel2";
+      this.panel2.Size = new System.Drawing.Size(258, 17);
+      this.panel2.TabIndex = 7;
+      // 
+      // DataRowVisualPropertiesControl
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.lineChartGroupBox);
+      this.Controls.Add(this.histoGramGroupBox);
+      this.Controls.Add(this.commonGroupBox);
+      this.Name = "DataRowVisualPropertiesControl";
+      this.Size = new System.Drawing.Size(327, 331);
+      ((System.ComponentModel.ISupportInitialize)(this.binsNumericUpDown)).EndInit();
+      this.commonGroupBox.ResumeLayout(false);
+      this.commonGroupBox.PerformLayout();
+      this.axisGroupBox.ResumeLayout(false);
+      this.axisGroupBox.PerformLayout();
+      this.histoGramGroupBox.ResumeLayout(false);
+      this.histoGramGroupBox.PerformLayout();
+      this.lineChartGroupBox.ResumeLayout(false);
+      this.lineChartGroupBox.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.lineWidthNumericUpDown)).EndInit();
+      this.panel1.ResumeLayout(false);
+      this.panel1.PerformLayout();
+      this.panel2.ResumeLayout(false);
+      this.panel2.PerformLayout();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.ComboBox chartTypeComboBox;
+    private System.Windows.Forms.ColorDialog colorDialog;
+    private System.Windows.Forms.Button colorButton;
+    private System.Windows.Forms.CheckBox startIndexZeroCheckBox;
+    private System.Windows.Forms.NumericUpDown binsNumericUpDown;
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.Label label2;
+    private System.Windows.Forms.Label label3;
+    private System.Windows.Forms.GroupBox commonGroupBox;
+    private System.Windows.Forms.GroupBox histoGramGroupBox;
+    private System.Windows.Forms.RadioButton xAxisSecondaryRadioButton;
+    private System.Windows.Forms.RadioButton yAxisSecondaryRadioButton;
+    private System.Windows.Forms.RadioButton xAxisPrimaryRadioButton;
+    private System.Windows.Forms.RadioButton yAxisPrimaryRadioButton;
+    private System.Windows.Forms.Label label6;
+    private System.Windows.Forms.GroupBox lineChartGroupBox;
+    private System.Windows.Forms.NumericUpDown lineWidthNumericUpDown;
+    private System.Windows.Forms.Label label4;
+    private System.Windows.Forms.Label label7;
+    private System.Windows.Forms.RadioButton binsExactRadioButton;
+    private System.Windows.Forms.RadioButton binsApproximatelyRadioButton;
+    private System.Windows.Forms.ComboBox lineStyleComboBox;
+    private System.Windows.Forms.Label label8;
+    private System.Windows.Forms.Label label5;
+    private System.Windows.Forms.GroupBox axisGroupBox;
+    private System.Windows.Forms.TextBox displayNameTextBox;
+    private System.Windows.Forms.Label label9;
+    private System.Windows.Forms.Panel panel2;
+    private System.Windows.Forms.Panel panel1;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataRowVisualPropertiesControl.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataRowVisualPropertiesControl.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataRowVisualPropertiesControl.cs	(revision 12764)
@@ -0,0 +1,192 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Analysis.Views {
+  [View("DataRow Visual Properties")]
+  public partial class DataRowVisualPropertiesControl : UserControl {
+    protected bool SuppressEvents { get; set; }
+
+    private DataRowVisualProperties content;
+    public DataRowVisualProperties Content {
+      get { return content; }
+      set {
+        bool changed = (value != content);
+        content = value;
+        if (changed) OnContentChanged();
+      }
+    }
+
+    public DataRowVisualPropertiesControl() {
+      InitializeComponent();
+      chartTypeComboBox.DataSource = Enum.GetValues(typeof(DataRowVisualProperties.DataRowChartType));
+      lineStyleComboBox.DataSource = Enum.GetValues(typeof(DataRowVisualProperties.DataRowLineStyle));
+      SetEnabledStateOfControls();
+    }
+
+    protected virtual void OnContentChanged() {
+      SuppressEvents = true;
+      try {
+        if (Content == null) {
+          chartTypeComboBox.SelectedIndex = -1;
+          colorButton.BackColor = SystemColors.Control;
+          colorButton.Text = "?";
+          yAxisPrimaryRadioButton.Checked = false;
+          yAxisSecondaryRadioButton.Checked = false;
+          xAxisPrimaryRadioButton.Checked = false;
+          xAxisSecondaryRadioButton.Checked = false;
+          lineStyleComboBox.SelectedIndex = -1;
+          startIndexZeroCheckBox.Checked = false;
+          lineWidthNumericUpDown.Value = 1;
+          binsNumericUpDown.Value = 1;
+          binsApproximatelyRadioButton.Checked = false;
+          binsExactRadioButton.Checked = false;
+          displayNameTextBox.Text = String.Empty;
+        } else {
+          chartTypeComboBox.SelectedItem = Content.ChartType;
+          if (Content.Color.IsEmpty) {
+            colorButton.BackColor = SystemColors.Control;
+            colorButton.Text = "?";
+          } else {
+            colorButton.BackColor = Content.Color;
+            colorButton.Text = String.Empty;
+          }
+          yAxisPrimaryRadioButton.Checked = !Content.SecondYAxis;
+          yAxisSecondaryRadioButton.Checked = Content.SecondYAxis;
+          xAxisPrimaryRadioButton.Checked = !Content.SecondXAxis;
+          xAxisSecondaryRadioButton.Checked = Content.SecondXAxis;
+          lineStyleComboBox.SelectedItem = Content.LineStyle;
+          startIndexZeroCheckBox.Checked = Content.StartIndexZero;
+          if (Content.LineWidth < lineWidthNumericUpDown.Minimum)
+            lineWidthNumericUpDown.Value = lineWidthNumericUpDown.Minimum;
+          else if (Content.LineWidth > lineWidthNumericUpDown.Maximum)
+            lineWidthNumericUpDown.Value = lineWidthNumericUpDown.Maximum;
+          else lineWidthNumericUpDown.Value = Content.LineWidth;
+          if (Content.Bins < binsNumericUpDown.Minimum)
+            binsNumericUpDown.Value = binsNumericUpDown.Minimum;
+          else if (Content.Bins > binsNumericUpDown.Maximum)
+            binsNumericUpDown.Value = binsNumericUpDown.Maximum;
+          else binsNumericUpDown.Value = Content.Bins;
+          binsApproximatelyRadioButton.Checked = !Content.ExactBins;
+          binsExactRadioButton.Checked = Content.ExactBins;
+          displayNameTextBox.Text = Content.DisplayName;
+        }
+      } finally { SuppressEvents = false; }
+      SetEnabledStateOfControls();
+    }
+
+    protected virtual void SetEnabledStateOfControls() {
+      commonGroupBox.Enabled = Content != null;
+      lineChartGroupBox.Enabled = Content != null && Content.ChartType == DataRowVisualProperties.DataRowChartType.Line;
+      histoGramGroupBox.Enabled = Content != null && Content.ChartType == DataRowVisualProperties.DataRowChartType.Histogram;
+    }
+
+    #region Event Handlers
+    private void chartTypeComboBox_SelectedValueChanged(object sender, EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        DataRowVisualProperties.DataRowChartType selected = (DataRowVisualProperties.DataRowChartType)chartTypeComboBox.SelectedValue;
+        Content.ChartType = selected;
+        if (Content.ChartType != selected) {
+          MessageBox.Show("There may be incompatibilities with other series or the data is not suited to be displayed as " + selected.ToString() + ".", "Failed to set type to " + selected.ToString());
+          SuppressEvents = true;
+          try {
+            chartTypeComboBox.SelectedItem = Content.ChartType;
+          } finally { SuppressEvents = false; }
+        }
+        SetEnabledStateOfControls();
+      }
+    }
+
+    private void colorButton_Click(object sender, EventArgs e) {
+      if (colorDialog.ShowDialog() == DialogResult.OK) {
+        Content.Color = colorDialog.Color;
+        colorButton.BackColor = Content.Color;
+        colorButton.Text = String.Empty;
+      }
+    }
+
+    private void yAxisRadioButton_CheckedChanged(object sender, EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.SecondYAxis = yAxisSecondaryRadioButton.Checked;
+        } finally { SuppressEvents = false; }
+      }
+    }
+
+    private void xAxisRadioButton_CheckedChanged(object sender, EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.SecondXAxis = xAxisSecondaryRadioButton.Checked;
+        } finally { SuppressEvents = false; }
+      }
+    }
+
+    private void lineStyleComboBox_SelectedValueChanged(object sender, EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        Content.LineStyle = (DataRowVisualProperties.DataRowLineStyle)lineStyleComboBox.SelectedValue;
+      }
+    }
+
+    private void startIndexZeroCheckBox_CheckedChanged(object sender, EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        Content.StartIndexZero = startIndexZeroCheckBox.Checked;
+      }
+    }
+
+    private void lineWidthNumericUpDown_ValueChanged(object sender, EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        Content.LineWidth = (int)lineWidthNumericUpDown.Value;
+      }
+    }
+
+    private void binsNumericUpDown_ValueChanged(object sender, EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        Content.Bins = (int)binsNumericUpDown.Value;
+      }
+    }
+
+    private void binNumberRadioButton_CheckedChanged(object sender, EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.ExactBins = binsExactRadioButton.Checked;
+        } finally { SuppressEvents = false; }
+      }
+    }
+
+    private void displayNameTextBox_Validated(object sender, EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.DisplayName = displayNameTextBox.Text;
+        } finally { SuppressEvents = false; }
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableHistoryView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableHistoryView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableHistoryView.Designer.cs	(revision 12764)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Analysis.Views {
+  partial class DataTableHistoryView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+    }
+
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableHistoryView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableHistoryView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableHistoryView.cs	(revision 12764)
@@ -0,0 +1,56 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Windows.Forms;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Analysis.Views {
+  [View("DataTableHistory View")]
+  [Content(typeof(DataTableHistory), true)]
+  public partial class DataTableHistoryView : MovieView<DataTable>, IConfigureableView {
+    public DataTableHistoryView() {
+      InitializeComponent();
+      itemsGroupBox.Text = "Data Table";
+    }
+
+    public void ShowConfiguration() {
+      DataTable current = viewHost.Content as DataTable;
+      if (current == null) return;
+      using (DataTableVisualPropertiesDialog dialog = new DataTableVisualPropertiesDialog(current)) {
+        if (dialog.ShowDialog(this) != DialogResult.OK) return;
+        HashSet<string> modifiedDisplayNames = new HashSet<string>(dialog.RowsWithModifiedDisplayNames);
+        foreach (DataTable dt in Content) {
+          if (current == dt) continue;
+          dt.VisualProperties = (DataTableVisualProperties)current.VisualProperties.Clone();
+          foreach (DataRow row in current.Rows) {
+            if (!dt.Rows.ContainsKey(row.Name)) continue;
+            string oldDisplayName = dt.Rows[row.Name].VisualProperties.DisplayName;
+            dt.Rows[row.Name].VisualProperties = (DataRowVisualProperties)row.VisualProperties.Clone();
+            if (!modifiedDisplayNames.Contains(row.Name))
+              dt.Rows[row.Name].VisualProperties.DisplayName = oldDisplayName;
+          }
+        }
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableView.Designer.cs	(revision 12764)
@@ -0,0 +1,125 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Analysis.Views {
+  partial class DataTableView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+      System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
+      System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
+      System.Windows.Forms.DataVisualization.Charting.Title title1 = new System.Windows.Forms.DataVisualization.Charting.Title();
+      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      ((System.ComponentModel.ISupportInitialize)(this.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.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);
+      // 
+      // DataTableView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      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.infoLabel, 0);
+      this.Controls.SetChildIndex(this.chart, 0);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 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;
+
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableView.cs	(revision 12764)
@@ -0,0 +1,660 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.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.Analysis.Views {
+  [View("DataTable View")]
+  [Content(typeof(DataTable), true)]
+  public partial class DataTableView : NamedItemView, IConfigureableView {
+    protected List<Series> invisibleSeries;
+    protected Dictionary<IObservableList<double>, DataRow> valuesRowsTable;
+
+    public new DataTable Content {
+      get { return (DataTable)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public DataTableView() {
+      InitializeComponent();
+      valuesRowsTable = new Dictionary<IObservableList<double>, DataRow>();
+      invisibleSeries = new List<Series>();
+      chart.CustomizeAllChartAreas();
+      chart.ChartAreas[0].CursorX.Interval = 1;
+    }
+
+    #region Event Handler Registration
+    protected override void DeregisterContentEvents() {
+      foreach (DataRow row in Content.Rows)
+        DeregisterDataRowEvents(row);
+      Content.VisualPropertiesChanged -= new EventHandler(Content_VisualPropertiesChanged);
+      Content.Rows.ItemsAdded -= new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsAdded);
+      Content.Rows.ItemsRemoved -= new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsRemoved);
+      Content.Rows.ItemsReplaced -= new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsReplaced);
+      Content.Rows.CollectionReset -= new CollectionItemsChangedEventHandler<DataRow>(Rows_CollectionReset);
+      base.DeregisterContentEvents();
+    }
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.VisualPropertiesChanged += new EventHandler(Content_VisualPropertiesChanged);
+      Content.Rows.ItemsAdded += new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsAdded);
+      Content.Rows.ItemsRemoved += new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsRemoved);
+      Content.Rows.ItemsReplaced += new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsReplaced);
+      Content.Rows.CollectionReset += new CollectionItemsChangedEventHandler<DataRow>(Rows_CollectionReset);
+    }
+
+    protected virtual void RegisterDataRowEvents(DataRow row) {
+      row.NameChanged += new EventHandler(Row_NameChanged);
+      row.VisualPropertiesChanged += new EventHandler(Row_VisualPropertiesChanged);
+      valuesRowsTable.Add(row.Values, row);
+      row.Values.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsAdded);
+      row.Values.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsRemoved);
+      row.Values.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsReplaced);
+      row.Values.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsMoved);
+      row.Values.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_CollectionReset);
+    }
+    protected virtual void DeregisterDataRowEvents(DataRow row) {
+      row.Values.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsAdded);
+      row.Values.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsRemoved);
+      row.Values.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsReplaced);
+      row.Values.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsMoved);
+      row.Values.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_CollectionReset);
+      valuesRowsTable.Remove(row.Values);
+      row.VisualPropertiesChanged -= new EventHandler(Row_VisualPropertiesChanged);
+      row.NameChanged -= new EventHandler(Row_NameChanged);
+    }
+    #endregion
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      invisibleSeries.Clear();
+      chart.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;
+        AddDataRows(Content.Rows);
+        ConfigureChartArea(chart.ChartAreas[0]);
+        RecalculateAxesScale(chart.ChartAreas[0]);
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      chart.Enabled = Content != null;
+    }
+
+    public void ShowConfiguration() {
+      if (Content != null) {
+        using (var dialog = new DataTableVisualPropertiesDialog(Content)) {
+          dialog.ShowDialog(this);
+        }
+      } else MessageBox.Show("Nothing to configure.");
+    }
+    protected virtual void AddDataRows(IEnumerable<DataRow> rows) {
+      foreach (var row in rows) {
+        RegisterDataRowEvents(row);
+        var series = new Series(row.Name);
+        if (row.VisualProperties.DisplayName.Trim() != String.Empty) series.LegendText = row.VisualProperties.DisplayName;
+        else series.LegendText = row.Name;
+        ConfigureSeries(series, row);
+        FillSeriesWithRowValues(series, row);
+        chart.Series.Add(series);
+      }
+      ConfigureChartArea(chart.ChartAreas[0]);
+      RecalculateAxesScale(chart.ChartAreas[0]);
+      UpdateYCursorInterval();
+    }
+
+    protected virtual void RemoveDataRows(IEnumerable<DataRow> rows) {
+      foreach (var row in rows) {
+        DeregisterDataRowEvents(row);
+        Series series = chart.Series[row.Name];
+        chart.Series.Remove(series);
+        if (invisibleSeries.Contains(series))
+          invisibleSeries.Remove(series);
+      }
+      RecalculateAxesScale(chart.ChartAreas[0]);
+    }
+
+    private void ConfigureSeries(Series series, DataRow row) {
+      RemoveCustomPropertyIfExists(series, "PointWidth");
+      series.BorderWidth = 1;
+      series.BorderDashStyle = ChartDashStyle.Solid;
+      series.BorderColor = Color.Empty;
+
+      if (row.VisualProperties.Color != Color.Empty)
+        series.Color = row.VisualProperties.Color;
+      else series.Color = Color.Empty;
+      series.IsVisibleInLegend = row.VisualProperties.IsVisibleInLegend;
+
+      switch (row.VisualProperties.ChartType) {
+        case DataRowVisualProperties.DataRowChartType.Line:
+          series.ChartType = SeriesChartType.FastLine;
+          series.BorderWidth = row.VisualProperties.LineWidth;
+          series.BorderDashStyle = ConvertLineStyle(row.VisualProperties.LineStyle);
+          break;
+        case DataRowVisualProperties.DataRowChartType.Bars:
+          // Bar is incompatible with anything but Bar and StackedBar*
+          if (!chart.Series.Any(x => x.ChartType != SeriesChartType.Bar && x.ChartType != SeriesChartType.StackedBar && x.ChartType != SeriesChartType.StackedBar100))
+            series.ChartType = SeriesChartType.Bar;
+          else {
+            series.ChartType = SeriesChartType.FastPoint; //default
+            row.VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Points;
+          }
+          break;
+        case DataRowVisualProperties.DataRowChartType.Columns:
+          series.ChartType = SeriesChartType.Column;
+          break;
+        case DataRowVisualProperties.DataRowChartType.Points:
+          series.ChartType = SeriesChartType.FastPoint;
+          break;
+        case DataRowVisualProperties.DataRowChartType.Histogram:
+          series.ChartType = SeriesChartType.Column;
+          series.SetCustomProperty("PointWidth", "1");
+          if (!series.Color.IsEmpty && series.Color.GetBrightness() < 0.25)
+            series.BorderColor = Color.White;
+          else series.BorderColor = Color.Black;
+          break;
+        case DataRowVisualProperties.DataRowChartType.StepLine:
+          series.ChartType = SeriesChartType.StepLine;
+          series.BorderWidth = row.VisualProperties.LineWidth;
+          series.BorderDashStyle = ConvertLineStyle(row.VisualProperties.LineStyle);
+          break;
+        default:
+          series.ChartType = SeriesChartType.FastPoint;
+          break;
+      }
+      series.YAxisType = row.VisualProperties.SecondYAxis ? AxisType.Secondary : AxisType.Primary;
+      series.XAxisType = row.VisualProperties.SecondXAxis ? AxisType.Secondary : AxisType.Primary;
+      if (row.VisualProperties.DisplayName.Trim() != String.Empty) series.LegendText = row.VisualProperties.DisplayName;
+      else series.LegendText = row.Name;
+
+      string xAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.XAxisTitle)
+                      ? "X"
+                      : Content.VisualProperties.XAxisTitle;
+      string yAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.YAxisTitle)
+                            ? "Y"
+                            : Content.VisualProperties.YAxisTitle;
+      series.ToolTip =
+        series.LegendText + Environment.NewLine +
+        xAxisTitle + " = " + "#INDEX," + Environment.NewLine +
+        yAxisTitle + " = " + "#VAL";
+    }
+
+    private void ConfigureChartArea(ChartArea area) {
+      if (Content.VisualProperties.TitleFont != null) chart.Titles[0].Font = Content.VisualProperties.TitleFont;
+      if (!Content.VisualProperties.TitleColor.IsEmpty) chart.Titles[0].ForeColor = Content.VisualProperties.TitleColor;
+      chart.Titles[0].Text = Content.VisualProperties.Title;
+
+      if (Content.VisualProperties.AxisTitleFont != null) area.AxisX.TitleFont = Content.VisualProperties.AxisTitleFont;
+      if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisX.TitleForeColor = Content.VisualProperties.AxisTitleColor;
+      area.AxisX.Title = Content.VisualProperties.XAxisTitle;
+
+      if (Content.VisualProperties.AxisTitleFont != null) area.AxisX2.TitleFont = Content.VisualProperties.AxisTitleFont;
+      if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisX2.TitleForeColor = Content.VisualProperties.AxisTitleColor;
+      area.AxisX2.Title = Content.VisualProperties.SecondXAxisTitle;
+
+      if (Content.VisualProperties.AxisTitleFont != null) area.AxisY.TitleFont = Content.VisualProperties.AxisTitleFont;
+      if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisY.TitleForeColor = Content.VisualProperties.AxisTitleColor;
+      area.AxisY.Title = Content.VisualProperties.YAxisTitle;
+
+      if (Content.VisualProperties.AxisTitleFont != null) area.AxisY2.TitleFont = Content.VisualProperties.AxisTitleFont;
+      if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisY2.TitleForeColor = Content.VisualProperties.AxisTitleColor;
+      area.AxisY2.Title = Content.VisualProperties.SecondYAxisTitle;
+
+      area.AxisX.IsLogarithmic = Content.VisualProperties.XAxisLogScale;
+      area.AxisX2.IsLogarithmic = Content.VisualProperties.SecondXAxisLogScale;
+      area.AxisY.IsLogarithmic = Content.VisualProperties.YAxisLogScale;
+      area.AxisY2.IsLogarithmic = Content.VisualProperties.SecondYAxisLogScale;
+    }
+
+    private void RecalculateAxesScale(ChartArea area) {
+      // Reset the axes bounds so that RecalculateAxesScale() will assign new bounds
+      foreach (Axis a in area.Axes) {
+        a.Minimum = double.NaN;
+        a.Maximum = double.NaN;
+      }
+      area.RecalculateAxesScale();
+      area.AxisX.IsMarginVisible = false;
+      area.AxisX2.IsMarginVisible = false;
+
+      if (!Content.VisualProperties.XAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.XAxisMinimumFixedValue)) area.AxisX.Minimum = Content.VisualProperties.XAxisMinimumFixedValue;
+      if (!Content.VisualProperties.XAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.XAxisMaximumFixedValue)) area.AxisX.Maximum = Content.VisualProperties.XAxisMaximumFixedValue;
+      if (!Content.VisualProperties.SecondXAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.SecondXAxisMinimumFixedValue)) area.AxisX2.Minimum = Content.VisualProperties.SecondXAxisMinimumFixedValue;
+      if (!Content.VisualProperties.SecondXAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.SecondXAxisMaximumFixedValue)) area.AxisX2.Maximum = Content.VisualProperties.SecondXAxisMaximumFixedValue;
+      if (!Content.VisualProperties.YAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.YAxisMinimumFixedValue)) area.AxisY.Minimum = Content.VisualProperties.YAxisMinimumFixedValue;
+      if (!Content.VisualProperties.YAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.YAxisMaximumFixedValue)) area.AxisY.Maximum = Content.VisualProperties.YAxisMaximumFixedValue;
+      if (!Content.VisualProperties.SecondYAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.SecondYAxisMinimumFixedValue)) area.AxisY2.Minimum = Content.VisualProperties.SecondYAxisMinimumFixedValue;
+      if (!Content.VisualProperties.SecondYAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.SecondYAxisMaximumFixedValue)) area.AxisY2.Maximum = Content.VisualProperties.SecondYAxisMaximumFixedValue;
+      if (area.AxisX.Minimum >= area.AxisX.Maximum) area.AxisX.Maximum = area.AxisX.Minimum + 1;
+      if (area.AxisX2.Minimum >= area.AxisX2.Maximum) area.AxisX2.Maximum = area.AxisX2.Minimum + 1;
+      if (area.AxisY.Minimum >= area.AxisY.Maximum) area.AxisY.Maximum = area.AxisY.Minimum + 1;
+      if (area.AxisY2.Minimum >= area.AxisY2.Maximum) area.AxisY2.Maximum = area.AxisY2.Minimum + 1;
+    }
+
+    protected virtual void UpdateYCursorInterval() {
+      double interestingValuesRange = (
+        from series in chart.Series
+        where series.Enabled
+        let values = (from point in series.Points
+                      where !point.IsEmpty
+                      select point.YValues[0]).DefaultIfEmpty(1.0)
+        let range = values.Max() - values.Min()
+        where range > 0.0
+        select range
+        ).DefaultIfEmpty(1.0).Min();
+
+      double digits = (int)Math.Log10(interestingValuesRange) - 3;
+      double yZoomInterval = Math.Pow(10, digits);
+      this.chart.ChartAreas[0].CursorY.Interval = yZoomInterval;
+    }
+
+    #region Event Handlers
+    #region Content Event Handlers
+    protected override void Content_NameChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_NameChanged), sender, e);
+      else {
+        chart.Titles[0].Text = 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
+      }
+    }
+    #endregion
+    #region Rows Event Handlers
+    private void Rows_ItemsAdded(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsAdded), sender, e);
+      else {
+        AddDataRows(e.Items);
+      }
+    }
+    private void Rows_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsRemoved), sender, e);
+      else {
+        RemoveDataRows(e.Items);
+      }
+    }
+    private void Rows_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsReplaced), sender, e);
+      else {
+        RemoveDataRows(e.OldItems);
+        AddDataRows(e.Items);
+      }
+    }
+    private void Rows_CollectionReset(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_CollectionReset), sender, e);
+      else {
+        RemoveDataRows(e.OldItems);
+        AddDataRows(e.Items);
+      }
+    }
+    #endregion
+    #region Row Event Handlers
+    private void Row_VisualPropertiesChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Row_VisualPropertiesChanged), sender, e);
+      else {
+        DataRow row = (DataRow)sender;
+        Series series = chart.Series[row.Name];
+        series.Points.Clear();
+        ConfigureSeries(series, row);
+        FillSeriesWithRowValues(series, row);
+        RecalculateAxesScale(chart.ChartAreas[0]);
+      }
+    }
+    private void Row_NameChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Row_NameChanged), sender, e);
+      else {
+        DataRow row = (DataRow)sender;
+        chart.Series[row.Name].Name = row.Name;
+      }
+    }
+    #endregion
+    #region Values Event Handlers
+    private void Values_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsAdded), sender, e);
+      else {
+        DataRow row = null;
+        valuesRowsTable.TryGetValue((IObservableList<double>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            rowSeries.Points.Clear();
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    private void Values_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsRemoved), sender, e);
+      else {
+        DataRow row = null;
+        valuesRowsTable.TryGetValue((IObservableList<double>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            rowSeries.Points.Clear();
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    private void Values_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsReplaced), sender, e);
+      else {
+        DataRow row = null;
+        valuesRowsTable.TryGetValue((IObservableList<double>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            if (row.VisualProperties.ChartType == DataRowVisualProperties.DataRowChartType.Histogram) {
+              rowSeries.Points.Clear();
+              FillSeriesWithRowValues(rowSeries, row);
+            } else {
+              foreach (IndexedItem<double> item in e.Items) {
+                if (IsInvalidValue(item.Value))
+                  rowSeries.Points[item.Index].IsEmpty = true;
+                else {
+                  rowSeries.Points[item.Index].YValues = new double[] { item.Value };
+                  rowSeries.Points[item.Index].IsEmpty = false;
+                }
+              }
+            }
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    private void Values_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsMoved), sender, e);
+      else {
+        DataRow row = null;
+        valuesRowsTable.TryGetValue((IObservableList<double>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            rowSeries.Points.Clear();
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+
+    private void Values_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_CollectionReset), sender, e);
+      else {
+        DataRow row = null;
+        valuesRowsTable.TryGetValue((IObservableList<double>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            rowSeries.Points.Clear();
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    #endregion
+    #endregion
+
+    #region Chart Event Handlers
+    private void chart_MouseDown(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem) {
+        ToggleSeriesVisible(result.Series);
+      }
+    }
+    private void chart_MouseMove(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem)
+        this.Cursor = Cursors.Hand;
+      else
+        this.Cursor = Cursors.Default;
+    }
+    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
+      foreach (LegendItem legendItem in e.LegendItems) {
+        var series = chart.Series[legendItem.SeriesName];
+        if (series != null) {
+          bool seriesIsInvisible = invisibleSeries.Contains(series);
+          foreach (LegendCell cell in legendItem.Cells) {
+            cell.ForeColor = seriesIsInvisible ? Color.Gray : Color.Black;
+          }
+        }
+      }
+    }
+    #endregion
+
+    private void ToggleSeriesVisible(Series series) {
+      if (!invisibleSeries.Contains(series)) {
+        series.Points.Clear();
+        invisibleSeries.Add(series);
+      } else {
+        invisibleSeries.Remove(series);
+        if (Content != null) {
+
+          var row = (from r in Content.Rows
+                     where r.Name == series.Name
+                     select r).Single();
+          FillSeriesWithRowValues(series, row);
+          this.chart.Legends[series.Legend].ForeColor = Color.Black;
+          RecalculateAxesScale(chart.ChartAreas[0]);
+          UpdateYCursorInterval();
+        }
+      }
+    }
+
+    private void FillSeriesWithRowValues(Series series, DataRow row) {
+      switch (row.VisualProperties.ChartType) {
+        case DataRowVisualProperties.DataRowChartType.Histogram:
+          CalculateHistogram(series, row);
+          break;
+        default: {
+            bool yLogarithmic = series.YAxisType == AxisType.Primary
+                                  ? Content.VisualProperties.YAxisLogScale
+                                  : Content.VisualProperties.SecondYAxisLogScale;
+            bool xLogarithmic = series.XAxisType == AxisType.Primary
+                                  ? Content.VisualProperties.XAxisLogScale
+                                  : Content.VisualProperties.SecondXAxisLogScale;
+            for (int i = 0; i < row.Values.Count; i++) {
+              var value = row.Values[i];
+              var point = new DataPoint();
+              point.XValue = row.VisualProperties.StartIndexZero && !xLogarithmic ? i : i + 1;
+              if (IsInvalidValue(value) || (yLogarithmic && value <= 0))
+                point.IsEmpty = true;
+              else
+                point.YValues = new double[] { value };
+              series.Points.Add(point);
+            }
+          }
+          break;
+      }
+    }
+
+    protected virtual void CalculateHistogram(Series series, DataRow row) {
+      series.Points.Clear();
+      if (!row.Values.Any()) return;
+      int bins = row.VisualProperties.Bins;
+
+      double minValue = row.Values.Min();
+      double maxValue = row.Values.Max();
+      double intervalWidth = (maxValue - minValue) / bins;
+      if (intervalWidth < 0) return;
+      if (intervalWidth == 0) {
+        series.Points.AddXY(minValue, row.Values.Count);
+        return;
+      }
+
+      if (!row.VisualProperties.ExactBins) {
+        intervalWidth = HumanRoundRange(intervalWidth);
+        minValue = Math.Floor(minValue / intervalWidth) * intervalWidth;
+        maxValue = Math.Ceiling(maxValue / intervalWidth) * intervalWidth;
+      }
+
+      double intervalCenter = intervalWidth / 2;
+
+      double min = 0.0, max = 0.0;
+      if (!Double.IsNaN(Content.VisualProperties.XAxisMinimumFixedValue) && !Content.VisualProperties.XAxisMinimumAuto)
+        min = Content.VisualProperties.XAxisMinimumFixedValue;
+      else min = minValue;
+      if (!Double.IsNaN(Content.VisualProperties.XAxisMaximumFixedValue) && !Content.VisualProperties.XAxisMaximumAuto)
+        max = Content.VisualProperties.XAxisMaximumFixedValue;
+      else max = maxValue + intervalWidth;
+
+      double axisInterval = intervalWidth / row.VisualProperties.ScaleFactor;
+
+      var area = chart.ChartAreas[0];
+      area.AxisX.Interval = axisInterval;
+
+      series.SetCustomProperty("PointWidth", "1"); // 0.8 is the default value
+
+      // get the range or intervals which define the grouping of the frequency values
+      var doubleRange = DoubleRange(min, max, intervalWidth).Skip(1).ToList();
+
+      // aggregate the row values by unique key and frequency value
+      var valueFrequencies = (from v in row.Values
+                              where !IsInvalidValue(v)
+                              orderby v
+                              group v by v into g
+                              select new Tuple<double, double>(g.First(), g.Count())).ToList();
+
+      // shift the chart to the left so the bars are placed on the intervals
+      if (valueFrequencies.First().Item1 < doubleRange.First())
+        series.Points.Add(new DataPoint(min - intervalWidth, 0));
+
+      // add data points
+      int j = 0;
+      foreach (var d in doubleRange) {
+        double sum = 0.0;
+        // sum the frequency values that fall within the same interval
+        while (j < valueFrequencies.Count && valueFrequencies[j].Item1 < d) {
+          sum += valueFrequencies[j].Item2;
+          ++j;
+        }
+        string xAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.XAxisTitle)
+                              ? "X"
+                              : Content.VisualProperties.XAxisTitle;
+        string yAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.YAxisTitle)
+                              ? "Y"
+                              : Content.VisualProperties.YAxisTitle;
+        series.Points.Add(new DataPoint(d - intervalCenter, sum) {
+          ToolTip =
+            xAxisTitle + ": [" + (d - intervalWidth) + "-" + d + ")" + Environment.NewLine +
+            yAxisTitle + ": " + sum
+        });
+      }
+    }
+
+    #region Helpers
+    public static IEnumerable<double> DoubleRange(double min, double max, double step) {
+      double i;
+      for (i = min; i <= max; i += step)
+        yield return i;
+
+      if (i != max + step)
+        yield return i;
+    }
+
+    protected void RemoveCustomPropertyIfExists(Series series, string property) {
+      if (series.IsCustomPropertySet(property)) series.DeleteCustomProperty(property);
+    }
+
+    private double HumanRoundRange(double range) {
+      double base10 = Math.Pow(10.0, Math.Floor(Math.Log10(range)));
+      double rounding = range / base10;
+      if (rounding <= 1.5) rounding = 1;
+      else if (rounding <= 2.25) rounding = 2;
+      else if (rounding <= 3.75) rounding = 2.5;
+      else if (rounding <= 7.5) rounding = 5;
+      else rounding = 10;
+      return rounding * base10;
+    }
+
+    private double HumanRoundMax(double max) {
+      double base10;
+      if (max > 0) base10 = Math.Pow(10.0, Math.Floor(Math.Log10(max)));
+      else base10 = Math.Pow(10.0, Math.Ceiling(Math.Log10(-max)));
+      double rounding = (max > 0) ? base10 : -base10;
+      while (rounding < max) rounding += base10;
+      return rounding;
+    }
+
+    private ChartDashStyle ConvertLineStyle(DataRowVisualProperties.DataRowLineStyle dataRowLineStyle) {
+      switch (dataRowLineStyle) {
+        case DataRowVisualProperties.DataRowLineStyle.Dash:
+          return ChartDashStyle.Dash;
+        case DataRowVisualProperties.DataRowLineStyle.DashDot:
+          return ChartDashStyle.DashDot;
+        case DataRowVisualProperties.DataRowLineStyle.DashDotDot:
+          return ChartDashStyle.DashDotDot;
+        case DataRowVisualProperties.DataRowLineStyle.Dot:
+          return ChartDashStyle.Dot;
+        case DataRowVisualProperties.DataRowLineStyle.NotSet:
+          return ChartDashStyle.NotSet;
+        case DataRowVisualProperties.DataRowLineStyle.Solid:
+          return ChartDashStyle.Solid;
+        default:
+          return ChartDashStyle.NotSet;
+      }
+    }
+
+    protected static bool IsInvalidValue(double x) {
+      return double.IsNaN(x) || x < (double)decimal.MinValue || x > (double)decimal.MaxValue;
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableVisualPropertiesControl.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableVisualPropertiesControl.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableVisualPropertiesControl.Designer.cs	(revision 12764)
@@ -0,0 +1,1008 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Analysis.Views {
+  partial class DataTableVisualPropertiesControl {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      this.label1 = new System.Windows.Forms.Label();
+      this.yAxisPrimaryTitleTextBox = new System.Windows.Forms.TextBox();
+      this.yAxisSecondaryTitleTextBox = new System.Windows.Forms.TextBox();
+      this.label4 = new System.Windows.Forms.Label();
+      this.xAxisPrimaryGroupBox = new System.Windows.Forms.GroupBox();
+      this.xAxisPrimaryLogScaleCheckBox = new System.Windows.Forms.CheckBox();
+      this.panel2 = new System.Windows.Forms.Panel();
+      this.xAxisPrimaryMaximumFixedRadioButton = new System.Windows.Forms.RadioButton();
+      this.xAxisPrimaryMaximumAutoRadioButton = new System.Windows.Forms.RadioButton();
+      this.panel1 = new System.Windows.Forms.Panel();
+      this.xAxisPrimaryMinimumFixedRadioButton = new System.Windows.Forms.RadioButton();
+      this.xAxisPrimaryMinimumAutoRadioButton = new System.Windows.Forms.RadioButton();
+      this.xAxisPrimaryMinimumFixedTextBox = new System.Windows.Forms.TextBox();
+      this.xAxisPrimaryMaximumFixedTextBox = new System.Windows.Forms.TextBox();
+      this.label12 = new System.Windows.Forms.Label();
+      this.label9 = new System.Windows.Forms.Label();
+      this.xAxisPrimaryTitleTextBox = new System.Windows.Forms.TextBox();
+      this.label11 = new System.Windows.Forms.Label();
+      this.xAxisSecondaryGroupBox = new System.Windows.Forms.GroupBox();
+      this.xAxisSecondaryLogScaleCheckBox = new System.Windows.Forms.CheckBox();
+      this.panel4 = new System.Windows.Forms.Panel();
+      this.xAxisSecondaryMaximumFixedRadioButton = new System.Windows.Forms.RadioButton();
+      this.xAxisSecondaryMaximumAutoRadioButton = new System.Windows.Forms.RadioButton();
+      this.panel3 = new System.Windows.Forms.Panel();
+      this.xAxisSecondaryMinimumFixedRadioButton = new System.Windows.Forms.RadioButton();
+      this.xAxisSecondaryMinimumAutoRadioButton = new System.Windows.Forms.RadioButton();
+      this.xAxisSecondaryMinimumFixedTextBox = new System.Windows.Forms.TextBox();
+      this.xAxisSecondaryMaximumFixedTextBox = new System.Windows.Forms.TextBox();
+      this.label10 = new System.Windows.Forms.Label();
+      this.xAxisSecondaryTitleTextBox = new System.Windows.Forms.TextBox();
+      this.label5 = new System.Windows.Forms.Label();
+      this.label6 = new System.Windows.Forms.Label();
+      this.axisTabControl = new System.Windows.Forms.TabControl();
+      this.xAxisTabPage = new System.Windows.Forms.TabPage();
+      this.yAxisTabPage = new System.Windows.Forms.TabPage();
+      this.yAxisSecondaryGroupBox = new System.Windows.Forms.GroupBox();
+      this.yAxisSecondaryLogScaleCheckBox = new System.Windows.Forms.CheckBox();
+      this.panel8 = new System.Windows.Forms.Panel();
+      this.yAxisSecondaryMaximumFixedRadioButton = new System.Windows.Forms.RadioButton();
+      this.yAxisSecondaryMaximumAutoRadioButton = new System.Windows.Forms.RadioButton();
+      this.panel7 = new System.Windows.Forms.Panel();
+      this.yAxisSecondaryMinimumFixedRadioButton = new System.Windows.Forms.RadioButton();
+      this.yAxisSecondaryMinimumAutoRadioButton = new System.Windows.Forms.RadioButton();
+      this.yAxisSecondaryMinimumFixedTextBox = new System.Windows.Forms.TextBox();
+      this.yAxisSecondaryMaximumFixedTextBox = new System.Windows.Forms.TextBox();
+      this.label13 = new System.Windows.Forms.Label();
+      this.label14 = new System.Windows.Forms.Label();
+      this.yAxisPrimaryGroupBox = new System.Windows.Forms.GroupBox();
+      this.yAxisPrimaryLogScaleCheckBox = new System.Windows.Forms.CheckBox();
+      this.panel6 = new System.Windows.Forms.Panel();
+      this.yAxisPrimaryMaximumFixedRadioButton = new System.Windows.Forms.RadioButton();
+      this.yAxisPrimaryMaximumAutoRadioButton = new System.Windows.Forms.RadioButton();
+      this.panel5 = new System.Windows.Forms.Panel();
+      this.yAxisPrimaryMinimumAutoRadioButton = new System.Windows.Forms.RadioButton();
+      this.yAxisPrimaryMinimumFixedRadioButton = new System.Windows.Forms.RadioButton();
+      this.yAxisPrimaryMinimumFixedTextBox = new System.Windows.Forms.TextBox();
+      this.yAxisPrimaryMaximumFixedTextBox = new System.Windows.Forms.TextBox();
+      this.label7 = new System.Windows.Forms.Label();
+      this.label8 = new System.Windows.Forms.Label();
+      this.titleTextBox = new System.Windows.Forms.TextBox();
+      this.label15 = new System.Windows.Forms.Label();
+      this.axisFontLabel = new System.Windows.Forms.Label();
+      this.titleFontLabel = new System.Windows.Forms.Label();
+      this.axisFontButton = new System.Windows.Forms.Button();
+      this.label3 = new System.Windows.Forms.Label();
+      this.titleFontButton = new System.Windows.Forms.Button();
+      this.label2 = new System.Windows.Forms.Label();
+      this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      this.titleFontDialog = new System.Windows.Forms.FontDialog();
+      this.axisFontDialog = new System.Windows.Forms.FontDialog();
+      this.xAxisPrimaryGroupBox.SuspendLayout();
+      this.panel2.SuspendLayout();
+      this.panel1.SuspendLayout();
+      this.xAxisSecondaryGroupBox.SuspendLayout();
+      this.panel4.SuspendLayout();
+      this.panel3.SuspendLayout();
+      this.axisTabControl.SuspendLayout();
+      this.xAxisTabPage.SuspendLayout();
+      this.yAxisTabPage.SuspendLayout();
+      this.yAxisSecondaryGroupBox.SuspendLayout();
+      this.panel8.SuspendLayout();
+      this.panel7.SuspendLayout();
+      this.yAxisPrimaryGroupBox.SuspendLayout();
+      this.panel6.SuspendLayout();
+      this.panel5.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(6, 22);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(30, 13);
+      this.label1.TabIndex = 0;
+      this.label1.Text = "&Title:";
+      // 
+      // yAxisPrimaryTitleTextBox
+      // 
+      this.yAxisPrimaryTitleTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.yAxisPrimaryTitleTextBox.Location = new System.Drawing.Point(74, 19);
+      this.yAxisPrimaryTitleTextBox.Name = "yAxisPrimaryTitleTextBox";
+      this.yAxisPrimaryTitleTextBox.Size = new System.Drawing.Size(361, 20);
+      this.yAxisPrimaryTitleTextBox.TabIndex = 1;
+      this.yAxisPrimaryTitleTextBox.Validated += new System.EventHandler(this.yPrimaryTitleTextBox_Validated);
+      // 
+      // yAxisSecondaryTitleTextBox
+      // 
+      this.yAxisSecondaryTitleTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.yAxisSecondaryTitleTextBox.Location = new System.Drawing.Point(74, 19);
+      this.yAxisSecondaryTitleTextBox.Name = "yAxisSecondaryTitleTextBox";
+      this.yAxisSecondaryTitleTextBox.Size = new System.Drawing.Size(361, 20);
+      this.yAxisSecondaryTitleTextBox.TabIndex = 1;
+      this.yAxisSecondaryTitleTextBox.Validated += new System.EventHandler(this.ySecondaryTitleTextBox_Validated);
+      // 
+      // label4
+      // 
+      this.label4.AutoSize = true;
+      this.label4.Location = new System.Drawing.Point(6, 22);
+      this.label4.Name = "label4";
+      this.label4.Size = new System.Drawing.Size(30, 13);
+      this.label4.TabIndex = 0;
+      this.label4.Text = "&Title:";
+      // 
+      // xAxisPrimaryGroupBox
+      // 
+      this.xAxisPrimaryGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.xAxisPrimaryGroupBox.Controls.Add(this.xAxisPrimaryLogScaleCheckBox);
+      this.xAxisPrimaryGroupBox.Controls.Add(this.panel2);
+      this.xAxisPrimaryGroupBox.Controls.Add(this.panel1);
+      this.xAxisPrimaryGroupBox.Controls.Add(this.xAxisPrimaryMinimumFixedTextBox);
+      this.xAxisPrimaryGroupBox.Controls.Add(this.xAxisPrimaryMaximumFixedTextBox);
+      this.xAxisPrimaryGroupBox.Controls.Add(this.label12);
+      this.xAxisPrimaryGroupBox.Controls.Add(this.label9);
+      this.xAxisPrimaryGroupBox.Controls.Add(this.xAxisPrimaryTitleTextBox);
+      this.xAxisPrimaryGroupBox.Controls.Add(this.label11);
+      this.xAxisPrimaryGroupBox.Location = new System.Drawing.Point(3, 3);
+      this.xAxisPrimaryGroupBox.Name = "xAxisPrimaryGroupBox";
+      this.xAxisPrimaryGroupBox.Size = new System.Drawing.Size(441, 126);
+      this.xAxisPrimaryGroupBox.TabIndex = 0;
+      this.xAxisPrimaryGroupBox.TabStop = false;
+      this.xAxisPrimaryGroupBox.Text = "Primary Axis";
+      // 
+      // xAxisPrimaryLogScaleCheckBox
+      // 
+      this.xAxisPrimaryLogScaleCheckBox.AutoSize = true;
+      this.xAxisPrimaryLogScaleCheckBox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
+      this.xAxisPrimaryLogScaleCheckBox.Location = new System.Drawing.Point(6, 99);
+      this.xAxisPrimaryLogScaleCheckBox.Name = "xAxisPrimaryLogScaleCheckBox";
+      this.xAxisPrimaryLogScaleCheckBox.Size = new System.Drawing.Size(83, 17);
+      this.xAxisPrimaryLogScaleCheckBox.TabIndex = 8;
+      this.xAxisPrimaryLogScaleCheckBox.Text = "Logarithmic:";
+      this.xAxisPrimaryLogScaleCheckBox.UseVisualStyleBackColor = true;
+      this.xAxisPrimaryLogScaleCheckBox.CheckedChanged += new System.EventHandler(this.xAxisPrimaryLogScaleCheckBox_CheckedChanged);
+      // 
+      // panel2
+      // 
+      this.panel2.Controls.Add(this.xAxisPrimaryMaximumFixedRadioButton);
+      this.panel2.Controls.Add(this.xAxisPrimaryMaximumAutoRadioButton);
+      this.panel2.Location = new System.Drawing.Point(74, 71);
+      this.panel2.Name = "panel2";
+      this.panel2.Size = new System.Drawing.Size(106, 20);
+      this.panel2.TabIndex = 6;
+      // 
+      // xAxisPrimaryMaximumFixedRadioButton
+      // 
+      this.xAxisPrimaryMaximumFixedRadioButton.AutoSize = true;
+      this.xAxisPrimaryMaximumFixedRadioButton.Location = new System.Drawing.Point(53, 1);
+      this.xAxisPrimaryMaximumFixedRadioButton.Name = "xAxisPrimaryMaximumFixedRadioButton";
+      this.xAxisPrimaryMaximumFixedRadioButton.Size = new System.Drawing.Size(53, 17);
+      this.xAxisPrimaryMaximumFixedRadioButton.TabIndex = 1;
+      this.xAxisPrimaryMaximumFixedRadioButton.TabStop = true;
+      this.xAxisPrimaryMaximumFixedRadioButton.Text = "&Fixed:";
+      this.xAxisPrimaryMaximumFixedRadioButton.UseVisualStyleBackColor = true;
+      this.xAxisPrimaryMaximumFixedRadioButton.CheckedChanged += new System.EventHandler(this.xAxisPrimaryMaximumRadioButton_CheckedChanged);
+      // 
+      // xAxisPrimaryMaximumAutoRadioButton
+      // 
+      this.xAxisPrimaryMaximumAutoRadioButton.AutoSize = true;
+      this.xAxisPrimaryMaximumAutoRadioButton.Location = new System.Drawing.Point(0, 1);
+      this.xAxisPrimaryMaximumAutoRadioButton.Name = "xAxisPrimaryMaximumAutoRadioButton";
+      this.xAxisPrimaryMaximumAutoRadioButton.Size = new System.Drawing.Size(47, 17);
+      this.xAxisPrimaryMaximumAutoRadioButton.TabIndex = 0;
+      this.xAxisPrimaryMaximumAutoRadioButton.TabStop = true;
+      this.xAxisPrimaryMaximumAutoRadioButton.Text = "&Auto";
+      this.xAxisPrimaryMaximumAutoRadioButton.UseVisualStyleBackColor = true;
+      this.xAxisPrimaryMaximumAutoRadioButton.CheckedChanged += new System.EventHandler(this.xAxisPrimaryMaximumRadioButton_CheckedChanged);
+      // 
+      // panel1
+      // 
+      this.panel1.Controls.Add(this.xAxisPrimaryMinimumFixedRadioButton);
+      this.panel1.Controls.Add(this.xAxisPrimaryMinimumAutoRadioButton);
+      this.panel1.Location = new System.Drawing.Point(74, 45);
+      this.panel1.Name = "panel1";
+      this.panel1.Size = new System.Drawing.Size(106, 20);
+      this.panel1.TabIndex = 3;
+      // 
+      // xAxisPrimaryMinimumFixedRadioButton
+      // 
+      this.xAxisPrimaryMinimumFixedRadioButton.AutoSize = true;
+      this.xAxisPrimaryMinimumFixedRadioButton.Location = new System.Drawing.Point(53, 1);
+      this.xAxisPrimaryMinimumFixedRadioButton.Name = "xAxisPrimaryMinimumFixedRadioButton";
+      this.xAxisPrimaryMinimumFixedRadioButton.Size = new System.Drawing.Size(53, 17);
+      this.xAxisPrimaryMinimumFixedRadioButton.TabIndex = 1;
+      this.xAxisPrimaryMinimumFixedRadioButton.TabStop = true;
+      this.xAxisPrimaryMinimumFixedRadioButton.Text = "&Fixed:";
+      this.xAxisPrimaryMinimumFixedRadioButton.UseVisualStyleBackColor = true;
+      this.xAxisPrimaryMinimumFixedRadioButton.CheckedChanged += new System.EventHandler(this.xAxisPrimaryMinimumRadioButton_CheckedChanged);
+      // 
+      // xAxisPrimaryMinimumAutoRadioButton
+      // 
+      this.xAxisPrimaryMinimumAutoRadioButton.AutoSize = true;
+      this.xAxisPrimaryMinimumAutoRadioButton.Location = new System.Drawing.Point(0, 1);
+      this.xAxisPrimaryMinimumAutoRadioButton.Name = "xAxisPrimaryMinimumAutoRadioButton";
+      this.xAxisPrimaryMinimumAutoRadioButton.Size = new System.Drawing.Size(47, 17);
+      this.xAxisPrimaryMinimumAutoRadioButton.TabIndex = 0;
+      this.xAxisPrimaryMinimumAutoRadioButton.TabStop = true;
+      this.xAxisPrimaryMinimumAutoRadioButton.Text = "&Auto";
+      this.xAxisPrimaryMinimumAutoRadioButton.UseVisualStyleBackColor = true;
+      this.xAxisPrimaryMinimumAutoRadioButton.CheckedChanged += new System.EventHandler(this.xAxisPrimaryMinimumRadioButton_CheckedChanged);
+      // 
+      // xAxisPrimaryMinimumFixedTextBox
+      // 
+      this.xAxisPrimaryMinimumFixedTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.xAxisPrimaryMinimumFixedTextBox.Location = new System.Drawing.Point(191, 45);
+      this.xAxisPrimaryMinimumFixedTextBox.Name = "xAxisPrimaryMinimumFixedTextBox";
+      this.xAxisPrimaryMinimumFixedTextBox.Size = new System.Drawing.Size(244, 20);
+      this.xAxisPrimaryMinimumFixedTextBox.TabIndex = 4;
+      this.xAxisPrimaryMinimumFixedTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.xAxisPrimaryMinimumFixedTextBox_Validating);
+      // 
+      // xAxisPrimaryMaximumFixedTextBox
+      // 
+      this.xAxisPrimaryMaximumFixedTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.xAxisPrimaryMaximumFixedTextBox.Location = new System.Drawing.Point(191, 71);
+      this.xAxisPrimaryMaximumFixedTextBox.Name = "xAxisPrimaryMaximumFixedTextBox";
+      this.xAxisPrimaryMaximumFixedTextBox.Size = new System.Drawing.Size(244, 20);
+      this.xAxisPrimaryMaximumFixedTextBox.TabIndex = 7;
+      this.xAxisPrimaryMaximumFixedTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.xAxisPrimaryMaximumFixedTextBox_Validating);
+      // 
+      // label12
+      // 
+      this.label12.AutoSize = true;
+      this.label12.Location = new System.Drawing.Point(6, 74);
+      this.label12.Name = "label12";
+      this.label12.Size = new System.Drawing.Size(54, 13);
+      this.label12.TabIndex = 5;
+      this.label12.Text = "&Maximum:";
+      // 
+      // label9
+      // 
+      this.label9.AutoSize = true;
+      this.label9.Location = new System.Drawing.Point(6, 22);
+      this.label9.Name = "label9";
+      this.label9.Size = new System.Drawing.Size(30, 13);
+      this.label9.TabIndex = 0;
+      this.label9.Text = "&Title:";
+      // 
+      // xAxisPrimaryTitleTextBox
+      // 
+      this.xAxisPrimaryTitleTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.xAxisPrimaryTitleTextBox.Location = new System.Drawing.Point(74, 19);
+      this.xAxisPrimaryTitleTextBox.Name = "xAxisPrimaryTitleTextBox";
+      this.xAxisPrimaryTitleTextBox.Size = new System.Drawing.Size(361, 20);
+      this.xAxisPrimaryTitleTextBox.TabIndex = 1;
+      this.xAxisPrimaryTitleTextBox.Validated += new System.EventHandler(this.xPrimaryTitleTextBox_Validated);
+      // 
+      // label11
+      // 
+      this.label11.AutoSize = true;
+      this.label11.Location = new System.Drawing.Point(6, 48);
+      this.label11.Name = "label11";
+      this.label11.Size = new System.Drawing.Size(51, 13);
+      this.label11.TabIndex = 2;
+      this.label11.Text = "&Minimum:";
+      // 
+      // xAxisSecondaryGroupBox
+      // 
+      this.xAxisSecondaryGroupBox.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.xAxisSecondaryGroupBox.Controls.Add(this.xAxisSecondaryLogScaleCheckBox);
+      this.xAxisSecondaryGroupBox.Controls.Add(this.panel4);
+      this.xAxisSecondaryGroupBox.Controls.Add(this.panel3);
+      this.xAxisSecondaryGroupBox.Controls.Add(this.xAxisSecondaryMinimumFixedTextBox);
+      this.xAxisSecondaryGroupBox.Controls.Add(this.xAxisSecondaryMaximumFixedTextBox);
+      this.xAxisSecondaryGroupBox.Controls.Add(this.label10);
+      this.xAxisSecondaryGroupBox.Controls.Add(this.xAxisSecondaryTitleTextBox);
+      this.xAxisSecondaryGroupBox.Controls.Add(this.label5);
+      this.xAxisSecondaryGroupBox.Controls.Add(this.label6);
+      this.xAxisSecondaryGroupBox.Location = new System.Drawing.Point(3, 135);
+      this.xAxisSecondaryGroupBox.Name = "xAxisSecondaryGroupBox";
+      this.xAxisSecondaryGroupBox.Size = new System.Drawing.Size(441, 125);
+      this.xAxisSecondaryGroupBox.TabIndex = 1;
+      this.xAxisSecondaryGroupBox.TabStop = false;
+      this.xAxisSecondaryGroupBox.Text = "Secondary Axis";
+      // 
+      // xAxisSecondaryLogScaleCheckBox
+      // 
+      this.xAxisSecondaryLogScaleCheckBox.AutoSize = true;
+      this.xAxisSecondaryLogScaleCheckBox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
+      this.xAxisSecondaryLogScaleCheckBox.Location = new System.Drawing.Point(6, 99);
+      this.xAxisSecondaryLogScaleCheckBox.Name = "xAxisSecondaryLogScaleCheckBox";
+      this.xAxisSecondaryLogScaleCheckBox.Size = new System.Drawing.Size(83, 17);
+      this.xAxisSecondaryLogScaleCheckBox.TabIndex = 8;
+      this.xAxisSecondaryLogScaleCheckBox.Text = "Logarithmic:";
+      this.xAxisSecondaryLogScaleCheckBox.UseVisualStyleBackColor = true;
+      this.xAxisSecondaryLogScaleCheckBox.CheckedChanged += new System.EventHandler(this.xAxisSecondaryLogScaleCheckBox_CheckedChanged);
+      // 
+      // panel4
+      // 
+      this.panel4.Controls.Add(this.xAxisSecondaryMaximumFixedRadioButton);
+      this.panel4.Controls.Add(this.xAxisSecondaryMaximumAutoRadioButton);
+      this.panel4.Location = new System.Drawing.Point(74, 71);
+      this.panel4.Name = "panel4";
+      this.panel4.Size = new System.Drawing.Size(106, 20);
+      this.panel4.TabIndex = 6;
+      // 
+      // xAxisSecondaryMaximumFixedRadioButton
+      // 
+      this.xAxisSecondaryMaximumFixedRadioButton.AutoSize = true;
+      this.xAxisSecondaryMaximumFixedRadioButton.Location = new System.Drawing.Point(53, 1);
+      this.xAxisSecondaryMaximumFixedRadioButton.Name = "xAxisSecondaryMaximumFixedRadioButton";
+      this.xAxisSecondaryMaximumFixedRadioButton.Size = new System.Drawing.Size(53, 17);
+      this.xAxisSecondaryMaximumFixedRadioButton.TabIndex = 1;
+      this.xAxisSecondaryMaximumFixedRadioButton.TabStop = true;
+      this.xAxisSecondaryMaximumFixedRadioButton.Text = "&Fixed:";
+      this.xAxisSecondaryMaximumFixedRadioButton.UseVisualStyleBackColor = true;
+      this.xAxisSecondaryMaximumFixedRadioButton.CheckedChanged += new System.EventHandler(this.xAxisSecondaryMaximumRadioButton_CheckedChanged);
+      // 
+      // xAxisSecondaryMaximumAutoRadioButton
+      // 
+      this.xAxisSecondaryMaximumAutoRadioButton.AutoSize = true;
+      this.xAxisSecondaryMaximumAutoRadioButton.Location = new System.Drawing.Point(0, 1);
+      this.xAxisSecondaryMaximumAutoRadioButton.Name = "xAxisSecondaryMaximumAutoRadioButton";
+      this.xAxisSecondaryMaximumAutoRadioButton.Size = new System.Drawing.Size(47, 17);
+      this.xAxisSecondaryMaximumAutoRadioButton.TabIndex = 0;
+      this.xAxisSecondaryMaximumAutoRadioButton.TabStop = true;
+      this.xAxisSecondaryMaximumAutoRadioButton.Text = "&Auto";
+      this.xAxisSecondaryMaximumAutoRadioButton.UseVisualStyleBackColor = true;
+      this.xAxisSecondaryMaximumAutoRadioButton.CheckedChanged += new System.EventHandler(this.xAxisSecondaryMaximumRadioButton_CheckedChanged);
+      // 
+      // panel3
+      // 
+      this.panel3.Controls.Add(this.xAxisSecondaryMinimumFixedRadioButton);
+      this.panel3.Controls.Add(this.xAxisSecondaryMinimumAutoRadioButton);
+      this.panel3.Location = new System.Drawing.Point(74, 45);
+      this.panel3.Name = "panel3";
+      this.panel3.Size = new System.Drawing.Size(106, 20);
+      this.panel3.TabIndex = 3;
+      // 
+      // xAxisSecondaryMinimumFixedRadioButton
+      // 
+      this.xAxisSecondaryMinimumFixedRadioButton.AutoSize = true;
+      this.xAxisSecondaryMinimumFixedRadioButton.Location = new System.Drawing.Point(53, 1);
+      this.xAxisSecondaryMinimumFixedRadioButton.Name = "xAxisSecondaryMinimumFixedRadioButton";
+      this.xAxisSecondaryMinimumFixedRadioButton.Size = new System.Drawing.Size(53, 17);
+      this.xAxisSecondaryMinimumFixedRadioButton.TabIndex = 1;
+      this.xAxisSecondaryMinimumFixedRadioButton.TabStop = true;
+      this.xAxisSecondaryMinimumFixedRadioButton.Text = "&Fixed:";
+      this.xAxisSecondaryMinimumFixedRadioButton.UseVisualStyleBackColor = true;
+      this.xAxisSecondaryMinimumFixedRadioButton.CheckedChanged += new System.EventHandler(this.xAxisSecondaryMinimumRadioButton_CheckedChanged);
+      // 
+      // xAxisSecondaryMinimumAutoRadioButton
+      // 
+      this.xAxisSecondaryMinimumAutoRadioButton.AutoSize = true;
+      this.xAxisSecondaryMinimumAutoRadioButton.Location = new System.Drawing.Point(0, 1);
+      this.xAxisSecondaryMinimumAutoRadioButton.Name = "xAxisSecondaryMinimumAutoRadioButton";
+      this.xAxisSecondaryMinimumAutoRadioButton.Size = new System.Drawing.Size(47, 17);
+      this.xAxisSecondaryMinimumAutoRadioButton.TabIndex = 0;
+      this.xAxisSecondaryMinimumAutoRadioButton.TabStop = true;
+      this.xAxisSecondaryMinimumAutoRadioButton.Text = "&Auto";
+      this.xAxisSecondaryMinimumAutoRadioButton.UseVisualStyleBackColor = true;
+      this.xAxisSecondaryMinimumAutoRadioButton.CheckedChanged += new System.EventHandler(this.xAxisSecondaryMinimumRadioButton_CheckedChanged);
+      // 
+      // xAxisSecondaryMinimumFixedTextBox
+      // 
+      this.xAxisSecondaryMinimumFixedTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.xAxisSecondaryMinimumFixedTextBox.Location = new System.Drawing.Point(191, 45);
+      this.xAxisSecondaryMinimumFixedTextBox.Name = "xAxisSecondaryMinimumFixedTextBox";
+      this.xAxisSecondaryMinimumFixedTextBox.Size = new System.Drawing.Size(244, 20);
+      this.xAxisSecondaryMinimumFixedTextBox.TabIndex = 4;
+      this.xAxisSecondaryMinimumFixedTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.xAxisSecondaryMinimumFixedTextBox_Validating);
+      // 
+      // xAxisSecondaryMaximumFixedTextBox
+      // 
+      this.xAxisSecondaryMaximumFixedTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.xAxisSecondaryMaximumFixedTextBox.Location = new System.Drawing.Point(191, 71);
+      this.xAxisSecondaryMaximumFixedTextBox.Name = "xAxisSecondaryMaximumFixedTextBox";
+      this.xAxisSecondaryMaximumFixedTextBox.Size = new System.Drawing.Size(244, 20);
+      this.xAxisSecondaryMaximumFixedTextBox.TabIndex = 7;
+      this.xAxisSecondaryMaximumFixedTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.xAxisSecondaryMaximumFixedTextBox_Validating);
+      // 
+      // label10
+      // 
+      this.label10.AutoSize = true;
+      this.label10.Location = new System.Drawing.Point(6, 22);
+      this.label10.Name = "label10";
+      this.label10.Size = new System.Drawing.Size(30, 13);
+      this.label10.TabIndex = 0;
+      this.label10.Text = "&Title:";
+      // 
+      // xAxisSecondaryTitleTextBox
+      // 
+      this.xAxisSecondaryTitleTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.xAxisSecondaryTitleTextBox.Location = new System.Drawing.Point(74, 19);
+      this.xAxisSecondaryTitleTextBox.Name = "xAxisSecondaryTitleTextBox";
+      this.xAxisSecondaryTitleTextBox.Size = new System.Drawing.Size(361, 20);
+      this.xAxisSecondaryTitleTextBox.TabIndex = 1;
+      this.xAxisSecondaryTitleTextBox.Validated += new System.EventHandler(this.xSecondaryTitleTextBox_Validated);
+      // 
+      // label5
+      // 
+      this.label5.AutoSize = true;
+      this.label5.Location = new System.Drawing.Point(6, 74);
+      this.label5.Name = "label5";
+      this.label5.Size = new System.Drawing.Size(54, 13);
+      this.label5.TabIndex = 5;
+      this.label5.Text = "&Maximum:";
+      // 
+      // label6
+      // 
+      this.label6.AutoSize = true;
+      this.label6.Location = new System.Drawing.Point(6, 48);
+      this.label6.Name = "label6";
+      this.label6.Size = new System.Drawing.Size(51, 13);
+      this.label6.TabIndex = 2;
+      this.label6.Text = "&Minimum:";
+      // 
+      // axisTabControl
+      // 
+      this.axisTabControl.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.axisTabControl.Controls.Add(this.xAxisTabPage);
+      this.axisTabControl.Controls.Add(this.yAxisTabPage);
+      this.axisTabControl.Location = new System.Drawing.Point(0, 84);
+      this.axisTabControl.Name = "axisTabControl";
+      this.axisTabControl.SelectedIndex = 0;
+      this.axisTabControl.Size = new System.Drawing.Size(455, 289);
+      this.axisTabControl.TabIndex = 8;
+      // 
+      // xAxisTabPage
+      // 
+      this.xAxisTabPage.Controls.Add(this.xAxisSecondaryGroupBox);
+      this.xAxisTabPage.Controls.Add(this.xAxisPrimaryGroupBox);
+      this.xAxisTabPage.Location = new System.Drawing.Point(4, 22);
+      this.xAxisTabPage.Name = "xAxisTabPage";
+      this.xAxisTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.xAxisTabPage.Size = new System.Drawing.Size(447, 263);
+      this.xAxisTabPage.TabIndex = 0;
+      this.xAxisTabPage.Text = "X-Axis";
+      this.xAxisTabPage.UseVisualStyleBackColor = true;
+      // 
+      // yAxisTabPage
+      // 
+      this.yAxisTabPage.Controls.Add(this.yAxisSecondaryGroupBox);
+      this.yAxisTabPage.Controls.Add(this.yAxisPrimaryGroupBox);
+      this.yAxisTabPage.Location = new System.Drawing.Point(4, 22);
+      this.yAxisTabPage.Name = "yAxisTabPage";
+      this.yAxisTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.yAxisTabPage.Size = new System.Drawing.Size(447, 263);
+      this.yAxisTabPage.TabIndex = 1;
+      this.yAxisTabPage.Text = "Y-Axis";
+      this.yAxisTabPage.UseVisualStyleBackColor = true;
+      // 
+      // yAxisSecondaryGroupBox
+      // 
+      this.yAxisSecondaryGroupBox.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.yAxisSecondaryGroupBox.Controls.Add(this.yAxisSecondaryLogScaleCheckBox);
+      this.yAxisSecondaryGroupBox.Controls.Add(this.panel8);
+      this.yAxisSecondaryGroupBox.Controls.Add(this.panel7);
+      this.yAxisSecondaryGroupBox.Controls.Add(this.yAxisSecondaryMinimumFixedTextBox);
+      this.yAxisSecondaryGroupBox.Controls.Add(this.yAxisSecondaryMaximumFixedTextBox);
+      this.yAxisSecondaryGroupBox.Controls.Add(this.yAxisSecondaryTitleTextBox);
+      this.yAxisSecondaryGroupBox.Controls.Add(this.label4);
+      this.yAxisSecondaryGroupBox.Controls.Add(this.label13);
+      this.yAxisSecondaryGroupBox.Controls.Add(this.label14);
+      this.yAxisSecondaryGroupBox.Location = new System.Drawing.Point(3, 135);
+      this.yAxisSecondaryGroupBox.Name = "yAxisSecondaryGroupBox";
+      this.yAxisSecondaryGroupBox.Size = new System.Drawing.Size(441, 125);
+      this.yAxisSecondaryGroupBox.TabIndex = 1;
+      this.yAxisSecondaryGroupBox.TabStop = false;
+      this.yAxisSecondaryGroupBox.Text = "Secondary Axis";
+      // 
+      // yAxisSecondaryLogScaleCheckBox
+      // 
+      this.yAxisSecondaryLogScaleCheckBox.AutoSize = true;
+      this.yAxisSecondaryLogScaleCheckBox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
+      this.yAxisSecondaryLogScaleCheckBox.Location = new System.Drawing.Point(6, 99);
+      this.yAxisSecondaryLogScaleCheckBox.Name = "yAxisSecondaryLogScaleCheckBox";
+      this.yAxisSecondaryLogScaleCheckBox.Size = new System.Drawing.Size(83, 17);
+      this.yAxisSecondaryLogScaleCheckBox.TabIndex = 9;
+      this.yAxisSecondaryLogScaleCheckBox.Text = "Logarithmic:";
+      this.yAxisSecondaryLogScaleCheckBox.UseVisualStyleBackColor = true;
+      this.yAxisSecondaryLogScaleCheckBox.CheckedChanged += new System.EventHandler(this.yAxisSecondaryLogScaleCheckBox_CheckedChanged);
+      // 
+      // panel8
+      // 
+      this.panel8.Controls.Add(this.yAxisSecondaryMaximumFixedRadioButton);
+      this.panel8.Controls.Add(this.yAxisSecondaryMaximumAutoRadioButton);
+      this.panel8.Location = new System.Drawing.Point(74, 71);
+      this.panel8.Name = "panel8";
+      this.panel8.Size = new System.Drawing.Size(106, 20);
+      this.panel8.TabIndex = 6;
+      // 
+      // yAxisSecondaryMaximumFixedRadioButton
+      // 
+      this.yAxisSecondaryMaximumFixedRadioButton.AutoSize = true;
+      this.yAxisSecondaryMaximumFixedRadioButton.Location = new System.Drawing.Point(53, 1);
+      this.yAxisSecondaryMaximumFixedRadioButton.Name = "yAxisSecondaryMaximumFixedRadioButton";
+      this.yAxisSecondaryMaximumFixedRadioButton.Size = new System.Drawing.Size(53, 17);
+      this.yAxisSecondaryMaximumFixedRadioButton.TabIndex = 1;
+      this.yAxisSecondaryMaximumFixedRadioButton.TabStop = true;
+      this.yAxisSecondaryMaximumFixedRadioButton.Text = "&Fixed:";
+      this.yAxisSecondaryMaximumFixedRadioButton.UseVisualStyleBackColor = true;
+      this.yAxisSecondaryMaximumFixedRadioButton.CheckedChanged += new System.EventHandler(this.yAxisSecondaryMaximumRadioButton_CheckedChanged);
+      // 
+      // yAxisSecondaryMaximumAutoRadioButton
+      // 
+      this.yAxisSecondaryMaximumAutoRadioButton.AutoSize = true;
+      this.yAxisSecondaryMaximumAutoRadioButton.Location = new System.Drawing.Point(0, 1);
+      this.yAxisSecondaryMaximumAutoRadioButton.Name = "yAxisSecondaryMaximumAutoRadioButton";
+      this.yAxisSecondaryMaximumAutoRadioButton.Size = new System.Drawing.Size(47, 17);
+      this.yAxisSecondaryMaximumAutoRadioButton.TabIndex = 0;
+      this.yAxisSecondaryMaximumAutoRadioButton.TabStop = true;
+      this.yAxisSecondaryMaximumAutoRadioButton.Text = "&Auto";
+      this.yAxisSecondaryMaximumAutoRadioButton.UseVisualStyleBackColor = true;
+      this.yAxisSecondaryMaximumAutoRadioButton.CheckedChanged += new System.EventHandler(this.yAxisSecondaryMaximumRadioButton_CheckedChanged);
+      // 
+      // panel7
+      // 
+      this.panel7.Controls.Add(this.yAxisSecondaryMinimumFixedRadioButton);
+      this.panel7.Controls.Add(this.yAxisSecondaryMinimumAutoRadioButton);
+      this.panel7.Location = new System.Drawing.Point(74, 45);
+      this.panel7.Name = "panel7";
+      this.panel7.Size = new System.Drawing.Size(106, 20);
+      this.panel7.TabIndex = 3;
+      // 
+      // yAxisSecondaryMinimumFixedRadioButton
+      // 
+      this.yAxisSecondaryMinimumFixedRadioButton.AutoSize = true;
+      this.yAxisSecondaryMinimumFixedRadioButton.Location = new System.Drawing.Point(53, 1);
+      this.yAxisSecondaryMinimumFixedRadioButton.Name = "yAxisSecondaryMinimumFixedRadioButton";
+      this.yAxisSecondaryMinimumFixedRadioButton.Size = new System.Drawing.Size(53, 17);
+      this.yAxisSecondaryMinimumFixedRadioButton.TabIndex = 1;
+      this.yAxisSecondaryMinimumFixedRadioButton.TabStop = true;
+      this.yAxisSecondaryMinimumFixedRadioButton.Text = "&Fixed:";
+      this.yAxisSecondaryMinimumFixedRadioButton.UseVisualStyleBackColor = true;
+      this.yAxisSecondaryMinimumFixedRadioButton.CheckedChanged += new System.EventHandler(this.yAxisSecondaryMinimumRadioButton_CheckedChanged);
+      // 
+      // yAxisSecondaryMinimumAutoRadioButton
+      // 
+      this.yAxisSecondaryMinimumAutoRadioButton.AutoSize = true;
+      this.yAxisSecondaryMinimumAutoRadioButton.Location = new System.Drawing.Point(0, 1);
+      this.yAxisSecondaryMinimumAutoRadioButton.Name = "yAxisSecondaryMinimumAutoRadioButton";
+      this.yAxisSecondaryMinimumAutoRadioButton.Size = new System.Drawing.Size(47, 17);
+      this.yAxisSecondaryMinimumAutoRadioButton.TabIndex = 0;
+      this.yAxisSecondaryMinimumAutoRadioButton.TabStop = true;
+      this.yAxisSecondaryMinimumAutoRadioButton.Text = "&Auto";
+      this.yAxisSecondaryMinimumAutoRadioButton.UseVisualStyleBackColor = true;
+      this.yAxisSecondaryMinimumAutoRadioButton.CheckedChanged += new System.EventHandler(this.yAxisSecondaryMinimumRadioButton_CheckedChanged);
+      // 
+      // yAxisSecondaryMinimumFixedTextBox
+      // 
+      this.yAxisSecondaryMinimumFixedTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.yAxisSecondaryMinimumFixedTextBox.Location = new System.Drawing.Point(191, 45);
+      this.yAxisSecondaryMinimumFixedTextBox.Name = "yAxisSecondaryMinimumFixedTextBox";
+      this.yAxisSecondaryMinimumFixedTextBox.Size = new System.Drawing.Size(244, 20);
+      this.yAxisSecondaryMinimumFixedTextBox.TabIndex = 4;
+      this.yAxisSecondaryMinimumFixedTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.yAxisSecondaryMinimumFixedTextBox_Validating);
+      // 
+      // yAxisSecondaryMaximumFixedTextBox
+      // 
+      this.yAxisSecondaryMaximumFixedTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.yAxisSecondaryMaximumFixedTextBox.Location = new System.Drawing.Point(191, 71);
+      this.yAxisSecondaryMaximumFixedTextBox.Name = "yAxisSecondaryMaximumFixedTextBox";
+      this.yAxisSecondaryMaximumFixedTextBox.Size = new System.Drawing.Size(244, 20);
+      this.yAxisSecondaryMaximumFixedTextBox.TabIndex = 7;
+      this.yAxisSecondaryMaximumFixedTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.yAxisSecondaryMaximumFixedTextBox_Validating);
+      // 
+      // label13
+      // 
+      this.label13.AutoSize = true;
+      this.label13.Location = new System.Drawing.Point(6, 74);
+      this.label13.Name = "label13";
+      this.label13.Size = new System.Drawing.Size(54, 13);
+      this.label13.TabIndex = 5;
+      this.label13.Text = "&Maximum:";
+      // 
+      // label14
+      // 
+      this.label14.AutoSize = true;
+      this.label14.Location = new System.Drawing.Point(6, 48);
+      this.label14.Name = "label14";
+      this.label14.Size = new System.Drawing.Size(51, 13);
+      this.label14.TabIndex = 2;
+      this.label14.Text = "&Minimum:";
+      // 
+      // yAxisPrimaryGroupBox
+      // 
+      this.yAxisPrimaryGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.yAxisPrimaryGroupBox.Controls.Add(this.yAxisPrimaryLogScaleCheckBox);
+      this.yAxisPrimaryGroupBox.Controls.Add(this.panel6);
+      this.yAxisPrimaryGroupBox.Controls.Add(this.panel5);
+      this.yAxisPrimaryGroupBox.Controls.Add(this.yAxisPrimaryMinimumFixedTextBox);
+      this.yAxisPrimaryGroupBox.Controls.Add(this.yAxisPrimaryMaximumFixedTextBox);
+      this.yAxisPrimaryGroupBox.Controls.Add(this.label7);
+      this.yAxisPrimaryGroupBox.Controls.Add(this.yAxisPrimaryTitleTextBox);
+      this.yAxisPrimaryGroupBox.Controls.Add(this.label8);
+      this.yAxisPrimaryGroupBox.Controls.Add(this.label1);
+      this.yAxisPrimaryGroupBox.Location = new System.Drawing.Point(3, 3);
+      this.yAxisPrimaryGroupBox.Name = "yAxisPrimaryGroupBox";
+      this.yAxisPrimaryGroupBox.Size = new System.Drawing.Size(441, 126);
+      this.yAxisPrimaryGroupBox.TabIndex = 0;
+      this.yAxisPrimaryGroupBox.TabStop = false;
+      this.yAxisPrimaryGroupBox.Text = "Primary Axis";
+      // 
+      // yAxisPrimaryLogScaleCheckBox
+      // 
+      this.yAxisPrimaryLogScaleCheckBox.AutoSize = true;
+      this.yAxisPrimaryLogScaleCheckBox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
+      this.yAxisPrimaryLogScaleCheckBox.Location = new System.Drawing.Point(6, 99);
+      this.yAxisPrimaryLogScaleCheckBox.Name = "yAxisPrimaryLogScaleCheckBox";
+      this.yAxisPrimaryLogScaleCheckBox.Size = new System.Drawing.Size(83, 17);
+      this.yAxisPrimaryLogScaleCheckBox.TabIndex = 10;
+      this.yAxisPrimaryLogScaleCheckBox.Text = "Logarithmic:";
+      this.yAxisPrimaryLogScaleCheckBox.UseVisualStyleBackColor = true;
+      this.yAxisPrimaryLogScaleCheckBox.CheckedChanged += new System.EventHandler(this.yAxisPrimaryLogScaleCheckBox_CheckedChanged);
+      // 
+      // panel6
+      // 
+      this.panel6.Controls.Add(this.yAxisPrimaryMaximumFixedRadioButton);
+      this.panel6.Controls.Add(this.yAxisPrimaryMaximumAutoRadioButton);
+      this.panel6.Location = new System.Drawing.Point(74, 71);
+      this.panel6.Name = "panel6";
+      this.panel6.Size = new System.Drawing.Size(106, 20);
+      this.panel6.TabIndex = 6;
+      // 
+      // yAxisPrimaryMaximumFixedRadioButton
+      // 
+      this.yAxisPrimaryMaximumFixedRadioButton.AutoSize = true;
+      this.yAxisPrimaryMaximumFixedRadioButton.Location = new System.Drawing.Point(53, 1);
+      this.yAxisPrimaryMaximumFixedRadioButton.Name = "yAxisPrimaryMaximumFixedRadioButton";
+      this.yAxisPrimaryMaximumFixedRadioButton.Size = new System.Drawing.Size(53, 17);
+      this.yAxisPrimaryMaximumFixedRadioButton.TabIndex = 1;
+      this.yAxisPrimaryMaximumFixedRadioButton.TabStop = true;
+      this.yAxisPrimaryMaximumFixedRadioButton.Text = "&Fixed:";
+      this.yAxisPrimaryMaximumFixedRadioButton.UseVisualStyleBackColor = true;
+      this.yAxisPrimaryMaximumFixedRadioButton.CheckedChanged += new System.EventHandler(this.yAxisPrimaryMaximumRadioButton_CheckedChanged);
+      // 
+      // yAxisPrimaryMaximumAutoRadioButton
+      // 
+      this.yAxisPrimaryMaximumAutoRadioButton.AutoSize = true;
+      this.yAxisPrimaryMaximumAutoRadioButton.Location = new System.Drawing.Point(0, 1);
+      this.yAxisPrimaryMaximumAutoRadioButton.Name = "yAxisPrimaryMaximumAutoRadioButton";
+      this.yAxisPrimaryMaximumAutoRadioButton.Size = new System.Drawing.Size(47, 17);
+      this.yAxisPrimaryMaximumAutoRadioButton.TabIndex = 0;
+      this.yAxisPrimaryMaximumAutoRadioButton.TabStop = true;
+      this.yAxisPrimaryMaximumAutoRadioButton.Text = "&Auto";
+      this.yAxisPrimaryMaximumAutoRadioButton.UseVisualStyleBackColor = true;
+      this.yAxisPrimaryMaximumAutoRadioButton.CheckedChanged += new System.EventHandler(this.yAxisPrimaryMaximumRadioButton_CheckedChanged);
+      // 
+      // panel5
+      // 
+      this.panel5.Controls.Add(this.yAxisPrimaryMinimumAutoRadioButton);
+      this.panel5.Controls.Add(this.yAxisPrimaryMinimumFixedRadioButton);
+      this.panel5.Location = new System.Drawing.Point(74, 45);
+      this.panel5.Name = "panel5";
+      this.panel5.Size = new System.Drawing.Size(106, 20);
+      this.panel5.TabIndex = 3;
+      // 
+      // yAxisPrimaryMinimumAutoRadioButton
+      // 
+      this.yAxisPrimaryMinimumAutoRadioButton.AutoSize = true;
+      this.yAxisPrimaryMinimumAutoRadioButton.Location = new System.Drawing.Point(0, 1);
+      this.yAxisPrimaryMinimumAutoRadioButton.Name = "yAxisPrimaryMinimumAutoRadioButton";
+      this.yAxisPrimaryMinimumAutoRadioButton.Size = new System.Drawing.Size(47, 17);
+      this.yAxisPrimaryMinimumAutoRadioButton.TabIndex = 0;
+      this.yAxisPrimaryMinimumAutoRadioButton.TabStop = true;
+      this.yAxisPrimaryMinimumAutoRadioButton.Text = "&Auto";
+      this.yAxisPrimaryMinimumAutoRadioButton.UseVisualStyleBackColor = true;
+      this.yAxisPrimaryMinimumAutoRadioButton.CheckedChanged += new System.EventHandler(this.yAxisPrimaryMinimumRadioButton_CheckedChanged);
+      // 
+      // yAxisPrimaryMinimumFixedRadioButton
+      // 
+      this.yAxisPrimaryMinimumFixedRadioButton.AutoSize = true;
+      this.yAxisPrimaryMinimumFixedRadioButton.Location = new System.Drawing.Point(53, 1);
+      this.yAxisPrimaryMinimumFixedRadioButton.Name = "yAxisPrimaryMinimumFixedRadioButton";
+      this.yAxisPrimaryMinimumFixedRadioButton.Size = new System.Drawing.Size(53, 17);
+      this.yAxisPrimaryMinimumFixedRadioButton.TabIndex = 1;
+      this.yAxisPrimaryMinimumFixedRadioButton.TabStop = true;
+      this.yAxisPrimaryMinimumFixedRadioButton.Text = "&Fixed:";
+      this.yAxisPrimaryMinimumFixedRadioButton.UseVisualStyleBackColor = true;
+      this.yAxisPrimaryMinimumFixedRadioButton.CheckedChanged += new System.EventHandler(this.yAxisPrimaryMinimumRadioButton_CheckedChanged);
+      // 
+      // yAxisPrimaryMinimumFixedTextBox
+      // 
+      this.yAxisPrimaryMinimumFixedTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.yAxisPrimaryMinimumFixedTextBox.Location = new System.Drawing.Point(191, 45);
+      this.yAxisPrimaryMinimumFixedTextBox.Name = "yAxisPrimaryMinimumFixedTextBox";
+      this.yAxisPrimaryMinimumFixedTextBox.Size = new System.Drawing.Size(244, 20);
+      this.yAxisPrimaryMinimumFixedTextBox.TabIndex = 4;
+      this.yAxisPrimaryMinimumFixedTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.yAxisPrimaryMinimumFixedTextBox_Validating);
+      // 
+      // yAxisPrimaryMaximumFixedTextBox
+      // 
+      this.yAxisPrimaryMaximumFixedTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.yAxisPrimaryMaximumFixedTextBox.Location = new System.Drawing.Point(191, 71);
+      this.yAxisPrimaryMaximumFixedTextBox.Name = "yAxisPrimaryMaximumFixedTextBox";
+      this.yAxisPrimaryMaximumFixedTextBox.Size = new System.Drawing.Size(244, 20);
+      this.yAxisPrimaryMaximumFixedTextBox.TabIndex = 7;
+      this.yAxisPrimaryMaximumFixedTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.yAxisPrimaryMaximumFixedTextBox_Validating);
+      // 
+      // label7
+      // 
+      this.label7.AutoSize = true;
+      this.label7.Location = new System.Drawing.Point(6, 74);
+      this.label7.Name = "label7";
+      this.label7.Size = new System.Drawing.Size(54, 13);
+      this.label7.TabIndex = 5;
+      this.label7.Text = "&Maximum:";
+      // 
+      // label8
+      // 
+      this.label8.AutoSize = true;
+      this.label8.Location = new System.Drawing.Point(6, 48);
+      this.label8.Name = "label8";
+      this.label8.Size = new System.Drawing.Size(51, 13);
+      this.label8.TabIndex = 2;
+      this.label8.Text = "&Minimum:";
+      // 
+      // titleTextBox
+      // 
+      this.titleTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.titleTextBox.Location = new System.Drawing.Point(66, 0);
+      this.titleTextBox.Name = "titleTextBox";
+      this.titleTextBox.Size = new System.Drawing.Size(389, 20);
+      this.titleTextBox.TabIndex = 1;
+      this.titleTextBox.Validated += new System.EventHandler(this.titleTextBox_Validated);
+      // 
+      // label15
+      // 
+      this.label15.AutoSize = true;
+      this.label15.Location = new System.Drawing.Point(3, 3);
+      this.label15.Name = "label15";
+      this.label15.Size = new System.Drawing.Size(30, 13);
+      this.label15.TabIndex = 0;
+      this.label15.Text = "&Title:";
+      // 
+      // axisFontLabel
+      // 
+      this.axisFontLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.axisFontLabel.AutoSize = true;
+      this.axisFontLabel.Location = new System.Drawing.Point(98, 60);
+      this.axisFontLabel.Name = "axisFontLabel";
+      this.axisFontLabel.Size = new System.Drawing.Size(43, 13);
+      this.axisFontLabel.TabIndex = 7;
+      this.axisFontLabel.Text = "( none )";
+      // 
+      // titleFontLabel
+      // 
+      this.titleFontLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.titleFontLabel.AutoSize = true;
+      this.titleFontLabel.Location = new System.Drawing.Point(98, 31);
+      this.titleFontLabel.Name = "titleFontLabel";
+      this.titleFontLabel.Size = new System.Drawing.Size(43, 13);
+      this.titleFontLabel.TabIndex = 4;
+      this.titleFontLabel.Text = "( none )";
+      // 
+      // axisFontButton
+      // 
+      this.axisFontButton.Location = new System.Drawing.Point(66, 55);
+      this.axisFontButton.Name = "axisFontButton";
+      this.axisFontButton.Size = new System.Drawing.Size(26, 23);
+      this.axisFontButton.TabIndex = 6;
+      this.axisFontButton.Text = "...";
+      this.axisFontButton.UseVisualStyleBackColor = true;
+      this.axisFontButton.Click += new System.EventHandler(this.axisFontButton_Click);
+      // 
+      // label3
+      // 
+      this.label3.AutoSize = true;
+      this.label3.Location = new System.Drawing.Point(3, 60);
+      this.label3.Name = "label3";
+      this.label3.Size = new System.Drawing.Size(57, 13);
+      this.label3.TabIndex = 5;
+      this.label3.Text = "&Axes Font:";
+      // 
+      // titleFontButton
+      // 
+      this.titleFontButton.Location = new System.Drawing.Point(66, 26);
+      this.titleFontButton.Name = "titleFontButton";
+      this.titleFontButton.Size = new System.Drawing.Size(26, 23);
+      this.titleFontButton.TabIndex = 3;
+      this.titleFontButton.Text = "...";
+      this.titleFontButton.UseVisualStyleBackColor = true;
+      this.titleFontButton.Click += new System.EventHandler(this.titleFontButton_Click);
+      // 
+      // label2
+      // 
+      this.label2.AutoSize = true;
+      this.label2.Location = new System.Drawing.Point(3, 31);
+      this.label2.Name = "label2";
+      this.label2.Size = new System.Drawing.Size(54, 13);
+      this.label2.TabIndex = 2;
+      this.label2.Text = "&Title Font:";
+      // 
+      // errorProvider
+      // 
+      this.errorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
+      this.errorProvider.ContainerControl = this;
+      // 
+      // titleFontDialog
+      // 
+      this.titleFontDialog.Color = System.Drawing.SystemColors.ControlText;
+      this.titleFontDialog.FontMustExist = true;
+      this.titleFontDialog.ShowColor = true;
+      // 
+      // axisFontDialog
+      // 
+      this.axisFontDialog.Color = System.Drawing.SystemColors.ControlText;
+      // 
+      // DataTableVisualPropertiesControl
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.axisFontLabel);
+      this.Controls.Add(this.label15);
+      this.Controls.Add(this.axisFontButton);
+      this.Controls.Add(this.titleFontLabel);
+      this.Controls.Add(this.label3);
+      this.Controls.Add(this.titleTextBox);
+      this.Controls.Add(this.axisTabControl);
+      this.Controls.Add(this.label2);
+      this.Controls.Add(this.titleFontButton);
+      this.Name = "DataTableVisualPropertiesControl";
+      this.Size = new System.Drawing.Size(455, 373);
+      this.xAxisPrimaryGroupBox.ResumeLayout(false);
+      this.xAxisPrimaryGroupBox.PerformLayout();
+      this.panel2.ResumeLayout(false);
+      this.panel2.PerformLayout();
+      this.panel1.ResumeLayout(false);
+      this.panel1.PerformLayout();
+      this.xAxisSecondaryGroupBox.ResumeLayout(false);
+      this.xAxisSecondaryGroupBox.PerformLayout();
+      this.panel4.ResumeLayout(false);
+      this.panel4.PerformLayout();
+      this.panel3.ResumeLayout(false);
+      this.panel3.PerformLayout();
+      this.axisTabControl.ResumeLayout(false);
+      this.xAxisTabPage.ResumeLayout(false);
+      this.yAxisTabPage.ResumeLayout(false);
+      this.yAxisSecondaryGroupBox.ResumeLayout(false);
+      this.yAxisSecondaryGroupBox.PerformLayout();
+      this.panel8.ResumeLayout(false);
+      this.panel8.PerformLayout();
+      this.panel7.ResumeLayout(false);
+      this.panel7.PerformLayout();
+      this.yAxisPrimaryGroupBox.ResumeLayout(false);
+      this.yAxisPrimaryGroupBox.PerformLayout();
+      this.panel6.ResumeLayout(false);
+      this.panel6.PerformLayout();
+      this.panel5.ResumeLayout(false);
+      this.panel5.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.TextBox yAxisPrimaryTitleTextBox;
+    private System.Windows.Forms.TextBox yAxisSecondaryTitleTextBox;
+    private System.Windows.Forms.Label label4;
+    private System.Windows.Forms.GroupBox xAxisPrimaryGroupBox;
+    private System.Windows.Forms.Label label12;
+    private System.Windows.Forms.Label label9;
+    private System.Windows.Forms.TextBox xAxisPrimaryTitleTextBox;
+    private System.Windows.Forms.Label label11;
+    private System.Windows.Forms.TextBox xAxisPrimaryMaximumFixedTextBox;
+    private System.Windows.Forms.RadioButton xAxisPrimaryMaximumFixedRadioButton;
+    private System.Windows.Forms.RadioButton xAxisPrimaryMaximumAutoRadioButton;
+    private System.Windows.Forms.TextBox xAxisPrimaryMinimumFixedTextBox;
+    private System.Windows.Forms.RadioButton xAxisPrimaryMinimumFixedRadioButton;
+    private System.Windows.Forms.RadioButton xAxisPrimaryMinimumAutoRadioButton;
+    private System.Windows.Forms.GroupBox xAxisSecondaryGroupBox;
+    private System.Windows.Forms.Label label10;
+    private System.Windows.Forms.TextBox xAxisSecondaryTitleTextBox;
+    private System.Windows.Forms.Label label5;
+    private System.Windows.Forms.Label label6;
+    private System.Windows.Forms.TextBox xAxisSecondaryMaximumFixedTextBox;
+    private System.Windows.Forms.RadioButton xAxisSecondaryMaximumFixedRadioButton;
+    private System.Windows.Forms.RadioButton xAxisSecondaryMaximumAutoRadioButton;
+    private System.Windows.Forms.TextBox xAxisSecondaryMinimumFixedTextBox;
+    private System.Windows.Forms.RadioButton xAxisSecondaryMinimumFixedRadioButton;
+    private System.Windows.Forms.RadioButton xAxisSecondaryMinimumAutoRadioButton;
+    private System.Windows.Forms.TabControl axisTabControl;
+    private System.Windows.Forms.TabPage xAxisTabPage;
+    private System.Windows.Forms.TabPage yAxisTabPage;
+    private System.Windows.Forms.GroupBox yAxisSecondaryGroupBox;
+    private System.Windows.Forms.Label label13;
+    private System.Windows.Forms.Label label14;
+    private System.Windows.Forms.TextBox yAxisSecondaryMaximumFixedTextBox;
+    private System.Windows.Forms.RadioButton yAxisSecondaryMaximumFixedRadioButton;
+    private System.Windows.Forms.RadioButton yAxisSecondaryMaximumAutoRadioButton;
+    private System.Windows.Forms.TextBox yAxisSecondaryMinimumFixedTextBox;
+    private System.Windows.Forms.RadioButton yAxisSecondaryMinimumFixedRadioButton;
+    private System.Windows.Forms.RadioButton yAxisSecondaryMinimumAutoRadioButton;
+    private System.Windows.Forms.GroupBox yAxisPrimaryGroupBox;
+    private System.Windows.Forms.Label label7;
+    private System.Windows.Forms.Label label8;
+    private System.Windows.Forms.TextBox yAxisPrimaryMaximumFixedTextBox;
+    private System.Windows.Forms.RadioButton yAxisPrimaryMaximumFixedRadioButton;
+    private System.Windows.Forms.RadioButton yAxisPrimaryMaximumAutoRadioButton;
+    private System.Windows.Forms.TextBox yAxisPrimaryMinimumFixedTextBox;
+    private System.Windows.Forms.RadioButton yAxisPrimaryMinimumFixedRadioButton;
+    private System.Windows.Forms.RadioButton yAxisPrimaryMinimumAutoRadioButton;
+    private System.Windows.Forms.ErrorProvider errorProvider;
+    private System.Windows.Forms.FontDialog titleFontDialog;
+    private System.Windows.Forms.Button titleFontButton;
+    private System.Windows.Forms.Label label2;
+    private System.Windows.Forms.Button axisFontButton;
+    private System.Windows.Forms.Label label3;
+    private System.Windows.Forms.Label axisFontLabel;
+    private System.Windows.Forms.Label titleFontLabel;
+    private System.Windows.Forms.FontDialog axisFontDialog;
+    private System.Windows.Forms.Label label15;
+    private System.Windows.Forms.TextBox titleTextBox;
+    private System.Windows.Forms.Panel panel1;
+    private System.Windows.Forms.Panel panel2;
+    private System.Windows.Forms.Panel panel4;
+    private System.Windows.Forms.Panel panel3;
+    private System.Windows.Forms.Panel panel6;
+    private System.Windows.Forms.Panel panel5;
+    private System.Windows.Forms.Panel panel7;
+    private System.Windows.Forms.Panel panel8;
+    private System.Windows.Forms.CheckBox xAxisPrimaryLogScaleCheckBox;
+    private System.Windows.Forms.CheckBox xAxisSecondaryLogScaleCheckBox;
+    private System.Windows.Forms.CheckBox yAxisSecondaryLogScaleCheckBox;
+    private System.Windows.Forms.CheckBox yAxisPrimaryLogScaleCheckBox;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableVisualPropertiesControl.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableVisualPropertiesControl.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableVisualPropertiesControl.cs	(revision 12764)
@@ -0,0 +1,492 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace HeuristicLab.Analysis.Views {
+  [View("DataTable Visual Properties")]
+  public partial class DataTableVisualPropertiesControl : UserControl {
+    protected bool SuppressEvents { get; set; }
+
+    private DataTableVisualProperties content;
+    public DataTableVisualProperties Content {
+      get { return content; }
+      set {
+        bool changed = (value != content);
+        content = value;
+        if (changed) OnContentChanged();
+      }
+    }
+
+    public DataTableVisualPropertiesControl() {
+      InitializeComponent();
+      errorProvider.SetIconAlignment(xAxisPrimaryMinimumFixedTextBox, ErrorIconAlignment.MiddleLeft);
+      errorProvider.SetIconAlignment(xAxisPrimaryMaximumFixedTextBox, ErrorIconAlignment.MiddleLeft);
+      errorProvider.SetIconAlignment(xAxisSecondaryMinimumFixedTextBox, ErrorIconAlignment.MiddleLeft);
+      errorProvider.SetIconAlignment(xAxisSecondaryMaximumFixedTextBox, ErrorIconAlignment.MiddleLeft);
+      errorProvider.SetIconAlignment(yAxisPrimaryMinimumFixedTextBox, ErrorIconAlignment.MiddleLeft);
+      errorProvider.SetIconAlignment(yAxisPrimaryMaximumFixedTextBox, ErrorIconAlignment.MiddleLeft);
+      errorProvider.SetIconAlignment(yAxisSecondaryMinimumFixedTextBox, ErrorIconAlignment.MiddleLeft);
+      errorProvider.SetIconAlignment(yAxisSecondaryMaximumFixedTextBox, ErrorIconAlignment.MiddleLeft);
+      errorProvider.SetIconPadding(xAxisPrimaryMinimumFixedTextBox, 2);
+      errorProvider.SetIconPadding(xAxisPrimaryMaximumFixedTextBox, 2);
+      errorProvider.SetIconPadding(xAxisSecondaryMinimumFixedTextBox, 2);
+      errorProvider.SetIconPadding(xAxisSecondaryMaximumFixedTextBox, 2);
+      errorProvider.SetIconPadding(yAxisPrimaryMinimumFixedTextBox, 2);
+      errorProvider.SetIconPadding(yAxisPrimaryMaximumFixedTextBox, 2);
+      errorProvider.SetIconPadding(yAxisSecondaryMinimumFixedTextBox, 2);
+      errorProvider.SetIconPadding(yAxisSecondaryMaximumFixedTextBox, 2);
+    }
+
+    protected virtual void OnContentChanged() {
+      SuppressEvents = true;
+      try {
+        if (Content == null) {
+          titleFontLabel.Text = "( none )";
+          axisFontLabel.Text = "( none )";
+          titleTextBox.Text = string.Empty;
+
+          xAxisPrimaryTitleTextBox.Text = string.Empty;
+          xAxisPrimaryMinimumAutoRadioButton.Checked = false;
+          xAxisPrimaryMinimumFixedRadioButton.Checked = false;
+          xAxisPrimaryMinimumFixedTextBox.Text = string.Empty;
+          xAxisPrimaryMaximumAutoRadioButton.Checked = false;
+          xAxisPrimaryMaximumFixedRadioButton.Checked = false;
+          xAxisPrimaryMaximumFixedTextBox.Text = string.Empty;
+          xAxisPrimaryLogScaleCheckBox.Checked = false;
+          xAxisSecondaryTitleTextBox.Text = string.Empty;
+          xAxisSecondaryMinimumAutoRadioButton.Checked = false;
+          xAxisSecondaryMinimumFixedRadioButton.Checked = false;
+          xAxisSecondaryMinimumFixedTextBox.Text = string.Empty;
+          xAxisSecondaryMaximumAutoRadioButton.Checked = false;
+          xAxisSecondaryMaximumFixedRadioButton.Checked = false;
+          xAxisSecondaryMaximumFixedTextBox.Text = string.Empty;
+          xAxisSecondaryLogScaleCheckBox.Checked = false;
+
+          yAxisPrimaryTitleTextBox.Text = string.Empty;
+          yAxisPrimaryMinimumAutoRadioButton.Checked = false;
+          yAxisPrimaryMinimumFixedRadioButton.Checked = false;
+          yAxisPrimaryMinimumFixedTextBox.Text = string.Empty;
+          yAxisPrimaryMaximumAutoRadioButton.Checked = false;
+          yAxisPrimaryMaximumFixedRadioButton.Checked = false;
+          yAxisPrimaryMaximumFixedTextBox.Text = string.Empty;
+          yAxisPrimaryLogScaleCheckBox.Checked = false;
+          yAxisSecondaryTitleTextBox.Text = string.Empty;
+          yAxisSecondaryMinimumAutoRadioButton.Checked = false;
+          yAxisSecondaryMinimumFixedRadioButton.Checked = false;
+          yAxisSecondaryMinimumFixedTextBox.Text = string.Empty;
+          yAxisSecondaryMaximumAutoRadioButton.Checked = false;
+          yAxisSecondaryMaximumFixedRadioButton.Checked = false;
+          yAxisSecondaryMaximumFixedTextBox.Text = string.Empty;
+          yAxisSecondaryLogScaleCheckBox.Checked = false;
+        } else {
+          titleFontLabel.Text = "( " + FormatFont(Content.TitleFont) + " )";
+          axisFontLabel.Text = "( " + FormatFont(Content.AxisTitleFont) + " )";
+          titleTextBox.Text = Content.Title;
+
+          xAxisPrimaryTitleTextBox.Text = Content.XAxisTitle;
+          xAxisPrimaryMinimumAutoRadioButton.Checked = Content.XAxisMinimumAuto;
+          xAxisPrimaryMinimumFixedRadioButton.Checked = !Content.XAxisMinimumAuto;
+          xAxisPrimaryMinimumFixedTextBox.Text = Content.XAxisMinimumFixedValue.ToString();
+          xAxisPrimaryMaximumAutoRadioButton.Checked = Content.XAxisMaximumAuto;
+          xAxisPrimaryMaximumFixedRadioButton.Checked = !Content.XAxisMaximumAuto;
+          xAxisPrimaryMaximumFixedTextBox.Text = Content.XAxisMaximumFixedValue.ToString();
+          xAxisPrimaryLogScaleCheckBox.Checked = Content.XAxisLogScale;
+          xAxisSecondaryTitleTextBox.Text = Content.SecondXAxisTitle;
+          xAxisSecondaryMinimumAutoRadioButton.Checked = Content.SecondXAxisMinimumAuto;
+          xAxisSecondaryMinimumFixedRadioButton.Checked = !Content.SecondXAxisMinimumAuto;
+          xAxisSecondaryMinimumFixedTextBox.Text = Content.SecondXAxisMinimumFixedValue.ToString();
+          xAxisSecondaryMaximumAutoRadioButton.Checked = Content.SecondXAxisMaximumAuto;
+          xAxisSecondaryMaximumFixedRadioButton.Checked = !Content.SecondXAxisMaximumAuto;
+          xAxisSecondaryMaximumFixedTextBox.Text = Content.SecondXAxisMaximumFixedValue.ToString();
+          xAxisSecondaryLogScaleCheckBox.Checked = Content.SecondXAxisLogScale;
+
+          yAxisPrimaryTitleTextBox.Text = Content.YAxisTitle;
+          yAxisPrimaryMinimumAutoRadioButton.Checked = Content.YAxisMinimumAuto;
+          yAxisPrimaryMinimumFixedRadioButton.Checked = !Content.YAxisMinimumAuto;
+          yAxisPrimaryMinimumFixedTextBox.Text = Content.YAxisMinimumFixedValue.ToString();
+          yAxisPrimaryMaximumAutoRadioButton.Checked = Content.YAxisMaximumAuto;
+          yAxisPrimaryMaximumFixedRadioButton.Checked = !Content.YAxisMaximumAuto;
+          yAxisPrimaryMaximumFixedTextBox.Text = Content.YAxisMaximumFixedValue.ToString();
+          yAxisPrimaryLogScaleCheckBox.Checked = Content.YAxisLogScale;
+          yAxisSecondaryTitleTextBox.Text = Content.SecondYAxisTitle;
+          yAxisSecondaryMinimumAutoRadioButton.Checked = Content.SecondYAxisMinimumAuto;
+          yAxisSecondaryMinimumFixedRadioButton.Checked = !Content.SecondYAxisMinimumAuto;
+          yAxisSecondaryMinimumFixedTextBox.Text = Content.SecondYAxisMinimumFixedValue.ToString();
+          yAxisSecondaryMaximumAutoRadioButton.Checked = Content.SecondYAxisMaximumAuto;
+          yAxisSecondaryMaximumFixedRadioButton.Checked = !Content.SecondYAxisMaximumAuto;
+          yAxisSecondaryMaximumFixedTextBox.Text = Content.SecondYAxisMaximumFixedValue.ToString();
+          yAxisSecondaryLogScaleCheckBox.Checked = Content.SecondYAxisLogScale;
+        }
+      } finally { SuppressEvents = false; }
+      SetEnabledStateOfControls();
+    }
+
+    protected virtual void SetEnabledStateOfControls() {
+      axisTabControl.Enabled = Content != null;
+      xAxisPrimaryMinimumFixedTextBox.Enabled = xAxisPrimaryMinimumFixedRadioButton.Checked;
+      xAxisPrimaryMaximumFixedTextBox.Enabled = xAxisPrimaryMaximumFixedRadioButton.Checked;
+      xAxisSecondaryMinimumFixedTextBox.Enabled = xAxisSecondaryMinimumFixedRadioButton.Checked;
+      xAxisSecondaryMaximumFixedTextBox.Enabled = xAxisSecondaryMaximumFixedRadioButton.Checked;
+
+      yAxisPrimaryMinimumFixedTextBox.Enabled = yAxisPrimaryMinimumFixedRadioButton.Checked;
+      yAxisPrimaryMaximumFixedTextBox.Enabled = yAxisPrimaryMaximumFixedRadioButton.Checked;
+      yAxisSecondaryMinimumFixedTextBox.Enabled = yAxisSecondaryMinimumFixedRadioButton.Checked;
+      yAxisSecondaryMaximumFixedTextBox.Enabled = yAxisSecondaryMaximumFixedRadioButton.Checked;
+    }
+
+    #region Event Handlers
+    private void yPrimaryTitleTextBox_Validated(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        Content.YAxisTitle = yAxisPrimaryTitleTextBox.Text;
+      }
+    }
+
+    private void ySecondaryTitleTextBox_Validated(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        Content.SecondYAxisTitle = yAxisSecondaryTitleTextBox.Text;
+      }
+    }
+
+    private void xPrimaryTitleTextBox_Validated(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        Content.XAxisTitle = xAxisPrimaryTitleTextBox.Text;
+      }
+    }
+
+    private void xSecondaryTitleTextBox_Validated(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        Content.SecondXAxisTitle = xAxisSecondaryTitleTextBox.Text;
+      }
+    }
+
+    private void xAxisPrimaryMinimumFixedTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        TextBox tb = (TextBox)sender;
+        double val;
+        if (double.TryParse(tb.Text, out val)) {
+          if (val >= Content.XAxisMaximumFixedValue) {
+            errorProvider.SetError(tb, "Number must be smaller than maximum.");
+            e.Cancel = true;
+          } else {
+            Content.XAxisMinimumFixedValue = val;
+            errorProvider.SetError(tb, string.Empty);
+          }
+        } else {
+          errorProvider.SetError(tb, "Not a valid number.");
+          e.Cancel = true;
+        }
+      }
+    }
+
+    private void xAxisPrimaryMaximumFixedTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        TextBox tb = (TextBox)sender;
+        double val;
+        if (double.TryParse(tb.Text, out val)) {
+          if (val <= Content.XAxisMinimumFixedValue) {
+            errorProvider.SetError(tb, "Number must be greater than minimum.");
+            e.Cancel = true;
+          } else {
+            Content.XAxisMaximumFixedValue = val;
+            errorProvider.SetError(tb, string.Empty);
+          }
+        } else {
+          errorProvider.SetError(tb, "Not a valid number.");
+          e.Cancel = true;
+        }
+      }
+    }
+
+    private void xAxisSecondaryMinimumFixedTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        TextBox tb = (TextBox)sender;
+        double val;
+        if (double.TryParse(tb.Text, out val)) {
+          if (val >= Content.SecondXAxisMaximumFixedValue) {
+            errorProvider.SetError(tb, "Number must be smaller than maximum.");
+            e.Cancel = true;
+          } else {
+            Content.SecondXAxisMinimumFixedValue = val;
+            errorProvider.SetError(tb, string.Empty);
+          }
+        } else {
+          errorProvider.SetError(tb, "Not a valid number.");
+          e.Cancel = true;
+        }
+      }
+    }
+
+    private void xAxisSecondaryMaximumFixedTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        TextBox tb = (TextBox)sender;
+        double val;
+        if (double.TryParse(tb.Text, out val)) {
+          if (val <= Content.SecondXAxisMinimumFixedValue) {
+            errorProvider.SetError(tb, "Number must be greater than minimum.");
+            e.Cancel = true;
+          } else {
+            Content.SecondXAxisMaximumFixedValue = val;
+            errorProvider.SetError(tb, string.Empty);
+          }
+        } else {
+          errorProvider.SetError(tb, "Not a valid number.");
+          e.Cancel = true;
+        }
+      }
+    }
+
+    private void yAxisPrimaryMinimumFixedTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        TextBox tb = (TextBox)sender;
+        double val;
+        if (double.TryParse(tb.Text, out val)) {
+          if (val >= Content.YAxisMaximumFixedValue) {
+            errorProvider.SetError(tb, "Number must be smaller than maximum.");
+            e.Cancel = true;
+          } else {
+            Content.YAxisMinimumFixedValue = val;
+            errorProvider.SetError(tb, string.Empty);
+          }
+        } else {
+          errorProvider.SetError(tb, "Not a valid number.");
+          e.Cancel = true;
+        }
+      }
+    }
+
+    private void yAxisPrimaryMaximumFixedTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        TextBox tb = (TextBox)sender;
+        double val;
+        if (double.TryParse(tb.Text, out val)) {
+          if (val <= Content.YAxisMinimumFixedValue) {
+            errorProvider.SetError(tb, "Number must be greater than minimum.");
+            e.Cancel = true;
+          } else {
+            Content.YAxisMaximumFixedValue = val;
+            errorProvider.SetError(tb, string.Empty);
+          }
+        } else {
+          errorProvider.SetError(tb, "Not a valid number.");
+          e.Cancel = true;
+        }
+      }
+    }
+
+    private void yAxisSecondaryMinimumFixedTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        TextBox tb = (TextBox)sender;
+        double val;
+        if (double.TryParse(tb.Text, out val)) {
+          if (val >= Content.SecondYAxisMaximumFixedValue) {
+            errorProvider.SetError(tb, "Number must be smaller than maximum.");
+            e.Cancel = true;
+          } else {
+            Content.SecondYAxisMinimumFixedValue = val;
+            errorProvider.SetError(tb, string.Empty);
+          }
+        } else {
+          errorProvider.SetError(tb, "Not a valid number.");
+          e.Cancel = true;
+        }
+      }
+    }
+
+    private void yAxisSecondaryMaximumFixedTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        TextBox tb = (TextBox)sender;
+        double val;
+        if (double.TryParse(tb.Text, out val)) {
+          if (val <= Content.SecondYAxisMinimumFixedValue) {
+            errorProvider.SetError(tb, "Number must be greater than minimum.");
+            e.Cancel = true;
+          } else {
+            Content.SecondYAxisMaximumFixedValue = val;
+            errorProvider.SetError(tb, string.Empty);
+          }
+        } else {
+          errorProvider.SetError(tb, "Not a valid number.");
+          e.Cancel = true;
+        }
+      }
+    }
+
+    private void xAxisPrimaryMinimumRadioButton_CheckedChanged(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.XAxisMinimumAuto = xAxisPrimaryMinimumAutoRadioButton.Checked;
+          if (Content.XAxisMinimumAuto) xAxisPrimaryMinimumFixedTextBox.Text = double.NaN.ToString();
+        } finally { SuppressEvents = false; }
+        SetEnabledStateOfControls();
+      }
+    }
+
+    private void xAxisPrimaryMaximumRadioButton_CheckedChanged(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.XAxisMaximumAuto = xAxisPrimaryMaximumAutoRadioButton.Checked;
+          if (Content.XAxisMaximumAuto) xAxisPrimaryMaximumFixedTextBox.Text = double.NaN.ToString();
+        } finally { SuppressEvents = false; }
+        SetEnabledStateOfControls();
+      }
+    }
+
+    private void xAxisSecondaryMinimumRadioButton_CheckedChanged(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.SecondXAxisMinimumAuto = xAxisSecondaryMinimumAutoRadioButton.Checked;
+          if (Content.SecondXAxisMinimumAuto) xAxisSecondaryMinimumFixedTextBox.Text = double.NaN.ToString();
+        } finally { SuppressEvents = false; }
+        SetEnabledStateOfControls();
+      }
+    }
+
+    private void xAxisSecondaryMaximumRadioButton_CheckedChanged(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.SecondXAxisMaximumAuto = xAxisSecondaryMaximumAutoRadioButton.Checked;
+          if (Content.SecondXAxisMaximumAuto) xAxisSecondaryMaximumFixedTextBox.Text = double.NaN.ToString();
+        } finally { SuppressEvents = false; }
+        SetEnabledStateOfControls();
+      }
+    }
+
+    private void yAxisPrimaryMinimumRadioButton_CheckedChanged(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.YAxisMinimumAuto = yAxisPrimaryMinimumAutoRadioButton.Checked;
+          if (Content.YAxisMinimumAuto) yAxisPrimaryMinimumFixedTextBox.Text = double.NaN.ToString();
+        } finally { SuppressEvents = false; }
+        SetEnabledStateOfControls();
+      }
+    }
+
+    private void yAxisPrimaryMaximumRadioButton_CheckedChanged(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.YAxisMaximumAuto = yAxisPrimaryMaximumAutoRadioButton.Checked;
+          if (Content.YAxisMaximumAuto) yAxisPrimaryMaximumFixedTextBox.Text = double.NaN.ToString();
+        } finally { SuppressEvents = false; }
+        SetEnabledStateOfControls();
+      }
+    }
+
+    private void yAxisSecondaryMinimumRadioButton_CheckedChanged(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.SecondYAxisMinimumAuto = yAxisSecondaryMinimumAutoRadioButton.Checked;
+          if (Content.SecondYAxisMinimumAuto) yAxisSecondaryMinimumFixedTextBox.Text = double.NaN.ToString();
+        } finally { SuppressEvents = false; }
+        SetEnabledStateOfControls();
+      }
+    }
+
+    private void yAxisSecondaryMaximumRadioButton_CheckedChanged(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.SecondYAxisMaximumAuto = yAxisSecondaryMaximumAutoRadioButton.Checked;
+          if (Content.SecondYAxisMaximumAuto) yAxisSecondaryMaximumFixedTextBox.Text = double.NaN.ToString();
+        } finally { SuppressEvents = false; }
+        SetEnabledStateOfControls();
+      }
+    }
+
+    private void xAxisPrimaryLogScaleCheckBox_CheckedChanged(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.XAxisLogScale = xAxisPrimaryLogScaleCheckBox.Checked;
+        } finally { SuppressEvents = false; }
+      }
+    }
+
+    private void xAxisSecondaryLogScaleCheckBox_CheckedChanged(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.SecondXAxisLogScale = xAxisSecondaryLogScaleCheckBox.Checked;
+        } finally { SuppressEvents = false; }
+      }
+    }
+
+    private void yAxisPrimaryLogScaleCheckBox_CheckedChanged(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.YAxisLogScale = yAxisPrimaryLogScaleCheckBox.Checked;
+        } finally { SuppressEvents = false; }
+      }
+    }
+
+    private void yAxisSecondaryLogScaleCheckBox_CheckedChanged(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.SecondYAxisLogScale = yAxisSecondaryLogScaleCheckBox.Checked;
+        } finally { SuppressEvents = false; }
+      }
+    }
+
+    private void titleFontButton_Click(object sender, System.EventArgs e) {
+      titleFontDialog.Font = Content.TitleFont;
+      titleFontDialog.Color = Content.TitleColor;
+      if (titleFontDialog.ShowDialog() == DialogResult.OK) {
+        Content.TitleFont = titleFontDialog.Font;
+        Content.TitleColor = titleFontDialog.Color;
+        titleFontLabel.Text = "( " + FormatFont(Content.TitleFont) + " )";
+      }
+    }
+
+    private void axisFontButton_Click(object sender, System.EventArgs e) {
+      axisFontDialog.Font = Content.AxisTitleFont;
+      axisFontDialog.Color = Content.AxisTitleColor;
+      if (axisFontDialog.ShowDialog() == DialogResult.OK) {
+        Content.AxisTitleFont = axisFontDialog.Font;
+        Content.AxisTitleColor = axisFontDialog.Color;
+        axisFontLabel.Text = "( " + FormatFont(Content.AxisTitleFont) + " )";
+      }
+    }
+
+    private void titleTextBox_Validated(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        Content.Title = titleTextBox.Text;
+      }
+    }
+    #endregion
+
+    private string FormatFont(Font f) {
+      if (f == null) return "default";
+      else return f.Name + ", " + f.SizeInPoints.ToString() + "pt, " + f.Style.ToString();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableVisualPropertiesDialog.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableVisualPropertiesDialog.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableVisualPropertiesDialog.Designer.cs	(revision 12764)
@@ -0,0 +1,252 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Analysis.Views {
+  partial class DataTableVisualPropertiesDialog {
+    /// <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.okButton = new System.Windows.Forms.Button();
+      this.cancelButton = new System.Windows.Forms.Button();
+      this.tabControl = new System.Windows.Forms.TabControl();
+      this.seriesTabPage = new System.Windows.Forms.TabPage();
+      this.splitContainer = new System.Windows.Forms.SplitContainer();
+      this.downButton = new System.Windows.Forms.Button();
+      this.upButton = new System.Windows.Forms.Button();
+      this.seriesListView = new System.Windows.Forms.ListView();
+      this.dataRowVisualPropertiesControl = new HeuristicLab.Analysis.Views.DataRowVisualPropertiesControl();
+      this.chartTabPage = new System.Windows.Forms.TabPage();
+      this.dataTableVisualPropertiesControl = new HeuristicLab.Analysis.Views.DataTableVisualPropertiesControl();
+      this.tabControl.SuspendLayout();
+      this.seriesTabPage.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.chartTabPage.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // okButton
+      // 
+      this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.okButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+      this.okButton.Location = new System.Drawing.Point(325, 425);
+      this.okButton.Name = "okButton";
+      this.okButton.Size = new System.Drawing.Size(75, 23);
+      this.okButton.TabIndex = 0;
+      this.okButton.Text = "&OK";
+      this.okButton.UseVisualStyleBackColor = true;
+      this.okButton.Click += new System.EventHandler(this.okButton_Click);
+      // 
+      // 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(406, 425);
+      this.cancelButton.Name = "cancelButton";
+      this.cancelButton.Size = new System.Drawing.Size(75, 23);
+      this.cancelButton.TabIndex = 1;
+      this.cancelButton.Text = "&Cancel";
+      this.cancelButton.UseVisualStyleBackColor = true;
+      this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
+      // 
+      // tabControl
+      // 
+      this.tabControl.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.tabControl.Controls.Add(this.seriesTabPage);
+      this.tabControl.Controls.Add(this.chartTabPage);
+      this.tabControl.Location = new System.Drawing.Point(12, 12);
+      this.tabControl.Name = "tabControl";
+      this.tabControl.SelectedIndex = 0;
+      this.tabControl.Size = new System.Drawing.Size(469, 407);
+      this.tabControl.TabIndex = 2;
+      // 
+      // seriesTabPage
+      // 
+      this.seriesTabPage.Controls.Add(this.splitContainer);
+      this.seriesTabPage.Location = new System.Drawing.Point(4, 22);
+      this.seriesTabPage.Name = "seriesTabPage";
+      this.seriesTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.seriesTabPage.Size = new System.Drawing.Size(461, 381);
+      this.seriesTabPage.TabIndex = 0;
+      this.seriesTabPage.Text = "Series";
+      this.seriesTabPage.UseVisualStyleBackColor = true;
+      // 
+      // splitContainer
+      // 
+      this.splitContainer.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.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
+      this.splitContainer.Location = new System.Drawing.Point(0, 0);
+      this.splitContainer.Name = "splitContainer";
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.downButton);
+      this.splitContainer.Panel1.Controls.Add(this.upButton);
+      this.splitContainer.Panel1.Controls.Add(this.seriesListView);
+      this.splitContainer.Panel1MinSize = 20;
+      // 
+      // splitContainer.Panel2
+      // 
+      this.splitContainer.Panel2.Controls.Add(this.dataRowVisualPropertiesControl);
+      this.splitContainer.Panel2MinSize = 50;
+      this.splitContainer.Size = new System.Drawing.Size(461, 381);
+      this.splitContainer.SplitterDistance = 125;
+      this.splitContainer.TabIndex = 0;
+      // 
+      // downButton
+      // 
+      this.downButton.Enabled = false;
+      this.downButton.Location = new System.Drawing.Point(35, 3);
+      this.downButton.Name = "downButton";
+      this.downButton.Size = new System.Drawing.Size(26, 23);
+      this.downButton.TabIndex = 1;
+      this.downButton.Text = "Down";
+      this.downButton.UseVisualStyleBackColor = true;
+      this.downButton.Click += new System.EventHandler(this.downButton_Click);
+      // 
+      // upButton
+      // 
+      this.upButton.Enabled = false;
+      this.upButton.Location = new System.Drawing.Point(3, 3);
+      this.upButton.Name = "upButton";
+      this.upButton.Size = new System.Drawing.Size(26, 23);
+      this.upButton.TabIndex = 0;
+      this.upButton.Text = "Up";
+      this.upButton.UseVisualStyleBackColor = true;
+      this.upButton.Click += new System.EventHandler(this.upButton_Click);
+      // 
+      // seriesListView
+      // 
+      this.seriesListView.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.seriesListView.HideSelection = false;
+      this.seriesListView.Location = new System.Drawing.Point(3, 32);
+      this.seriesListView.MultiSelect = false;
+      this.seriesListView.Name = "seriesListView";
+      this.seriesListView.ShowGroups = false;
+      this.seriesListView.Size = new System.Drawing.Size(119, 346);
+      this.seriesListView.TabIndex = 2;
+      this.seriesListView.UseCompatibleStateImageBehavior = false;
+      this.seriesListView.View = System.Windows.Forms.View.List;
+      this.seriesListView.SelectedIndexChanged += new System.EventHandler(this.seriesListView_SelectedIndexChanged);
+      // 
+      // dataRowVisualPropertiesControl
+      // 
+      this.dataRowVisualPropertiesControl.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.dataRowVisualPropertiesControl.Content = null;
+      this.dataRowVisualPropertiesControl.Location = new System.Drawing.Point(3, 26);
+      this.dataRowVisualPropertiesControl.Name = "dataRowVisualPropertiesControl";
+      this.dataRowVisualPropertiesControl.Size = new System.Drawing.Size(326, 352);
+      this.dataRowVisualPropertiesControl.TabIndex = 0;
+      // 
+      // chartTabPage
+      // 
+      this.chartTabPage.Controls.Add(this.dataTableVisualPropertiesControl);
+      this.chartTabPage.Location = new System.Drawing.Point(4, 22);
+      this.chartTabPage.Name = "chartTabPage";
+      this.chartTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.chartTabPage.Size = new System.Drawing.Size(461, 381);
+      this.chartTabPage.TabIndex = 1;
+      this.chartTabPage.Text = "Chart";
+      this.chartTabPage.UseVisualStyleBackColor = true;
+      // 
+      // dataTableVisualPropertiesControl
+      // 
+      this.dataTableVisualPropertiesControl.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.dataTableVisualPropertiesControl.Content = null;
+      this.dataTableVisualPropertiesControl.Location = new System.Drawing.Point(3, 6);
+      this.dataTableVisualPropertiesControl.Name = "dataTableVisualPropertiesControl";
+      this.dataTableVisualPropertiesControl.Size = new System.Drawing.Size(455, 372);
+      this.dataTableVisualPropertiesControl.TabIndex = 0;
+      // 
+      // DataTableVisualPropertiesDialog
+      // 
+      this.AcceptButton = this.okButton;
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.CancelButton = this.cancelButton;
+      this.ClientSize = new System.Drawing.Size(493, 460);
+      this.Controls.Add(this.tabControl);
+      this.Controls.Add(this.cancelButton);
+      this.Controls.Add(this.okButton);
+      this.MaximizeBox = false;
+      this.MinimizeBox = false;
+      this.Name = "DataTableVisualPropertiesDialog";
+      this.ShowIcon = false;
+      this.ShowInTaskbar = false;
+      this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+      this.Text = "Customize Visual Properties";
+      this.TopMost = true;
+      this.tabControl.ResumeLayout(false);
+      this.seriesTabPage.ResumeLayout(false);
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.chartTabPage.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Button okButton;
+    private System.Windows.Forms.Button cancelButton;
+    private System.Windows.Forms.TabControl tabControl;
+    private System.Windows.Forms.TabPage seriesTabPage;
+    private System.Windows.Forms.SplitContainer splitContainer;
+    private System.Windows.Forms.ListView seriesListView;
+    private System.Windows.Forms.TabPage chartTabPage;
+    private DataRowVisualPropertiesControl dataRowVisualPropertiesControl;
+    private DataTableVisualPropertiesControl dataTableVisualPropertiesControl;
+    private System.Windows.Forms.Button downButton;
+    private System.Windows.Forms.Button upButton;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableVisualPropertiesDialog.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableVisualPropertiesDialog.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/DataTableVisualPropertiesDialog.cs	(revision 12764)
@@ -0,0 +1,179 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Common.Resources;
+
+namespace HeuristicLab.Analysis.Views {
+  public partial class DataTableVisualPropertiesDialog : Form {
+    protected bool SuppressEvents { get; set; }
+    protected DataTable Content { get; private set; }
+    private DataTableVisualProperties originalDataTableVPs;
+    private Dictionary<string, DataRowVisualProperties> originalDataRowVPs;
+
+    private HashSet<string> modifiedDisplayNames;
+    public IEnumerable<string> RowsWithModifiedDisplayNames { get { return modifiedDisplayNames.AsEnumerable(); } }
+
+    public DataTableVisualPropertiesDialog(DataTable dataTable) {
+      InitializeComponent();
+      #region Prepare controls
+      upButton.Text = string.Empty;
+      upButton.Image = VSImageLibrary.ArrowUp;
+      downButton.Text = string.Empty;
+      downButton.Image = VSImageLibrary.ArrowDown;
+      seriesListView.Items.Clear();
+      seriesListView.SmallImageList = new ImageList();
+      seriesListView.SmallImageList.Images.Add(VSImageLibrary.Graph);
+      #endregion
+
+      Content = dataTable;
+      originalDataTableVPs = (DataTableVisualProperties)Content.VisualProperties.Clone();
+      originalDataRowVPs = new Dictionary<string, DataRowVisualProperties>();
+      foreach (DataRow row in Content.Rows)
+        originalDataRowVPs.Add(row.Name, (DataRowVisualProperties)row.VisualProperties.Clone());
+
+      dataTableVisualPropertiesControl.Content = Content.VisualProperties;
+
+      modifiedDisplayNames = new HashSet<string>();
+      FillSeriesListView();
+      RegisterContentEvents();
+    }
+
+    private void RegisterContentEvents() {
+      foreach (DataRow row in Content.Rows) {
+        row.VisualProperties.PropertyChanged += new PropertyChangedEventHandler(Row_VisualProperties_PropertyChanged);
+      }
+    }
+
+    private void DeregisterContentEvents() {
+      foreach (DataRow row in Content.Rows) {
+        row.VisualProperties.PropertyChanged -= new PropertyChangedEventHandler(Row_VisualProperties_PropertyChanged);
+      }
+    }
+
+    protected override void OnClosing(CancelEventArgs e) {
+      DeregisterContentEvents();
+      Application.DoEvents();
+      base.OnClosing(e);
+    }
+
+    private void Row_VisualProperties_PropertyChanged(object sender, PropertyChangedEventArgs e) {
+      foreach (DataRow row in Content.Rows) {
+        if (e.PropertyName == "DisplayName" && row.VisualProperties == sender) {
+          modifiedDisplayNames.Add(row.Name);
+          break;
+        }
+      }
+    }
+
+    private void seriesListView_SelectedIndexChanged(object sender, System.EventArgs e) {
+      if (!SuppressEvents) {
+        if (seriesListView.SelectedItems.Count != 1) {
+          dataRowVisualPropertiesControl.Content = null;
+          upButton.Enabled = downButton.Enabled = false;
+        } else {
+          string rowName = seriesListView.SelectedItems[0].Text;
+          dataRowVisualPropertiesControl.Content = Content.Rows[rowName].VisualProperties;
+          upButton.Enabled = seriesListView.SelectedIndices[0] > 0;
+          downButton.Enabled = seriesListView.SelectedIndices[0] < seriesListView.Items.Count - 1;
+        }
+      }
+    }
+
+    private void okButton_Click(object sender, System.EventArgs e) {
+      DialogResult = DialogResult.OK;
+      Close();
+    }
+
+    private void cancelButton_Click(object sender, System.EventArgs e) {
+      DialogResult = DialogResult.Cancel;
+      foreach (DataRow row in Content.Rows) {
+        row.VisualProperties = originalDataRowVPs[row.Name];
+      }
+      modifiedDisplayNames.Clear();
+      Content.VisualProperties = originalDataTableVPs;
+      Close();
+    }
+
+    private void upButton_Click(object sender, System.EventArgs e) {
+      if (seriesListView.SelectedIndices.Count == 1 && seriesListView.SelectedIndices[0] > 0) {
+        int index = seriesListView.SelectedIndices[0];
+        SuppressEvents = true;
+        try {
+          seriesListView.BeginUpdate();
+          ListViewItem selectedSeriesItem = seriesListView.Items[index];
+          seriesListView.Items.RemoveAt(index);
+          ListViewItem temp = seriesListView.Items[index - 1];
+          seriesListView.Items.RemoveAt(index - 1);
+          seriesListView.Items.Insert(index - 1, selectedSeriesItem);
+          seriesListView.Items.Insert(index, temp);
+          seriesListView.SelectedIndices.Clear();
+          seriesListView.EndUpdate();
+        } finally { SuppressEvents = false; }
+        seriesListView.SelectedIndices.Add(index - 1);
+        UpdateAllSeriesPositions();
+      }
+    }
+
+    private void downButton_Click(object sender, System.EventArgs e) {
+      if (seriesListView.SelectedIndices.Count == 1 && seriesListView.SelectedIndices[0] < seriesListView.Items.Count - 1) {
+        int index = seriesListView.SelectedIndices[0];
+        SuppressEvents = true;
+        try {
+          seriesListView.BeginUpdate();
+          ListViewItem temp = seriesListView.Items[index + 1];
+          seriesListView.Items.RemoveAt(index + 1);
+          ListViewItem selectedSeriesItem = seriesListView.Items[index];
+          seriesListView.Items.RemoveAt(index);
+          seriesListView.Items.Insert(index, temp);
+          seriesListView.Items.Insert(index + 1, selectedSeriesItem);
+          seriesListView.SelectedIndices.Clear();
+          seriesListView.EndUpdate();
+        } finally { SuppressEvents = false; }
+        seriesListView.SelectedIndices.Add(index + 1);
+        UpdateAllSeriesPositions();
+      }
+    }
+
+    #region Helpers
+    private void FillSeriesListView() {
+      seriesListView.SelectedIndices.Clear();
+      foreach (DataRow row in Content.Rows) {
+        seriesListView.Items.Add(new ListViewItem(row.Name, 0));
+      }
+      if (seriesListView.Items.Count > 0)
+        seriesListView.SelectedIndices.Add(0);
+    }
+
+    private void UpdateAllSeriesPositions() {
+      Dictionary<string, DataRow> rows = Content.Rows.ToDictionary(x => x.Name);
+      Content.Rows.Clear();
+      for (int i = 0; i < seriesListView.Items.Count; i++) {
+        ListViewItem item = seriesListView.Items[i];
+        Content.Rows.Add(rows[item.Text]);
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HeatMapHistoryView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HeatMapHistoryView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HeatMapHistoryView.Designer.cs	(revision 12764)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Analysis.Views {
+  partial class HeatMapHistoryView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+    }
+
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HeatMapHistoryView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HeatMapHistoryView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HeatMapHistoryView.cs	(revision 12764)
@@ -0,0 +1,35 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Windows.Forms;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Analysis.Views {
+  [View("HeatMapHistory View")]
+  [Content(typeof(HeatMapHistory), true)]
+  public partial class HeatMapHistoryView : MovieView<HeatMap> {
+    public HeatMapHistoryView() {
+      InitializeComponent();
+      itemsGroupBox.Text = "Heat Map";
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HeatMapView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HeatMapView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HeatMapView.Designer.cs	(revision 12764)
@@ -0,0 +1,178 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Analysis.Views {
+  partial class HeatMapView {
+    /// <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() {
+      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+      System.Windows.Forms.DataVisualization.Charting.Title title1 = new System.Windows.Forms.DataVisualization.Charting.Title();
+      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(HeatMapView));
+      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      this.colorsPictureBox = new System.Windows.Forms.PictureBox();
+      this.minimumLabel = new System.Windows.Forms.Label();
+      this.maximumLabel = new System.Windows.Forms.Label();
+      this.grayscalesPictureBox = new System.Windows.Forms.PictureBox();
+      this.grayscaleCheckBox = new System.Windows.Forms.CheckBox();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.colorsPictureBox)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.grayscalesPictureBox)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // chart
+      // 
+      this.chart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.chart.BorderlineColor = System.Drawing.Color.Black;
+      this.chart.BorderlineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;
+      chartArea1.AxisX.IntervalAutoMode = System.Windows.Forms.DataVisualization.Charting.IntervalAutoMode.VariableCount;
+      chartArea1.AxisX.LabelAutoFitStyle = ((System.Windows.Forms.DataVisualization.Charting.LabelAutoFitStyles)((System.Windows.Forms.DataVisualization.Charting.LabelAutoFitStyles.IncreaseFont | System.Windows.Forms.DataVisualization.Charting.LabelAutoFitStyles.DecreaseFont)));
+      chartArea1.AxisX.Title = "Column Index";
+      chartArea1.AxisY.Title = "Row Index";
+      chartArea1.CursorX.IsUserEnabled = true;
+      chartArea1.CursorX.IsUserSelectionEnabled = true;
+      chartArea1.CursorY.IsUserEnabled = true;
+      chartArea1.CursorY.IsUserSelectionEnabled = true;
+      chartArea1.Name = "Default";
+      this.chart.ChartAreas.Add(chartArea1);
+      this.chart.Location = new System.Drawing.Point(0, 0);
+      this.chart.Name = "chart";
+      this.chart.Size = new System.Drawing.Size(406, 463);
+      this.chart.TabIndex = 0;
+      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 = "Heat Map";
+      this.chart.Titles.Add(title1);
+      // 
+      // colorsPictureBox
+      // 
+      this.colorsPictureBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.colorsPictureBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+      this.colorsPictureBox.Image = ((System.Drawing.Image)(resources.GetObject("colorsPictureBox.Image")));
+      this.colorsPictureBox.Location = new System.Drawing.Point(430, 28);
+      this.colorsPictureBox.Name = "colorsPictureBox";
+      this.colorsPictureBox.Size = new System.Drawing.Size(35, 393);
+      this.colorsPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
+      this.colorsPictureBox.TabIndex = 11;
+      this.colorsPictureBox.TabStop = false;
+      // 
+      // minimumLabel
+      // 
+      this.minimumLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.minimumLabel.BackColor = System.Drawing.Color.Transparent;
+      this.minimumLabel.Location = new System.Drawing.Point(412, 424);
+      this.minimumLabel.Name = "minimumLabel";
+      this.minimumLabel.Size = new System.Drawing.Size(73, 19);
+      this.minimumLabel.TabIndex = 2;
+      this.minimumLabel.Text = "0.0";
+      this.minimumLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter;
+      // 
+      // maximumLabel
+      // 
+      this.maximumLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.maximumLabel.BackColor = System.Drawing.Color.Transparent;
+      this.maximumLabel.Location = new System.Drawing.Point(412, 0);
+      this.maximumLabel.Name = "maximumLabel";
+      this.maximumLabel.Size = new System.Drawing.Size(73, 25);
+      this.maximumLabel.TabIndex = 1;
+      this.maximumLabel.Text = "1.0";
+      this.maximumLabel.TextAlign = System.Drawing.ContentAlignment.BottomCenter;
+      // 
+      // grayscalesPictureBox
+      // 
+      this.grayscalesPictureBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.grayscalesPictureBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+      this.grayscalesPictureBox.Image = ((System.Drawing.Image)(resources.GetObject("grayscalesPictureBox.Image")));
+      this.grayscalesPictureBox.Location = new System.Drawing.Point(430, 28);
+      this.grayscalesPictureBox.Name = "grayscalesPictureBox";
+      this.grayscalesPictureBox.Size = new System.Drawing.Size(35, 393);
+      this.grayscalesPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
+      this.grayscalesPictureBox.TabIndex = 15;
+      this.grayscalesPictureBox.TabStop = false;
+      this.grayscalesPictureBox.Visible = false;
+      // 
+      // grayscaleCheckBox
+      // 
+      this.grayscaleCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.grayscaleCheckBox.AutoSize = true;
+      this.grayscaleCheckBox.Location = new System.Drawing.Point(412, 446);
+      this.grayscaleCheckBox.Name = "grayscaleCheckBox";
+      this.grayscaleCheckBox.Size = new System.Drawing.Size(73, 17);
+      this.grayscaleCheckBox.TabIndex = 3;
+      this.grayscaleCheckBox.Text = "Grayscale";
+      this.grayscaleCheckBox.UseVisualStyleBackColor = true;
+      this.grayscaleCheckBox.CheckedChanged += new System.EventHandler(this.grayscaledImagesCheckBox_CheckedChanged);
+      // 
+      // HeatMapView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.grayscaleCheckBox);
+      this.Controls.Add(this.minimumLabel);
+      this.Controls.Add(this.maximumLabel);
+      this.Controls.Add(this.colorsPictureBox);
+      this.Controls.Add(this.chart);
+      this.Controls.Add(this.grayscalesPictureBox);
+      this.Name = "HeatMapView";
+      this.Size = new System.Drawing.Size(485, 463);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      ((System.ComponentModel.ISupportInitialize)(this.colorsPictureBox)).EndInit();
+      ((System.ComponentModel.ISupportInitialize)(this.grayscalesPictureBox)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    protected HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
+    protected System.Windows.Forms.PictureBox colorsPictureBox;
+    protected System.Windows.Forms.Label minimumLabel;
+    protected System.Windows.Forms.Label maximumLabel;
+    protected System.Windows.Forms.PictureBox grayscalesPictureBox;
+    protected System.Windows.Forms.CheckBox grayscaleCheckBox;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HeatMapView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HeatMapView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HeatMapView.cs	(revision 12764)
@@ -0,0 +1,146 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.Common;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Analysis.Views {
+  [View("HeatMap View")]
+  [Content(typeof(HeatMap), true)]
+  public partial class HeatMapView : ItemView {
+    protected static Color[] colors = new Color[256];
+    public new HeatMap Content {
+      get { return (HeatMap)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public HeatMapView() {
+      InitializeComponent();
+      chart.CustomizeAllChartAreas();
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.TitleChanged -= new EventHandler(Content_TitleChanged);
+      Content.MinimumChanged -= new EventHandler(Content_MinimumChanged);
+      Content.MaximumChanged -= new EventHandler(Content_MaximumChanged);
+      base.DeregisterContentEvents();
+    }
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.TitleChanged += new EventHandler(Content_TitleChanged);
+      Content.MinimumChanged += new EventHandler(Content_MinimumChanged);
+      Content.MaximumChanged += new EventHandler(Content_MaximumChanged);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        chart.Series.Clear();
+        chart.Titles[0].Text = "Heat Map";
+        minimumLabel.Text = "0.0";
+        maximumLabel.Text = "1.0";
+      } else {
+        chart.Titles[0].Text = Content.Title;
+        minimumLabel.Text = Content.Minimum.ToString();
+        maximumLabel.Text = Content.Maximum.ToString();
+        UpdatePoints();
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      chart.Enabled = Content != null;
+      grayscaleCheckBox.Enabled = Content != null;
+    }
+
+    protected virtual void UpdatePoints() {
+      chart.Series.Clear();
+      Series series = new Series();
+      series.ChartType = SeriesChartType.Point;
+      series.XValueType = ChartValueType.Int32;
+      series.YValueType = ChartValueType.Int32;
+      series.YAxisType = AxisType.Primary;
+      for (int i = 1; i < Content.Rows + 1; i++)
+        for (int j = 1; j < Content.Columns + 1; j++)
+          series.Points.Add(CreateDataPoint(j, i, Content[i - 1, j - 1]));
+      chart.ChartAreas[0].AxisX.Minimum = 0;
+      chart.ChartAreas[0].AxisX.Maximum = Content.Columns + 1;
+      chart.ChartAreas[0].AxisY.Minimum = 0;
+      chart.ChartAreas[0].AxisY.Maximum = Content.Rows + 1;
+      chart.Series.Add(series);
+    }
+
+    protected virtual DataPoint CreateDataPoint(int index1, int index2, double value) {
+      DataPoint p = new DataPoint(index1, index2);
+      p.Color = GetDataPointColor(value, Content.Minimum, Content.Maximum, grayscaleCheckBox.Checked);
+      p.MarkerStyle = MarkerStyle.Square;
+      return p;
+    }
+
+    protected virtual Color GetDataPointColor(double value, double min, double max, bool grayscale) {
+      IList<Color> colors = grayscale ? ColorGradient.GrayscaledColors : ColorGradient.Colors;
+      int index = (int)((colors.Count - 1) * (value - min) / (max - min));
+      if (index >= colors.Count) index = colors.Count - 1;
+      if (index < 0) index = 0;
+      return colors[index];
+    }
+
+    #region Content Events
+    protected virtual void Content_TitleChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_TitleChanged), sender, e);
+      else {
+        chart.Titles[0].Text = Content.Title;
+      }
+    }
+    protected virtual void Content_MinimumChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_MinimumChanged), sender, e);
+      else {
+        minimumLabel.Text = Content.Minimum.ToString();
+        UpdatePoints();
+      }
+    }
+    protected virtual void Content_MaximumChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_MaximumChanged), sender, e);
+      else {
+        maximumLabel.Text = Content.Maximum.ToString();
+        UpdatePoints();
+      }
+    }
+    #endregion
+
+    #region Control Events
+    protected virtual void grayscaledImagesCheckBox_CheckedChanged(object sender, EventArgs e) {
+      grayscalesPictureBox.Visible = grayscaleCheckBox.Checked;
+      colorsPictureBox.Visible = !grayscaleCheckBox.Checked;
+      UpdatePoints();
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HeatMapView.resx
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HeatMapView.resx	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HeatMapView.resx	(revision 12764)
@@ -0,0 +1,1923 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+  <data name="colorsPictureBox.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        Qk0S0gAAAAAAADYAAAAoAAAAMQAAAGsBAAABABgAAAAAAAAAAADEDgAAxA4AAAAAAAAAAAAA/wAe/wAe
+        /wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe
+        /wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe
+        /wAe/wAe/wAe/wAe/wAe/wAe/wAeAP8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8A
+        G/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8A
+        G/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AGwD/ABj/ABj/ABj/
+        ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/
+        ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/
+        ABj/ABj/ABj/ABj/ABj/ABgA/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV
+        /wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV
+        /wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAVAP8AEv8AEv8AEv8AEv8A
+        Ev8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8A
+        Ev8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8A
+        Ev8AEv8AEv8AEv8AEgD/AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//
+        AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//
+        AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA8A/wAM/wAM/wAM/wAM/wAM/wAM
+        /wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM
+        /wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM
+        /wAM/wAM/wAMAP8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8A
+        Cf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8A
+        Cf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACQD/AAb/AAb/AAb/AAb/AAb/AAb/AAb/
+        AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/
+        AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/
+        AAb/AAYA/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG
+        /wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG
+        /wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAGAP8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8A
+        A/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8A
+        A/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8A
+        AwD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/
+        AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/
+        AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA
+        /wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA
+        /wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMAAP8G
+        AP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8G
+        AP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8G
+        AP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAAD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/
+        CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/
+        CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQAA/wwA/wwA
+        /wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA
+        /wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA
+        /wwA/wwA/wwA/wwA/wwA/wwA/wwAAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8P
+        AP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8P
+        AP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAAD/EgD/EgD/EgD/
+        EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/
+        EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/
+        EgD/EgD/EgD/EgD/EgD/EgAA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA
+        /xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA
+        /xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUAAP8YAP8YAP8YAP8YAP8Y
+        AP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8Y
+        AP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8Y
+        AP8YAP8YAP8YAP8YAAD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/
+        GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/
+        GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwAA/x4A/x4A/x4A/x4A/x4A/x4A
+        /x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A
+        /x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A
+        /x4A/x4A/x4AAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8h
+        AP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8h
+        AP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/
+        JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/
+        JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/
+        JAD/JAAA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA
+        /ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA
+        /ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycAAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8q
+        AP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8q
+        AP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8q
+        AAD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/
+        LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/
+        LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA
+        /zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA
+        /zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAAAP8z
+        AP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8z
+        AP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8z
+        AP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAAD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/
+        NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/
+        NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgAA/zkA/zkA
+        /zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA
+        /zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA
+        /zkA/zkA/zkA/zkA/zkA/zkA/zkAAP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88
+        AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88
+        AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AAD/PwD/PwD/PwD/
+        PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/
+        PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/
+        PwD/PwD/PwD/PwD/PwD/PwAA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA
+        /0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA
+        /0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IAAP9FAP9FAP9FAP9FAP9F
+        AP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9F
+        AP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9F
+        AP9FAP9FAP9FAP9FAAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/
+        SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/
+        SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAAA/0sA/0sA/0sA/0sA/0sA/0sA
+        /0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA
+        /0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA
+        /0sA/0sA/0sAAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9L
+        AP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9L
+        AP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAAD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/
+        TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/
+        TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/
+        TgD/TgAA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA
+        /1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA
+        /1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EAAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9U
+        AP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9U
+        AP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9U
+        AAD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/
+        VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/
+        VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwAA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA
+        /1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA
+        /1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oAAP9d
+        AP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9d
+        AP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9d
+        AP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/
+        YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/
+        YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAAA/2MA/2MA
+        /2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA
+        /2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA
+        /2MA/2MA/2MA/2MA/2MA/2MA/2MAAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9m
+        AP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9m
+        AP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAAD/aQD/aQD/aQD/
+        aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/
+        aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/
+        aQD/aQD/aQD/aQD/aQD/aQAA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA
+        /2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA
+        /2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wAAP9vAP9vAP9vAP9vAP9v
+        AP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9v
+        AP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9v
+        AP9vAP9vAP9vAP9vAAD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/
+        cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/
+        cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgAA/3UA/3UA/3UA/3UA/3UA/3UA
+        /3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA
+        /3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA
+        /3UA/3UA/3UAAP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94
+        AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94
+        AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AAD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/
+        ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/
+        ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/
+        ewD/ewAA/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A
+        /34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A
+        /34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34AAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+B
+        AP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+B
+        AP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+B
+        AAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/
+        hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/
+        hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAAA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA
+        /4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA
+        /4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cAAP+K
+        AP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+K
+        AP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+K
+        AP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAAD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/
+        jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/
+        jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQAA/5AA/5AA
+        /5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA
+        /5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA
+        /5AA/5AA/5AA/5AA/5AA/5AA/5AAAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+T
+        AP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+T
+        AP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAAD/lgD/lgD/lgD/
+        lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/
+        lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/
+        lgD/lgD/lgD/lgD/lgD/lgAA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA
+        /5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA
+        /5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kAAP+ZAP+ZAP+ZAP+ZAP+Z
+        AP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+Z
+        AP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+Z
+        AP+ZAP+ZAP+ZAP+ZAAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/
+        nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/
+        nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAAA/58A/58A/58A/58A/58A/58A
+        /58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A
+        /58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A
+        /58A/58A/58AAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+i
+        AP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+i
+        AP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAAD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/
+        pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/
+        pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/
+        pQD/pQAA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA
+        /6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA
+        /6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gAAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+r
+        AP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+r
+        AP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+r
+        AAD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/
+        rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/
+        rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgAA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA
+        /7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA
+        /7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EAAP+0
+        AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0
+        AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0
+        AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AAD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/
+        twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/
+        twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twAA/7oA/7oA
+        /7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA
+        /7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA
+        /7oA/7oA/7oA/7oA/7oA/7oA/7oAAP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9
+        AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9
+        AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AAD/wAD/wAD/wAD/
+        wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/
+        wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/
+        wAD/wAD/wAD/wAD/wAD/wAAA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA
+        /8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA
+        /8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MAAP/GAP/GAP/GAP/GAP/G
+        AP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/G
+        AP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/G
+        AP/GAP/GAP/GAP/GAAD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/
+        yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/
+        yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQAA/8wA/8wA/8wA/8wA/8wA/8wA
+        /8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA
+        /8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA
+        /8wA/8wA/8wAAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/P
+        AP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/P
+        AP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAAD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/
+        0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/
+        0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/
+        0gD/0gAA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA
+        /9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA
+        /9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UAAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/Y
+        AP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/Y
+        AP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/Y
+        AAD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/
+        2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/
+        2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wAA/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A
+        /94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A
+        /94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94AAP/h
+        AP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/h
+        AP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/h
+        AP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAAD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/
+        5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/
+        5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AAA/+cA/+cA
+        /+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA
+        /+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA
+        /+cA/+cA/+cA/+cA/+cA/+cA/+cAAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/n
+        AP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/n
+        AP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAAD/6gD/6gD/6gD/
+        6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/
+        6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/
+        6gD/6gD/6gD/6gD/6gD/6gAA/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A
+        /+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A
+        /+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0AAP/wAP/wAP/wAP/wAP/w
+        AP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/w
+        AP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/w
+        AP/wAP/wAP/wAP/wAAD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/
+        8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/
+        8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wAA//YA//YA//YA//YA//YA//YA
+        //YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA
+        //YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA
+        //YA//YA//YAAP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5
+        AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5
+        AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AAD//AD//AD//AD//AD//AD//AD//AD/
+        /AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD/
+        /AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD/
+        /AD//AAA//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A
+        //8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A
+        //8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8AAPz/APz/APz/APz/APz/APz/APz/APz/APz/
+        APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/
+        APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/
+        AAD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5
+        /wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5
+        /wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wAA9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A
+        9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A
+        9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8AAPP/
+        APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/
+        APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/
+        APP/APP/APP/APP/APP/APP/APP/APP/AADw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw
+        /wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw
+        /wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wAA7f8A7f8A
+        7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A
+        7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A
+        7f8A7f8A7f8A7f8A7f8A7f8A7f8AAOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/
+        AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/
+        AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AADn/wDn/wDn/wDn
+        /wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn
+        /wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn
+        /wDn/wDn/wDn/wDn/wDn/wAA5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A
+        5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A
+        5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8AAOH/AOH/AOH/AOH/AOH/
+        AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/
+        AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/
+        AOH/AOH/AOH/AOH/AADe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe
+        /wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe
+        /wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wAA2/8A2/8A2/8A2/8A2/8A2/8A
+        2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A
+        2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A
+        2/8A2/8A2/8AANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/
+        ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/
+        ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/AADV/wDV/wDV/wDV/wDV/wDV/wDV/wDV
+        /wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV
+        /wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV
+        /wDV/wAA0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A
+        0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A
+        0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8AAM//AM//AM//AM//AM//AM//AM//AM//AM//
+        AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//
+        AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//
+        AADM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM
+        /wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM
+        /wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wAAyf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8A
+        yf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8A
+        yf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8AAMb/
+        AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/
+        AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/
+        AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AADG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG
+        /wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG
+        /wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wAAw/8Aw/8A
+        w/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8A
+        w/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8A
+        w/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8AAMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/
+        AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/
+        AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AAC9/wC9/wC9/wC9
+        /wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9
+        /wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9
+        /wC9/wC9/wC9/wC9/wC9/wAAuv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8A
+        uv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8A
+        uv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8AALf/ALf/ALf/ALf/ALf/
+        ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/
+        ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/
+        ALf/ALf/ALf/ALf/AAC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0
+        /wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0
+        /wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wAAsf8Asf8Asf8Asf8Asf8Asf8A
+        sf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8A
+        sf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8A
+        sf8Asf8Asf8AAK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/
+        AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/
+        AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AACr/wCr/wCr/wCr/wCr/wCr/wCr/wCr
+        /wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr
+        /wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr
+        /wCr/wAAqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8A
+        qP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8A
+        qP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AAKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/
+        AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/
+        AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/
+        AACi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi
+        /wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi
+        /wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wAAn/8An/8An/8An/8An/8An/8An/8An/8An/8An/8A
+        n/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8A
+        n/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8AAJz/
+        AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/
+        AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/
+        AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AACZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ
+        /wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ
+        /wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wAAlv8Alv8A
+        lv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8A
+        lv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8A
+        lv8Alv8Alv8Alv8Alv8Alv8Alv8AAJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/
+        AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/
+        AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AACQ/wCQ/wCQ/wCQ
+        /wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ
+        /wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ
+        /wCQ/wCQ/wCQ/wCQ/wCQ/wAAjf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8A
+        jf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8A
+        jf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8AAIr/AIr/AIr/AIr/AIr/
+        AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/
+        AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/
+        AIr/AIr/AIr/AIr/AACH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH
+        /wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH
+        /wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wAAhP8AhP8AhP8AhP8AhP8AhP8A
+        hP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8A
+        hP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8A
+        hP8AhP8AhP8AAIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/
+        AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/
+        AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AAB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+
+        /wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+
+        /wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+
+        /wB+/wAAe/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8A
+        e/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8A
+        e/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8AAHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/
+        AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/
+        AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/
+        AAB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4
+        /wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4
+        /wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wAAdf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8A
+        df8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8A
+        df8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8AAHL/
+        AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/
+        AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/
+        AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AABv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv
+        /wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv
+        /wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wAAbP8AbP8A
+        bP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8A
+        bP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8A
+        bP8AbP8AbP8AbP8AbP8AbP8AbP8AAGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/
+        AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/
+        AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AABm/wBm/wBm/wBm
+        /wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm
+        /wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm
+        /wBm/wBm/wBm/wBm/wBm/wAAY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8A
+        Y/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8A
+        Y/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AAGD/AGD/AGD/AGD/AGD/
+        AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/
+        AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/
+        AGD/AGD/AGD/AGD/AABd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd
+        /wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd
+        /wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wAAWv8AWv8AWv8AWv8AWv8AWv8A
+        Wv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8A
+        Wv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8A
+        Wv8AWv8AWv8AAFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/
+        AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/
+        AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AABU/wBU/wBU/wBU/wBU/wBU/wBU/wBU
+        /wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU
+        /wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU
+        /wBU/wAAUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8A
+        Uf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8A
+        Uf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AAE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/
+        AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/
+        AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/
+        AABL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL
+        /wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL
+        /wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wAASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8A
+        SP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8A
+        SP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8AAEX/
+        AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/
+        AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/
+        AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AABC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC
+        /wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC
+        /wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wAAP/8AP/8A
+        P/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8A
+        P/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8A
+        P/8AP/8AP/8AP/8AP/8AP/8AP/8AADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/
+        ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/
+        ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/AAA5/wA5/wA5/wA5
+        /wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5
+        /wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5
+        /wA5/wA5/wA5/wA5/wA5/wAANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8A
+        Nv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8A
+        Nv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8AADP/ADP/ADP/ADP/ADP/
+        ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/
+        ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/
+        ADP/ADP/ADP/ADP/AAAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw
+        /wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw
+        /wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAALf8ALf8ALf8ALf8ALf8ALf8A
+        Lf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8A
+        Lf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8A
+        Lf8ALf8ALf8AACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/
+        ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/
+        ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/AAAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq
+        /wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq
+        /wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq
+        /wAq/wAAJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8A
+        J/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8A
+        J/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/
+        ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/
+        ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/
+        AAAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh
+        /wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh
+        /wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAAHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8A
+        Hv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8A
+        Hv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AABv/
+        ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/
+        ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/
+        ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/AAAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY
+        /wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY
+        /wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAAFf8AFf8A
+        Ff8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8A
+        Ff8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8A
+        Ff8AFf8AFf8AFf8AFf8AFf8AFf8AABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/
+        ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/
+        ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/AAAP/wAP/wAP/wAP
+        /wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP
+        /wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP
+        /wAP/wAP/wAP/wAP/wAP/wAADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8A
+        DP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8A
+        DP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8AAAn/AAn/AAn/AAn/AAn/
+        AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/
+        AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/
+        AAn/AAn/AAn/AAn/AAAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG
+        /wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG
+        /wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAAA/8AA/8AA/8AA/8AA/8AA/8A
+        A/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8A
+        A/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8A
+        A/8AA/8AA/8AAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/
+        AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/
+        AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAA/wMA/wMA/wMA/wMA/wMA/wMA/wMA
+        /wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA
+        /wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA
+        /wMA/wMAAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8G
+        AP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8G
+        AP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAAD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/
+        CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/
+        CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/
+        CQAA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA
+        /wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA
+        /wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwAAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8P
+        AP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8P
+        AP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAAD/
+        EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/
+        EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/
+        EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgAA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA
+        /xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA
+        /xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUAAP8YAP8Y
+        AP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8Y
+        AP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8Y
+        AP8YAP8YAP8YAP8YAP8YAP8YAP8YAAD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/
+        GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/
+        GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwAA/x4A/x4A/x4A
+        /x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A
+        /x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A
+        /x4A/x4A/x4A/x4A/x4A/x4AAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8h
+        AP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8h
+        AP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAAD/JAD/JAD/JAD/JAD/
+        JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/
+        JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/
+        JAD/JAD/JAD/JAD/JAAA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA
+        /ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA
+        /ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycAAP8nAP8nAP8nAP8nAP8nAP8n
+        AP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8n
+        AP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8n
+        AP8nAP8nAP8nAAD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/
+        KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/
+        KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgAA/y0A/y0A/y0A/y0A/y0A/y0A/y0A
+        /y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A
+        /y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A
+        /y0A/y0AAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8w
+        AP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8w
+        AP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAAD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/
+        MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/
+        MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/
+        MwAA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA
+        /zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA
+        /zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYAAP85AP85AP85AP85AP85AP85AP85AP85AP85AP85
+        AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85
+        AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AAD/
+        PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/
+        PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/
+        PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAAA/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A
+        /z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A
+        /z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8AAP9CAP9C
+        AP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9C
+        AP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9C
+        AP9CAP9CAP9CAP9CAP9CAP9CAP9CAAD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/
+        RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/
+        RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQAA/0gA/0gA/0gA
+        /0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA
+        /0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA
+        /0gA/0gA/0gA/0gA/0gA/0gAAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9L
+        AP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9L
+        AP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAAD/TgD/TgD/TgD/TgD/
+        TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/
+        TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/
+        TgD/TgD/TgD/TgD/TgAA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA
+        /1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA
+        /1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EAAP9UAP9UAP9UAP9UAP9UAP9U
+        AP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9U
+        AP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9U
+        AP9UAP9UAP9UAAD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/
+        VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/
+        VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwAA/1oA/1oA/1oA/1oA/1oA/1oA/1oA
+        /1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA
+        /1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA
+        /1oA/1oAAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9d
+        AP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9d
+        AP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/
+        YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/
+        YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/
+        YAAA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA
+        /2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA
+        /2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MAAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9m
+        AP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9m
+        AP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAAD/
+        aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/
+        aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/
+        aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQAA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA
+        /2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA
+        /2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wAAP9vAP9v
+        AP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9v
+        AP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9v
+        AP9vAP9vAP9vAP9vAP9vAP9vAP9vAAD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/
+        cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/
+        cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgAA/3UA/3UA/3UA
+        /3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA
+        /3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA
+        /3UA/3UA/3UA/3UA/3UA/3UAAP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91
+        AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91
+        AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AAD/eAD/eAD/eAD/eAD/
+        eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/
+        eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/
+        eAD/eAD/eAD/eAD/eAAA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA
+        /3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA
+        /3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sAAP9+AP9+AP9+AP9+AP9+AP9+
+        AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+
+        AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+
+        AP9+AP9+AP9+AAD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/
+        gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/
+        gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQAA/4QA/4QA/4QA/4QA/4QA/4QA/4QA
+        /4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA
+        /4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA
+        /4QA/4QAAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+H
+        AP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+H
+        AP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAAD/igD/igD/igD/igD/igD/igD/igD/igD/
+        igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/
+        igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/
+        igAA/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A
+        /40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A
+        /40A/40A/40A/40A/40A/40A/40A/40A/40A/40AAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+Q
+        AP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+Q
+        AP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAAD/
+        kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/
+        kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/
+        kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwAA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA
+        /5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA
+        /5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YAAP+ZAP+Z
+        AP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+Z
+        AP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+Z
+        AP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/
+        nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/
+        nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAAA/58A/58A/58A
+        /58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A
+        /58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A
+        /58A/58A/58A/58A/58A/58AAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+i
+        AP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+i
+        AP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAAD/pQD/pQD/pQD/pQD/
+        pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/
+        pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/
+        pQD/pQD/pQD/pQD/pQAA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA
+        /6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA
+        /6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gAAP+rAP+rAP+rAP+rAP+rAP+r
+        AP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+r
+        AP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+r
+        AP+rAP+rAP+rAAD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/
+        rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/
+        rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgAA/7EA/7EA/7EA/7EA/7EA/7EA/7EA
+        /7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA
+        /7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA
+        /7EA/7EAAP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0
+        AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0
+        AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AAD/twD/twD/twD/twD/twD/twD/twD/twD/
+        twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/
+        twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/
+        twAA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA
+        /7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA
+        /7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oAAP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9
+        AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9
+        AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AAD/
+        wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/
+        wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/
+        wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAAA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA
+        /8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA
+        /8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MAAP/DAP/D
+        AP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/D
+        AP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/D
+        AP/DAP/DAP/DAP/DAP/DAP/DAP/DAAD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/
+        xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/
+        xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgAA/8kA/8kA/8kA
+        /8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA
+        /8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA
+        /8kA/8kA/8kA/8kA/8kA/8kAAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/M
+        AP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/M
+        AP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAAD/zwD/zwD/zwD/zwD/
+        zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/
+        zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/
+        zwD/zwD/zwD/zwD/zwAA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA
+        /9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA
+        /9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IAAP/VAP/VAP/VAP/VAP/VAP/V
+        AP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/V
+        AP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/V
+        AP/VAP/VAP/VAAD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/
+        2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/
+        2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AAA/9sA/9sA/9sA/9sA/9sA/9sA/9sA
+        /9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA
+        /9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA
+        /9sA/9sAAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/e
+        AP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/e
+        AP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAAD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/
+        4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/
+        4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/
+        4QAA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA
+        /+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA
+        /+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QAAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/n
+        AP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/n
+        AP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAAD/
+        6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/
+        6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/
+        6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gAA/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A
+        /+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A
+        /+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0AAP/wAP/w
+        AP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/w
+        AP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/w
+        AP/wAP/wAP/wAP/wAP/wAP/wAP/wAAD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/
+        8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/
+        8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wAA//YA//YA//YA
+        //YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA
+        //YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA
+        //YA//YA//YA//YA//YA//YAAP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5
+        AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5
+        AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AAD//AD//AD//AD//AD/
+        /AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD/
+        /AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD/
+        /AD//AD//AD//AD//AAA//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A
+        //8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A
+        //8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8AAPz/APz/APz/APz/APz/APz/
+        APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/
+        APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/
+        APz/APz/APz/AAD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5
+        /wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5
+        /wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wAA9v8A9v8A9v8A9v8A9v8A9v8A9v8A
+        9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A
+        9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A
+        9v8A9v8AAPP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/
+        APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/
+        APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/AADw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw
+        /wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw
+        /wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw
+        /wAA7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A
+        7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A
+        7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8AAOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/
+        AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/
+        AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AADq
+        /wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq
+        /wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq
+        /wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wAA5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A
+        5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A
+        5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8AAOT/AOT/
+        AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/
+        AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/
+        AOT/AOT/AOT/AOT/AOT/AOT/AOT/AADh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh
+        /wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh
+        /wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wAA3v8A3v8A3v8A
+        3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A
+        3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A
+        3v8A3v8A3v8A3v8A3v8A3v8AANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/
+        ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/
+        ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/AADY/wDY/wDY/wDY/wDY
+        /wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY
+        /wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY
+        /wDY/wDY/wDY/wDY/wAA1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A
+        1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A
+        1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8AANL/ANL/ANL/ANL/ANL/ANL/
+        ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/
+        ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/
+        ANL/ANL/ANL/AADP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP
+        /wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP
+        /wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wAAzP8AzP8AzP8AzP8AzP8AzP8AzP8A
+        zP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8A
+        zP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8A
+        zP8AzP8AAMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/
+        AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/
+        AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AADG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG
+        /wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG
+        /wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG
+        /wAAw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8A
+        w/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8A
+        w/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8AAMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/
+        AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/
+        AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AAC9
+        /wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9
+        /wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9
+        /wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wAAuv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8A
+        uv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8A
+        uv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8AALf/ALf/
+        ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/
+        ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/
+        ALf/ALf/ALf/ALf/ALf/ALf/ALf/AAC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0
+        /wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0
+        /wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wAAsf8Asf8Asf8A
+        sf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8A
+        sf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8A
+        sf8Asf8Asf8Asf8Asf8Asf8AAK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/
+        AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/
+        AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AACr/wCr/wCr/wCr/wCr
+        /wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr
+        /wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr
+        /wCr/wCr/wCr/wCr/wAAqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8A
+        qP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8A
+        qP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AAKX/AKX/AKX/AKX/AKX/AKX/
+        AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/
+        AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/
+        AKX/AKX/AKX/AACi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi
+        /wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi
+        /wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wAAn/8An/8An/8An/8An/8An/8An/8A
+        n/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8A
+        n/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8A
+        n/8An/8AAJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/
+        AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/
+        AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AACc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc
+        /wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc
+        /wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc
+        /wAAmf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8A
+        mf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8A
+        mf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8AAJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/
+        AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/
+        AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AACT
+        /wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT
+        /wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT
+        /wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wAAkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8A
+        kP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8A
+        kP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AAI3/AI3/
+        AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/
+        AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/
+        AI3/AI3/AI3/AI3/AI3/AI3/AI3/AACK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK
+        /wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK
+        /wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wAAh/8Ah/8Ah/8A
+        h/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8A
+        h/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8A
+        h/8Ah/8Ah/8Ah/8Ah/8Ah/8AAIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/
+        AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/
+        AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AACB/wCB/wCB/wCB/wCB
+        /wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB
+        /wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB
+        /wCB/wCB/wCB/wCB/wAAfv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8A
+        fv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8A
+        fv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8AAHv/AHv/AHv/AHv/AHv/AHv/
+        AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/
+        AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/
+        AHv/AHv/AHv/AAB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4
+        /wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4
+        /wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wAAdf8Adf8Adf8Adf8Adf8Adf8Adf8A
+        df8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8A
+        df8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8A
+        df8Adf8AAHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/
+        AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/
+        AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AABv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv
+        /wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv
+        /wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv
+        /wAAbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8A
+        bP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8A
+        bP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AAGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/
+        AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/
+        AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AABm
+        /wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm
+        /wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm
+        /wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wAAY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8A
+        Y/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8A
+        Y/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AAGD/AGD/
+        AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/
+        AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/
+        AGD/AGD/AGD/AGD/AGD/AGD/AGD/AABd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd
+        /wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd
+        /wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wAAWv8AWv8AWv8A
+        Wv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8A
+        Wv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8A
+        Wv8AWv8AWv8AWv8AWv8AWv8AAFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/
+        AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/
+        AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AABU/wBU/wBU/wBU/wBU
+        /wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU
+        /wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU
+        /wBU/wBU/wBU/wBU/wAAUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8A
+        Uf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8A
+        Uf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AAE7/AE7/AE7/AE7/AE7/AE7/
+        AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/
+        AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/
+        AE7/AE7/AE7/AABO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO
+        /wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO
+        /wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wAAS/8AS/8AS/8AS/8AS/8AS/8AS/8A
+        S/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8A
+        S/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8A
+        S/8AS/8AAEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/
+        AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/
+        AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AABF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF
+        /wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF
+        /wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF
+        /wAAQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8A
+        Qv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8A
+        Qv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AAD//AD//AD//AD//AD//AD//AD//AD//AD//AD//
+        AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//
+        AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AAA8
+        /wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8
+        /wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8
+        /wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wAAOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8A
+        Of8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8A
+        Of8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AADb/ADb/
+        ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/
+        ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/
+        ADb/ADb/ADb/ADb/ADb/ADb/ADb/AAAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz
+        /wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz
+        /wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAAMP8AMP8AMP8A
+        MP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8A
+        MP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8A
+        MP8AMP8AMP8AMP8AMP8AMP8AAC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/
+        AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/
+        AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AAAq/wAq/wAq/wAq/wAq
+        /wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq
+        /wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq
+        /wAq/wAq/wAq/wAq/wAAJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8A
+        J/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8A
+        J/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AACT/ACT/ACT/ACT/ACT/ACT/
+        ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/
+        ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/
+        ACT/ACT/ACT/AAAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh
+        /wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh
+        /wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAAHv8AHv8AHv8AHv8AHv8AHv8AHv8A
+        Hv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8A
+        Hv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8A
+        Hv8AHv8AABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/
+        ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/
+        ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/AAAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY
+        /wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY
+        /wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY
+        /wAAFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8A
+        Ff8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8A
+        Ff8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/
+        ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/
+        ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/AAAP
+        /wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP
+        /wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP
+        /wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8A
+        DP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8A
+        DP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8AAAn/AAn/
+        AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/
+        AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/
+        AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG
+        /wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG
+        /wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAAA/8AA/8AA/8A
+        A/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8A
+        A/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8A
+        A/8AA/8AA/8AA/8AA/8AA/8A
+</value>
+  </data>
+  <data name="grayscalesPictureBox.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        Qk0S0gAAAAAAADYAAAAoAAAAMQAAAGsBAAABABgAAAAAAAAAAADEDgAAxA4AAAAAAAAAAAAA////////
+        ////////////////////////////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////////////
+        ////////////////////////////AP//////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////////////
+        /////////////////////////////////////////////////////////////////wD/////////////
+        ////////////////////////////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////////////
+        //////////////////////8A////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////AP//////////////////
+        ////////////////////////////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////////////
+        /////////////////wD+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+
+        /v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+
+        /v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v4A/v7+/v7+/v7+/v7+/v7+/v7+
+        /v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+
+        /v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+
+        /v7+/v7+/v7+AP7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+
+        /v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+
+        /v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/gD9/f39/f39/f39/f39/f39/f39/f39
+        /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39
+        /f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39
+        /f39/f0A/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8
+        /Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8
+        /Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8APv7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7
+        +/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7
+        +/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7
+        +wD7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7
+        +/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7
+        +/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/sA+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6
+        +vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6
+        +vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6APn5
+        +fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5
+        +fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5
+        +fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+QD5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5
+        +fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5
+        +fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fkA+Pj4+Pj4
+        +Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4
+        +Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4
+        +Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4APf39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f3
+        9/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f3
+        9/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39wD29vb29vb29vb2
+        9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb2
+        9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb2
+        9vb29vb29vb29vb29vb29vYA9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb2
+        9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb2
+        9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb2APX19fX19fX19fX19fX1
+        9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX1
+        9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX1
+        9fX19fX19fX19fX19QD09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0
+        9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0
+        9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQA9PT09PT09PT09PT09PT09PT0
+        9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0
+        9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0
+        9PT09PT09PT0APPz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz
+        8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz
+        8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8wDy8vLy8vLy8vLy8vLy8vLy8vLy8vLy
+        8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy
+        8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy
+        8vLy8vIA8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx
+        8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx
+        8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHxAPHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx
+        8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx
+        8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx
+        8QDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw
+        8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw
+        8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PAA7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v
+        7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v
+        7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/vAO/v
+        7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v
+        7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v
+        7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7wDu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u
+        7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u
+        7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u4A7e3t7e3t
+        7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t
+        7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t
+        7e3t7e3t7e3t7e3t7e3t7e3t7e3tAOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs
+        7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs
+        7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7ADs7Ozs7Ozs7Ozs
+        7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs
+        7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs
+        7Ozs7Ozs7Ozs7Ozs7Ozs7OwA6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr
+        6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr
+        6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vrAOrq6urq6urq6urq6urq
+        6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq
+        6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq
+        6urq6urq6urq6urq6gDq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq
+        6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq
+        6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6uoA6enp6enp6enp6enp6enp6enp
+        6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp
+        6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp
+        6enp6enp6enpAOjo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo
+        6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo
+        6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6ADn5+fn5+fn5+fn5+fn5+fn5+fn5+fn
+        5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn
+        5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn
+        5+fn5+cA5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn
+        5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn
+        5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fnAObm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm
+        5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm
+        5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm
+        5gDl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl
+        5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl
+        5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eUA5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl
+        5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl
+        5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXlAOTk
+        5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk
+        5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk
+        5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5ADj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj
+        4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj
+        4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+MA4+Pj4+Pj
+        4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj
+        4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj
+        4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+PjAOLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi
+        4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi
+        4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4gDh4eHh4eHh4eHh
+        4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh
+        4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh
+        4eHh4eHh4eHh4eHh4eHh4eEA4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg
+        4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg
+        4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODgAODg4ODg4ODg4ODg4ODg
+        4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg
+        4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg
+        4ODg4ODg4ODg4ODg4ADf39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f
+        39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f
+        39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f398A3t7e3t7e3t7e3t7e3t7e3t7e
+        3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e
+        3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e
+        3t7e3t7e3t7eAN7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e
+        3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e
+        3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3gDd3d3d3d3d3d3d3d3d3d3d3d3d3d3d
+        3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d
+        3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d
+        3d3d3d0A3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc
+        3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc
+        3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3NzcANvb29vb29vb29vb29vb29vb29vb29vb29vb
+        29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb
+        29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb
+        2wDb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb
+        29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb
+        29vb29vb29vb29vb29vb29vb29vb29vb29vb29sA2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra
+        2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra
+        2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2traANnZ
+        2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ
+        2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ
+        2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2QDZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ
+        2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ
+        2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dkA2NjY2NjY
+        2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY
+        2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY
+        2NjY2NjY2NjY2NjY2NjY2NjY2NjYANfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX
+        19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX
+        19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX1wDW1tbW1tbW1tbW
+        1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW
+        1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW
+        1tbW1tbW1tbW1tbW1tbW1tYA1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW
+        1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW
+        1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbWANXV1dXV1dXV1dXV1dXV
+        1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV
+        1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV
+        1dXV1dXV1dXV1dXV1QDU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU
+        1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU
+        1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NQA1NTU1NTU1NTU1NTU1NTU1NTU
+        1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU
+        1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU
+        1NTU1NTU1NTUANPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT
+        09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT
+        09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0wDS0tLS0tLS0tLS0tLS0tLS0tLS0tLS
+        0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS
+        0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS
+        0tLS0tIA0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR
+        0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR
+        0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHRANHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR
+        0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR
+        0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR
+        0QDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ
+        0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ
+        0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NAAz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/P
+        z8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/P
+        z8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/PAM/P
+        z8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/P
+        z8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/P
+        z8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/PzwDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O
+        zs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O
+        zs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs4Azc3Nzc3N
+        zc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3N
+        zc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3N
+        zc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3NAMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM
+        zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM
+        zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzADMzMzMzMzMzMzM
+        zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM
+        zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM
+        zMzMzMzMzMzMzMzMzMzMzMwAy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL
+        y8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL
+        y8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLAMrKysrKysrKysrKysrK
+        ysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrK
+        ysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrK
+        ysrKysrKysrKysrKygDKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrK
+        ysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrK
+        ysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysoAycnJycnJycnJycnJycnJycnJ
+        ycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJ
+        ycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJ
+        ycnJycnJycnJAMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjI
+        yMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjI
+        yMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyADIyMjIyMjIyMjIyMjIyMjIyMjIyMjI
+        yMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjI
+        yMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjI
+        yMjIyMgAx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fH
+        x8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fH
+        x8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHAMbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbG
+        xsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbG
+        xsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbG
+        xgDFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXF
+        xcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXF
+        xcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcUAxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXF
+        xcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXF
+        xcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFAMTE
+        xMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTE
+        xMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTE
+        xMTExMTExMTExMTExMTExMTExMTExMTExADDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD
+        w8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD
+        w8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8MAw8PDw8PD
+        w8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD
+        w8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PD
+        w8PDw8PDw8PDw8PDw8PDw8PDw8PDAMLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLC
+        wsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLC
+        wsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwgDBwcHBwcHBwcHB
+        wcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHB
+        wcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHB
+        wcHBwcHBwcHBwcHBwcHBwcEAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA
+        wMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA
+        wMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAMDAwMDAwMDAwMDAwMDA
+        wMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA
+        wMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA
+        wMDAwMDAwMDAwMDAwAC/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/
+        v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/
+        v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v78Avr6+vr6+vr6+vr6+vr6+vr6+
+        vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+
+        vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+
+        vr6+vr6+vr6+AL6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+
+        vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+
+        vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vgC9vb29vb29vb29vb29vb29vb29vb29
+        vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29
+        vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29
+        vb29vb0AvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8
+        vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8
+        vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8ALu7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7
+        u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7
+        u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7
+        uwC7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7
+        u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7
+        u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7sAurq6urq6urq6urq6urq6urq6urq6urq6urq6urq6
+        urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6
+        urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6ALm5
+        ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5
+        ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5
+        ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5uQC5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5
+        ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5
+        ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubkAuLi4uLi4
+        uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4
+        uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4
+        uLi4uLi4uLi4uLi4uLi4uLi4uLi4ALe3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3
+        t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3
+        t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3twC2tra2tra2tra2
+        tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2
+        tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2
+        tra2tra2tra2tra2tra2trYAtra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2
+        tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2
+        tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2ALW1tbW1tbW1tbW1tbW1
+        tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1
+        tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1
+        tbW1tbW1tbW1tbW1tQC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0
+        tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0
+        tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQAtLS0tLS0tLS0tLS0tLS0tLS0
+        tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0
+        tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0
+        tLS0tLS0tLS0ALOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Oz
+        s7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Oz
+        s7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzswCysrKysrKysrKysrKysrKysrKysrKy
+        srKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKy
+        srKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKy
+        srKysrIAsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx
+        sbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx
+        sbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxALGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx
+        sbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx
+        sbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx
+        sQCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCw
+        sLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCw
+        sLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLAAr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+v
+        r6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+v
+        r6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vAK+v
+        r6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+v
+        r6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+v
+        r6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vrwCurq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6u
+        rq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6u
+        rq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq4Ara2tra2t
+        ra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2t
+        ra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2t
+        ra2tra2tra2tra2tra2tra2tra2tAKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKys
+        rKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKys
+        rKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrACsrKysrKysrKys
+        rKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKys
+        rKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKys
+        rKysrKysrKysrKysrKysrKwAq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6ur
+        q6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6ur
+        q6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urAKqqqqqqqqqqqqqqqqqq
+        qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
+        qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
+        qqqqqqqqqqqqqqqqqgCqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
+        qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
+        qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqoAqampqampqampqampqampqamp
+        qampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqamp
+        qampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqamp
+        qampqampqampAKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKio
+        qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKio
+        qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqACoqKioqKioqKioqKioqKioqKioqKio
+        qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKio
+        qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKio
+        qKioqKgAp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6en
+        p6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6en
+        p6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enAKampqampqampqampqampqampqampqampqam
+        pqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqam
+        pqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqam
+        pgClpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl
+        paWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl
+        paWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaUApaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl
+        paWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWl
+        paWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlAKSk
+        pKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSk
+        pKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSk
+        pKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpACjo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Oj
+        o6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Oj
+        o6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6MAo6Ojo6Oj
+        o6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Oj
+        o6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Oj
+        o6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6OjAKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi
+        oqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi
+        oqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogChoaGhoaGhoaGh
+        oaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGh
+        oaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGh
+        oaGhoaGhoaGhoaGhoaGhoaEAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg
+        oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg
+        oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgAKCgoKCgoKCgoKCgoKCg
+        oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg
+        oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg
+        oKCgoKCgoKCgoKCgoACfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+f
+        n5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+f
+        n5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn58Anp6enp6enp6enp6enp6enp6e
+        np6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6e
+        np6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6e
+        np6enp6enp6eAJ6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6e
+        np6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6e
+        np6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6engCdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2d
+        nZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2d
+        nZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2d
+        nZ2dnZ0AnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJyc
+        nJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJyc
+        nJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycAJubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ub
+        m5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ub
+        m5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ub
+        mwCbm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ub
+        m5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ub
+        m5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5sAmpqampqampqampqampqampqampqampqampqampqa
+        mpqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqa
+        mpqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqaAJmZ
+        mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ
+        mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ
+        mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmQCZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ
+        mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ
+        mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZkAmJiYmJiY
+        mJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiY
+        mJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiY
+        mJiYmJiYmJiYmJiYmJiYmJiYmJiYAJeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eX
+        l5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eX
+        l5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXlwCWlpaWlpaWlpaW
+        lpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaW
+        lpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaW
+        lpaWlpaWlpaWlpaWlpaWlpYAlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaW
+        lpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaW
+        lpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWAJWVlZWVlZWVlZWVlZWV
+        lZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWV
+        lZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWV
+        lZWVlZWVlZWVlZWVlQCUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSU
+        lJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSU
+        lJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJQAlJSUlJSUlJSUlJSUlJSUlJSU
+        lJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSU
+        lJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSU
+        lJSUlJSUlJSUAJOTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OT
+        k5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OT
+        k5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTkwCSkpKSkpKSkpKSkpKSkpKSkpKSkpKS
+        kpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKS
+        kpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKS
+        kpKSkpIAkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGR
+        kZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGR
+        kZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRAJGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGR
+        kZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGR
+        kZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGR
+        kQCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQ
+        kJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQ
+        kJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJAAj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+P
+        j4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+P
+        j4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+PAI+P
+        j4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+P
+        j4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+P
+        j4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+PjwCOjo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6O
+        jo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6O
+        jo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo4AjY2NjY2N
+        jY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2N
+        jY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2N
+        jY2NjY2NjY2NjY2NjY2NjY2NjY2NAI2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2N
+        jY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2N
+        jY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjQCMjIyMjIyMjIyM
+        jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyM
+        jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyM
+        jIyMjIyMjIyMjIyMjIyMjIwAi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uL
+        i4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uL
+        i4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLAIqKioqKioqKioqKioqK
+        ioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqK
+        ioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqK
+        ioqKioqKioqKioqKigCKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqK
+        ioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqK
+        ioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiooAiYmJiYmJiYmJiYmJiYmJiYmJ
+        iYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJ
+        iYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJ
+        iYmJiYmJiYmJAIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI
+        iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI
+        iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiACIiIiIiIiIiIiIiIiIiIiIiIiIiIiI
+        iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI
+        iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI
+        iIiIiIgAh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eH
+        h4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eH
+        h4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHAIaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaG
+        hoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaG
+        hoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaG
+        hgCFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWF
+        hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWF
+        hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYUAhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWF
+        hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWF
+        hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFAISE
+        hISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISE
+        hISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISE
+        hISEhISEhISEhISEhISEhISEhISEhISEhACDg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4OD
+        g4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4OD
+        g4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4MAg4ODg4OD
+        g4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4OD
+        g4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4OD
+        g4ODg4ODg4ODg4ODg4ODg4ODg4ODAIKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKC
+        goKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKC
+        goKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCggCBgYGBgYGBgYGB
+        gYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGB
+        gYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGB
+        gYGBgYGBgYGBgYGBgYGBgYEAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA
+        gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA
+        gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAAICAgICAgICAgICAgICA
+        gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA
+        gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA
+        gICAgICAgICAgICAgAB/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/
+        f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/
+        f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f38Afn5+fn5+fn5+fn5+fn5+fn5+
+        fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+
+        fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+
+        fn5+fn5+fn5+AH5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+
+        fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+
+        fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fgB9fX19fX19fX19fX19fX19fX19fX19
+        fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19
+        fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19
+        fX19fX0AfHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8
+        fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8
+        fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8AHt7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7
+        e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7
+        e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7
+        ewB7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7
+        e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7
+        e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3sAenp6enp6enp6enp6enp6enp6enp6enp6enp6enp6
+        enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6
+        enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6enp6AHl5
+        eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5
+        eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5
+        eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eQB5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5
+        eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5
+        eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXkAeHh4eHh4
+        eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4
+        eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4
+        eHh4eHh4eHh4eHh4eHh4eHh4eHh4AHd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3
+        d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3
+        d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3dwB2dnZ2dnZ2dnZ2
+        dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2
+        dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2
+        dnZ2dnZ2dnZ2dnZ2dnZ2dnYAdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2
+        dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2
+        dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2AHV1dXV1dXV1dXV1dXV1
+        dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1
+        dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1
+        dXV1dXV1dXV1dXV1dQB0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0
+        dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0
+        dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHQAdHR0dHR0dHR0dHR0dHR0dHR0
+        dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0
+        dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0
+        dHR0dHR0dHR0AHNzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nz
+        c3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nz
+        c3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3NzcwBycnJycnJycnJycnJycnJycnJycnJy
+        cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
+        cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
+        cnJycnIAcnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
+        cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
+        cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJyAHFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFx
+        cXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFx
+        cXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFx
+        cQBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBw
+        cHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBw
+        cHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHAAb29vb29vb29vb29vb29vb29vb29vb29vb29vb29v
+        b29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29v
+        b29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vAG9v
+        b29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29v
+        b29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29v
+        b29vb29vb29vb29vb29vb29vb29vb29vbwBubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5u
+        bm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5u
+        bm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubm4AbW1tbW1t
+        bW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1t
+        bW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1t
+        bW1tbW1tbW1tbW1tbW1tbW1tbW1tAG1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1t
+        bW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1t
+        bW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbQBsbGxsbGxsbGxs
+        bGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxs
+        bGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxs
+        bGxsbGxsbGxsbGxsbGxsbGwAa2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tr
+        a2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tr
+        a2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2tra2trAGpqampqampqampqampq
+        ampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampq
+        ampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampq
+        ampqampqampqampqagBqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampq
+        ampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampq
+        ampqampqampqampqampqampqampqampqampqampqampqampqampqamoAaWlpaWlpaWlpaWlpaWlpaWlp
+        aWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlp
+        aWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlp
+        aWlpaWlpaWlpAGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGho
+        aGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGho
+        aGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaABoaGhoaGhoaGhoaGhoaGhoaGhoaGho
+        aGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGho
+        aGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGho
+        aGhoaGgAZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dn
+        Z2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dn
+        Z2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2dnAGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm
+        ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm
+        ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm
+        ZgBlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVl
+        ZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVl
+        ZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUAZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVl
+        ZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVl
+        ZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlAGRk
+        ZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRk
+        ZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRk
+        ZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZABjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2Nj
+        Y2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2Nj
+        Y2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MAY2NjY2Nj
+        Y2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2Nj
+        Y2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2Nj
+        Y2NjY2NjY2NjY2NjY2NjY2NjY2NjAGJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJi
+        YmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJi
+        YmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYgBhYWFhYWFhYWFh
+        YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh
+        YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh
+        YWFhYWFhYWFhYWFhYWFhYWEAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBg
+        YGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBg
+        YGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgAGBgYGBgYGBgYGBgYGBg
+        YGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBg
+        YGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBg
+        YGBgYGBgYGBgYGBgYABfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f
+        X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f
+        X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18AXl5eXl5eXl5eXl5eXl5eXl5e
+        Xl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5e
+        Xl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5e
+        Xl5eXl5eXl5eAF5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5e
+        Xl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5e
+        Xl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXgBdXV1dXV1dXV1dXV1dXV1dXV1dXV1d
+        XV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1d
+        XV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1d
+        XV1dXV0AXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxc
+        XFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxc
+        XFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcAFtbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tb
+        W1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tb
+        W1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tb
+        WwBbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tb
+        W1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tb
+        W1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1tbW1sAWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpa
+        WlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpa
+        WlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaAFlZ
+        WVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZ
+        WVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZ
+        WVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWQBZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZ
+        WVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZ
+        WVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVkAWFhYWFhY
+        WFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhY
+        WFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhY
+        WFhYWFhYWFhYWFhYWFhYWFhYWFhYAFdXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dX
+        V1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dX
+        V1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXVwBXV1dXV1dXV1dX
+        V1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dX
+        V1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dX
+        V1dXV1dXV1dXV1dXV1dXV1cAVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZW
+        VlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZW
+        VlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWAFVVVVVVVVVVVVVVVVVV
+        VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
+        VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
+        VVVVVVVVVVVVVVVVVQBUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRU
+        VFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRU
+        VFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFQAVFRUVFRUVFRUVFRUVFRUVFRU
+        VFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRU
+        VFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRU
+        VFRUVFRUVFRUAFNTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NT
+        U1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NT
+        U1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTUwBSUlJSUlJSUlJSUlJSUlJSUlJSUlJS
+        UlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJS
+        UlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJS
+        UlJSUlIAUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJS
+        UlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJS
+        UlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAFFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFR
+        UVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFR
+        UVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFR
+        UQBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ
+        UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ
+        UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFAAT09PT09PT09PT09PT09PT09PT09PT09PT09PT09P
+        T09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09P
+        T09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PAE9P
+        T09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09P
+        T09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09P
+        T09PT09PT09PT09PT09PT09PT09PT09PTwBOTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5O
+        Tk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5O
+        Tk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk4ATU1NTU1N
+        TU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1N
+        TU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1N
+        TU1NTU1NTU1NTU1NTU1NTU1NTU1NAE1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1N
+        TU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1N
+        TU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTQBMTExMTExMTExM
+        TExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExM
+        TExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExM
+        TExMTExMTExMTExMTExMTEwAS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tL
+        S0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tL
+        S0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLAEpKSkpKSkpKSkpKSkpK
+        SkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpK
+        SkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpK
+        SkpKSkpKSkpKSkpKSgBKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpK
+        SkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpK
+        SkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkoASUlJSUlJSUlJSUlJSUlJSUlJ
+        SUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJ
+        SUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJ
+        SUlJSUlJSUlJAEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhI
+        SEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhI
+        SEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISABISEhISEhISEhISEhISEhISEhISEhI
+        SEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhI
+        SEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhI
+        SEhISEgAR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dH
+        R0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dH
+        R0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHAEZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZG
+        RkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZG
+        RkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZG
+        RgBFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVF
+        RUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVF
+        RUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUUARUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVF
+        RUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVF
+        RUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFAERE
+        RERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERE
+        RERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERE
+        RERERERERERERERERERERERERERERERERABDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0ND
+        Q0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0ND
+        Q0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0MAQ0NDQ0ND
+        Q0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0ND
+        Q0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0ND
+        Q0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDAEJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJC
+        QkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJC
+        QkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQgBBQUFBQUFBQUFB
+        QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB
+        QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB
+        QUFBQUFBQUFBQUFBQUFBQUEAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA
+        QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA
+        QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBA
+        QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA
+        QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA
+        QEBAQEBAQEBAQEBAQAA/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/
+        Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/
+        Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8APj4+Pj4+Pj4+Pj4+Pj4+Pj4+
+        Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+
+        Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+
+        Pj4+Pj4+Pj4+AD4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+
+        Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+
+        Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+PgA9PT09PT09PT09PT09PT09PT09PT09
+        PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
+        PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
+        PT09PT0APDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8
+        PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8
+        PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8ADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8
+        PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8
+        PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8
+        PAA7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7
+        Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7
+        Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsAOjo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6
+        Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6
+        Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6ADk5
+        OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5
+        OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5
+        OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OQA5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5
+        OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5
+        OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTkAODg4ODg4
+        ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4
+        ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4
+        ODg4ODg4ODg4ODg4ODg4ODg4ODg4ADc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
+        Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
+        Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3NwA3Nzc3Nzc3Nzc3
+        Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
+        Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3
+        Nzc3Nzc3Nzc3Nzc3Nzc3NzcANjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2
+        NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2
+        NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2ADU1NTU1NTU1NTU1NTU1
+        NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1
+        NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1
+        NTU1NTU1NTU1NTU1NQA0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0
+        NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0
+        NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQANDQ0NDQ0NDQ0NDQ0NDQ0NDQ0
+        NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0
+        NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0
+        NDQ0NDQ0NDQ0ADMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz
+        MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz
+        MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMwAyMjIyMjIyMjIyMjIyMjIyMjIyMjIy
+        MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy
+        MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy
+        MjIyMjIAMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy
+        MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy
+        MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyADExMTExMTExMTExMTExMTExMTExMTExMTEx
+        MTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEx
+        MTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEx
+        MQAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw
+        MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw
+        MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAALy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v
+        Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v
+        Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vAC8v
+        Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v
+        Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v
+        Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwAuLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u
+        Li4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u
+        Li4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4ALS0tLS0t
+        LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
+        LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
+        LS0tLS0tLS0tLS0tLS0tLS0tLS0tAC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
+        LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
+        LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQAsLCwsLCwsLCws
+        LCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCws
+        LCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCws
+        LCwsLCwsLCwsLCwsLCwsLCwAKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr
+        KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr
+        KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrACoqKioqKioqKioqKioq
+        KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
+        KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
+        KioqKioqKioqKioqKgAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
+        KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
+        KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioAKSkpKSkpKSkpKSkpKSkpKSkp
+        KSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkp
+        KSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkp
+        KSkpKSkpKSkpACgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo
+        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo
+        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKAAoKCgoKCgoKCgoKCgoKCgoKCgoKCgo
+        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo
+        KCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo
+        KCgoKCgAJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycn
+        JycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycn
+        JycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnACYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYm
+        JiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYm
+        JiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYm
+        JgAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUl
+        JSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUl
+        JSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUAJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUl
+        JSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUl
+        JSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlACQk
+        JCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQk
+        JCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQk
+        JCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJAAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
+        IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
+        IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMAIyMjIyMj
+        IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
+        IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj
+        IyMjIyMjIyMjIyMjIyMjIyMjIyMjACIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi
+        IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi
+        IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIgAhISEhISEhISEh
+        ISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEh
+        ISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEh
+        ISEhISEhISEhISEhISEhISEAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+        ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+        ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAgICAgICAgICAgICAg
+        ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+        ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+        ICAgICAgICAgICAgIAAfHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f
+        Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f
+        Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8AHh4eHh4eHh4eHh4eHh4eHh4e
+        Hh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4e
+        Hh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4e
+        Hh4eHh4eHh4eAB4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4e
+        Hh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4e
+        Hh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHgAdHR0dHR0dHR0dHR0dHR0dHR0dHR0d
+        HR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0d
+        HR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0d
+        HR0dHR0AHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwc
+        HBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwc
+        HBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcABwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwc
+        HBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwc
+        HBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwc
+        HAAbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsb
+        GxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsb
+        GxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsAGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoa
+        GhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoa
+        GhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaABkZ
+        GRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZ
+        GRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZ
+        GRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQAZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZ
+        GRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZ
+        GRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkAGBgYGBgY
+        GBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgY
+        GBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgY
+        GBgYGBgYGBgYGBgYGBgYGBgYGBgYABcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcX
+        FxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcX
+        FxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFwAXFxcXFxcXFxcX
+        FxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcX
+        FxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcX
+        FxcXFxcXFxcXFxcXFxcXFxcAFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYW
+        FhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYW
+        FhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWABUVFRUVFRUVFRUVFRUV
+        FRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUV
+        FRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUV
+        FRUVFRUVFRUVFRUVFQAUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU
+        FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU
+        FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQAFBQUFBQUFBQUFBQUFBQUFBQU
+        FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU
+        FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU
+        FBQUFBQUFBQUABMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMT
+        ExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMT
+        ExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEwASEhISEhISEhISEhISEhISEhISEhIS
+        EhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhIS
+        EhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhIS
+        EhISEhIAEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhIS
+        EhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhIS
+        EhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISABERERERERERERERERERERERERERERERERER
+        ERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERER
+        ERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERER
+        EQAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ
+        EBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ
+        EBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAADw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8P
+        Dw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8P
+        Dw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PAA8P
+        Dw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8P
+        Dw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8P
+        Dw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDwAODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4O
+        Dg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4O
+        Dg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ADQ0NDQ0N
+        DQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0N
+        DQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0N
+        DQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NAA0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0N
+        DQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0N
+        DQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQAMDAwMDAwMDAwM
+        DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM
+        DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM
+        DAwMDAwMDAwMDAwMDAwMDAwACwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsL
+        CwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsL
+        CwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLAAoKCgoKCgoKCgoKCgoK
+        CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK
+        CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK
+        CgoKCgoKCgoKCgoKCgAKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK
+        CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK
+        CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoACQkJCQkJCQkJCQkJCQkJCQkJ
+        CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJ
+        CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJ
+        CQkJCQkJCQkJAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI
+        CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI
+        CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAAICAgICAgICAgICAgICAgICAgICAgI
+        CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI
+        CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI
+        CAgICAgABwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcH
+        BwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcH
+        BwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHAAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYG
+        BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYG
+        BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYG
+        BgAFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUF
+        BQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUF
+        BQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUABQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUF
+        BQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUF
+        BQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFAAQE
+        BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE
+        BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE
+        BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD
+        AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD
+        AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAwMDAwMD
+        AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD
+        AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD
+        AwMDAwMDAwMDAwMDAwMDAwMDAwMDAAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC
+        AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC
+        AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgABAQEBAQEBAQEB
+        AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
+        AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
+        AQEBAQEBAQEBAQEBAQEBAQEA
+</value>
+  </data>
+</root>
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HeuristicLab.Analysis.Views-3.3.csproj
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HeuristicLab.Analysis.Views-3.3.csproj	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HeuristicLab.Analysis.Views-3.3.csproj	(revision 12764)
@@ -0,0 +1,336 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{76945D76-CA61-4147-9DC2-0ACDCDDF87F9}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Analysis.Views</RootNamespace>
+    <AssemblyName>HeuristicLab.Analysis.Views-3.3</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation />
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>
+    </DocumentationFile>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <ItemGroup>
+    <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, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <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, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <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, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.MainForm-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.MainForm.WindowsForms-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.MainForm.WindowsForms-3.3.dll</HintPath>
+      <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\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" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Windows.Forms.DataVisualization" />
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="IndexedDataTableView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="IndexedDataTableView.Designer.cs">
+      <DependentUpon>IndexedDataTableView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ScatterPlotVisualPropertiesDialog.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="ScatterPlotVisualPropertiesDialog.Designer.cs">
+      <DependentUpon>ScatterPlotVisualPropertiesDialog.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ScatterPlotVisualPropertiesControl.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ScatterPlotVisualPropertiesControl.Designer.cs">
+      <DependentUpon>ScatterPlotVisualPropertiesControl.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ScatterPlotDataRowVisualPropertiesControl.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ScatterPlotDataRowVisualPropertiesControl.Designer.cs">
+      <DependentUpon>ScatterPlotDataRowVisualPropertiesControl.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ScatterPlotView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ScatterPlotView.Designer.cs">
+      <DependentUpon>ScatterPlotView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ScatterPlotHistoryView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ScatterPlotHistoryView.Designer.cs">
+      <DependentUpon>ScatterPlotHistoryView.cs</DependentUpon>
+    </Compile>
+    <None Include="Plugin.cs.frame" />
+    <Compile Include="AlleleFrequencyCollectionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="AlleleFrequencyCollectionView.Designer.cs">
+      <DependentUpon>AlleleFrequencyCollectionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="DataRowVisualPropertiesControl.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="DataRowVisualPropertiesControl.Designer.cs">
+      <DependentUpon>DataRowVisualPropertiesControl.cs</DependentUpon>
+    </Compile>
+    <Compile Include="DataTableVisualPropertiesControl.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="DataTableVisualPropertiesControl.Designer.cs">
+      <DependentUpon>DataTableVisualPropertiesControl.cs</DependentUpon>
+    </Compile>
+    <Compile Include="DataTableVisualPropertiesDialog.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="DataTableVisualPropertiesDialog.Designer.cs">
+      <DependentUpon>DataTableVisualPropertiesDialog.cs</DependentUpon>
+    </Compile>
+    <Compile Include="HeatMapHistoryView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="HeatMapHistoryView.Designer.cs">
+      <DependentUpon>HeatMapHistoryView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="DataTableHistoryView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="DataTableHistoryView.Designer.cs">
+      <DependentUpon>DataTableHistoryView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="HeatMapView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="HeatMapView.Designer.cs">
+      <DependentUpon>HeatMapView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="AlleleFrequencyView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="AlleleFrequencyView.Designer.cs">
+      <DependentUpon>AlleleFrequencyView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="AlleleFrequencyCollectionHistoryView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="AlleleFrequencyCollectionHistoryView.Designer.cs">
+      <DependentUpon>AlleleFrequencyCollectionHistoryView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Plugin.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="DataTableView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="DataTableView.Designer.cs">
+      <DependentUpon>DataTableView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="HistogramControl.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="HistogramControl.Designer.cs">
+      <DependentUpon>HistogramControl.cs</DependentUpon>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
+      <Project>{887425B4-4348-49ED-A457-B7D2C26DDBF9}</Project>
+      <Name>HeuristicLab.Analysis-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="HeatMapView.resx">
+      <DependentUpon>HeatMapView.cs</DependentUpon>
+    </EmbeddedResource>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <PropertyGroup>
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd
+</PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HistogramControl.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HistogramControl.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HistogramControl.Designer.cs	(revision 12764)
@@ -0,0 +1,202 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Visualization.ChartControlsExtensions;
+
+namespace HeuristicLab.Analysis.Views {
+  partial class HistogramControl {
+    /// <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 chartArea2 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+      System.Windows.Forms.DataVisualization.Charting.Legend legend2 = new System.Windows.Forms.DataVisualization.Charting.Legend();
+      System.Windows.Forms.DataVisualization.Charting.Series series2 = new System.Windows.Forms.DataVisualization.Charting.Series();
+      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      this.binsNumericUpDown = new System.Windows.Forms.NumericUpDown();
+      this.label1 = new System.Windows.Forms.Label();
+      this.exactCheckBox = new System.Windows.Forms.CheckBox();
+      this.label2 = new System.Windows.Forms.Label();
+      this.bandwidthNumericUpDown = new System.Windows.Forms.NumericUpDown();
+      this.noDataLabel = new System.Windows.Forms.Label();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.binsNumericUpDown)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.bandwidthNumericUpDown)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // chart
+      // 
+      this.chart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      chartArea2.Name = "ChartArea1";
+      this.chart.ChartAreas.Add(chartArea2);
+      legend2.Alignment = System.Drawing.StringAlignment.Center;
+      legend2.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend2.Name = "Default";
+      this.chart.Legends.Add(legend2);
+      this.chart.Location = new System.Drawing.Point(0, 27);
+      this.chart.Name = "chart";
+      series2.ChartArea = "ChartArea1";
+      series2.Legend = "Default";
+      series2.Name = "Series1";
+      this.chart.Series.Add(series2);
+      this.chart.Size = new System.Drawing.Size(465, 336);
+      this.chart.TabIndex = 0;
+      // 
+      // binsNumericUpDown
+      // 
+      this.binsNumericUpDown.Location = new System.Drawing.Point(91, 3);
+      this.binsNumericUpDown.Maximum = new decimal(new int[] {
+            100000,
+            0,
+            0,
+            0});
+      this.binsNumericUpDown.Minimum = new decimal(new int[] {
+            2,
+            0,
+            0,
+            0});
+      this.binsNumericUpDown.Name = "binsNumericUpDown";
+      this.binsNumericUpDown.Size = new System.Drawing.Size(61, 20);
+      this.binsNumericUpDown.TabIndex = 1;
+      this.binsNumericUpDown.Value = new decimal(new int[] {
+            10,
+            0,
+            0,
+            0});
+      this.binsNumericUpDown.ValueChanged += new System.EventHandler(this.binsNumericUpDown_ValueChanged);
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(3, 5);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(82, 13);
+      this.label1.TabIndex = 2;
+      this.label1.Text = "Number of Bins:";
+      // 
+      // exactCheckBox
+      // 
+      this.exactCheckBox.AutoSize = true;
+      this.exactCheckBox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
+      this.exactCheckBox.Location = new System.Drawing.Point(291, 4);
+      this.exactCheckBox.Name = "exactCheckBox";
+      this.exactCheckBox.Size = new System.Drawing.Size(56, 17);
+      this.exactCheckBox.TabIndex = 3;
+      this.exactCheckBox.Text = "Exact:";
+      this.exactCheckBox.UseVisualStyleBackColor = true;
+      this.exactCheckBox.CheckedChanged += new System.EventHandler(this.exactCheckBox_CheckedChanged);
+      // 
+      // label2
+      // 
+      this.label2.AutoSize = true;
+      this.label2.Location = new System.Drawing.Point(158, 5);
+      this.label2.Name = "label2";
+      this.label2.Size = new System.Drawing.Size(60, 13);
+      this.label2.TabIndex = 5;
+      this.label2.Text = "Bandwidth:";
+      // 
+      // bandwidthNumericUpDown
+      // 
+      this.bandwidthNumericUpDown.DecimalPlaces = 2;
+      this.bandwidthNumericUpDown.Location = new System.Drawing.Point(224, 3);
+      this.bandwidthNumericUpDown.Maximum = new decimal(new int[] {
+            100000000,
+            0,
+            0,
+            0});
+      this.bandwidthNumericUpDown.Minimum = new decimal(new int[] {
+            1,
+            0,
+            0,
+            851968});
+      this.bandwidthNumericUpDown.Name = "bandwidthNumericUpDown";
+      this.bandwidthNumericUpDown.Size = new System.Drawing.Size(61, 20);
+      this.bandwidthNumericUpDown.TabIndex = 4;
+      this.bandwidthNumericUpDown.Value = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+      this.bandwidthNumericUpDown.ValueChanged += new System.EventHandler(this.bandwidthNumericUpDown_ValueChanged);
+      // 
+      // noDataLabel
+      // 
+      this.noDataLabel.Anchor = System.Windows.Forms.AnchorStyles.None;
+      this.noDataLabel.AutoSize = true;
+      this.noDataLabel.Location = new System.Drawing.Point(163, 175);
+      this.noDataLabel.Name = "noDataLabel";
+      this.noDataLabel.Size = new System.Drawing.Size(139, 13);
+      this.noDataLabel.TabIndex = 22;
+      this.noDataLabel.Text = "No data could be displayed.";
+      // 
+      // HistogramControl
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.noDataLabel);
+      this.Controls.Add(this.label2);
+      this.Controls.Add(this.bandwidthNumericUpDown);
+      this.Controls.Add(this.exactCheckBox);
+      this.Controls.Add(this.label1);
+      this.Controls.Add(this.binsNumericUpDown);
+      this.Controls.Add(this.chart);
+      this.Name = "HistogramControl";
+      this.Size = new System.Drawing.Size(465, 363);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      ((System.ComponentModel.ISupportInitialize)(this.binsNumericUpDown)).EndInit();
+      ((System.ComponentModel.ISupportInitialize)(this.bandwidthNumericUpDown)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private EnhancedChart chart;
+    private System.Windows.Forms.NumericUpDown binsNumericUpDown;
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.CheckBox exactCheckBox;
+    private System.Windows.Forms.Label label2;
+    private System.Windows.Forms.NumericUpDown bandwidthNumericUpDown;
+    private System.Windows.Forms.Label noDataLabel;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HistogramControl.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HistogramControl.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/HistogramControl.cs	(revision 12764)
@@ -0,0 +1,256 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.Analysis.Statistics;
+
+namespace HeuristicLab.Analysis.Views {
+  public partial class HistogramControl : UserControl {
+    protected static readonly string SeriesName = "Histogram";
+    protected static readonly decimal bandwidthMin = 0.0000000000001m;
+    protected Dictionary<string, List<double>> points;
+    protected bool suppressUpdate;
+
+    public int NumberOfBins {
+      get { return (int)binsNumericUpDown.Value; }
+      set { binsNumericUpDown.Value = value; }
+    }
+
+    public int MinimumNumberOfBins {
+      get { return (int)binsNumericUpDown.Minimum; }
+      set { binsNumericUpDown.Minimum = value; }
+    }
+
+    public int MaximumNumberOfBins {
+      get { return (int)binsNumericUpDown.Maximum; }
+      set { binsNumericUpDown.Maximum = value; }
+    }
+
+    public int IncrementNumberOfBins {
+      get { return (int)binsNumericUpDown.Increment; }
+      set { binsNumericUpDown.Increment = value; }
+    }
+
+    public bool CalculateExactBins {
+      get { return exactCheckBox.Checked; }
+      set { exactCheckBox.Checked = value; }
+    }
+
+    public bool ShowExactCheckbox {
+      get { return exactCheckBox.Visible; }
+      set { exactCheckBox.Visible = value; }
+    }
+
+    public HistogramControl() {
+      InitializeComponent();
+      points = new Dictionary<string, List<double>>();
+    }
+
+    protected void InitNewRow(string name) {
+      if (!points.ContainsKey(name)) {
+        points.Add(name, new List<double>());
+      }
+    }
+
+    protected void InitSeries(string name) {
+      if (!chart.Series.Any(x => x.Name == name)) {
+        Series s = chart.Series.Add(name);
+        s.ChartType = SeriesChartType.Column;
+        s.BorderColor = Color.Black;
+        s.BorderWidth = 1;
+        s.BorderDashStyle = ChartDashStyle.Solid;
+      }
+    }
+
+    public void AddPoint(double point) {
+      InitNewRow(SeriesName);
+      InitSeries(SeriesName);
+      points[SeriesName].Add(point);
+      UpdateHistogram();
+    }
+
+    public void AddPoints(IEnumerable<double> points) {
+      InitNewRow(SeriesName);
+      InitSeries(SeriesName);
+      this.points[SeriesName].AddRange(points);
+      UpdateHistogram();
+    }
+
+    public void AddPoint(string name, double point, bool replace = false) {
+      InitNewRow(name);
+      InitSeries(name);
+      if (replace) {
+        points[name].Clear();
+      }
+      points[name].Add(point);
+      UpdateHistogram();
+    }
+
+    public void AddPoints(string name, IEnumerable<double> points, bool replace = false) {
+      InitNewRow(name);
+      InitSeries(name);
+      if (replace) {
+        this.points[name].Clear();
+      }
+      this.points[name].AddRange(points);
+      UpdateHistogram();
+    }
+
+    public void ClearPoints() {
+      points.Clear();
+      UpdateHistogram();
+    }
+
+    protected void UpdateHistogram(double bandwith = double.NaN) {
+      if (InvokeRequired) {
+        Invoke((Action<double>)UpdateHistogram, bandwith);
+        return;
+      }
+
+      double overallMin = double.MaxValue;
+      double overallMax = double.MinValue;
+      int bins = (int)binsNumericUpDown.Value;
+
+      chart.Series.Clear();
+      foreach (var point in points) {
+        if (!point.Value.Any()) continue;
+
+        double minValue = point.Value.Min();
+        double maxValue = point.Value.Max();
+        double intervalWidth = (maxValue - minValue) / bins;
+        if (intervalWidth <= 0) continue;
+
+        Series histogramSeries = new Series(point.Key);
+        chart.Series.Add(histogramSeries);
+
+        if (!exactCheckBox.Checked) {
+          intervalWidth = HumanRoundRange(intervalWidth);
+          minValue = Math.Floor(minValue / intervalWidth) * intervalWidth;
+          maxValue = Math.Ceiling(maxValue / intervalWidth) * intervalWidth;
+        }
+
+        double current = minValue, intervalCenter = intervalWidth / 2.0;
+        int count = 0;
+        foreach (double v in point.Value.OrderBy(x => x)) {
+          while (v > current + intervalWidth) {
+            histogramSeries.Points.AddXY(current + intervalCenter, count);
+            current += intervalWidth;
+            count = 0;
+          }
+          count++;
+        }
+        histogramSeries.Points.AddXY(current + intervalCenter, count);
+        histogramSeries["PointWidth"] = "1";
+
+        overallMax = Math.Max(overallMax, maxValue);
+        overallMin = Math.Min(overallMin, minValue);
+
+        chart.ApplyPaletteColors();
+        CalculateDensity(histogramSeries, point.Value, bandwith);
+      }
+
+      if (chart.Series.Any()) {
+        noDataLabel.Visible = false;
+      } else {
+        noDataLabel.Visible = true;
+      }
+
+      ChartArea chartArea = chart.ChartAreas[0];
+      // don't show grid lines for second y-axis
+      chartArea.AxisY2.MajorGrid.Enabled = false;
+      chartArea.AxisY2.MinorGrid.Enabled = false;
+      chartArea.AxisY.Title = "Frequency";
+
+      double overallIntervalWidth = (overallMax - overallMin) / bins;
+      double axisInterval = overallIntervalWidth;
+      while ((overallMax - overallMin) / axisInterval > 10.0) {
+        axisInterval *= 2.0;
+      }
+      chartArea.AxisX.Interval = axisInterval;
+    }
+
+    protected void CalculateDensity(Series series, List<double> row, double bandwidth = double.NaN) {
+      string densitySeriesName = "Density " + series.Name;
+      double stepWidth = series.Points[1].XValue - series.Points[0].XValue;
+      var rowArray = row.ToArray();
+
+      if (chart.Series.Any(x => x.Name == densitySeriesName)) {
+        var ds = chart.Series.Single(x => x.Name == densitySeriesName);
+        chart.Series.Remove(ds);
+      }
+
+      if (double.IsNaN(bandwidth)) {
+        bandwidth = KernelDensityEstimator.EstimateBandwidth(rowArray);
+        decimal bwDecimal = (decimal)bandwidth;
+        if (bwDecimal < bandwidthMin) {
+          bwDecimal = bandwidthMin;
+          bandwidth = decimal.ToDouble(bwDecimal);
+        }
+        suppressUpdate = true;
+        bandwidthNumericUpDown.Value = bwDecimal;
+      }
+      var density = KernelDensityEstimator.Density(rowArray, rowArray.Length, stepWidth, bandwidth);
+
+      Series newSeries = new Series(densitySeriesName);
+      newSeries.Color = series.Color;
+      newSeries.ChartType = SeriesChartType.FastLine;
+      newSeries.BorderWidth = 2;
+      foreach (var d in density) {
+        newSeries.Points.Add(new DataPoint(d.Item1, d.Item2));
+      }
+
+      // densities should be plotted on the second axis (different scale)
+      newSeries.YAxisType = AxisType.Secondary;
+      chart.Series.Add(newSeries);
+    }
+
+    protected 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 void binsNumericUpDown_ValueChanged(object sender, EventArgs e) {
+      UpdateHistogram();
+    }
+
+    private void exactCheckBox_CheckedChanged(object sender, EventArgs e) {
+      UpdateHistogram();
+    }
+
+    private void bandwidthNumericUpDown_ValueChanged(object sender, EventArgs e) {
+      if (!suppressUpdate) {
+        UpdateHistogram(decimal.ToDouble(bandwidthNumericUpDown.Value));
+      }
+      suppressUpdate = false;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/IndexedDataTableView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/IndexedDataTableView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/IndexedDataTableView.Designer.cs	(revision 12764)
@@ -0,0 +1,125 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Analysis.Views {
+  partial class IndexedDataTableView<T> {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+      System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
+      System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
+      System.Windows.Forms.DataVisualization.Charting.Title title1 = new System.Windows.Forms.DataVisualization.Charting.Title();
+      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      ((System.ComponentModel.ISupportInitialize)(this.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.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);
+      // 
+      // DataTableView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.chart);
+      this.Name = "DataTableView";
+      this.Size = new System.Drawing.Size(359, 274);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      this.Controls.SetChildIndex(this.chart, 0);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 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;
+
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/IndexedDataTableView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/IndexedDataTableView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/IndexedDataTableView.cs	(revision 12764)
@@ -0,0 +1,574 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.Collections;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Analysis.Views {
+  [View("IndexedDataTable View")]
+  [Content(typeof(IndexedDataTable<>), true)]
+  public partial class IndexedDataTableView<T> : NamedItemView {
+    protected List<Series> invisibleSeries;
+    protected Dictionary<IObservableList<Tuple<T, double>>, IndexedDataRow<T>> valuesRowsTable;
+    /// <summary>
+    /// Gets or sets the variable to represent visually.
+    /// </summary>
+    /// <remarks>Uses property <see cref="ViewBase.Item"/> of base class <see cref="ViewBase"/>.
+    /// No own data storage present.</remarks>
+    public new IndexedDataTable<T> Content {
+      get { return (IndexedDataTable<T>)base.Content; }
+      set { base.Content = value; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of <see cref="VariableView"/> with caption "Variable".
+    /// </summary>
+    public IndexedDataTableView() {
+      InitializeComponent();
+      valuesRowsTable = new Dictionary<IObservableList<Tuple<T, double>>, IndexedDataRow<T>>();
+      invisibleSeries = new List<Series>();
+      chart.CustomizeAllChartAreas();
+      chart.ChartAreas[0].CursorX.Interval = 1;
+    }
+
+    #region Event Handler Registration
+    /// <summary>
+    /// Removes the eventhandlers from the underlying <see cref="Variable"/>.
+    /// </summary>
+    /// <remarks>Calls <see cref="ViewBase.RemoveItemEvents"/> of base class <see cref="ViewBase"/>.</remarks>
+    protected override void DeregisterContentEvents() {
+      foreach (var row in Content.Rows)
+        DeregisterDataRowEvents(row);
+      Content.VisualPropertiesChanged -= new EventHandler(Content_VisualPropertiesChanged);
+      Content.Rows.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(Rows_ItemsAdded);
+      Content.Rows.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(Rows_ItemsRemoved);
+      Content.Rows.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(Rows_ItemsReplaced);
+      Content.Rows.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(Rows_CollectionReset);
+      base.DeregisterContentEvents();
+    }
+
+    /// <summary>
+    /// Adds eventhandlers to the underlying <see cref="Variable"/>.
+    /// </summary>
+    /// <remarks>Calls <see cref="ViewBase.AddItemEvents"/> of base class <see cref="ViewBase"/>.</remarks>
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.VisualPropertiesChanged += new EventHandler(Content_VisualPropertiesChanged);
+      Content.Rows.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(Rows_ItemsAdded);
+      Content.Rows.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(Rows_ItemsRemoved);
+      Content.Rows.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(Rows_ItemsReplaced);
+      Content.Rows.CollectionReset += new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(Rows_CollectionReset);
+      foreach (var row in Content.Rows)
+        RegisterDataRowEvents(row);
+    }
+
+    /// <summary>
+    /// Automatically called for every existing data row and whenever a data row is added
+    /// to the data table. Do not call this method directly.
+    /// </summary>
+    /// <param name="row">The DataRow that was added.</param>
+    protected virtual void RegisterDataRowEvents(IndexedDataRow<T> 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<T, double>>>(Values_ItemsAdded);
+      row.Values.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_ItemsRemoved);
+      row.Values.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_ItemsReplaced);
+      row.Values.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_ItemsMoved);
+      row.Values.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_CollectionReset);
+    }
+
+    /// <summary>
+    /// Automatically called for every data row that is removed from the DataTable. Do
+    /// not directly call this method.
+    /// </summary>
+    /// <param name="row">The DataRow that was removed.</param>
+    protected virtual void DeregisterDataRowEvents(IndexedDataRow<T> row) {
+      row.Values.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_ItemsAdded);
+      row.Values.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_ItemsRemoved);
+      row.Values.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_ItemsReplaced);
+      row.Values.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_ItemsMoved);
+      row.Values.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, 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;
+        foreach (var row in Content.Rows)
+          AddDataRow(row);
+        ConfigureChartArea(chart.ChartAreas[0]);
+        RecalculateAxesScale(chart.ChartAreas[0]);
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      chart.Enabled = Content != null;
+    }
+
+    /// <summary>
+    /// Add the DataRow as a series to the chart.
+    /// </summary>
+    /// <param name="row">DataRow to add as series to the chart.</param>
+    protected virtual void AddDataRow(IndexedDataRow<T> row) {
+      Series series = new Series(row.Name);
+      if (row.VisualProperties.DisplayName.Trim() != String.Empty) series.LegendText = row.VisualProperties.DisplayName;
+      else series.LegendText = row.Name;
+      ConfigureSeries(series, row);
+      FillSeriesWithRowValues(series, row);
+
+      chart.Series.Add(series);
+      ConfigureChartArea(chart.ChartAreas[0]);
+      RecalculateAxesScale(chart.ChartAreas[0]);
+      UpdateYCursorInterval();
+    }
+
+    private void ConfigureSeries(Series series, IndexedDataRow<T> row) {
+      RemoveCustomPropertyIfExists(series, "PointWidth");
+      series.BorderWidth = 1;
+      series.BorderDashStyle = ChartDashStyle.Solid;
+      series.BorderColor = Color.Empty;
+      if (!typeof(T).Equals(typeof(DateTime)))
+        series.IsXValueIndexed = true;
+
+      if (row.VisualProperties.Color != Color.Empty)
+        series.Color = row.VisualProperties.Color;
+      else series.Color = Color.Empty;
+      series.IsVisibleInLegend = row.VisualProperties.IsVisibleInLegend;
+
+      switch (row.VisualProperties.ChartType) {
+        case DataRowVisualProperties.DataRowChartType.Line:
+          series.ChartType = SeriesChartType.FastLine;
+          series.BorderWidth = row.VisualProperties.LineWidth;
+          series.BorderDashStyle = ConvertLineStyle(row.VisualProperties.LineStyle);
+          break;
+        case DataRowVisualProperties.DataRowChartType.Bars:
+          // Bar is incompatible with anything but Bar and StackedBar*
+          if (!chart.Series.Any(x => x.ChartType != SeriesChartType.Bar && x.ChartType != SeriesChartType.StackedBar && x.ChartType != SeriesChartType.StackedBar100)) {
+            series.ChartType = SeriesChartType.Bar;
+            chart.ChartAreas[0].AxisX.Interval = 1;
+          } 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.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;
+      series.ToolTip = series.LegendText + " X = #VALX, Y = #VALY";
+    }
+
+    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;
+
+      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;
+
+      if (typeof(T).Equals(typeof(DateTime))) {
+        area.AxisX.IntervalType = DateTimeIntervalType.Hours;
+        area.AxisX.LabelStyle.Format = "dd.MM.yyyy HH:mm";
+        area.AxisX.IntervalAutoMode = IntervalAutoMode.VariableCount;
+      }
+    }
+
+    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;
+    }
+
+    /// <summary>
+    /// Set the Y Cursor interval to visible points of enabled series.
+    /// </summary>
+    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;
+    }
+
+
+    /// <summary>
+    /// Remove the corresponding series for a certain DataRow.
+    /// </summary>
+    /// <param name="row">DataRow which series should be removed.</param>
+    protected virtual void RemoveDataRow(IndexedDataRow<T> row) {
+      Series series = chart.Series[row.Name];
+      chart.Series.Remove(series);
+      if (invisibleSeries.Contains(series))
+        invisibleSeries.Remove(series);
+      RecalculateAxesScale(chart.ChartAreas[0]);
+    }
+
+    #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 {
+        chart.Titles[0].Text = 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
+      }
+    }
+    #endregion
+    #region Rows Event Handlers
+    private void Rows_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedDataRow<T>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(Rows_ItemsAdded), sender, e);
+      else {
+        foreach (var row in e.Items) {
+          AddDataRow(row);
+          RegisterDataRowEvents(row);
+        }
+      }
+    }
+    private void Rows_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedDataRow<T>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(Rows_ItemsRemoved), sender, e);
+      else {
+        foreach (var row in e.Items) {
+          DeregisterDataRowEvents(row);
+          RemoveDataRow(row);
+        }
+      }
+    }
+    private void Rows_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedDataRow<T>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(Rows_ItemsReplaced), sender, e);
+      else {
+        foreach (var row in e.OldItems) {
+          DeregisterDataRowEvents(row);
+          RemoveDataRow(row);
+        }
+        foreach (var row in e.Items) {
+          AddDataRow(row);
+          RegisterDataRowEvents(row);
+        }
+      }
+    }
+    private void Rows_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedDataRow<T>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(Rows_CollectionReset), sender, e);
+      else {
+        foreach (var row in e.OldItems) {
+          DeregisterDataRowEvents(row);
+          RemoveDataRow(row);
+        }
+        foreach (var row in e.Items) {
+          AddDataRow(row);
+          RegisterDataRowEvents(row);
+        }
+      }
+    }
+    #endregion
+    #region Row Event Handlers
+    private void Row_VisualPropertiesChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Row_VisualPropertiesChanged), sender, e);
+      else {
+        var row = (IndexedDataRow<T>)sender;
+        Series series = chart.Series[row.Name];
+        series.Points.Clear();
+        ConfigureSeries(series, row);
+        FillSeriesWithRowValues(series, row);
+        RecalculateAxesScale(chart.ChartAreas[0]);
+      }
+    }
+    private void Row_NameChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Row_NameChanged), sender, e);
+      else {
+        var row = (IndexedDataRow<T>)sender;
+        chart.Series[row.Name].Name = row.Name;
+      }
+    }
+    #endregion
+    #region Values Event Handlers
+    private void Values_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<T, double>>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_ItemsAdded), sender, e);
+      else {
+        IndexedDataRow<T> row = null;
+        valuesRowsTable.TryGetValue((IObservableList<Tuple<T, double>>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            rowSeries.Points.Clear();
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    private void Values_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<T, double>>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_ItemsRemoved), sender, e);
+      else {
+        IndexedDataRow<T> row = null;
+        valuesRowsTable.TryGetValue((IObservableList<Tuple<T, double>>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            rowSeries.Points.Clear();
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    private void Values_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<T, double>>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_ItemsReplaced), sender, e);
+      else {
+        IndexedDataRow<T> row = null;
+        valuesRowsTable.TryGetValue((IObservableList<Tuple<T, double>>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            if (row.VisualProperties.ChartType == DataRowVisualProperties.DataRowChartType.Histogram) {
+              rowSeries.Points.Clear();
+              FillSeriesWithRowValues(rowSeries, row);
+            } else {
+              foreach (IndexedItem<Tuple<T, double>> item in e.Items) {
+                rowSeries.Points[item.Index].SetValueXY(item.Value.Item1, item.Value.Item2);
+              }
+            }
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    private void Values_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<T, double>>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_ItemsMoved), sender, e);
+      else {
+        IndexedDataRow<T> row = null;
+        valuesRowsTable.TryGetValue((IObservableList<Tuple<T, double>>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            rowSeries.Points.Clear();
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+
+    private void Values_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<T, double>>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_CollectionReset), sender, e);
+      else {
+        IndexedDataRow<T> row = null;
+        valuesRowsTable.TryGetValue((IObservableList<Tuple<T, double>>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            rowSeries.Points.Clear();
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    #endregion
+    #endregion
+
+    #region Chart Event Handlers
+    private void chart_MouseDown(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem) {
+        ToggleSeriesVisible(result.Series);
+      }
+    }
+    private void chart_MouseMove(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem)
+        this.Cursor = Cursors.Hand;
+      else
+        this.Cursor = Cursors.Default;
+    }
+    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
+      foreach (LegendItem legendItem in e.LegendItems) {
+        var series = chart.Series[legendItem.SeriesName];
+        if (series != null) {
+          bool seriesIsInvisible = invisibleSeries.Contains(series);
+          foreach (LegendCell cell in legendItem.Cells) {
+            cell.ForeColor = seriesIsInvisible ? Color.Gray : Color.Black;
+          }
+        }
+      }
+    }
+    #endregion
+
+    private void ToggleSeriesVisible(Series series) {
+      if (!invisibleSeries.Contains(series)) {
+        series.Points.Clear();
+        invisibleSeries.Add(series);
+      } else {
+        invisibleSeries.Remove(series);
+        if (Content != null) {
+
+          var row = (from r in Content.Rows
+                     where r.Name == series.Name
+                     select r).Single();
+          FillSeriesWithRowValues(series, row);
+          this.chart.Legends[series.Legend].ForeColor = Color.Black;
+          RecalculateAxesScale(chart.ChartAreas[0]);
+          UpdateYCursorInterval();
+        }
+      }
+    }
+
+    private void FillSeriesWithRowValues(Series series, IndexedDataRow<T> row) {
+      for (int i = 0; i < row.Values.Count; i++) {
+        var value = row.Values[i];
+        DataPoint point = new DataPoint();
+        point.SetValueXY(value.Item1, value.Item2);
+        series.Points.Add(point);
+      }
+    }
+
+    #region Helpers
+    protected void RemoveCustomPropertyIfExists(Series series, string property) {
+      if (series.IsCustomPropertySet(property)) series.DeleteCustomProperty(property);
+    }
+
+    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;
+      }
+    }
+
+    /// <summary>
+    /// Determines whether a double value can be displayed (converted to Decimal and not an NaN).
+    /// </summary>
+    /// <param name="x">The number to check.</param>
+    /// <returns><code>true</code> if the value can be safely shwon in the chart,
+    /// <code>false</code> otherwise.</returns>
+    protected static bool IsInvalidValue(double x) {
+      return double.IsNaN(x) || x < (double)decimal.MinValue || x > (double)decimal.MaxValue;
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/Plugin.cs.frame
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/Plugin.cs.frame	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/Plugin.cs.frame	(revision 12764)
@@ -0,0 +1,42 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Analysis.Views {
+  /// <summary>
+  /// Plugin class for HeuristicLab.Analysis.Views plugin.
+  /// </summary>
+  [Plugin("HeuristicLab.Analysis.Views", "3.3.12.$WCREV$")]
+  [PluginFile("HeuristicLab.Analysis.Views-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Analysis", "3.3")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Core.Views", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.MainForm", "3.3")]
+  [PluginDependency("HeuristicLab.MainForm.WindowsForms", "3.3")]
+  [PluginDependency("HeuristicLab.Visualization.ChartControlsExtensions", "3.3")]
+  public class HeuristicLabAnalysisViewsPlugin : PluginBase {
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/Properties/AssemblyInfo.cs.frame	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/Properties/AssemblyInfo.cs.frame	(revision 12764)
@@ -0,0 +1,56 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.Analysis.Views")]
+[assembly: AssemblyDescription("Views of the HeuristicLab algorithm analysis classes")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2015 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("bb4e3c6d-ba36-4bb9-a601-04d3c714c0f1")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.12.$WCREV$")]
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotDataRowVisualPropertiesControl.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotDataRowVisualPropertiesControl.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotDataRowVisualPropertiesControl.Designer.cs	(revision 12764)
@@ -0,0 +1,208 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Analysis.Views {
+  partial class ScatterPlotDataRowVisualPropertiesControl {
+    /// <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.pointStyleComboBox = new System.Windows.Forms.ComboBox();
+      this.colorDialog = new System.Windows.Forms.ColorDialog();
+      this.colorButton = new System.Windows.Forms.Button();
+      this.isVisibleInLegendCheckBox = new System.Windows.Forms.CheckBox();
+      this.label1 = new System.Windows.Forms.Label();
+      this.label2 = new System.Windows.Forms.Label();
+      this.pointSizeNumericUpDown = new System.Windows.Forms.NumericUpDown();
+      this.label3 = new System.Windows.Forms.Label();
+      this.displayNameTextBox = new System.Windows.Forms.TextBox();
+      this.label9 = new System.Windows.Forms.Label();
+      this.label7 = new System.Windows.Forms.Label();
+      ((System.ComponentModel.ISupportInitialize)(this.pointSizeNumericUpDown)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // pointStyleComboBox
+      // 
+      this.pointStyleComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.pointStyleComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.pointStyleComboBox.FormattingEnabled = true;
+      this.pointStyleComboBox.Location = new System.Drawing.Point(99, 34);
+      this.pointStyleComboBox.Name = "pointStyleComboBox";
+      this.pointStyleComboBox.Size = new System.Drawing.Size(240, 21);
+      this.pointStyleComboBox.TabIndex = 3;
+      this.pointStyleComboBox.SelectedValueChanged += new System.EventHandler(this.pointStyleComboBox_SelectedValueChanged);
+      // 
+      // colorDialog
+      // 
+      this.colorDialog.Color = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(128)))), ((int)(((byte)(255)))));
+      // 
+      // colorButton
+      // 
+      this.colorButton.BackColor = System.Drawing.SystemColors.Control;
+      this.colorButton.Location = new System.Drawing.Point(99, 61);
+      this.colorButton.Name = "colorButton";
+      this.colorButton.Size = new System.Drawing.Size(23, 23);
+      this.colorButton.TabIndex = 5;
+      this.colorButton.UseVisualStyleBackColor = false;
+      this.colorButton.Click += new System.EventHandler(this.colorButton_Click);
+      // 
+      // isVisibleInLegendCheckBox
+      // 
+      this.isVisibleInLegendCheckBox.AutoSize = true;
+      this.isVisibleInLegendCheckBox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
+      this.isVisibleInLegendCheckBox.Location = new System.Drawing.Point(99, 116);
+      this.isVisibleInLegendCheckBox.Name = "isVisibleInLegendCheckBox";
+      this.isVisibleInLegendCheckBox.Size = new System.Drawing.Size(15, 14);
+      this.isVisibleInLegendCheckBox.TabIndex = 3;
+      this.isVisibleInLegendCheckBox.UseVisualStyleBackColor = true;
+      this.isVisibleInLegendCheckBox.CheckedChanged += new System.EventHandler(this.isVisibleInLegendCheckBox_CheckedChanged);
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(3, 37);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(60, 13);
+      this.label1.TabIndex = 2;
+      this.label1.Text = "&Point Style:";
+      // 
+      // label2
+      // 
+      this.label2.AutoSize = true;
+      this.label2.Location = new System.Drawing.Point(3, 66);
+      this.label2.Name = "label2";
+      this.label2.Size = new System.Drawing.Size(61, 13);
+      this.label2.TabIndex = 4;
+      this.label2.Text = "Point &Color:";
+      // 
+      // pointSizeNumericUpDown
+      // 
+      this.pointSizeNumericUpDown.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.pointSizeNumericUpDown.Location = new System.Drawing.Point(99, 90);
+      this.pointSizeNumericUpDown.Minimum = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+      this.pointSizeNumericUpDown.Name = "pointSizeNumericUpDown";
+      this.pointSizeNumericUpDown.Size = new System.Drawing.Size(240, 20);
+      this.pointSizeNumericUpDown.TabIndex = 5;
+      this.pointSizeNumericUpDown.Value = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+      this.pointSizeNumericUpDown.ValueChanged += new System.EventHandler(this.pointSizeNumericUpDown_ValueChanged);
+      // 
+      // label3
+      // 
+      this.label3.AutoSize = true;
+      this.label3.Location = new System.Drawing.Point(3, 92);
+      this.label3.Name = "label3";
+      this.label3.Size = new System.Drawing.Size(57, 13);
+      this.label3.TabIndex = 6;
+      this.label3.Text = "Point &Size:";
+      // 
+      // displayNameTextBox
+      // 
+      this.displayNameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.displayNameTextBox.Location = new System.Drawing.Point(99, 8);
+      this.displayNameTextBox.Name = "displayNameTextBox";
+      this.displayNameTextBox.Size = new System.Drawing.Size(240, 20);
+      this.displayNameTextBox.TabIndex = 1;
+      this.displayNameTextBox.Validated += new System.EventHandler(this.displayNameTextBox_Validated);
+      // 
+      // label9
+      // 
+      this.label9.AutoSize = true;
+      this.label9.Location = new System.Drawing.Point(3, 11);
+      this.label9.Name = "label9";
+      this.label9.Size = new System.Drawing.Size(38, 13);
+      this.label9.TabIndex = 0;
+      this.label9.Text = "&Name:";
+      // 
+      // label7
+      // 
+      this.label7.AutoSize = true;
+      this.label7.Location = new System.Drawing.Point(3, 116);
+      this.label7.Name = "label7";
+      this.label7.Size = new System.Drawing.Size(90, 13);
+      this.label7.TabIndex = 2;
+      this.label7.Text = "&Visible in Legend:";
+      // 
+      // ScatterPlotDataRowVisualPropertiesControl
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.pointSizeNumericUpDown);
+      this.Controls.Add(this.isVisibleInLegendCheckBox);
+      this.Controls.Add(this.label9);
+      this.Controls.Add(this.label3);
+      this.Controls.Add(this.pointStyleComboBox);
+      this.Controls.Add(this.label7);
+      this.Controls.Add(this.label2);
+      this.Controls.Add(this.displayNameTextBox);
+      this.Controls.Add(this.label1);
+      this.Controls.Add(this.colorButton);
+      this.Name = "ScatterPlotDataRowVisualPropertiesControl";
+      this.Size = new System.Drawing.Size(342, 135);
+      ((System.ComponentModel.ISupportInitialize)(this.pointSizeNumericUpDown)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.ComboBox pointStyleComboBox;
+    private System.Windows.Forms.ColorDialog colorDialog;
+    private System.Windows.Forms.Button colorButton;
+    private System.Windows.Forms.CheckBox isVisibleInLegendCheckBox;
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.Label label2;
+    private System.Windows.Forms.NumericUpDown pointSizeNumericUpDown;
+    private System.Windows.Forms.Label label7;
+    private System.Windows.Forms.TextBox displayNameTextBox;
+    private System.Windows.Forms.Label label9;
+    private System.Windows.Forms.Label label3;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotDataRowVisualPropertiesControl.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotDataRowVisualPropertiesControl.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotDataRowVisualPropertiesControl.cs	(revision 12764)
@@ -0,0 +1,125 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Analysis.Views {
+  [View("ScatterPlot DataRow Visual Properties")]
+  public partial class ScatterPlotDataRowVisualPropertiesControl : UserControl {
+    protected bool SuppressEvents { get; set; }
+
+    private ScatterPlotDataRowVisualProperties content;
+    public ScatterPlotDataRowVisualProperties Content {
+      get { return content; }
+      set {
+        bool changed = (value != content);
+        content = value;
+        if (changed) OnContentChanged();
+      }
+    }
+
+    public ScatterPlotDataRowVisualPropertiesControl() {
+      InitializeComponent();
+      pointStyleComboBox.DataSource = Enum.GetValues(typeof(ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle));
+      SetEnabledStateOfControls();
+    }
+
+    protected virtual void OnContentChanged() {
+      SuppressEvents = true;
+      try {
+        if (Content == null) {
+          pointStyleComboBox.SelectedIndex = -1;
+          colorButton.BackColor = SystemColors.Control;
+          colorButton.Text = "?";
+          isVisibleInLegendCheckBox.Checked = false;
+          pointSizeNumericUpDown.Value = 1;
+          displayNameTextBox.Text = String.Empty;
+        } else {
+          displayNameTextBox.Text = Content.DisplayName;
+          pointStyleComboBox.SelectedItem = Content.PointStyle;
+          if (Content.Color.IsEmpty) {
+            colorButton.BackColor = SystemColors.Control;
+            colorButton.Text = "?";
+          } else {
+            colorButton.BackColor = Content.Color;
+            colorButton.Text = String.Empty;
+          }
+          pointSizeNumericUpDown.Value = Content.PointSize;
+          isVisibleInLegendCheckBox.Checked = Content.IsVisibleInLegend;
+        }
+      }
+      finally { SuppressEvents = false; }
+      SetEnabledStateOfControls();
+    }
+
+    protected virtual void SetEnabledStateOfControls() {
+      pointStyleComboBox.Enabled = Content != null;
+      colorButton.Enabled = Content != null;
+      colorButton.Enabled = Content != null;
+      isVisibleInLegendCheckBox.Enabled = Content != null;
+      pointSizeNumericUpDown.Enabled = Content != null;
+      displayNameTextBox.Enabled = Content != null;
+    }
+
+    #region Event Handlers
+    private void pointStyleComboBox_SelectedValueChanged(object sender, EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle selected = (ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle)pointStyleComboBox.SelectedValue;
+        Content.PointStyle = selected;
+      }
+    }
+
+    private void colorButton_Click(object sender, EventArgs e) {
+      if (colorDialog.ShowDialog() == DialogResult.OK) {
+        Content.Color = colorDialog.Color;
+        colorButton.BackColor = Content.Color;
+        colorButton.Text = String.Empty;
+      }
+    }
+
+    private void displayNameTextBox_Validated(object sender, EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.DisplayName = displayNameTextBox.Text;
+        }
+        finally { SuppressEvents = false; }
+      }
+    }
+
+    private void pointSizeNumericUpDown_ValueChanged(object sender, EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        Content.PointSize = (int)pointSizeNumericUpDown.Value;
+      }
+    }
+
+    private void isVisibleInLegendCheckBox_CheckedChanged(object sender, EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        Content.IsVisibleInLegend = isVisibleInLegendCheckBox.Checked;
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotHistoryView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotHistoryView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotHistoryView.Designer.cs	(revision 12764)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Analysis.Views {
+  partial class ScatterPlotHistoryView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+    }
+
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotHistoryView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotHistoryView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotHistoryView.cs	(revision 12764)
@@ -0,0 +1,35 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Windows.Forms;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Analysis.Views {
+  [View("ScatterPlotHistory View")]
+  [Content(typeof(ScatterPlotHistory), true)]
+  public partial class ScatterPlotHistoryView : MovieView<ScatterPlot> {
+    public ScatterPlotHistoryView() {
+      InitializeComponent();
+      itemsGroupBox.Text = "Scatter Plots";
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotView.Designer.cs	(revision 12764)
@@ -0,0 +1,125 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Analysis.Views {
+  partial class ScatterPlotView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+      System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
+      System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
+      System.Windows.Forms.DataVisualization.Charting.Title title1 = new System.Windows.Forms.DataVisualization.Charting.Title();
+      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      ((System.ComponentModel.ISupportInitialize)(this.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.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);
+      // 
+      // ScatterPlotView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.chart);
+      this.Name = "ScatterPlotView";
+      this.Size = new System.Drawing.Size(359, 274);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      this.Controls.SetChildIndex(this.chart, 0);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 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;
+
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotView.cs	(revision 12764)
@@ -0,0 +1,506 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Analysis.Views {
+  [View("ScatterPlot View")]
+  [Content(typeof(ScatterPlot), true)]
+  public partial class ScatterPlotView : NamedItemView, IConfigureableView {
+    protected List<Series> invisibleSeries;
+    protected Dictionary<IObservableList<Point2D<double>>, ScatterPlotDataRow> pointsRowsTable;
+    private double xMin, xMax, yMin, yMax;
+
+    public new ScatterPlot Content {
+      get { return (ScatterPlot)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ScatterPlotView() {
+      InitializeComponent();
+      pointsRowsTable = new Dictionary<IObservableList<Point2D<double>>, ScatterPlotDataRow>();
+      invisibleSeries = new List<Series>();
+      chart.CustomizeAllChartAreas();
+      chart.ChartAreas[0].CursorX.Interval = 1;
+    }
+
+    #region Event Handler Registration
+    protected override void DeregisterContentEvents() {
+      foreach (ScatterPlotDataRow row in Content.Rows)
+        DeregisterScatterPlotDataRowEvents(row);
+      Content.VisualPropertiesChanged -= new EventHandler(Content_VisualPropertiesChanged);
+      Content.Rows.ItemsAdded -= new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsAdded);
+      Content.Rows.ItemsRemoved -= new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsRemoved);
+      Content.Rows.ItemsReplaced -= new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsReplaced);
+      Content.Rows.CollectionReset -= new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_CollectionReset);
+      base.DeregisterContentEvents();
+    }
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.VisualPropertiesChanged += new EventHandler(Content_VisualPropertiesChanged);
+      Content.Rows.ItemsAdded += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsAdded);
+      Content.Rows.ItemsRemoved += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsRemoved);
+      Content.Rows.ItemsReplaced += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsReplaced);
+      Content.Rows.CollectionReset += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_CollectionReset);
+    }
+
+    protected virtual void RegisterScatterPlotDataRowEvents(ScatterPlotDataRow row) {
+      row.NameChanged += new EventHandler(Row_NameChanged);
+      row.VisualPropertiesChanged += new EventHandler(Row_VisualPropertiesChanged);
+      pointsRowsTable.Add(row.Points, row);
+      row.Points.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsAdded);
+      row.Points.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsRemoved);
+      row.Points.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsReplaced);
+      row.Points.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_CollectionReset);
+    }
+    protected virtual void DeregisterScatterPlotDataRowEvents(ScatterPlotDataRow row) {
+      row.Points.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsAdded);
+      row.Points.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsRemoved);
+      row.Points.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsReplaced);
+      row.Points.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_CollectionReset);
+      pointsRowsTable.Remove(row.Points);
+      row.VisualPropertiesChanged -= new EventHandler(Row_VisualPropertiesChanged);
+      row.NameChanged -= new EventHandler(Row_NameChanged);
+    }
+    #endregion
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      invisibleSeries.Clear();
+      chart.Titles[0].Text = string.Empty;
+      chart.ChartAreas[0].AxisX.Title = string.Empty;
+      chart.ChartAreas[0].AxisY.Title = string.Empty;
+      chart.Series.Clear();
+      if (Content != null) {
+        chart.Titles[0].Text = Content.Name;
+        AddScatterPlotDataRows(Content.Rows);
+        ConfigureChartArea(chart.ChartAreas[0]);
+        RecalculateMinMaxPointValues();
+        RecalculateAxesScale(chart.ChartAreas[0]);
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      chart.Enabled = Content != null;
+    }
+
+    public void ShowConfiguration() {
+      if (Content != null) {
+        using (ScatterPlotVisualPropertiesDialog dialog = new ScatterPlotVisualPropertiesDialog(Content)) {
+          dialog.ShowDialog(this);
+        }
+      } else MessageBox.Show("Nothing to configure.");
+    }
+
+    protected virtual void AddScatterPlotDataRows(IEnumerable<ScatterPlotDataRow> rows) {
+      foreach (var row in rows) {
+        RegisterScatterPlotDataRowEvents(row);
+        Series series = new Series(row.Name);
+        if (row.VisualProperties.DisplayName.Trim() != String.Empty) series.LegendText = row.VisualProperties.DisplayName;
+        else series.LegendText = row.Name;
+        ConfigureSeries(series, row);
+        FillSeriesWithRowValues(series, row);
+        chart.Series.Add(series);
+      }
+      ConfigureChartArea(chart.ChartAreas[0]);
+      RecalculateMinMaxPointValues();
+      RecalculateAxesScale(chart.ChartAreas[0]);
+      UpdateYCursorInterval();
+    }
+
+    protected virtual void RemoveScatterPlotDataRows(IEnumerable<ScatterPlotDataRow> rows) {
+      foreach (var row in rows) {
+        DeregisterScatterPlotDataRowEvents(row);
+        Series series = chart.Series[row.Name];
+        chart.Series.Remove(series);
+        if (invisibleSeries.Contains(series))
+          invisibleSeries.Remove(series);
+      }
+      RecalculateMinMaxPointValues();
+      RecalculateAxesScale(chart.ChartAreas[0]);
+    }
+
+    private void ConfigureSeries(Series series, ScatterPlotDataRow row) {
+      series.BorderWidth = 1;
+      series.BorderDashStyle = ChartDashStyle.Solid;
+      series.BorderColor = Color.Empty;
+
+      if (row.VisualProperties.Color != Color.Empty)
+        series.Color = row.VisualProperties.Color;
+      else series.Color = Color.Empty;
+      series.IsVisibleInLegend = row.VisualProperties.IsVisibleInLegend;
+      series.ChartType = SeriesChartType.FastPoint;
+      series.MarkerSize = row.VisualProperties.PointSize;
+      series.MarkerStyle = ConvertPointStyle(row.VisualProperties.PointStyle);
+      series.XAxisType = AxisType.Primary;
+      series.YAxisType = AxisType.Primary;
+
+      if (row.VisualProperties.DisplayName.Trim() != String.Empty) series.LegendText = row.VisualProperties.DisplayName;
+      else series.LegendText = row.Name;
+
+      string xAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.XAxisTitle)
+                      ? "X"
+                      : Content.VisualProperties.XAxisTitle;
+      string yAxisTitle = string.IsNullOrEmpty(Content.VisualProperties.YAxisTitle)
+                            ? "Y"
+                            : Content.VisualProperties.YAxisTitle;
+      series.ToolTip =
+        series.LegendText + Environment.NewLine +
+        xAxisTitle + " = " + "#VALX," + Environment.NewLine +
+        yAxisTitle + " = " + "#VAL";
+    }
+
+    private void ConfigureChartArea(ChartArea area) {
+      if (Content.VisualProperties.TitleFont != null) chart.Titles[0].Font = Content.VisualProperties.TitleFont;
+      if (!Content.VisualProperties.TitleColor.IsEmpty) chart.Titles[0].ForeColor = Content.VisualProperties.TitleColor;
+      chart.Titles[0].Text = Content.VisualProperties.Title;
+
+      if (Content.VisualProperties.AxisTitleFont != null) area.AxisX.TitleFont = Content.VisualProperties.AxisTitleFont;
+      if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisX.TitleForeColor = Content.VisualProperties.AxisTitleColor;
+      area.AxisX.Title = Content.VisualProperties.XAxisTitle;
+      area.AxisX.MajorGrid.Enabled = Content.VisualProperties.XAxisGrid;
+
+      if (Content.VisualProperties.AxisTitleFont != null) area.AxisY.TitleFont = Content.VisualProperties.AxisTitleFont;
+      if (!Content.VisualProperties.AxisTitleColor.IsEmpty) area.AxisY.TitleForeColor = Content.VisualProperties.AxisTitleColor;
+      area.AxisY.Title = Content.VisualProperties.YAxisTitle;
+      area.AxisY.MajorGrid.Enabled = Content.VisualProperties.YAxisGrid;
+    }
+
+    private void RecalculateAxesScale(ChartArea area) {
+      area.AxisX.Minimum = CalculateMinBound(xMin);
+      area.AxisX.Maximum = CalculateMaxBound(xMax);
+      if (area.AxisX.Minimum == area.AxisX.Maximum) {
+        area.AxisX.Minimum = xMin - 0.5;
+        area.AxisX.Maximum = xMax + 0.5;
+      }
+      area.AxisY.Minimum = CalculateMinBound(yMin);
+      area.AxisY.Maximum = CalculateMaxBound(yMax);
+      if (area.AxisY.Minimum == area.AxisY.Maximum) {
+        area.AxisY.Minimum = yMin - 0.5;
+        area.AxisY.Maximum = yMax + 0.5;
+      }
+      if (xMax - xMin > 0) area.CursorX.Interval = Math.Pow(10, Math.Floor(Math.Log10(area.AxisX.Maximum - area.AxisX.Minimum) - 3));
+      else area.CursorX.Interval = 1;
+      area.AxisX.IsMarginVisible = false;
+
+      if (!Content.VisualProperties.XAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.XAxisMinimumFixedValue)) area.AxisX.Minimum = Content.VisualProperties.XAxisMinimumFixedValue;
+      if (!Content.VisualProperties.XAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.XAxisMaximumFixedValue)) area.AxisX.Maximum = Content.VisualProperties.XAxisMaximumFixedValue;
+      if (!Content.VisualProperties.YAxisMinimumAuto && !double.IsNaN(Content.VisualProperties.YAxisMinimumFixedValue)) area.AxisY.Minimum = Content.VisualProperties.YAxisMinimumFixedValue;
+      if (!Content.VisualProperties.YAxisMaximumAuto && !double.IsNaN(Content.VisualProperties.YAxisMaximumFixedValue)) area.AxisY.Maximum = Content.VisualProperties.YAxisMaximumFixedValue;
+    }
+
+    private static double CalculateMinBound(double min) {
+      if (min == 0) return 0;
+      var scale = Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(min))));
+      return scale * (Math.Floor(min / scale));
+    }
+
+    private static double CalculateMaxBound(double max) {
+      if (max == 0) return 0;
+      var scale = Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(max))));
+      return scale * (Math.Ceiling(max / scale));
+    }
+
+    protected virtual void UpdateYCursorInterval() {
+      double interestingValuesRange = (
+        from series in chart.Series
+        where series.Enabled
+        let values = (from point in series.Points
+                      where !point.IsEmpty
+                      select point.YValues[0]).DefaultIfEmpty(1.0)
+        let range = values.Max() - values.Min()
+        where range > 0.0
+        select range
+        ).DefaultIfEmpty(1.0).Min();
+
+      double digits = (int)Math.Log10(interestingValuesRange) - 3;
+      double yZoomInterval = Math.Pow(10, digits);
+      this.chart.ChartAreas[0].CursorY.Interval = yZoomInterval;
+    }
+
+    #region Event Handlers
+    #region Content Event Handlers
+    protected override void Content_NameChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_NameChanged), sender, e);
+      else {
+        chart.Titles[0].Text = 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
+      }
+    }
+    #endregion
+    #region Rows Event Handlers
+    private void Rows_ItemsAdded(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsAdded), sender, e);
+      else {
+        AddScatterPlotDataRows(e.Items);
+      }
+    }
+    private void Rows_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsRemoved), sender, e);
+      else {
+        RemoveScatterPlotDataRows(e.Items);
+      }
+    }
+    private void Rows_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_ItemsReplaced), sender, e);
+      else {
+        RemoveScatterPlotDataRows(e.OldItems);
+        AddScatterPlotDataRows(e.Items);
+      }
+    }
+    private void Rows_CollectionReset(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(Rows_CollectionReset), sender, e);
+      else {
+        RemoveScatterPlotDataRows(e.OldItems);
+        AddScatterPlotDataRows(e.Items);
+      }
+    }
+    #endregion
+    #region Row Event Handlers
+    private void Row_VisualPropertiesChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Row_VisualPropertiesChanged), sender, e);
+      else {
+        ScatterPlotDataRow row = (ScatterPlotDataRow)sender;
+        Series series = chart.Series[row.Name];
+        series.Points.Clear();
+        ConfigureSeries(series, row);
+        FillSeriesWithRowValues(series, row);
+        RecalculateMinMaxPointValues();
+        RecalculateAxesScale(chart.ChartAreas[0]);
+      }
+    }
+    private void Row_NameChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Row_NameChanged), sender, e);
+      else {
+        ScatterPlotDataRow row = (ScatterPlotDataRow)sender;
+        chart.Series[row.Name].Name = row.Name;
+      }
+    }
+    #endregion
+    #region Points Event Handlers
+    private void Points_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsAdded), sender, e);
+      else {
+        ScatterPlotDataRow row = null;
+        pointsRowsTable.TryGetValue((IObservableList<Point2D<double>>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            rowSeries.Points.Clear();
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateMinMaxPointValues();
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    private void Points_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsRemoved), sender, e);
+      else {
+        ScatterPlotDataRow row = null;
+        pointsRowsTable.TryGetValue((IObservableList<Point2D<double>>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            rowSeries.Points.Clear();
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateMinMaxPointValues();
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    private void Points_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsReplaced), sender, e);
+      else {
+        ScatterPlotDataRow row = null;
+        pointsRowsTable.TryGetValue((IObservableList<Point2D<double>>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            rowSeries.Points.Clear();
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateMinMaxPointValues();
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    private void Points_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_CollectionReset), sender, e);
+      else {
+        ScatterPlotDataRow row = null;
+        pointsRowsTable.TryGetValue((IObservableList<Point2D<double>>)sender, out row);
+        if (row != null) {
+          Series rowSeries = chart.Series[row.Name];
+          if (!invisibleSeries.Contains(rowSeries)) {
+            rowSeries.Points.Clear();
+            FillSeriesWithRowValues(rowSeries, row);
+            RecalculateMinMaxPointValues();
+            RecalculateAxesScale(chart.ChartAreas[0]);
+            UpdateYCursorInterval();
+          }
+        }
+      }
+    }
+    #endregion
+    #endregion
+
+    #region Chart Event Handlers
+    private void chart_MouseDown(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem) {
+        ToggleSeriesVisible(result.Series);
+      }
+    }
+    private void chart_MouseMove(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem)
+        this.Cursor = Cursors.Hand;
+      else
+        this.Cursor = Cursors.Default;
+    }
+    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
+      foreach (LegendItem legendItem in e.LegendItems) {
+        var series = chart.Series[legendItem.SeriesName];
+        if (series != null) {
+          bool seriesIsInvisible = invisibleSeries.Contains(series);
+          foreach (LegendCell cell in legendItem.Cells) {
+            cell.ForeColor = seriesIsInvisible ? Color.Gray : Color.Black;
+          }
+        }
+      }
+    }
+    #endregion
+
+    private void ToggleSeriesVisible(Series series) {
+      if (!invisibleSeries.Contains(series)) {
+        series.Points.Clear();
+        invisibleSeries.Add(series);
+        RecalculateMinMaxPointValues();
+      } 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);
+          RecalculateMinMaxPointValues();
+          this.chart.Legends[series.Legend].ForeColor = Color.Black;
+          RecalculateAxesScale(chart.ChartAreas[0]);
+          UpdateYCursorInterval();
+        }
+      }
+    }
+
+    private void RecalculateMinMaxPointValues() {
+      yMin = xMin = double.MaxValue;
+      yMax = xMax = double.MinValue;
+      foreach (var s in chart.Series.Where(x => x.Enabled)) {
+        foreach (var p in s.Points) {
+          double x = p.XValue, y = p.YValues[0];
+          if (xMin > x) xMin = x;
+          if (xMax < x) xMax = x;
+          if (yMin > y) yMin = y;
+          if (yMax < y) yMax = y;
+        }
+      }
+    }
+
+    private void FillSeriesWithRowValues(Series series, ScatterPlotDataRow row) {
+      for (int i = 0; i < row.Points.Count; i++) {
+        var value = row.Points[i];
+        DataPoint point = new DataPoint();
+        if (IsInvalidValue(value.X) || IsInvalidValue(value.Y))
+          point.IsEmpty = true;
+        else {
+          point.XValue = value.X;
+          point.YValues = new double[] { value.Y };
+        }
+        series.Points.Add(point);
+      }
+    }
+
+    #region Helpers
+    private MarkerStyle ConvertPointStyle(ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle pointStyle) {
+      switch (pointStyle) {
+        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Circle:
+          return MarkerStyle.Circle;
+        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Cross:
+          return MarkerStyle.Cross;
+        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Diamond:
+          return MarkerStyle.Diamond;
+        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Square:
+          return MarkerStyle.Square;
+        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Star4:
+          return MarkerStyle.Star4;
+        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Star5:
+          return MarkerStyle.Star5;
+        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Star6:
+          return MarkerStyle.Star6;
+        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Star10:
+          return MarkerStyle.Star10;
+        case ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Triangle:
+          return MarkerStyle.Triangle;
+        default:
+          return MarkerStyle.None;
+      }
+    }
+
+    protected static bool IsInvalidValue(double x) {
+      return double.IsNaN(x) || x < (double)decimal.MinValue || x > (double)decimal.MaxValue;
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotVisualPropertiesControl.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotVisualPropertiesControl.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotVisualPropertiesControl.Designer.cs	(revision 12764)
@@ -0,0 +1,609 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Analysis.Views {
+  partial class ScatterPlotVisualPropertiesControl {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      this.label1 = new System.Windows.Forms.Label();
+      this.yAxisTitleTextBox = new System.Windows.Forms.TextBox();
+      this.panel2 = new System.Windows.Forms.Panel();
+      this.xAxisMaximumFixedRadioButton = new System.Windows.Forms.RadioButton();
+      this.xAxisMaximumAutoRadioButton = new System.Windows.Forms.RadioButton();
+      this.panel1 = new System.Windows.Forms.Panel();
+      this.xAxisMinimumFixedRadioButton = new System.Windows.Forms.RadioButton();
+      this.xAxisMinimumAutoRadioButton = new System.Windows.Forms.RadioButton();
+      this.xAxisMinimumFixedTextBox = new System.Windows.Forms.TextBox();
+      this.xAxisMaximumFixedTextBox = new System.Windows.Forms.TextBox();
+      this.label12 = new System.Windows.Forms.Label();
+      this.label9 = new System.Windows.Forms.Label();
+      this.xAxisTitleTextBox = new System.Windows.Forms.TextBox();
+      this.label11 = new System.Windows.Forms.Label();
+      this.axisTabControl = new System.Windows.Forms.TabControl();
+      this.xAxisTabPage = new System.Windows.Forms.TabPage();
+      this.xAxisGridCheckBox = new System.Windows.Forms.CheckBox();
+      this.label4 = new System.Windows.Forms.Label();
+      this.yAxisTabPage = new System.Windows.Forms.TabPage();
+      this.yAxisGridCheckBox = new System.Windows.Forms.CheckBox();
+      this.label5 = new System.Windows.Forms.Label();
+      this.panel6 = new System.Windows.Forms.Panel();
+      this.yAxisMaximumFixedRadioButton = new System.Windows.Forms.RadioButton();
+      this.yAxisMaximumAutoRadioButton = new System.Windows.Forms.RadioButton();
+      this.panel5 = new System.Windows.Forms.Panel();
+      this.yAxisMinimumAutoRadioButton = new System.Windows.Forms.RadioButton();
+      this.yAxisMinimumFixedRadioButton = new System.Windows.Forms.RadioButton();
+      this.yAxisMinimumFixedTextBox = new System.Windows.Forms.TextBox();
+      this.yAxisMaximumFixedTextBox = new System.Windows.Forms.TextBox();
+      this.label8 = new System.Windows.Forms.Label();
+      this.label7 = new System.Windows.Forms.Label();
+      this.titleTextBox = new System.Windows.Forms.TextBox();
+      this.label15 = new System.Windows.Forms.Label();
+      this.axisFontLabel = new System.Windows.Forms.Label();
+      this.titleFontLabel = new System.Windows.Forms.Label();
+      this.axisFontButton = new System.Windows.Forms.Button();
+      this.label3 = new System.Windows.Forms.Label();
+      this.titleFontButton = new System.Windows.Forms.Button();
+      this.label2 = new System.Windows.Forms.Label();
+      this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      this.titleFontDialog = new System.Windows.Forms.FontDialog();
+      this.axisFontDialog = new System.Windows.Forms.FontDialog();
+      this.panel2.SuspendLayout();
+      this.panel1.SuspendLayout();
+      this.axisTabControl.SuspendLayout();
+      this.xAxisTabPage.SuspendLayout();
+      this.yAxisTabPage.SuspendLayout();
+      this.panel6.SuspendLayout();
+      this.panel5.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(6, 12);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(30, 13);
+      this.label1.TabIndex = 0;
+      this.label1.Text = "&Title:";
+      // 
+      // yAxisPrimaryTitleTextBox
+      // 
+      this.yAxisTitleTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.yAxisTitleTextBox.Location = new System.Drawing.Point(71, 9);
+      this.yAxisTitleTextBox.Name = "yAxisPrimaryTitleTextBox";
+      this.yAxisTitleTextBox.Size = new System.Drawing.Size(370, 20);
+      this.yAxisTitleTextBox.TabIndex = 1;
+      this.yAxisTitleTextBox.Validated += new System.EventHandler(this.yTitleTextBox_Validated);
+      // 
+      // panel2
+      // 
+      this.panel2.Controls.Add(this.xAxisMaximumFixedRadioButton);
+      this.panel2.Controls.Add(this.xAxisMaximumAutoRadioButton);
+      this.panel2.Location = new System.Drawing.Point(71, 61);
+      this.panel2.Name = "panel2";
+      this.panel2.Size = new System.Drawing.Size(106, 16);
+      this.panel2.TabIndex = 6;
+      // 
+      // xAxisPrimaryMaximumFixedRadioButton
+      // 
+      this.xAxisMaximumFixedRadioButton.AutoSize = true;
+      this.xAxisMaximumFixedRadioButton.Location = new System.Drawing.Point(53, 1);
+      this.xAxisMaximumFixedRadioButton.Name = "xAxisPrimaryMaximumFixedRadioButton";
+      this.xAxisMaximumFixedRadioButton.Size = new System.Drawing.Size(53, 17);
+      this.xAxisMaximumFixedRadioButton.TabIndex = 1;
+      this.xAxisMaximumFixedRadioButton.TabStop = true;
+      this.xAxisMaximumFixedRadioButton.Text = "&Fixed:";
+      this.xAxisMaximumFixedRadioButton.UseVisualStyleBackColor = true;
+      this.xAxisMaximumFixedRadioButton.CheckedChanged += new System.EventHandler(this.xAxisMaximumRadioButton_CheckedChanged);
+      // 
+      // xAxisPrimaryMaximumAutoRadioButton
+      // 
+      this.xAxisMaximumAutoRadioButton.AutoSize = true;
+      this.xAxisMaximumAutoRadioButton.Location = new System.Drawing.Point(0, 1);
+      this.xAxisMaximumAutoRadioButton.Name = "xAxisPrimaryMaximumAutoRadioButton";
+      this.xAxisMaximumAutoRadioButton.Size = new System.Drawing.Size(47, 17);
+      this.xAxisMaximumAutoRadioButton.TabIndex = 0;
+      this.xAxisMaximumAutoRadioButton.TabStop = true;
+      this.xAxisMaximumAutoRadioButton.Text = "&Auto";
+      this.xAxisMaximumAutoRadioButton.UseVisualStyleBackColor = true;
+      this.xAxisMaximumAutoRadioButton.CheckedChanged += new System.EventHandler(this.xAxisMaximumRadioButton_CheckedChanged);
+      // 
+      // panel1
+      // 
+      this.panel1.Controls.Add(this.xAxisMinimumFixedRadioButton);
+      this.panel1.Controls.Add(this.xAxisMinimumAutoRadioButton);
+      this.panel1.Location = new System.Drawing.Point(71, 35);
+      this.panel1.Name = "panel1";
+      this.panel1.Size = new System.Drawing.Size(106, 16);
+      this.panel1.TabIndex = 3;
+      // 
+      // xAxisPrimaryMinimumFixedRadioButton
+      // 
+      this.xAxisMinimumFixedRadioButton.AutoSize = true;
+      this.xAxisMinimumFixedRadioButton.Location = new System.Drawing.Point(53, 1);
+      this.xAxisMinimumFixedRadioButton.Name = "xAxisPrimaryMinimumFixedRadioButton";
+      this.xAxisMinimumFixedRadioButton.Size = new System.Drawing.Size(53, 17);
+      this.xAxisMinimumFixedRadioButton.TabIndex = 1;
+      this.xAxisMinimumFixedRadioButton.TabStop = true;
+      this.xAxisMinimumFixedRadioButton.Text = "&Fixed:";
+      this.xAxisMinimumFixedRadioButton.UseVisualStyleBackColor = true;
+      this.xAxisMinimumFixedRadioButton.CheckedChanged += new System.EventHandler(this.xAxisMinimumRadioButton_CheckedChanged);
+      // 
+      // xAxisPrimaryMinimumAutoRadioButton
+      // 
+      this.xAxisMinimumAutoRadioButton.AutoSize = true;
+      this.xAxisMinimumAutoRadioButton.Location = new System.Drawing.Point(0, 1);
+      this.xAxisMinimumAutoRadioButton.Name = "xAxisPrimaryMinimumAutoRadioButton";
+      this.xAxisMinimumAutoRadioButton.Size = new System.Drawing.Size(47, 17);
+      this.xAxisMinimumAutoRadioButton.TabIndex = 0;
+      this.xAxisMinimumAutoRadioButton.TabStop = true;
+      this.xAxisMinimumAutoRadioButton.Text = "&Auto";
+      this.xAxisMinimumAutoRadioButton.UseVisualStyleBackColor = true;
+      this.xAxisMinimumAutoRadioButton.CheckedChanged += new System.EventHandler(this.xAxisMinimumRadioButton_CheckedChanged);
+      // 
+      // xAxisPrimaryMinimumFixedTextBox
+      // 
+      this.xAxisMinimumFixedTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.xAxisMinimumFixedTextBox.Location = new System.Drawing.Point(196, 35);
+      this.xAxisMinimumFixedTextBox.Name = "xAxisPrimaryMinimumFixedTextBox";
+      this.xAxisMinimumFixedTextBox.Size = new System.Drawing.Size(245, 20);
+      this.xAxisMinimumFixedTextBox.TabIndex = 4;
+      this.xAxisMinimumFixedTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.xAxisMinimumFixedTextBox_Validating);
+      // 
+      // xAxisPrimaryMaximumFixedTextBox
+      // 
+      this.xAxisMaximumFixedTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.xAxisMaximumFixedTextBox.Location = new System.Drawing.Point(196, 61);
+      this.xAxisMaximumFixedTextBox.Name = "xAxisPrimaryMaximumFixedTextBox";
+      this.xAxisMaximumFixedTextBox.Size = new System.Drawing.Size(245, 20);
+      this.xAxisMaximumFixedTextBox.TabIndex = 7;
+      this.xAxisMaximumFixedTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.xAxisMaximumFixedTextBox_Validating);
+      // 
+      // label12
+      // 
+      this.label12.AutoSize = true;
+      this.label12.Location = new System.Drawing.Point(6, 64);
+      this.label12.Name = "label12";
+      this.label12.Size = new System.Drawing.Size(54, 13);
+      this.label12.TabIndex = 5;
+      this.label12.Text = "&Maximum:";
+      // 
+      // label9
+      // 
+      this.label9.AutoSize = true;
+      this.label9.Location = new System.Drawing.Point(6, 12);
+      this.label9.Name = "label9";
+      this.label9.Size = new System.Drawing.Size(30, 13);
+      this.label9.TabIndex = 0;
+      this.label9.Text = "&Title:";
+      // 
+      // xAxisPrimaryTitleTextBox
+      // 
+      this.xAxisTitleTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.xAxisTitleTextBox.Location = new System.Drawing.Point(71, 9);
+      this.xAxisTitleTextBox.Name = "xAxisPrimaryTitleTextBox";
+      this.xAxisTitleTextBox.Size = new System.Drawing.Size(370, 20);
+      this.xAxisTitleTextBox.TabIndex = 1;
+      this.xAxisTitleTextBox.Validated += new System.EventHandler(this.xTitleTextBox_Validated);
+      // 
+      // label11
+      // 
+      this.label11.AutoSize = true;
+      this.label11.Location = new System.Drawing.Point(6, 38);
+      this.label11.Name = "label11";
+      this.label11.Size = new System.Drawing.Size(51, 13);
+      this.label11.TabIndex = 2;
+      this.label11.Text = "&Minimum:";
+      // 
+      // axisTabControl
+      // 
+      this.axisTabControl.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.axisTabControl.Controls.Add(this.xAxisTabPage);
+      this.axisTabControl.Controls.Add(this.yAxisTabPage);
+      this.axisTabControl.Location = new System.Drawing.Point(0, 84);
+      this.axisTabControl.Name = "axisTabControl";
+      this.axisTabControl.SelectedIndex = 0;
+      this.axisTabControl.Size = new System.Drawing.Size(455, 134);
+      this.axisTabControl.TabIndex = 8;
+      // 
+      // xAxisTabPage
+      // 
+      this.xAxisTabPage.Controls.Add(this.xAxisGridCheckBox);
+      this.xAxisTabPage.Controls.Add(this.label4);
+      this.xAxisTabPage.Controls.Add(this.panel2);
+      this.xAxisTabPage.Controls.Add(this.panel1);
+      this.xAxisTabPage.Controls.Add(this.xAxisTitleTextBox);
+      this.xAxisTabPage.Controls.Add(this.xAxisMinimumFixedTextBox);
+      this.xAxisTabPage.Controls.Add(this.label11);
+      this.xAxisTabPage.Controls.Add(this.xAxisMaximumFixedTextBox);
+      this.xAxisTabPage.Controls.Add(this.label9);
+      this.xAxisTabPage.Controls.Add(this.label12);
+      this.xAxisTabPage.Location = new System.Drawing.Point(4, 22);
+      this.xAxisTabPage.Name = "xAxisTabPage";
+      this.xAxisTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.xAxisTabPage.Size = new System.Drawing.Size(447, 108);
+      this.xAxisTabPage.TabIndex = 0;
+      this.xAxisTabPage.Text = "X-Axis";
+      this.xAxisTabPage.UseVisualStyleBackColor = true;
+      // 
+      // xAxisGridCheckBox
+      // 
+      this.xAxisGridCheckBox.AutoSize = true;
+      this.xAxisGridCheckBox.Location = new System.Drawing.Point(71, 85);
+      this.xAxisGridCheckBox.Name = "xAxisGridCheckBox";
+      this.xAxisGridCheckBox.Size = new System.Drawing.Size(15, 14);
+      this.xAxisGridCheckBox.TabIndex = 9;
+      this.xAxisGridCheckBox.UseVisualStyleBackColor = true;
+      this.xAxisGridCheckBox.CheckedChanged += new System.EventHandler(this.xAxisGridCheckBox_CheckedChanged);
+      // 
+      // label4
+      // 
+      this.label4.AutoSize = true;
+      this.label4.Location = new System.Drawing.Point(6, 85);
+      this.label4.Name = "label4";
+      this.label4.Size = new System.Drawing.Size(59, 13);
+      this.label4.TabIndex = 8;
+      this.label4.Text = "Show &Grid:";
+      // 
+      // yAxisTabPage
+      // 
+      this.yAxisTabPage.Controls.Add(this.yAxisGridCheckBox);
+      this.yAxisTabPage.Controls.Add(this.label5);
+      this.yAxisTabPage.Controls.Add(this.panel6);
+      this.yAxisTabPage.Controls.Add(this.panel5);
+      this.yAxisTabPage.Controls.Add(this.yAxisTitleTextBox);
+      this.yAxisTabPage.Controls.Add(this.yAxisMinimumFixedTextBox);
+      this.yAxisTabPage.Controls.Add(this.label1);
+      this.yAxisTabPage.Controls.Add(this.yAxisMaximumFixedTextBox);
+      this.yAxisTabPage.Controls.Add(this.label8);
+      this.yAxisTabPage.Controls.Add(this.label7);
+      this.yAxisTabPage.Location = new System.Drawing.Point(4, 22);
+      this.yAxisTabPage.Name = "yAxisTabPage";
+      this.yAxisTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.yAxisTabPage.Size = new System.Drawing.Size(447, 108);
+      this.yAxisTabPage.TabIndex = 1;
+      this.yAxisTabPage.Text = "Y-Axis";
+      this.yAxisTabPage.UseVisualStyleBackColor = true;
+      // 
+      // yAxisGridCheckBox
+      // 
+      this.yAxisGridCheckBox.AutoSize = true;
+      this.yAxisGridCheckBox.Location = new System.Drawing.Point(71, 85);
+      this.yAxisGridCheckBox.Name = "yAxisGridCheckBox";
+      this.yAxisGridCheckBox.Size = new System.Drawing.Size(15, 14);
+      this.yAxisGridCheckBox.TabIndex = 10;
+      this.yAxisGridCheckBox.UseVisualStyleBackColor = true;
+      this.yAxisGridCheckBox.CheckedChanged += new System.EventHandler(this.yAxisGridCheckBox_CheckedChanged);
+      // 
+      // label5
+      // 
+      this.label5.AutoSize = true;
+      this.label5.Location = new System.Drawing.Point(6, 85);
+      this.label5.Name = "label5";
+      this.label5.Size = new System.Drawing.Size(59, 13);
+      this.label5.TabIndex = 9;
+      this.label5.Text = "Show &Grid:";
+      // 
+      // panel6
+      // 
+      this.panel6.Controls.Add(this.yAxisMaximumFixedRadioButton);
+      this.panel6.Controls.Add(this.yAxisMaximumAutoRadioButton);
+      this.panel6.Location = new System.Drawing.Point(71, 61);
+      this.panel6.Name = "panel6";
+      this.panel6.Size = new System.Drawing.Size(106, 20);
+      this.panel6.TabIndex = 6;
+      // 
+      // yAxisPrimaryMaximumFixedRadioButton
+      // 
+      this.yAxisMaximumFixedRadioButton.AutoSize = true;
+      this.yAxisMaximumFixedRadioButton.Location = new System.Drawing.Point(53, 1);
+      this.yAxisMaximumFixedRadioButton.Name = "yAxisPrimaryMaximumFixedRadioButton";
+      this.yAxisMaximumFixedRadioButton.Size = new System.Drawing.Size(53, 17);
+      this.yAxisMaximumFixedRadioButton.TabIndex = 1;
+      this.yAxisMaximumFixedRadioButton.TabStop = true;
+      this.yAxisMaximumFixedRadioButton.Text = "&Fixed:";
+      this.yAxisMaximumFixedRadioButton.UseVisualStyleBackColor = true;
+      this.yAxisMaximumFixedRadioButton.CheckedChanged += new System.EventHandler(this.yAxisMaximumRadioButton_CheckedChanged);
+      // 
+      // yAxisPrimaryMaximumAutoRadioButton
+      // 
+      this.yAxisMaximumAutoRadioButton.AutoSize = true;
+      this.yAxisMaximumAutoRadioButton.Location = new System.Drawing.Point(0, 1);
+      this.yAxisMaximumAutoRadioButton.Name = "yAxisPrimaryMaximumAutoRadioButton";
+      this.yAxisMaximumAutoRadioButton.Size = new System.Drawing.Size(47, 17);
+      this.yAxisMaximumAutoRadioButton.TabIndex = 0;
+      this.yAxisMaximumAutoRadioButton.TabStop = true;
+      this.yAxisMaximumAutoRadioButton.Text = "&Auto";
+      this.yAxisMaximumAutoRadioButton.UseVisualStyleBackColor = true;
+      this.yAxisMaximumAutoRadioButton.CheckedChanged += new System.EventHandler(this.yAxisMaximumRadioButton_CheckedChanged);
+      // 
+      // panel5
+      // 
+      this.panel5.Controls.Add(this.yAxisMinimumAutoRadioButton);
+      this.panel5.Controls.Add(this.yAxisMinimumFixedRadioButton);
+      this.panel5.Location = new System.Drawing.Point(71, 35);
+      this.panel5.Name = "panel5";
+      this.panel5.Size = new System.Drawing.Size(106, 20);
+      this.panel5.TabIndex = 3;
+      // 
+      // yAxisPrimaryMinimumAutoRadioButton
+      // 
+      this.yAxisMinimumAutoRadioButton.AutoSize = true;
+      this.yAxisMinimumAutoRadioButton.Location = new System.Drawing.Point(0, 1);
+      this.yAxisMinimumAutoRadioButton.Name = "yAxisPrimaryMinimumAutoRadioButton";
+      this.yAxisMinimumAutoRadioButton.Size = new System.Drawing.Size(47, 17);
+      this.yAxisMinimumAutoRadioButton.TabIndex = 0;
+      this.yAxisMinimumAutoRadioButton.TabStop = true;
+      this.yAxisMinimumAutoRadioButton.Text = "&Auto";
+      this.yAxisMinimumAutoRadioButton.UseVisualStyleBackColor = true;
+      this.yAxisMinimumAutoRadioButton.CheckedChanged += new System.EventHandler(this.yAxisMinimumRadioButton_CheckedChanged);
+      // 
+      // yAxisPrimaryMinimumFixedRadioButton
+      // 
+      this.yAxisMinimumFixedRadioButton.AutoSize = true;
+      this.yAxisMinimumFixedRadioButton.Location = new System.Drawing.Point(53, 1);
+      this.yAxisMinimumFixedRadioButton.Name = "yAxisPrimaryMinimumFixedRadioButton";
+      this.yAxisMinimumFixedRadioButton.Size = new System.Drawing.Size(53, 17);
+      this.yAxisMinimumFixedRadioButton.TabIndex = 1;
+      this.yAxisMinimumFixedRadioButton.TabStop = true;
+      this.yAxisMinimumFixedRadioButton.Text = "&Fixed:";
+      this.yAxisMinimumFixedRadioButton.UseVisualStyleBackColor = true;
+      this.yAxisMinimumFixedRadioButton.CheckedChanged += new System.EventHandler(this.yAxisMinimumRadioButton_CheckedChanged);
+      // 
+      // yAxisPrimaryMinimumFixedTextBox
+      // 
+      this.yAxisMinimumFixedTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.yAxisMinimumFixedTextBox.Location = new System.Drawing.Point(196, 35);
+      this.yAxisMinimumFixedTextBox.Name = "yAxisPrimaryMinimumFixedTextBox";
+      this.yAxisMinimumFixedTextBox.Size = new System.Drawing.Size(245, 20);
+      this.yAxisMinimumFixedTextBox.TabIndex = 4;
+      this.yAxisMinimumFixedTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.yAxisMinimumFixedTextBox_Validating);
+      // 
+      // yAxisPrimaryMaximumFixedTextBox
+      // 
+      this.yAxisMaximumFixedTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.yAxisMaximumFixedTextBox.Location = new System.Drawing.Point(196, 61);
+      this.yAxisMaximumFixedTextBox.Name = "yAxisPrimaryMaximumFixedTextBox";
+      this.yAxisMaximumFixedTextBox.Size = new System.Drawing.Size(245, 20);
+      this.yAxisMaximumFixedTextBox.TabIndex = 7;
+      this.yAxisMaximumFixedTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.yAxisMaximumFixedTextBox_Validating);
+      // 
+      // label8
+      // 
+      this.label8.AutoSize = true;
+      this.label8.Location = new System.Drawing.Point(6, 38);
+      this.label8.Name = "label8";
+      this.label8.Size = new System.Drawing.Size(51, 13);
+      this.label8.TabIndex = 2;
+      this.label8.Text = "&Minimum:";
+      // 
+      // label7
+      // 
+      this.label7.AutoSize = true;
+      this.label7.Location = new System.Drawing.Point(6, 64);
+      this.label7.Name = "label7";
+      this.label7.Size = new System.Drawing.Size(54, 13);
+      this.label7.TabIndex = 5;
+      this.label7.Text = "&Maximum:";
+      // 
+      // titleTextBox
+      // 
+      this.titleTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.titleTextBox.Location = new System.Drawing.Point(66, 0);
+      this.titleTextBox.Name = "titleTextBox";
+      this.titleTextBox.Size = new System.Drawing.Size(389, 20);
+      this.titleTextBox.TabIndex = 1;
+      this.titleTextBox.Validated += new System.EventHandler(this.titleTextBox_Validated);
+      // 
+      // label15
+      // 
+      this.label15.AutoSize = true;
+      this.label15.Location = new System.Drawing.Point(3, 3);
+      this.label15.Name = "label15";
+      this.label15.Size = new System.Drawing.Size(30, 13);
+      this.label15.TabIndex = 0;
+      this.label15.Text = "&Title:";
+      // 
+      // axisFontLabel
+      // 
+      this.axisFontLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.axisFontLabel.AutoSize = true;
+      this.axisFontLabel.Location = new System.Drawing.Point(98, 60);
+      this.axisFontLabel.Name = "axisFontLabel";
+      this.axisFontLabel.Size = new System.Drawing.Size(43, 13);
+      this.axisFontLabel.TabIndex = 7;
+      this.axisFontLabel.Text = "( none )";
+      // 
+      // titleFontLabel
+      // 
+      this.titleFontLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.titleFontLabel.AutoSize = true;
+      this.titleFontLabel.Location = new System.Drawing.Point(98, 31);
+      this.titleFontLabel.Name = "titleFontLabel";
+      this.titleFontLabel.Size = new System.Drawing.Size(43, 13);
+      this.titleFontLabel.TabIndex = 4;
+      this.titleFontLabel.Text = "( none )";
+      // 
+      // axisFontButton
+      // 
+      this.axisFontButton.Location = new System.Drawing.Point(66, 55);
+      this.axisFontButton.Name = "axisFontButton";
+      this.axisFontButton.Size = new System.Drawing.Size(26, 23);
+      this.axisFontButton.TabIndex = 6;
+      this.axisFontButton.Text = "...";
+      this.axisFontButton.UseVisualStyleBackColor = true;
+      this.axisFontButton.Click += new System.EventHandler(this.axisFontButton_Click);
+      // 
+      // label3
+      // 
+      this.label3.AutoSize = true;
+      this.label3.Location = new System.Drawing.Point(3, 60);
+      this.label3.Name = "label3";
+      this.label3.Size = new System.Drawing.Size(57, 13);
+      this.label3.TabIndex = 5;
+      this.label3.Text = "&Axes Font:";
+      // 
+      // titleFontButton
+      // 
+      this.titleFontButton.Location = new System.Drawing.Point(66, 26);
+      this.titleFontButton.Name = "titleFontButton";
+      this.titleFontButton.Size = new System.Drawing.Size(26, 23);
+      this.titleFontButton.TabIndex = 3;
+      this.titleFontButton.Text = "...";
+      this.titleFontButton.UseVisualStyleBackColor = true;
+      this.titleFontButton.Click += new System.EventHandler(this.titleFontButton_Click);
+      // 
+      // label2
+      // 
+      this.label2.AutoSize = true;
+      this.label2.Location = new System.Drawing.Point(3, 31);
+      this.label2.Name = "label2";
+      this.label2.Size = new System.Drawing.Size(54, 13);
+      this.label2.TabIndex = 2;
+      this.label2.Text = "&Title Font:";
+      // 
+      // errorProvider
+      // 
+      this.errorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
+      this.errorProvider.ContainerControl = this;
+      // 
+      // titleFontDialog
+      // 
+      this.titleFontDialog.Color = System.Drawing.SystemColors.ControlText;
+      this.titleFontDialog.FontMustExist = true;
+      this.titleFontDialog.ShowColor = true;
+      // 
+      // axisFontDialog
+      // 
+      this.axisFontDialog.Color = System.Drawing.SystemColors.ControlText;
+      // 
+      // ScatterPlotVisualPropertiesControl
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.axisFontLabel);
+      this.Controls.Add(this.label15);
+      this.Controls.Add(this.axisFontButton);
+      this.Controls.Add(this.titleFontLabel);
+      this.Controls.Add(this.label3);
+      this.Controls.Add(this.titleTextBox);
+      this.Controls.Add(this.axisTabControl);
+      this.Controls.Add(this.label2);
+      this.Controls.Add(this.titleFontButton);
+      this.Name = "ScatterPlotVisualPropertiesControl";
+      this.Size = new System.Drawing.Size(455, 220);
+      this.panel2.ResumeLayout(false);
+      this.panel2.PerformLayout();
+      this.panel1.ResumeLayout(false);
+      this.panel1.PerformLayout();
+      this.axisTabControl.ResumeLayout(false);
+      this.xAxisTabPage.ResumeLayout(false);
+      this.xAxisTabPage.PerformLayout();
+      this.yAxisTabPage.ResumeLayout(false);
+      this.yAxisTabPage.PerformLayout();
+      this.panel6.ResumeLayout(false);
+      this.panel6.PerformLayout();
+      this.panel5.ResumeLayout(false);
+      this.panel5.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.TextBox yAxisTitleTextBox;
+    private System.Windows.Forms.Label label12;
+    private System.Windows.Forms.Label label9;
+    private System.Windows.Forms.TextBox xAxisTitleTextBox;
+    private System.Windows.Forms.Label label11;
+    private System.Windows.Forms.TextBox xAxisMaximumFixedTextBox;
+    private System.Windows.Forms.RadioButton xAxisMaximumFixedRadioButton;
+    private System.Windows.Forms.RadioButton xAxisMaximumAutoRadioButton;
+    private System.Windows.Forms.TextBox xAxisMinimumFixedTextBox;
+    private System.Windows.Forms.RadioButton xAxisMinimumFixedRadioButton;
+    private System.Windows.Forms.RadioButton xAxisMinimumAutoRadioButton;
+    private System.Windows.Forms.TabControl axisTabControl;
+    private System.Windows.Forms.TabPage xAxisTabPage;
+    private System.Windows.Forms.TabPage yAxisTabPage;
+    private System.Windows.Forms.Label label7;
+    private System.Windows.Forms.Label label8;
+    private System.Windows.Forms.TextBox yAxisMaximumFixedTextBox;
+    private System.Windows.Forms.RadioButton yAxisMaximumFixedRadioButton;
+    private System.Windows.Forms.RadioButton yAxisMaximumAutoRadioButton;
+    private System.Windows.Forms.TextBox yAxisMinimumFixedTextBox;
+    private System.Windows.Forms.RadioButton yAxisMinimumFixedRadioButton;
+    private System.Windows.Forms.RadioButton yAxisMinimumAutoRadioButton;
+    private System.Windows.Forms.ErrorProvider errorProvider;
+    private System.Windows.Forms.FontDialog titleFontDialog;
+    private System.Windows.Forms.Button titleFontButton;
+    private System.Windows.Forms.Label label2;
+    private System.Windows.Forms.Button axisFontButton;
+    private System.Windows.Forms.Label label3;
+    private System.Windows.Forms.Label axisFontLabel;
+    private System.Windows.Forms.Label titleFontLabel;
+    private System.Windows.Forms.FontDialog axisFontDialog;
+    private System.Windows.Forms.Label label15;
+    private System.Windows.Forms.TextBox titleTextBox;
+    private System.Windows.Forms.Panel panel1;
+    private System.Windows.Forms.Panel panel2;
+    private System.Windows.Forms.Panel panel6;
+    private System.Windows.Forms.Panel panel5;
+    private System.Windows.Forms.CheckBox xAxisGridCheckBox;
+    private System.Windows.Forms.Label label4;
+    private System.Windows.Forms.CheckBox yAxisGridCheckBox;
+    private System.Windows.Forms.Label label5;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotVisualPropertiesControl.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotVisualPropertiesControl.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotVisualPropertiesControl.cs	(revision 12764)
@@ -0,0 +1,297 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Drawing;
+using System.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Analysis.Views {
+  [View("Scatter Plot Visual Properties")]
+  public partial class ScatterPlotVisualPropertiesControl : UserControl {
+    protected bool SuppressEvents { get; set; }
+
+    private ScatterPlotVisualProperties content;
+    public ScatterPlotVisualProperties Content {
+      get { return content; }
+      set {
+        bool changed = (value != content);
+        content = value;
+        if (changed) OnContentChanged();
+      }
+    }
+
+    public ScatterPlotVisualPropertiesControl() {
+      InitializeComponent();
+      errorProvider.SetIconAlignment(xAxisMinimumFixedTextBox, ErrorIconAlignment.MiddleLeft);
+      errorProvider.SetIconAlignment(xAxisMaximumFixedTextBox, ErrorIconAlignment.MiddleLeft);
+      errorProvider.SetIconAlignment(yAxisMinimumFixedTextBox, ErrorIconAlignment.MiddleLeft);
+      errorProvider.SetIconAlignment(yAxisMaximumFixedTextBox, ErrorIconAlignment.MiddleLeft);
+      errorProvider.SetIconPadding(xAxisMinimumFixedTextBox, 2);
+      errorProvider.SetIconPadding(xAxisMaximumFixedTextBox, 2);
+      errorProvider.SetIconPadding(yAxisMinimumFixedTextBox, 2);
+      errorProvider.SetIconPadding(yAxisMaximumFixedTextBox, 2);
+    }
+
+    protected virtual void OnContentChanged() {
+      SuppressEvents = true;
+      try {
+        if (Content == null) {
+          titleFontLabel.Text = "( none )";
+          axisFontLabel.Text = "( none )";
+          titleTextBox.Text = string.Empty;
+
+          xAxisTitleTextBox.Text = string.Empty;
+          xAxisMinimumAutoRadioButton.Checked = false;
+          xAxisMinimumFixedRadioButton.Checked = false;
+          xAxisMinimumFixedTextBox.Text = string.Empty;
+          xAxisMaximumAutoRadioButton.Checked = false;
+          xAxisMaximumFixedRadioButton.Checked = false;
+          xAxisMaximumFixedTextBox.Text = string.Empty;
+          xAxisGridCheckBox.Checked = false;
+
+          yAxisTitleTextBox.Text = string.Empty;
+          yAxisMinimumAutoRadioButton.Checked = false;
+          yAxisMinimumFixedRadioButton.Checked = false;
+          yAxisMinimumFixedTextBox.Text = string.Empty;
+          yAxisMaximumAutoRadioButton.Checked = false;
+          yAxisMaximumFixedRadioButton.Checked = false;
+          yAxisMaximumFixedTextBox.Text = string.Empty;
+          yAxisGridCheckBox.Checked = false;
+        } else {
+          titleFontLabel.Text = "( " + FormatFont(Content.TitleFont) + " )";
+          axisFontLabel.Text = "( " + FormatFont(Content.AxisTitleFont) + " )";
+          titleTextBox.Text = Content.Title;
+
+          xAxisTitleTextBox.Text = Content.XAxisTitle;
+          xAxisMinimumAutoRadioButton.Checked = Content.XAxisMinimumAuto;
+          xAxisMinimumFixedRadioButton.Checked = !Content.XAxisMinimumAuto;
+          xAxisMinimumFixedTextBox.Text = Content.XAxisMinimumFixedValue.ToString();
+          xAxisMaximumAutoRadioButton.Checked = Content.XAxisMaximumAuto;
+          xAxisMaximumFixedRadioButton.Checked = !Content.XAxisMaximumAuto;
+          xAxisMaximumFixedTextBox.Text = Content.XAxisMaximumFixedValue.ToString();
+          xAxisGridCheckBox.Checked = Content.XAxisGrid;
+
+          yAxisTitleTextBox.Text = Content.YAxisTitle;
+          yAxisMinimumAutoRadioButton.Checked = Content.YAxisMinimumAuto;
+          yAxisMinimumFixedRadioButton.Checked = !Content.YAxisMinimumAuto;
+          yAxisMinimumFixedTextBox.Text = Content.YAxisMinimumFixedValue.ToString();
+          yAxisMaximumAutoRadioButton.Checked = Content.YAxisMaximumAuto;
+          yAxisMaximumFixedRadioButton.Checked = !Content.YAxisMaximumAuto;
+          yAxisMaximumFixedTextBox.Text = Content.YAxisMaximumFixedValue.ToString();
+          yAxisGridCheckBox.Checked = Content.YAxisGrid;
+        }
+      }
+      finally { SuppressEvents = false; }
+      SetEnabledStateOfControls();
+    }
+
+    protected virtual void SetEnabledStateOfControls() {
+      axisTabControl.Enabled = Content != null;
+      xAxisMinimumFixedTextBox.Enabled = xAxisMinimumFixedRadioButton.Checked;
+      xAxisMaximumFixedTextBox.Enabled = xAxisMaximumFixedRadioButton.Checked;
+
+      yAxisMinimumFixedTextBox.Enabled = yAxisMinimumFixedRadioButton.Checked;
+      yAxisMaximumFixedTextBox.Enabled = yAxisMaximumFixedRadioButton.Checked;
+    }
+
+    #region Event Handlers
+    private void yTitleTextBox_Validated(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        Content.YAxisTitle = yAxisTitleTextBox.Text;
+      }
+    }
+
+    private void xTitleTextBox_Validated(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        Content.XAxisTitle = xAxisTitleTextBox.Text;
+      }
+    }
+
+    private void xAxisMinimumFixedTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        TextBox tb = (TextBox)sender;
+        double val;
+        if (double.TryParse(tb.Text, out val)) {
+          if (val >= Content.XAxisMaximumFixedValue) {
+            errorProvider.SetError(tb, "Number must be smaller than maximum.");
+            e.Cancel = true;
+          } else {
+            Content.XAxisMinimumFixedValue = val;
+            errorProvider.SetError(tb, string.Empty);
+          }
+        } else {
+          errorProvider.SetError(tb, "Not a valid number.");
+          e.Cancel = true;
+        }
+      }
+    }
+
+    private void xAxisMaximumFixedTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        TextBox tb = (TextBox)sender;
+        double val;
+        if (double.TryParse(tb.Text, out val)) {
+          if (val <= Content.XAxisMinimumFixedValue) {
+            errorProvider.SetError(tb, "Number must be greater than minimum.");
+            e.Cancel = true;
+          } else {
+            Content.XAxisMaximumFixedValue = val;
+            errorProvider.SetError(tb, string.Empty);
+          }
+        } else {
+          errorProvider.SetError(tb, "Not a valid number.");
+          e.Cancel = true;
+        }
+      }
+    }
+
+    private void yAxisMinimumFixedTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        TextBox tb = (TextBox)sender;
+        double val;
+        if (double.TryParse(tb.Text, out val)) {
+          if (val >= Content.YAxisMaximumFixedValue) {
+            errorProvider.SetError(tb, "Number must be smaller than maximum.");
+            e.Cancel = true;
+          } else {
+            Content.YAxisMinimumFixedValue = val;
+            errorProvider.SetError(tb, string.Empty);
+          }
+        } else {
+          errorProvider.SetError(tb, "Not a valid number.");
+          e.Cancel = true;
+        }
+      }
+    }
+
+    private void yAxisMaximumFixedTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        TextBox tb = (TextBox)sender;
+        double val;
+        if (double.TryParse(tb.Text, out val)) {
+          if (val <= Content.YAxisMinimumFixedValue) {
+            errorProvider.SetError(tb, "Number must be greater than minimum.");
+            e.Cancel = true;
+          } else {
+            Content.YAxisMaximumFixedValue = val;
+            errorProvider.SetError(tb, string.Empty);
+          }
+        } else {
+          errorProvider.SetError(tb, "Not a valid number.");
+          e.Cancel = true;
+        }
+      }
+    }
+
+    private void xAxisMinimumRadioButton_CheckedChanged(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.XAxisMinimumAuto = xAxisMinimumAutoRadioButton.Checked;
+          if (Content.XAxisMinimumAuto) xAxisMinimumFixedTextBox.Text = double.NaN.ToString();
+        }
+        finally { SuppressEvents = false; }
+        SetEnabledStateOfControls();
+      }
+    }
+
+    private void xAxisMaximumRadioButton_CheckedChanged(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.XAxisMaximumAuto = xAxisMaximumAutoRadioButton.Checked;
+          if (Content.XAxisMaximumAuto) xAxisMaximumFixedTextBox.Text = double.NaN.ToString();
+        }
+        finally { SuppressEvents = false; }
+        SetEnabledStateOfControls();
+      }
+    }
+
+    private void yAxisMinimumRadioButton_CheckedChanged(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.YAxisMinimumAuto = yAxisMinimumAutoRadioButton.Checked;
+          if (Content.YAxisMinimumAuto) yAxisMinimumFixedTextBox.Text = double.NaN.ToString();
+        }
+        finally { SuppressEvents = false; }
+        SetEnabledStateOfControls();
+      }
+    }
+
+    private void yAxisMaximumRadioButton_CheckedChanged(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        SuppressEvents = true;
+        try {
+          Content.YAxisMaximumAuto = yAxisMaximumAutoRadioButton.Checked;
+          if (Content.YAxisMaximumAuto) yAxisMaximumFixedTextBox.Text = double.NaN.ToString();
+        }
+        finally { SuppressEvents = false; }
+        SetEnabledStateOfControls();
+      }
+    }
+
+    private void titleFontButton_Click(object sender, System.EventArgs e) {
+      titleFontDialog.Font = Content.TitleFont;
+      titleFontDialog.Color = Content.TitleColor;
+      if (titleFontDialog.ShowDialog() == DialogResult.OK) {
+        Content.TitleFont = titleFontDialog.Font;
+        Content.TitleColor = titleFontDialog.Color;
+        titleFontLabel.Text = "( " + FormatFont(Content.TitleFont) + " )";
+      }
+    }
+
+    private void axisFontButton_Click(object sender, System.EventArgs e) {
+      axisFontDialog.Font = Content.AxisTitleFont;
+      axisFontDialog.Color = Content.AxisTitleColor;
+      if (axisFontDialog.ShowDialog() == DialogResult.OK) {
+        Content.AxisTitleFont = axisFontDialog.Font;
+        Content.AxisTitleColor = axisFontDialog.Color;
+        axisFontLabel.Text = "( " + FormatFont(Content.AxisTitleFont) + " )";
+      }
+    }
+
+    private void titleTextBox_Validated(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        Content.Title = titleTextBox.Text;
+      }
+    }
+
+    private void yAxisGridCheckBox_CheckedChanged(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        Content.YAxisGrid = yAxisGridCheckBox.Checked;
+      }
+    }
+
+    private void xAxisGridCheckBox_CheckedChanged(object sender, System.EventArgs e) {
+      if (!SuppressEvents && Content != null) {
+        Content.XAxisGrid = xAxisGridCheckBox.Checked;
+      }
+    }
+    #endregion
+
+    private string FormatFont(Font f) {
+      if (f == null) return "default";
+      else return f.Name + ", " + f.SizeInPoints.ToString() + "pt, " + f.Style.ToString();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotVisualPropertiesDialog.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotVisualPropertiesDialog.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotVisualPropertiesDialog.Designer.cs	(revision 12764)
@@ -0,0 +1,252 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Analysis.Views {
+  partial class ScatterPlotVisualPropertiesDialog {
+    /// <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.okButton = new System.Windows.Forms.Button();
+      this.cancelButton = new System.Windows.Forms.Button();
+      this.tabControl = new System.Windows.Forms.TabControl();
+      this.seriesTabPage = new System.Windows.Forms.TabPage();
+      this.splitContainer = new System.Windows.Forms.SplitContainer();
+      this.downButton = new System.Windows.Forms.Button();
+      this.upButton = new System.Windows.Forms.Button();
+      this.seriesListView = new System.Windows.Forms.ListView();
+      this.dataRowVisualPropertiesControl = new HeuristicLab.Analysis.Views.ScatterPlotDataRowVisualPropertiesControl();
+      this.chartTabPage = new System.Windows.Forms.TabPage();
+      this.dataTableVisualPropertiesControl = new HeuristicLab.Analysis.Views.ScatterPlotVisualPropertiesControl();
+      this.tabControl.SuspendLayout();
+      this.seriesTabPage.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.chartTabPage.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // okButton
+      // 
+      this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.okButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+      this.okButton.Location = new System.Drawing.Point(325, 400);
+      this.okButton.Name = "okButton";
+      this.okButton.Size = new System.Drawing.Size(75, 23);
+      this.okButton.TabIndex = 0;
+      this.okButton.Text = "&OK";
+      this.okButton.UseVisualStyleBackColor = true;
+      this.okButton.Click += new System.EventHandler(this.okButton_Click);
+      // 
+      // 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(406, 400);
+      this.cancelButton.Name = "cancelButton";
+      this.cancelButton.Size = new System.Drawing.Size(75, 23);
+      this.cancelButton.TabIndex = 1;
+      this.cancelButton.Text = "&Cancel";
+      this.cancelButton.UseVisualStyleBackColor = true;
+      this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
+      // 
+      // tabControl
+      // 
+      this.tabControl.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.tabControl.Controls.Add(this.seriesTabPage);
+      this.tabControl.Controls.Add(this.chartTabPage);
+      this.tabControl.Location = new System.Drawing.Point(12, 12);
+      this.tabControl.Name = "tabControl";
+      this.tabControl.SelectedIndex = 0;
+      this.tabControl.Size = new System.Drawing.Size(469, 382);
+      this.tabControl.TabIndex = 2;
+      // 
+      // seriesTabPage
+      // 
+      this.seriesTabPage.Controls.Add(this.splitContainer);
+      this.seriesTabPage.Location = new System.Drawing.Point(4, 22);
+      this.seriesTabPage.Name = "seriesTabPage";
+      this.seriesTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.seriesTabPage.Size = new System.Drawing.Size(461, 356);
+      this.seriesTabPage.TabIndex = 0;
+      this.seriesTabPage.Text = "Series";
+      this.seriesTabPage.UseVisualStyleBackColor = true;
+      // 
+      // splitContainer
+      // 
+      this.splitContainer.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.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
+      this.splitContainer.Location = new System.Drawing.Point(0, 0);
+      this.splitContainer.Name = "splitContainer";
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.downButton);
+      this.splitContainer.Panel1.Controls.Add(this.upButton);
+      this.splitContainer.Panel1.Controls.Add(this.seriesListView);
+      this.splitContainer.Panel1MinSize = 20;
+      // 
+      // splitContainer.Panel2
+      // 
+      this.splitContainer.Panel2.Controls.Add(this.dataRowVisualPropertiesControl);
+      this.splitContainer.Panel2MinSize = 50;
+      this.splitContainer.Size = new System.Drawing.Size(461, 356);
+      this.splitContainer.SplitterDistance = 125;
+      this.splitContainer.TabIndex = 0;
+      // 
+      // downButton
+      // 
+      this.downButton.Enabled = false;
+      this.downButton.Location = new System.Drawing.Point(35, 3);
+      this.downButton.Name = "downButton";
+      this.downButton.Size = new System.Drawing.Size(26, 23);
+      this.downButton.TabIndex = 1;
+      this.downButton.Text = "Down";
+      this.downButton.UseVisualStyleBackColor = true;
+      this.downButton.Click += new System.EventHandler(this.downButton_Click);
+      // 
+      // upButton
+      // 
+      this.upButton.Enabled = false;
+      this.upButton.Location = new System.Drawing.Point(3, 3);
+      this.upButton.Name = "upButton";
+      this.upButton.Size = new System.Drawing.Size(26, 23);
+      this.upButton.TabIndex = 0;
+      this.upButton.Text = "Up";
+      this.upButton.UseVisualStyleBackColor = true;
+      this.upButton.Click += new System.EventHandler(this.upButton_Click);
+      // 
+      // seriesListView
+      // 
+      this.seriesListView.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.seriesListView.HideSelection = false;
+      this.seriesListView.Location = new System.Drawing.Point(3, 32);
+      this.seriesListView.MultiSelect = false;
+      this.seriesListView.Name = "seriesListView";
+      this.seriesListView.ShowGroups = false;
+      this.seriesListView.Size = new System.Drawing.Size(119, 321);
+      this.seriesListView.TabIndex = 2;
+      this.seriesListView.UseCompatibleStateImageBehavior = false;
+      this.seriesListView.View = System.Windows.Forms.View.List;
+      this.seriesListView.SelectedIndexChanged += new System.EventHandler(this.seriesListView_SelectedIndexChanged);
+      // 
+      // dataRowVisualPropertiesControl
+      // 
+      this.dataRowVisualPropertiesControl.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.dataRowVisualPropertiesControl.Content = null;
+      this.dataRowVisualPropertiesControl.Location = new System.Drawing.Point(3, 26);
+      this.dataRowVisualPropertiesControl.Name = "dataRowVisualPropertiesControl";
+      this.dataRowVisualPropertiesControl.Size = new System.Drawing.Size(326, 327);
+      this.dataRowVisualPropertiesControl.TabIndex = 0;
+      // 
+      // chartTabPage
+      // 
+      this.chartTabPage.Controls.Add(this.dataTableVisualPropertiesControl);
+      this.chartTabPage.Location = new System.Drawing.Point(4, 22);
+      this.chartTabPage.Name = "chartTabPage";
+      this.chartTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.chartTabPage.Size = new System.Drawing.Size(461, 356);
+      this.chartTabPage.TabIndex = 1;
+      this.chartTabPage.Text = "Chart";
+      this.chartTabPage.UseVisualStyleBackColor = true;
+      // 
+      // dataTableVisualPropertiesControl
+      // 
+      this.dataTableVisualPropertiesControl.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.dataTableVisualPropertiesControl.Content = null;
+      this.dataTableVisualPropertiesControl.Location = new System.Drawing.Point(3, 6);
+      this.dataTableVisualPropertiesControl.Name = "dataTableVisualPropertiesControl";
+      this.dataTableVisualPropertiesControl.Size = new System.Drawing.Size(455, 347);
+      this.dataTableVisualPropertiesControl.TabIndex = 0;
+      // 
+      // DataTableVisualPropertiesDialog
+      // 
+      this.AcceptButton = this.okButton;
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.CancelButton = this.cancelButton;
+      this.ClientSize = new System.Drawing.Size(493, 435);
+      this.Controls.Add(this.tabControl);
+      this.Controls.Add(this.cancelButton);
+      this.Controls.Add(this.okButton);
+      this.MaximizeBox = false;
+      this.MinimizeBox = false;
+      this.Name = "DataTableVisualPropertiesDialog";
+      this.ShowIcon = false;
+      this.ShowInTaskbar = false;
+      this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+      this.Text = "Customize Visual Properties";
+      this.TopMost = true;
+      this.tabControl.ResumeLayout(false);
+      this.seriesTabPage.ResumeLayout(false);
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.chartTabPage.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Button okButton;
+    private System.Windows.Forms.Button cancelButton;
+    private System.Windows.Forms.TabControl tabControl;
+    private System.Windows.Forms.TabPage seriesTabPage;
+    private System.Windows.Forms.SplitContainer splitContainer;
+    private System.Windows.Forms.ListView seriesListView;
+    private System.Windows.Forms.TabPage chartTabPage;
+    private ScatterPlotDataRowVisualPropertiesControl dataRowVisualPropertiesControl;
+    private ScatterPlotVisualPropertiesControl dataTableVisualPropertiesControl;
+    private System.Windows.Forms.Button downButton;
+    private System.Windows.Forms.Button upButton;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotVisualPropertiesDialog.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotVisualPropertiesDialog.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis.Views/3.3/ScatterPlotVisualPropertiesDialog.cs	(revision 12764)
@@ -0,0 +1,181 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Common.Resources;
+
+namespace HeuristicLab.Analysis.Views {
+  public partial class ScatterPlotVisualPropertiesDialog : Form {
+    protected bool SuppressEvents { get; set; }
+    protected ScatterPlot Content { get; private set; }
+    private ScatterPlotVisualProperties originalScatterPlotVPs;
+    private Dictionary<string, ScatterPlotDataRowVisualProperties> originalScatterPlotDataRowVPs;
+
+    private HashSet<string> modifiedDisplayNames;
+    public IEnumerable<string> RowsWithModifiedDisplayNames { get { return modifiedDisplayNames.AsEnumerable(); } }
+
+    public ScatterPlotVisualPropertiesDialog(ScatterPlot scatterPlot) {
+      InitializeComponent();
+      #region Prepare controls
+      upButton.Text = string.Empty;
+      upButton.Image = VSImageLibrary.ArrowUp;
+      downButton.Text = string.Empty;
+      downButton.Image = VSImageLibrary.ArrowDown;
+      seriesListView.Items.Clear();
+      seriesListView.SmallImageList = new ImageList();
+      seriesListView.SmallImageList.Images.Add(VSImageLibrary.Graph);
+      #endregion
+
+      Content = scatterPlot;
+      originalScatterPlotVPs = (ScatterPlotVisualProperties)Content.VisualProperties.Clone();
+      originalScatterPlotDataRowVPs = new Dictionary<string, ScatterPlotDataRowVisualProperties>();
+      foreach (ScatterPlotDataRow row in Content.Rows)
+        originalScatterPlotDataRowVPs.Add(row.Name, (ScatterPlotDataRowVisualProperties)row.VisualProperties.Clone());
+
+      dataTableVisualPropertiesControl.Content = Content.VisualProperties;
+
+      modifiedDisplayNames = new HashSet<string>();
+      FillSeriesListView();
+      RegisterContentEvents();
+    }
+
+    private void RegisterContentEvents() {
+      foreach (ScatterPlotDataRow row in Content.Rows) {
+        row.VisualProperties.PropertyChanged += new PropertyChangedEventHandler(Row_VisualProperties_PropertyChanged);
+      }
+    }
+
+    private void DeregisterContentEvents() {
+      foreach (ScatterPlotDataRow row in Content.Rows) {
+        row.VisualProperties.PropertyChanged -= new PropertyChangedEventHandler(Row_VisualProperties_PropertyChanged);
+      }
+    }
+
+    protected override void OnClosing(CancelEventArgs e) {
+      DeregisterContentEvents();
+      Application.DoEvents();
+      base.OnClosing(e);
+    }
+
+    private void Row_VisualProperties_PropertyChanged(object sender, PropertyChangedEventArgs e) {
+      foreach (ScatterPlotDataRow row in Content.Rows) {
+        if (e.PropertyName == "DisplayName" && row.VisualProperties == sender) {
+          modifiedDisplayNames.Add(row.Name);
+          break;
+        }
+      }
+    }
+
+    private void seriesListView_SelectedIndexChanged(object sender, System.EventArgs e) {
+      if (!SuppressEvents) {
+        if (seriesListView.SelectedItems.Count != 1) {
+          dataRowVisualPropertiesControl.Content = null;
+          upButton.Enabled = downButton.Enabled = false;
+        } else {
+          string rowName = seriesListView.SelectedItems[0].Text;
+          dataRowVisualPropertiesControl.Content = Content.Rows[rowName].VisualProperties;
+          upButton.Enabled = seriesListView.SelectedIndices[0] > 0;
+          downButton.Enabled = seriesListView.SelectedIndices[0] < seriesListView.Items.Count - 1;
+        }
+      }
+    }
+
+    private void okButton_Click(object sender, System.EventArgs e) {
+      DialogResult = DialogResult.OK;
+      Close();
+    }
+
+    private void cancelButton_Click(object sender, System.EventArgs e) {
+      DialogResult = DialogResult.Cancel;
+      foreach (ScatterPlotDataRow row in Content.Rows) {
+        row.VisualProperties = originalScatterPlotDataRowVPs[row.Name];
+      }
+      modifiedDisplayNames.Clear();
+      Content.VisualProperties = originalScatterPlotVPs;
+      Close();
+    }
+
+    private void upButton_Click(object sender, System.EventArgs e) {
+      if (seriesListView.SelectedIndices.Count == 1 && seriesListView.SelectedIndices[0] > 0) {
+        int index = seriesListView.SelectedIndices[0];
+        SuppressEvents = true;
+        try {
+          seriesListView.BeginUpdate();
+          ListViewItem selectedSeriesItem = seriesListView.Items[index];
+          seriesListView.Items.RemoveAt(index);
+          ListViewItem temp = seriesListView.Items[index - 1];
+          seriesListView.Items.RemoveAt(index - 1);
+          seriesListView.Items.Insert(index - 1, selectedSeriesItem);
+          seriesListView.Items.Insert(index, temp);
+          seriesListView.SelectedIndices.Clear();
+          seriesListView.EndUpdate();
+        }
+        finally { SuppressEvents = false; }
+        seriesListView.SelectedIndices.Add(index - 1);
+        UpdateAllSeriesPositions();
+      }
+    }
+
+    private void downButton_Click(object sender, System.EventArgs e) {
+      if (seriesListView.SelectedIndices.Count == 1 && seriesListView.SelectedIndices[0] < seriesListView.Items.Count - 1) {
+        int index = seriesListView.SelectedIndices[0];
+        SuppressEvents = true;
+        try {
+          seriesListView.BeginUpdate();
+          ListViewItem temp = seriesListView.Items[index + 1];
+          seriesListView.Items.RemoveAt(index + 1);
+          ListViewItem selectedSeriesItem = seriesListView.Items[index];
+          seriesListView.Items.RemoveAt(index);
+          seriesListView.Items.Insert(index, temp);
+          seriesListView.Items.Insert(index + 1, selectedSeriesItem);
+          seriesListView.SelectedIndices.Clear();
+          seriesListView.EndUpdate();
+        }
+        finally { SuppressEvents = false; }
+        seriesListView.SelectedIndices.Add(index + 1);
+        UpdateAllSeriesPositions();
+      }
+    }
+
+    #region Helpers
+    private void FillSeriesListView() {
+      seriesListView.SelectedIndices.Clear();
+      foreach (ScatterPlotDataRow row in Content.Rows) {
+        seriesListView.Items.Add(new ListViewItem(row.Name, 0));
+      }
+      if (seriesListView.Items.Count > 0)
+        seriesListView.SelectedIndices.Add(0);
+    }
+
+    private void UpdateAllSeriesPositions() {
+      Dictionary<string, ScatterPlotDataRow> rows = Content.Rows.ToDictionary(x => x.Name);
+      Content.Rows.Clear();
+      for (int i = 0; i < seriesListView.Items.Count; i++) {
+        ListViewItem item = seriesListView.Items[i];
+        Content.Rows.Add(rows[item.Text]);
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/Allele.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/Allele.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/Allele.cs	(revision 12764)
@@ -0,0 +1,87 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// Represents an allele of a solution which is used for allele analysis.
+  /// </summary>
+  [Item("Allele", "Represents an allele of a solution which is used for allele analysis.")]
+  [StorableClass]
+  public class Allele : Item {
+    private string id;
+    public string Id {
+      get { return id; }
+    }
+    private double impact;
+    public double Impact {
+      get { return impact; }
+    }
+
+    #region Storable Properties
+    [Storable(Name = "Id")]
+    private string StorableId {
+      get { return id; }
+      set { id = value; }
+    }
+    [Storable(Name = "Impact")]
+    private double StorableImpact {
+      get { return impact; }
+      set { impact = value; }
+    }
+    #endregion
+
+    #region Storing & Cloning
+    [StorableConstructor]
+    protected Allele(bool deserializing) : base(deserializing) { }
+    protected Allele(Allele original, Cloner cloner)
+      : base(original, cloner) {
+      this.id = original.id;
+      this.impact = original.impact;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Allele(this, cloner);
+    }
+    #endregion
+    public Allele()
+      : base() {
+      this.id = string.Empty;
+      this.impact = 0;
+    }
+    public Allele(string id)
+      : base() {
+      this.id = id;
+      this.impact = 0;
+    }
+    public Allele(string id, double impact)
+      : base() {
+      this.id = id;
+      this.impact = impact;
+    }
+
+    public override string ToString() {
+      return id + " (" + impact + ")";
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequency.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequency.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequency.cs	(revision 12764)
@@ -0,0 +1,130 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// Represents the frequency of an allele.
+  /// </summary>
+  [Item("AlleleFrequency", "Represents the frequency of an allele.")]
+  [StorableClass]
+  public class AlleleFrequency : Item {
+    private string id;
+    public string Id {
+      get { return id; }
+    }
+    private double frequency;
+    public double Frequency {
+      get { return frequency; }
+    }
+    private double averageImpact;
+    public double AverageImpact {
+      get { return averageImpact; }
+    }
+    private double averageSolutionQuality;
+    public double AverageSolutionQuality {
+      get { return averageSolutionQuality; }
+    }
+    private bool containedInBestKnownSolution;
+    public bool ContainedInBestKnownSolution {
+      get { return containedInBestKnownSolution; }
+    }
+    private bool containedInBestSolution;
+    public bool ContainedInBestSolution {
+      get { return containedInBestSolution; }
+    }
+
+    #region Storable Properties
+    [Storable(Name = "Id")]
+    private string StorableId {
+      get { return id; }
+      set { id = value; }
+    }
+    [Storable(Name = "Frequency")]
+    private double StorableFrequency {
+      get { return frequency; }
+      set { frequency = value; }
+    }
+    [Storable(Name = "AverageImpact")]
+    private double StorableAverageImpact {
+      get { return averageImpact; }
+      set { averageImpact = value; }
+    }
+    [Storable(Name = "AverageSolutionQuality")]
+    private double StorableAverageSolutionQuality {
+      get { return averageSolutionQuality; }
+      set { averageSolutionQuality = value; }
+    }
+    [Storable(Name = "ContainedInBestKnownSolution")]
+    private bool StorableContainedInBestKnownSolution {
+      get { return containedInBestKnownSolution; }
+      set { containedInBestKnownSolution = value; }
+    }
+    [Storable(Name = "ContainedInBestSolution")]
+    private bool StorableContainedInBestSolution {
+      get { return containedInBestSolution; }
+      set { containedInBestSolution = value; }
+    }
+    #endregion
+
+    #region Storing & Cloning
+    [StorableConstructor]
+    protected AlleleFrequency(bool deserializing) : base(deserializing) { }
+    protected AlleleFrequency(AlleleFrequency original, Cloner cloner)
+      : base(original, cloner) {
+      this.id = original.id;
+      this.frequency = original.frequency;
+      this.averageImpact = original.averageImpact;
+      this.averageSolutionQuality = original.averageSolutionQuality;
+      this.containedInBestKnownSolution = original.containedInBestKnownSolution;
+      this.containedInBestSolution = original.containedInBestSolution;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new AlleleFrequency(this, cloner);
+    }
+    #endregion
+    public AlleleFrequency()
+      : base() {
+      id = string.Empty;
+      frequency = 0;
+      averageImpact = 0;
+      averageSolutionQuality = 0;
+      containedInBestKnownSolution = false;
+      containedInBestSolution = false;
+    }
+    public AlleleFrequency(string id, double frequency, double averageImpact, double averageSolutionQuality, bool containedInBestKnownSolution, bool containedInBestSolution)
+      : base() {
+      this.id = id;
+      this.frequency = frequency;
+      this.averageImpact = averageImpact;
+      this.averageSolutionQuality = averageSolutionQuality;
+      this.containedInBestKnownSolution = containedInBestKnownSolution;
+      this.containedInBestSolution = containedInBestSolution;
+    }
+
+    public override string ToString() {
+      return id;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyAnalyzer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyAnalyzer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyAnalyzer.cs	(revision 12764)
@@ -0,0 +1,312 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// An operator for analyzing the frequency of alleles.
+  /// </summary>
+  [Item("AlleleFrequencyAnalyzer", "An operator for analyzing the frequency of alleles.")]
+  [StorableClass]
+  public abstract class AlleleFrequencyAnalyzer<T> : SingleSuccessorOperator, IAnalyzer, ISingleObjectiveOperator where T : class, IItem {
+    public virtual bool EnabledByDefault {
+      get { return false; }
+    }
+
+    public LookupParameter<BoolValue> MaximizationParameter {
+      get { return (LookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ScopeTreeLookupParameter<T> SolutionParameter {
+      get { return (ScopeTreeLookupParameter<T>)Parameters["Solution"]; }
+    }
+    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public LookupParameter<T> BestKnownSolutionParameter {
+      get { return (LookupParameter<T>)Parameters["BestKnownSolution"]; }
+    }
+    public ValueLookupParameter<ResultCollection> ResultsParameter {
+      get { return (ValueLookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    public ValueParameter<BoolValue> StoreHistoryParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["StoreHistory"]; }
+    }
+    public ValueParameter<IntValue> UpdateIntervalParameter {
+      get { return (ValueParameter<IntValue>)Parameters["UpdateInterval"]; }
+    }
+    public LookupParameter<IntValue> UpdateCounterParameter {
+      get { return (LookupParameter<IntValue>)Parameters["UpdateCounter"]; }
+    }
+
+    [StorableConstructor]
+    protected AlleleFrequencyAnalyzer(bool deserializing) : base(deserializing) { }
+    protected AlleleFrequencyAnalyzer(AlleleFrequencyAnalyzer<T> original, Cloner cloner) : base(original, cloner) { }
+    public AlleleFrequencyAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem."));
+      Parameters.Add(new ScopeTreeLookupParameter<T>("Solution", "The solutions whose alleles should be analyzed."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The qualities of the solutions which should be analyzed."));
+      Parameters.Add(new LookupParameter<T>("BestKnownSolution", "The best known solution."));
+      Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The result collection where the allele frequency analysis results should be stored."));
+      Parameters.Add(new ValueParameter<BoolValue>("StoreHistory", "True if the history of the allele frequency analysis should be stored.", new BoolValue(false)));
+      Parameters.Add(new ValueParameter<IntValue>("UpdateInterval", "The interval in which the allele frequency analysis should be applied.", new IntValue(1)));
+      Parameters.Add(new LookupParameter<IntValue>("UpdateCounter", "The value which counts how many times the operator was called since the last update.", "AlleleFrequencyAnalyzerUpdateCounter"));
+
+      MaximizationParameter.Hidden = true;
+      SolutionParameter.Hidden = true;
+      QualityParameter.Hidden = true;
+      BestKnownSolutionParameter.Hidden = true;
+      ResultsParameter.Hidden = true;
+      UpdateCounterParameter.Hidden = true;
+    }
+
+    #region Equality Comparers
+    private class AlleleIdEqualityComparer : IEqualityComparer<Allele> {
+      public bool Equals(Allele x, Allele y) {
+        return x.Id == y.Id;
+      }
+      public int GetHashCode(Allele obj) {
+        return obj.Id.GetHashCode();
+      }
+    }
+    private class AlleleFrequencyIdEqualityComparer : IEqualityComparer<AlleleFrequency> {
+      public bool Equals(AlleleFrequency x, AlleleFrequency y) {
+        return x.Id == y.Id;
+      }
+      public int GetHashCode(AlleleFrequency obj) {
+        return obj.Id.GetHashCode();
+      }
+    }
+    #endregion
+
+    public override IOperation Apply() {
+      int updateInterval = UpdateIntervalParameter.Value.Value;
+      IntValue updateCounter = UpdateCounterParameter.ActualValue;
+      if (updateCounter == null) {
+        updateCounter = new IntValue(updateInterval);
+        UpdateCounterParameter.ActualValue = updateCounter;
+      } else updateCounter.Value++;
+
+      if (updateCounter.Value == updateInterval) {
+        updateCounter.Value = 0;
+
+        bool max = MaximizationParameter.ActualValue.Value;
+        ItemArray<T> solutions = SolutionParameter.ActualValue;
+        double[] qualities = QualityParameter.ActualValue.Select(x => x.Value).ToArray();
+        T bestKnownSolution = BestKnownSolutionParameter.ActualValue;
+        bool storeHistory = StoreHistoryParameter.Value.Value;
+
+        // calculate index of current best solution
+        int bestIndex = -1;
+        if (!max) {
+          bestIndex = qualities
+            .Select((x, i) => new { Index = i, Value = x })
+            .OrderBy(x => x.Value)
+            .First().Index;
+        } else {
+          bestIndex = qualities
+            .Select((x, i) => new { Index = i, Value = x })
+            .OrderByDescending(x => x.Value)
+            .First().Index;
+        }
+
+        // calculate allels of current best and (if available) best known solution
+        Allele[] bestAlleles = CalculateAlleles(solutions[bestIndex]);
+        Allele[] bestKnownAlleles = null;
+        if (bestKnownSolution != null)
+          bestKnownAlleles = CalculateAlleles(bestKnownSolution);
+
+        // calculate allele frequencies
+        var frequencies = solutions.SelectMany((s, index) => CalculateAlleles(s).Select(a => new { Allele = a, Quality = qualities[index] })).
+                          GroupBy(x => x.Allele.Id).
+                          Select(x => new AlleleFrequency(x.Key,
+                                                          x.Count() / ((double)solutions.Length),
+                                                          x.Average(a => a.Allele.Impact),
+                                                          x.Average(a => a.Quality),
+                                                          bestKnownAlleles == null ? false : bestKnownAlleles.Any(a => a.Id == x.Key),
+                                                          bestAlleles.Any(a => a.Id == x.Key)));
+
+        // calculate dummy allele frequencies of alleles of best known solution which did not occur
+        if (bestKnownAlleles != null) {
+          var bestKnownFrequencies = bestKnownAlleles.Select(x => new AlleleFrequency(x.Id, 0, x.Impact, 0, true, false)).Except(frequencies, new AlleleFrequencyIdEqualityComparer());
+          frequencies = frequencies.Concat(bestKnownFrequencies);
+        }
+
+        // fetch results collection
+        ResultCollection results;
+        if (!ResultsParameter.ActualValue.ContainsKey(Name + " Results")) {
+          results = new ResultCollection();
+          ResultsParameter.ActualValue.Add(new Result(Name + " Results", results));
+        } else {
+          results = (ResultCollection)ResultsParameter.ActualValue[Name + " Results"].Value;
+        }
+
+        // store allele frequencies
+        AlleleFrequencyCollection frequenciesCollection = new AlleleFrequencyCollection(frequencies);
+        if (!results.ContainsKey("Allele Frequencies"))
+          results.Add(new Result("Allele Frequencies", frequenciesCollection));
+        else
+          results["Allele Frequencies"].Value = frequenciesCollection;
+
+        // store allele frequencies history
+        if (storeHistory) {
+          if (!results.ContainsKey("Allele Frequencies History")) {
+            AlleleFrequencyCollectionHistory history = new AlleleFrequencyCollectionHistory();
+            history.Add(frequenciesCollection);
+            results.Add(new Result("Allele Frequencies History", history));
+          } else {
+            ((AlleleFrequencyCollectionHistory)results["Allele Frequencies History"].Value).Add(frequenciesCollection);
+          }
+        }
+
+        // store alleles data table
+        DataTable allelesTable;
+        if (!results.ContainsKey("Alleles")) {
+          allelesTable = new DataTable("Alleles");
+          allelesTable.VisualProperties.XAxisTitle = "Iteration";
+          allelesTable.VisualProperties.YAxisTitle = "Number of Alleles";
+          allelesTable.VisualProperties.SecondYAxisTitle = "Number of Alleles";
+
+          allelesTable.Rows.Add(new DataRow("Unique Alleles"));
+          allelesTable.Rows["Unique Alleles"].VisualProperties.StartIndexZero = true;
+
+          allelesTable.Rows.Add(new DataRow("Unique Alleles of Best Known Solution", null));
+          allelesTable.Rows["Unique Alleles of Best Known Solution"].VisualProperties.SecondYAxis = true;
+          allelesTable.Rows["Unique Alleles of Best Known Solution"].VisualProperties.StartIndexZero = true;
+
+          allelesTable.Rows.Add(new DataRow("Fixed Alleles", null));
+          allelesTable.Rows["Fixed Alleles"].VisualProperties.SecondYAxis = true;
+          allelesTable.Rows["Fixed Alleles"].VisualProperties.StartIndexZero = true;
+
+          allelesTable.Rows.Add(new DataRow("Fixed Alleles of Best Known Solution", null));
+          allelesTable.Rows["Fixed Alleles of Best Known Solution"].VisualProperties.SecondYAxis = true;
+          allelesTable.Rows["Fixed Alleles of Best Known Solution"].VisualProperties.StartIndexZero = true;
+
+          allelesTable.Rows.Add(new DataRow("Lost Alleles of Best Known Solution", null));
+          allelesTable.Rows["Lost Alleles of Best Known Solution"].VisualProperties.SecondYAxis = true;
+          allelesTable.Rows["Lost Alleles of Best Known Solution"].VisualProperties.StartIndexZero = true;
+
+          results.Add(new Result("Alleles", allelesTable));
+        } else {
+          allelesTable = (DataTable)results["Alleles"].Value;
+        }
+
+        int fixedAllelesCount = frequenciesCollection.Where(x => x.Frequency == 1).Count();
+        var relevantAlleles = frequenciesCollection.Where(x => x.ContainedInBestKnownSolution);
+        int relevantAllelesCount = relevantAlleles.Count();
+        int fixedRelevantAllelesCount = relevantAlleles.Where(x => x.Frequency == 1).Count();
+        int lostRelevantAllelesCount = relevantAlleles.Where(x => x.Frequency == 0).Count();
+        int uniqueRelevantAllelesCount = relevantAllelesCount - lostRelevantAllelesCount;
+        allelesTable.Rows["Unique Alleles"].Values.Add(frequenciesCollection.Count);
+        allelesTable.Rows["Unique Alleles of Best Known Solution"].Values.Add(uniqueRelevantAllelesCount);
+        allelesTable.Rows["Fixed Alleles"].Values.Add(fixedAllelesCount);
+        allelesTable.Rows["Fixed Alleles of Best Known Solution"].Values.Add(fixedRelevantAllelesCount);
+        allelesTable.Rows["Lost Alleles of Best Known Solution"].Values.Add(lostRelevantAllelesCount);
+
+        // store alleles values
+        if (!results.ContainsKey("Unique Alleles"))
+          results.Add(new Result("Unique Alleles", new DoubleValue(frequenciesCollection.Count)));
+        else
+          ((DoubleValue)results["Unique Alleles"].Value).Value = frequenciesCollection.Count;
+
+        if (!results.ContainsKey("Unique Alleles of Best Known Solution"))
+          results.Add(new Result("Unique Alleles of Best Known Solution", new DoubleValue(uniqueRelevantAllelesCount)));
+        else
+          ((DoubleValue)results["Unique Alleles of Best Known Solution"].Value).Value = uniqueRelevantAllelesCount;
+
+        if (!results.ContainsKey("Fixed Alleles"))
+          results.Add(new Result("Fixed Alleles", new DoubleValue(fixedAllelesCount)));
+        else
+          ((DoubleValue)results["Fixed Alleles"].Value).Value = fixedAllelesCount;
+
+        if (!results.ContainsKey("Fixed Alleles of Best Known Solution"))
+          results.Add(new Result("Fixed Alleles of Best Known Solution", new DoubleValue(fixedRelevantAllelesCount)));
+        else
+          ((DoubleValue)results["Fixed Alleles of Best Known Solution"].Value).Value = fixedRelevantAllelesCount;
+
+        if (!results.ContainsKey("Lost Alleles of Best Known Solution"))
+          results.Add(new Result("Lost Alleles of Best Known Solution", new DoubleValue(lostRelevantAllelesCount)));
+        else
+          ((DoubleValue)results["Lost Alleles of Best Known Solution"].Value).Value = lostRelevantAllelesCount;
+
+        // calculate contained alleles of best known solution and relative quality
+        if (bestKnownAlleles != null) {
+          double qualityRange = Math.Abs(qualities.Max() - qualities.Min());
+          var points = solutions.Select((s, index) => new Point2D<double>(CalculateAlleles(s).Intersect(bestKnownAlleles, new AlleleIdEqualityComparer()).Count(),
+                                                                          Math.Abs(qualities[index] - qualities[bestIndex]) / qualityRange));
+          var avgContainedReleventAlleles = points.Select(x => x.X).Average();
+
+          var plot = new ScatterPlot("Contained Alleles of Best Known Solution and Relative Solution Qualtiy", null);
+          plot.VisualProperties.XAxisTitle = "Contained Alleles of Best Known Solution";
+          plot.VisualProperties.YAxisTitle = "Relative Solution Quality";
+          plot.VisualProperties.XAxisMinimumAuto = false;
+          plot.VisualProperties.XAxisMinimumFixedValue = 0.0;
+          plot.VisualProperties.XAxisMaximumAuto = false;
+          plot.VisualProperties.XAxisMaximumFixedValue = bestKnownAlleles.Length;
+          plot.VisualProperties.YAxisMinimumAuto = false;
+          plot.VisualProperties.YAxisMinimumFixedValue = 0.0;
+          plot.VisualProperties.YAxisMaximumAuto = false;
+          plot.VisualProperties.YAxisMaximumFixedValue = 1.0;
+          var row = new ScatterPlotDataRow("Solutions of Current Generation", null, points);
+          row.VisualProperties.PointStyle = ScatterPlotDataRowVisualProperties.ScatterPlotDataRowPointStyle.Circle;
+          row.VisualProperties.PointSize = 5;
+          plot.Rows.Add(row);
+
+          if (!results.ContainsKey("Scatter Plot"))
+            results.Add(new Result("Scatter Plot", plot));
+          else
+            results["Scatter Plot"].Value = plot;
+          if (storeHistory) {
+            if (!results.ContainsKey("Scatter Plot History")) {
+              results.Add(new Result("Scatter Plot History", new ScatterPlotHistory()));
+            }
+            ((ScatterPlotHistory)results["Scatter Plot History"].Value).Add(plot);
+          }
+
+          if (!allelesTable.Rows.ContainsKey("Average Contained Alleles of Best Known Solution")) {
+            allelesTable.Rows.Add(new DataRow("Average Contained Alleles of Best Known Solution", null));
+            allelesTable.Rows["Average Contained Alleles of Best Known Solution"].VisualProperties.SecondYAxis = true;
+            allelesTable.Rows["Average Contained Alleles of Best Known Solution"].VisualProperties.StartIndexZero = true;
+          }
+          allelesTable.Rows["Average Contained Alleles of Best Known Solution"].Values.Add(avgContainedReleventAlleles);
+
+          if (!results.ContainsKey("Average Contained Alleles of Best Known Solution"))
+            results.Add(new Result("Average Contained Alleles of Best Known Solution", new DoubleValue(avgContainedReleventAlleles)));
+          else
+            ((DoubleValue)results["Average Contained Alleles of Best Known Solution"].Value).Value = avgContainedReleventAlleles;
+        }
+      }
+      return base.Apply();
+    }
+
+    protected abstract Allele[] CalculateAlleles(T solution);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyCollection.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyCollection.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyCollection.cs	(revision 12764)
@@ -0,0 +1,49 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// Represents a collection of allele frequencies.
+  /// </summary>
+  [Item("AlleleFrequencyCollection", "Represents a collection of allele frequencies.")]
+  [StorableClass]
+  public class AlleleFrequencyCollection : ReadOnlyItemCollection<AlleleFrequency> {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Statistics; }
+    }
+
+    [StorableConstructor]
+    protected AlleleFrequencyCollection(bool deserializing) : base(deserializing) { }
+    protected AlleleFrequencyCollection(AlleleFrequencyCollection original, Cloner cloner) : base(original, cloner) { }
+    public AlleleFrequencyCollection() : base() { }
+    public AlleleFrequencyCollection(IEnumerable<AlleleFrequency> frequencies) : base(new ItemCollection<AlleleFrequency>(frequencies)) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new AlleleFrequencyCollection(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyCollectionHistory.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyCollectionHistory.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyCollectionHistory.cs	(revision 12764)
@@ -0,0 +1,49 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// Represents history values of allele frequencies collections.
+  /// </summary>
+  [Item("AlleleFrequencyCollectionHistory", "Represents history values of allele frequencies collections.")]
+  [StorableClass]
+  public class AlleleFrequencyCollectionHistory : ItemCollection<AlleleFrequencyCollection> {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Cab; }
+    }
+
+    [StorableConstructor]
+    protected AlleleFrequencyCollectionHistory(bool deserializing) : base(deserializing) { }
+    protected AlleleFrequencyCollectionHistory(AlleleFrequencyCollectionHistory original, Cloner cloner) : base(original, cloner) { }
+    public AlleleFrequencyCollectionHistory() : base() { }
+    public AlleleFrequencyCollectionHistory(IEnumerable<AlleleFrequencyCollection> collections) : base(new ItemCollection<AlleleFrequencyCollection>(collections)) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new AlleleFrequencyCollectionHistory(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/BestScopeSolutionAnalyzer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/BestScopeSolutionAnalyzer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/BestScopeSolutionAnalyzer.cs	(revision 12764)
@@ -0,0 +1,147 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// An operator that extracts (clones) the scope containing the best quality.
+  /// </summary>
+  [Item("BestScopeSolutionAnalyzer", "An operator that extracts the scope containing the best quality.")]
+  [StorableClass]
+  public class BestScopeSolutionAnalyzer : SingleSuccessorOperator, IAnalyzer, ISingleObjectiveOperator {
+
+    public virtual bool EnabledByDefault {
+      get { return true; }
+    }
+    public LookupParameter<BoolValue> MaximizationParameter {
+      get { return (LookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public IFixedValueParameter<StringValue> BestSolutionResultNameParameter {
+      get { return (IFixedValueParameter<StringValue>)Parameters["BestSolution ResultName"]; }
+    }
+    public ILookupParameter<DoubleValue> BestKnownQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
+    }
+    public IValueLookupParameter<ResultCollection> ResultsParameter {
+      get { return (IValueLookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+
+    public string BestSolutionResultName {
+      get { return BestSolutionResultNameParameter.Value.Value; }
+      set { BestSolutionResultNameParameter.Value.Value = value; }
+    }
+
+    #region Storing & Cloning
+    [StorableConstructor]
+    protected BestScopeSolutionAnalyzer(bool deserializing) : base(deserializing) { }
+    protected BestScopeSolutionAnalyzer(BestScopeSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BestScopeSolutionAnalyzer(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code, remove with 3.4
+      if (!Parameters.ContainsKey("BestSolution ResultName"))
+        Parameters.Add(new FixedValueParameter<StringValue>("BestSolution ResultName", "The name of the result for storing the best solution.", new StringValue("Best Solution")));
+      if (Parameters.ContainsKey("BestSolution")) Parameters.Remove("BestSolution");
+      if (Parameters.ContainsKey("BestKnownSolution")) Parameters.Remove("BestKnownSolution");
+      #endregion
+    }
+    #endregion
+    public BestScopeSolutionAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The qualities of the solutions."));
+      Parameters.Add(new FixedValueParameter<StringValue>("BestSolution ResultName", "The name of the result for storing the best solution.", new StringValue("Best Solution")));
+      Parameters.Add(new LookupParameter<DoubleValue>("BestKnownQuality", "The quality of the best known solution."));
+      Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The result collection where the solution should be stored."));
+    }
+
+    public override IOperation Apply() {
+      ItemArray<DoubleValue> qualities = QualityParameter.ActualValue;
+      ResultCollection results = ResultsParameter.ActualValue;
+      bool max = MaximizationParameter.ActualValue.Value;
+      DoubleValue bestKnownQuality = BestKnownQualityParameter.ActualValue;
+
+      if (results.ContainsKey(BestSolutionResultName) && !typeof(IScope).IsAssignableFrom(results[BestSolutionResultName].DataType)) {
+        throw new InvalidOperationException(string.Format("Could not add best solution result, because there is already a result with the name \"{0}\" present in the result collection.", BestSolutionResultName));
+      }
+
+      int i = -1;
+      if (!max)
+        i = qualities.Select((x, index) => new { index, x.Value }).OrderBy(x => x.Value).First().index;
+      else i = qualities.Select((x, index) => new { index, x.Value }).OrderByDescending(x => x.Value).First().index;
+
+      IEnumerable<IScope> scopes = new IScope[] { ExecutionContext.Scope };
+      for (int j = 0; j < QualityParameter.Depth; j++)
+        scopes = scopes.SelectMany(x => x.SubScopes);
+      IScope currentBestScope = scopes.ToList()[i];
+
+      if (bestKnownQuality == null ||
+          max && qualities[i].Value > bestKnownQuality.Value
+          || !max && qualities[i].Value < bestKnownQuality.Value) {
+        BestKnownQualityParameter.ActualValue = new DoubleValue(qualities[i].Value);
+      }
+
+      if (!results.ContainsKey(BestSolutionResultName)) {
+        var cloner = new Cloner();
+        //avoid cloning of subscopes and the results collection that the solution is put in
+        cloner.RegisterClonedObject(results, new ResultCollection());
+        cloner.RegisterClonedObject(currentBestScope.SubScopes, new ScopeList());
+        var solution = cloner.Clone(currentBestScope);
+
+        results.Add(new Result(BestSolutionResultName, solution));
+      } else {
+        var bestSolution = (IScope)results[BestSolutionResultName].Value;
+        string qualityName = QualityParameter.TranslatedName;
+        if (bestSolution.Variables.ContainsKey(qualityName)) {
+          double bestQuality = ((DoubleValue)bestSolution.Variables[qualityName].Value).Value;
+          if (max && qualities[i].Value > bestQuality
+              || !max && qualities[i].Value < bestQuality) {
+            var cloner = new Cloner();
+            //avoid cloning of subscopes and the results collection that the solution is put in
+            cloner.RegisterClonedObject(results, new ResultCollection());
+            cloner.RegisterClonedObject(currentBestScope.SubScopes, new ScopeList());
+            var solution = cloner.Clone(currentBestScope);
+
+            results[BestSolutionResultName].Value = solution;
+          }
+        }
+      }
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/DataRow.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/DataRow.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/DataRow.cs	(revision 12764)
@@ -0,0 +1,124 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// A row of data values.
+  /// </summary>
+  [Item("DataRow", "A row of data values.")]
+  [StorableClass]
+  public class DataRow : 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<double> values;
+    public ObservableList<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<double> StorableValues {
+      get { return values; }
+      set { values = new ObservableList<double>(value); }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected DataRow(bool deserializing) : base(deserializing) { }
+    protected DataRow(DataRow original, Cloner cloner)
+      : base(original, cloner) {
+      this.VisualProperties = (DataRowVisualProperties)cloner.Clone(original.visualProperties);
+      this.values = new ObservableList<double>(original.values);
+    }
+    public DataRow() : this("DataRow") { }
+    public DataRow(string name)
+      : base(name) {
+      if (string.IsNullOrEmpty(name)) throw new ArgumentException("Name of a DataRow cannot be empty", name);
+      VisualProperties = new DataRowVisualProperties(name);
+      values = new ObservableList<double>();
+    }
+    public DataRow(string name, string description)
+      : base(name, description) {
+      if (string.IsNullOrEmpty(name)) throw new ArgumentException("Name of a DataRow cannot be empty", name);
+      VisualProperties = new DataRowVisualProperties(name);
+      values = new ObservableList<double>();
+    }
+    public DataRow(string name, string description, IEnumerable<double> values)
+      : base(name, description) {
+      if (string.IsNullOrEmpty(name)) throw new ArgumentException("Name of a DataRow cannot be empty", name);
+      VisualProperties = new DataRowVisualProperties(name);
+      this.values = new ObservableList<double>(values);
+    }
+
+    // BackwardsCompatibility3.3
+    #region Backwards compatible code, remove with 3.4
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (VisualProperties == null) VisualProperties = new DataRowVisualProperties();
+    }
+    #endregion
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DataRow(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/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/DataRowVisualProperties.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/DataRowVisualProperties.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/DataRowVisualProperties.cs	(revision 12764)
@@ -0,0 +1,308 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// Visual properties of a DataRow.
+  /// </summary>
+  [StorableClass]
+  public class DataRowVisualProperties : DeepCloneable, INotifyPropertyChanged {
+    #region ChartType
+    public enum DataRowChartType {
+      Line,
+      Columns,
+      Points,
+      Bars,
+      Histogram,
+      StepLine
+    }
+    #endregion
+    #region LineStyle
+    public enum DataRowLineStyle {
+      Dash,
+      DashDot,
+      DashDotDot,
+      Dot,
+      NotSet,
+      Solid
+    }
+    #endregion
+
+    private DataRowChartType chartType;
+    public DataRowChartType ChartType {
+      get { return chartType; }
+      set {
+        if (chartType != value) {
+          chartType = value;
+          OnPropertyChanged("ChartType");
+        }
+      }
+    }
+    private bool secondYAxis;
+    public bool SecondYAxis {
+      get { return secondYAxis; }
+      set {
+        if (secondYAxis != value) {
+          secondYAxis = value;
+          OnPropertyChanged("SecondYAxis");
+        }
+      }
+    }
+    private bool secondXAxis;
+    public bool SecondXAxis {
+      get { return secondXAxis; }
+      set {
+        if (secondXAxis != value) {
+          secondXAxis = value;
+          OnPropertyChanged("SecondXAxis");
+        }
+      }
+    }
+    private Color color;
+    public Color Color {
+      get { return color; }
+      set {
+        if (color != value) {
+          color = value;
+          OnPropertyChanged("Color");
+        }
+      }
+    }
+    private DataRowLineStyle lineStyle;
+    public DataRowLineStyle LineStyle {
+      get { return lineStyle; }
+      set {
+        if (lineStyle != value) {
+          lineStyle = value;
+          OnPropertyChanged("LineStyle");
+        }
+      }
+    }
+    private bool startIndexZero;
+    public bool StartIndexZero {
+      get { return startIndexZero; }
+      set {
+        if (startIndexZero != value) {
+          startIndexZero = value;
+          OnPropertyChanged("StartIndexZero");
+        }
+      }
+    }
+    private int lineWidth;
+    public int LineWidth {
+      get { return lineWidth; }
+      set {
+        if (lineWidth != value) {
+          lineWidth = value;
+          OnPropertyChanged("LineWidth");
+        }
+      }
+    }
+    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 {
+      get { return scaleFactor; }
+      set {
+        if (scaleFactor != value) {
+          scaleFactor = value;
+          OnPropertyChanged("ScaleFactor");
+        }
+      }
+    }
+    private bool isVisibleInLegend;
+    public bool IsVisibleInLegend {
+      get { return isVisibleInLegend; }
+      set {
+        if (isVisibleInLegend != value) {
+          isVisibleInLegend = value;
+          OnPropertyChanged("IsVisibleInLegend");
+        }
+      }
+    }
+    private string displayName;
+    public string DisplayName {
+      get { return displayName == null ? String.Empty : displayName; }
+      set {
+        if (displayName != value) {
+          if (value == null && displayName != String.Empty) {
+            displayName = String.Empty;
+            OnPropertyChanged("DisplayName");
+          } else if (value != null) {
+            displayName = value;
+            OnPropertyChanged("DisplayName");
+          }
+        }
+      }
+    }
+
+    #region Persistence Properties
+    [Storable(Name = "ChartType")]
+    private DataRowChartType StorableChartType {
+      get { return chartType; }
+      set { chartType = value; }
+    }
+    [Storable(Name = "SecondYAxis")]
+    private bool StorableSecondYAxis {
+      get { return secondYAxis; }
+      set { secondYAxis = value; }
+    }
+    [Storable(Name = "SecondXAxis")]
+    private bool StorableSecondXAxis {
+      get { return secondXAxis; }
+      set { secondXAxis = value; }
+    }
+    [Storable(Name = "Color")]
+    private Color StorableColor {
+      get { return color; }
+      set { color = value; }
+    }
+    [Storable(Name = "LineStyle")]
+    private DataRowLineStyle StorableLineStyle {
+      get { return lineStyle; }
+      set { lineStyle = value; }
+    }
+    [Storable(Name = "StartIndexZero")]
+    private bool StorableStartIndexZero {
+      get { return startIndexZero; }
+      set { startIndexZero = value; }
+    }
+    [Storable(Name = "LineWidth")]
+    private int StorableLineWidth {
+      get { return lineWidth; }
+      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 {
+      get { return scaleFactor; }
+      set { scaleFactor = value; }
+    }
+    [Storable(Name = "IsVisibleInLegend", DefaultValue = true)]
+    private bool StorableIsVisibleInLegend {
+      get { return isVisibleInLegend; }
+      set { isVisibleInLegend = value; }
+    }
+    [Storable(Name = "DisplayName")]
+    private string StorableDisplayName {
+      get { return displayName; }
+      set { displayName = value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected DataRowVisualProperties(bool deserializing) : base() { }
+    protected DataRowVisualProperties(DataRowVisualProperties original, Cloner cloner)
+      : base(original, cloner) {
+      this.chartType = original.chartType;
+      this.secondYAxis = original.secondYAxis;
+      this.secondXAxis = original.secondXAxis;
+      this.color = original.color;
+      this.lineStyle = original.lineStyle;
+      this.startIndexZero = original.startIndexZero;
+      this.lineWidth = original.lineWidth;
+      this.bins = original.bins;
+      this.exactBins = original.exactBins;
+      this.scaleFactor = original.scaleFactor;
+      this.displayName = original.displayName;
+      this.isVisibleInLegend = original.isVisibleInLegend;
+    }
+    public DataRowVisualProperties() {
+      chartType = DataRowChartType.Line;
+      secondYAxis = false;
+      secondXAxis = false;
+      color = Color.Empty;
+      lineStyle = DataRowLineStyle.Solid;
+      startIndexZero = false;
+      lineWidth = 1;
+      bins = 10;
+      exactBins = false;
+      scaleFactor = 1.0;
+      displayName = String.Empty;
+      isVisibleInLegend = true;
+    }
+    public DataRowVisualProperties(string displayName)
+      : this() {
+      this.displayName = displayName;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DataRowVisualProperties(this, cloner);
+    }
+
+    public event PropertyChangedEventHandler PropertyChanged;
+    protected virtual void OnPropertyChanged(string propertyName) {
+      PropertyChangedEventHandler handler = PropertyChanged;
+      if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code, remove with 3.4
+      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;
+      }
+      #endregion
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/DataTable.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/DataTable.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/DataTable.cs	(revision 12764)
@@ -0,0 +1,287 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.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 {
+  /// <summary>
+  /// A table of data values.
+  /// </summary>
+  [Item("DataTable", "A table of data values.")]
+  [StorableClass]
+  public class DataTable : 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<DataRow> rows;
+    public NamedItemCollection<DataRow> 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<DataRow> StorableRows {
+      get { return rows; }
+      set { Rows = new NamedItemCollection<DataRow>(value); }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected DataTable(bool deserializing) : base(deserializing) { }
+    protected DataTable(DataTable original, Cloner cloner)
+      : base(original, cloner) {
+      VisualProperties = (DataTableVisualProperties)cloner.Clone(original.visualProperties);
+      Rows = cloner.Clone(original.rows);
+    }
+    public DataTable()
+      : base() {
+      Name = "DataTable";
+      VisualProperties = new DataTableVisualProperties();
+      Rows = new NamedItemCollection<DataRow>();
+    }
+    public DataTable(string name)
+      : base(name) {
+      VisualProperties = new DataTableVisualProperties(name);
+      Rows = new NamedItemCollection<DataRow>();
+    }
+    public DataTable(string name, string description)
+      : base(name, description) {
+      VisualProperties = new DataTableVisualProperties(name);
+      Rows = new NamedItemCollection<DataRow>();
+    }
+
+    // BackwardsCompatibility3.3
+    #region Backwards compatible code, remove with 3.4
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (VisualProperties == null) VisualProperties = new DataTableVisualProperties(name);
+      if (VisualProperties.Title == null) VisualProperties.Title = name;
+    }
+    #endregion
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DataTable(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 virtual void RegisterRowsEvents() {
+      rows.ItemsAdded += new CollectionItemsChangedEventHandler<DataRow>(rows_ItemsAdded);
+      rows.ItemsRemoved += new CollectionItemsChangedEventHandler<DataRow>(rows_ItemsRemoved);
+      rows.ItemsReplaced += new CollectionItemsChangedEventHandler<DataRow>(rows_ItemsReplaced);
+      rows.CollectionReset += new CollectionItemsChangedEventHandler<DataRow>(rows_CollectionReset);
+    }
+    private void rows_ItemsAdded(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
+      foreach (DataRow row in e.Items)
+        this.RegisterRowEvents(row);
+
+      this.OnColumnsChanged();
+      this.OnColumnNamesChanged();
+      this.OnReset();
+    }
+    private void rows_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
+      foreach (DataRow row in e.Items)
+        this.DeregisterRowEvents(row);
+
+      this.OnColumnsChanged();
+      this.OnColumnNamesChanged();
+      this.OnReset();
+    }
+    private void rows_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
+      foreach (DataRow row in e.OldItems)
+        this.DeregisterRowEvents(row);
+      foreach (DataRow row in e.Items)
+        this.RegisterRowEvents(row);
+
+      this.OnColumnsChanged();
+      this.OnColumnNamesChanged();
+      this.OnReset();
+    }
+    private void rows_CollectionReset(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
+      foreach (DataRow row in e.OldItems)
+        this.DeregisterRowEvents(row);
+      foreach (DataRow row in e.Items)
+        this.RegisterRowEvents(row);
+
+      if (e.OldItems.Count() != e.Items.Count())
+        this.OnColumnsChanged();
+      this.OnColumnNamesChanged();
+      this.OnReset();
+    }
+
+    protected virtual void RegisterRowEvents(DataRow row) {
+      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);
+    }
+    protected virtual void DeregisterRowEvents(DataRow row) {
+      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);
+    }
+
+    private void Values_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
+      this.OnReset();
+    }
+    private void Values_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
+      this.OnReset();
+    }
+    private void Values_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
+      this.OnReset();
+    }
+    private void Values_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
+      this.OnReset();
+    }
+    private void Values_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<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; }
+      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) && rowIndex < rows[columnName].Values.Count)
+          return rows[columnName].Values[rowIndex].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/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/DataTableHistory.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/DataTableHistory.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/DataTableHistory.cs	(revision 12764)
@@ -0,0 +1,49 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// Represents history values of data tables.
+  /// </summary>
+  [Item("DataTableHistory", "Represents history values of data tables.")]
+  [StorableClass]
+  public class DataTableHistory : ItemCollection<DataTable> {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Cab; }
+    }
+
+    [StorableConstructor]
+    protected DataTableHistory(bool deserializing) : base(deserializing) { }
+    protected DataTableHistory(DataTableHistory original, Cloner cloner) : base(original, cloner) { }
+    public DataTableHistory() : base() { }
+    public DataTableHistory(IEnumerable<DataTable> collection) : base(new ItemCollection<DataTable>(collection)) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DataTableHistory(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/DataTableValuesCollector.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/DataTableValuesCollector.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/DataTableValuesCollector.cs	(revision 12764)
@@ -0,0 +1,135 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// An operator which collects the actual values of parameters and adds them to a table of data values.
+  /// </summary>
+  [Item("DataTableValuesCollector", "An operator which collects the actual values of parameters and adds them to a table of data values.")]
+  [StorableClass]
+  public class DataTableValuesCollector : ValuesCollector {
+    public ValueLookupParameter<DataTable> DataTableParameter {
+      get { return (ValueLookupParameter<DataTable>)Parameters["DataTable"]; }
+    }
+    private IFixedValueParameter<BoolValue> StartIndexZeroParameter {
+      get { return (FixedValueParameter<BoolValue>)Parameters["StartIndexZero"]; }
+    }
+
+    public bool StartIndexZero {
+      get { return StartIndexZeroParameter.Value.Value; }
+      set { StartIndexZeroParameter.Value.Value = value; }
+    }
+
+    #region Storing & Cloning
+    [StorableConstructor]
+    protected DataTableValuesCollector(bool deserializing) : base(deserializing) { }
+    protected DataTableValuesCollector(DataTableValuesCollector original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DataTableValuesCollector(this, cloner);
+    }
+    #endregion
+    public DataTableValuesCollector()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<DataTable>("DataTable", "The table of data values where the collected values should be stored."));
+      Parameters.Add(new FixedValueParameter<BoolValue>("StartIndexZero", "True, if the collected data values should start with index 0, otherwise false.", new BoolValue(true), false));
+      StartIndexZeroParameter.Hidden = true;
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code (remove with 3.4)
+      if (!Parameters.ContainsKey("StartIndexZero")) {
+        Parameters.Add(new FixedValueParameter<BoolValue>("StartIndexZero", "True, if the collected data values should start with index 0, otherwise false.", new BoolValue(true), false));
+        StartIndexZeroParameter.Hidden = true;
+      }
+      #endregion
+    }
+
+    public override IOperation Apply() {
+      DataTable table = DataTableParameter.ActualValue;
+      if (table == null) {
+        table = new DataTable(DataTableParameter.ActualName);
+        DataTableParameter.ActualValue = table;
+      }
+
+      foreach (IParameter param in CollectedValues) {
+        ILookupParameter lookupParam = param as ILookupParameter;
+        string name = lookupParam != null ? lookupParam.TranslatedName : param.Name;
+
+        if (param.ActualValue is DoubleValue) {
+          AddValue(table, (param.ActualValue as DoubleValue).Value, name, param.Description);
+        } else if (param.ActualValue is IntValue) {
+          AddValue(table, (param.ActualValue as IntValue).Value, name, param.Description);
+        } else if (param.ActualValue is IEnumerable<DoubleValue>) {
+          IEnumerable<DoubleValue> values = (IEnumerable<DoubleValue>)param.ActualValue;
+          if (values.Count() <= 1) {
+            foreach (DoubleValue data in values)
+              AddValue(table, data != null ? data.Value : double.NaN, name, param.Description);
+          } else {
+            int counter = 1;
+            foreach (DoubleValue data in values) {
+              AddValue(table, data != null ? data.Value : double.NaN, name + " " + counter.ToString(), param.Description);
+              counter++;
+            }
+          }
+        } else if (param.ActualValue is IEnumerable<IntValue>) {
+          IEnumerable<IntValue> values = (IEnumerable<IntValue>)param.ActualValue;
+          if (values.Count() <= 1) {
+            foreach (IntValue data in values)
+              AddValue(table, data != null ? data.Value : double.NaN, name, param.Description);
+          } else {
+            int counter = 1;
+            foreach (IntValue data in values) {
+              AddValue(table, data != null ? data.Value : double.NaN, name + " " + counter.ToString(), param.Description);
+              counter++;
+            }
+          }
+        } else {
+          AddValue(table, double.NaN, name, param.Description);
+        }
+      }
+      return base.Apply();
+    }
+
+    private void AddValue(DataTable table, double data, string name, string description) {
+      DataRow row;
+      table.Rows.TryGetValue(name, out row);
+      if (row == null) {
+        row = new DataRow(name, description);
+        row.VisualProperties.StartIndexZero = StartIndexZero;
+        row.Values.Add(data);
+        table.Rows.Add(row);
+      } else {
+        row.Values.Add(data);
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/DataTableVisualProperties.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/DataTableVisualProperties.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/DataTableVisualProperties.cs	(revision 12764)
@@ -0,0 +1,621 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using System.ComponentModel;
+using System.Drawing;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// Visual properties of a DataTable.
+  /// </summary>
+  [StorableClass]
+  public class DataTableVisualProperties : DeepCloneable, INotifyPropertyChanged {
+    private Font titleFont;
+    public Font TitleFont {
+      get { return titleFont; }
+      set {
+        if (titleFont == null || value == null
+          || titleFont.Name != value.Name || titleFont.Size != value.Size || titleFont.Style != value.Style) {
+          titleFont = value;
+          OnPropertyChanged("TitleFont");
+        }
+      }
+    }
+    private Color titleColor;
+    public Color TitleColor {
+      get { return titleColor; }
+      set {
+        if (titleColor != value) {
+          titleColor = value;
+          OnPropertyChanged("TitleFontColor");
+        }
+      }
+    }
+    private string title;
+    public string Title {
+      get { return title; }
+      set {
+        if (title != value) {
+          title = value;
+          OnPropertyChanged("Title");
+        }
+      }
+    }
+    private Font axisTitleFont;
+    public Font AxisTitleFont {
+      get { return axisTitleFont; }
+      set {
+        if (axisTitleFont == null || axisTitleFont == null
+          || axisTitleFont.Name != value.Name || axisTitleFont.Size != value.Size || axisTitleFont.Style != value.Style) {
+          axisTitleFont = value;
+          OnPropertyChanged("AxisTitleFont");
+        }
+      }
+    }
+    private Color axisTitleColor;
+    public Color AxisTitleColor {
+      get { return axisTitleColor; }
+      set {
+        if (axisTitleColor != value) {
+          axisTitleColor = value;
+          OnPropertyChanged("AxisTitleColor");
+        }
+      }
+    }
+    private string xAxisTitle;
+    public string XAxisTitle {
+      get { return xAxisTitle; }
+      set {
+        if (value == null) value = string.Empty;
+        if (xAxisTitle != value) {
+          xAxisTitle = value;
+          OnPropertyChanged("XAxisTitle");
+        }
+      }
+    }
+
+    private string yAxisTitle;
+    public string YAxisTitle {
+      get { return yAxisTitle; }
+      set {
+        if (value == null) value = string.Empty;
+        if (yAxisTitle != value) {
+          yAxisTitle = value;
+          OnPropertyChanged("YAxisTitle");
+        }
+      }
+    }
+
+    private string secondXAxisTitle;
+    public string SecondXAxisTitle {
+      get { return secondXAxisTitle; }
+      set {
+        if (value == null) value = string.Empty;
+        if (secondXAxisTitle != value) {
+          secondXAxisTitle = value;
+          OnPropertyChanged("SecondXAxisTitle");
+        }
+      }
+    }
+
+    private string secondYAxisTitle;
+    public string SecondYAxisTitle {
+      get { return secondYAxisTitle; }
+      set {
+        if (value == null) value = string.Empty;
+        if (secondYAxisTitle != value) {
+          secondYAxisTitle = value;
+          OnPropertyChanged("SecondYAxisTitle");
+        }
+      }
+    }
+
+    private bool xAxisMinimumAuto;
+    public bool XAxisMinimumAuto {
+      get { return xAxisMinimumAuto; }
+      set {
+        if (xAxisMinimumAuto != value) {
+          xAxisMinimumAuto = value;
+          if (value) xAxisMinimumFixedValue = double.NaN;
+          OnPropertyChanged("XAxisMinimumAuto");
+        }
+      }
+    }
+
+    private bool xAxisMaximumAuto;
+    public bool XAxisMaximumAuto {
+      get { return xAxisMaximumAuto; }
+      set {
+        if (xAxisMaximumAuto != value) {
+          xAxisMaximumAuto = value;
+          if (value) xAxisMaximumFixedValue = double.NaN;
+          OnPropertyChanged("XAxisMaximumAuto");
+        }
+      }
+    }
+
+    private double xAxisMinimumFixedValue;
+    public double XAxisMinimumFixedValue {
+      get { return xAxisMinimumFixedValue; }
+      set {
+        if (xAxisMinimumFixedValue != value) {
+          xAxisMinimumFixedValue = value;
+          OnPropertyChanged("XAxisMinimumFixedValue");
+        }
+      }
+    }
+
+    private double xAxisMaximumFixedValue;
+    public double XAxisMaximumFixedValue {
+      get { return xAxisMaximumFixedValue; }
+      set {
+        if (xAxisMaximumFixedValue != value) {
+          xAxisMaximumFixedValue = value;
+          OnPropertyChanged("XAxisMaximumFixedValue");
+        }
+      }
+    }
+
+    private bool secondXAxisMinimumAuto;
+    public bool SecondXAxisMinimumAuto {
+      get { return secondXAxisMinimumAuto; }
+      set {
+        if (secondXAxisMinimumAuto != value) {
+          secondXAxisMinimumAuto = value;
+          if (value) secondXAxisMinimumFixedValue = double.NaN;
+          OnPropertyChanged("SecondXAxisMinimumAuto");
+        }
+      }
+    }
+
+    private bool secondXAxisMaximumAuto;
+    public bool SecondXAxisMaximumAuto {
+      get { return secondXAxisMaximumAuto; }
+      set {
+        if (secondXAxisMaximumAuto != value) {
+          secondXAxisMaximumAuto = value;
+          if (value) secondXAxisMaximumFixedValue = double.NaN;
+          OnPropertyChanged("SecondXAxisMaximumAuto");
+        }
+      }
+    }
+
+    private double secondXAxisMinimumFixedValue;
+    public double SecondXAxisMinimumFixedValue {
+      get { return secondXAxisMinimumFixedValue; }
+      set {
+        if (secondXAxisMinimumFixedValue != value) {
+          secondXAxisMinimumFixedValue = value;
+          OnPropertyChanged("SecondXAxisMinimumFixedValue");
+        }
+      }
+    }
+
+    private double secondXAxisMaximumFixedValue;
+    public double SecondXAxisMaximumFixedValue {
+      get { return secondXAxisMaximumFixedValue; }
+      set {
+        if (secondXAxisMaximumFixedValue != value) {
+          secondXAxisMaximumFixedValue = value;
+          OnPropertyChanged("SecondXAxisMaximumFixedValue");
+        }
+      }
+    }
+
+    private bool yAxisMinimumAuto;
+    public bool YAxisMinimumAuto {
+      get { return yAxisMinimumAuto; }
+      set {
+        if (yAxisMinimumAuto != value) {
+          yAxisMinimumAuto = value;
+          if (value) yAxisMinimumFixedValue = double.NaN;
+          OnPropertyChanged("YAxisMinimumAuto");
+        }
+      }
+    }
+
+    private bool yAxisMaximumAuto;
+    public bool YAxisMaximumAuto {
+      get { return yAxisMaximumAuto; }
+      set {
+        if (yAxisMaximumAuto != value) {
+          yAxisMaximumAuto = value;
+          if (value) yAxisMaximumFixedValue = double.NaN;
+          OnPropertyChanged("YAxisMaximumAuto");
+        }
+      }
+    }
+
+    private double yAxisMinimumFixedValue;
+    public double YAxisMinimumFixedValue {
+      get { return yAxisMinimumFixedValue; }
+      set {
+        if (yAxisMinimumFixedValue != value) {
+          yAxisMinimumFixedValue = value;
+          OnPropertyChanged("YAxisMinimumFixedValue");
+        }
+      }
+    }
+
+    private double yAxisMaximumFixedValue;
+    public double YAxisMaximumFixedValue {
+      get { return yAxisMaximumFixedValue; }
+      set {
+        if (yAxisMaximumFixedValue != value) {
+          yAxisMaximumFixedValue = value;
+          OnPropertyChanged("YAxisMaximumFixedValue");
+        }
+      }
+    }
+
+    private bool secondYAxisMinimumAuto;
+    public bool SecondYAxisMinimumAuto {
+      get { return secondYAxisMinimumAuto; }
+      set {
+        if (secondYAxisMinimumAuto != value) {
+          secondYAxisMinimumAuto = value;
+          if (value) secondYAxisMinimumFixedValue = double.NaN;
+          OnPropertyChanged("SecondYAxisMinimumAuto");
+        }
+      }
+    }
+
+    private bool secondYAxisMaximumAuto;
+    public bool SecondYAxisMaximumAuto {
+      get { return secondYAxisMaximumAuto; }
+      set {
+        if (secondYAxisMaximumAuto != value) {
+          secondYAxisMaximumAuto = value;
+          if (value) secondYAxisMaximumFixedValue = double.NaN;
+          OnPropertyChanged("SecondYAxisMaximumAuto");
+        }
+      }
+    }
+
+    private double secondYAxisMinimumFixedValue;
+    public double SecondYAxisMinimumFixedValue {
+      get { return secondYAxisMinimumFixedValue; }
+      set {
+        if (secondYAxisMinimumFixedValue != value) {
+          secondYAxisMinimumFixedValue = value;
+          OnPropertyChanged("SecondYAxisMinimumFixedValue");
+        }
+      }
+    }
+
+    private double secondYAxisMaximumFixedValue;
+    public double SecondYAxisMaximumFixedValue {
+      get { return secondYAxisMaximumFixedValue; }
+      set {
+        if (secondYAxisMaximumFixedValue != value) {
+          secondYAxisMaximumFixedValue = value;
+          OnPropertyChanged("SecondYAxisMaximumFixedValue");
+        }
+      }
+    }
+
+    private bool xAxisLogScale;
+    public bool XAxisLogScale {
+      get { return xAxisLogScale; }
+      set {
+        if (xAxisLogScale == value) return;
+        xAxisLogScale = value;
+        OnPropertyChanged("XAxisLogScale");
+      }
+    }
+
+    private bool secondXAxisLogScale;
+    public bool SecondXAxisLogScale {
+      get { return secondXAxisLogScale; }
+      set {
+        if (secondXAxisLogScale == value) return;
+        secondXAxisLogScale = value;
+        OnPropertyChanged("SecondXAxisLogScale");
+      }
+    }
+
+    private bool yAxisLogScale;
+    public bool YAxisLogScale {
+      get { return yAxisLogScale; }
+      set {
+        if (yAxisLogScale == value) return;
+        yAxisLogScale = value;
+        OnPropertyChanged("YAxisLogScale");
+      }
+    }
+
+    private bool secondYAxisLogScale;
+    public bool SecondYAxisLogScale {
+      get { return secondYAxisLogScale; }
+      set {
+        if (secondYAxisLogScale == value) return;
+        secondYAxisLogScale = value;
+        OnPropertyChanged("SecondYAxisLogScale");
+      }
+    }
+
+    #region Persistence Properties
+    [Storable(Name = "TitleFont")]
+    private Font StorableTitleFont {
+      get { return titleFont; }
+      set { titleFont = value; }
+    }
+    [Storable(Name = "TitleColor")]
+    private Color StorableTitleColor {
+      get { return titleColor; }
+      set { titleColor = value; }
+    }
+    [Storable(Name = "Title")]
+    private string StorableTitle {
+      get { return title; }
+      set { title = value; }
+    }
+    [Storable(Name = "AxisTitleFont")]
+    private Font StorableAxisTitleFont {
+      get { return axisTitleFont; }
+      set { axisTitleFont = value; }
+    }
+    [Storable(Name = "AxisTitleColor")]
+    private Color StorableAxisTitleColor {
+      get { return axisTitleColor; }
+      set { axisTitleColor = value; }
+    }
+    [Storable(Name = "XAxisTitle")]
+    private string StorableXAxisTitle {
+      get { return xAxisTitle; }
+      set { xAxisTitle = value; }
+    }
+    [Storable(Name = "YAxisTitle")]
+    private string StorableYAxisTitle {
+      get { return yAxisTitle; }
+      set { yAxisTitle = value; }
+    }
+    [Storable(Name = "SecondXAxisTitle")]
+    private string StorableSecondXAxisTitle {
+      get { return secondXAxisTitle; }
+      set { secondXAxisTitle = value; }
+    }
+    [Storable(Name = "SecondYAxisTitle")]
+    private string StorableSecondYAxisTitle {
+      get { return secondYAxisTitle; }
+      set { secondYAxisTitle = value; }
+    }
+    [Storable(Name = "XAxisMinimumAuto")]
+    private bool StorableXAxisMinimumAuto {
+      get { return xAxisMinimumAuto; }
+      set { xAxisMinimumAuto = value; }
+    }
+    [Storable(Name = "XAxisMaximumAuto")]
+    private bool StorableXAxisMaximumAuto {
+      get { return xAxisMaximumAuto; }
+      set { xAxisMaximumAuto = value; }
+    }
+    [Storable(Name = "XAxisMinimumFixedValue")]
+    private double StorableXAxisMinimumFixedValue {
+      get { return xAxisMinimumFixedValue; }
+      set { xAxisMinimumFixedValue = value; }
+    }
+    [Storable(Name = "XAxisMaximumFixedValue")]
+    private double StorableXAxisMaximumFixedValue {
+      get { return xAxisMaximumFixedValue; }
+      set { xAxisMaximumFixedValue = value; }
+    }
+    [Storable(Name = "SecondXAxisMinimumAuto")]
+    private bool StorableSecondXAxisMinimumAuto {
+      get { return secondXAxisMinimumAuto; }
+      set { secondXAxisMinimumAuto = value; }
+    }
+    [Storable(Name = "SecondXAxisMaximumAuto")]
+    private bool StorableSecondXAxisMaximumAuto {
+      get { return secondXAxisMaximumAuto; }
+      set { secondXAxisMaximumAuto = value; }
+    }
+    [Storable(Name = "SecondXAxisMinimumFixedValue")]
+    private double StorableSecondXAxisMinimumFixedValue {
+      get { return secondXAxisMinimumFixedValue; }
+      set { secondXAxisMinimumFixedValue = value; }
+    }
+    [Storable(Name = "SecondXAxisMaximumFixedValue")]
+    private double StorableSecondXAxisMaximumFixedValue {
+      get { return secondXAxisMaximumFixedValue; }
+      set { secondXAxisMaximumFixedValue = value; }
+    }
+    [Storable(Name = "YAxisMinimumAuto")]
+    private bool StorableYAxisMinimumAuto {
+      get { return yAxisMinimumAuto; }
+      set { yAxisMinimumAuto = value; }
+    }
+    [Storable(Name = "YAxisMaximumAuto")]
+    private bool StorableYAxisMaximumAuto {
+      get { return yAxisMaximumAuto; }
+      set { yAxisMaximumAuto = value; }
+    }
+    [Storable(Name = "YAxisMinimumFixedValue")]
+    private double StorableYAxisMinimumFixedValue {
+      get { return yAxisMinimumFixedValue; }
+      set { yAxisMinimumFixedValue = value; }
+    }
+    [Storable(Name = "YAxisMaximumFixedValue")]
+    private double StorableYAxisMaximumFixedValue {
+      get { return yAxisMaximumFixedValue; }
+      set { yAxisMaximumFixedValue = value; }
+    }
+    [Storable(Name = "SecondYAxisMinimumAuto")]
+    private bool StorableSecondYAxisMinimumAuto {
+      get { return secondYAxisMinimumAuto; }
+      set { secondYAxisMinimumAuto = value; }
+    }
+    [Storable(Name = "SecondYAxisMaximumAuto")]
+    private bool StorableSecondYAxisMaximumAuto {
+      get { return secondYAxisMaximumAuto; }
+      set { secondYAxisMaximumAuto = value; }
+    }
+    [Storable(Name = "SecondYAxisMinimumFixedValue")]
+    private double StorableSecondYAxisMinimumFixedValue {
+      get { return secondYAxisMinimumFixedValue; }
+      set { secondYAxisMinimumFixedValue = value; }
+    }
+    [Storable(Name = "SecondYAxisMaximumFixedValue")]
+    private double StorableSecondYAxisMaximumFixedValue {
+      get { return secondYAxisMaximumFixedValue; }
+      set { secondYAxisMaximumFixedValue = value; }
+    }
+    [Storable(Name = "XAxisLogScale")]
+    private bool StorableXAxisLogScale {
+      get { return xAxisLogScale; }
+      set { xAxisLogScale = value; }
+    }
+    [Storable(Name = "SecondXAxisLogScale")]
+    private bool StorableSecondXAxisLogScale {
+      get { return secondXAxisLogScale; }
+      set { secondXAxisLogScale = value; }
+    }
+    [Storable(Name = "YAxisLogScale")]
+    private bool StorableYAxisLogScale {
+      get { return yAxisLogScale; }
+      set { yAxisLogScale = value; }
+    }
+    [Storable(Name = "SecondYAxisLogScale")]
+    private bool StorableSecondYAxisLogScale {
+      get { return secondYAxisLogScale; }
+      set { secondYAxisLogScale = value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected DataTableVisualProperties(bool deserializing) : base() { }
+    protected DataTableVisualProperties(DataTableVisualProperties original, Cloner cloner)
+      : base(original, cloner) {
+      if (original.titleFont != null)
+        this.titleFont = (Font)original.titleFont.Clone();
+      if (original.axisTitleFont != null)
+        this.axisTitleFont = (Font)original.axisTitleFont.Clone();
+      this.title = original.title;
+      this.xAxisTitle = original.xAxisTitle;
+      this.yAxisTitle = original.yAxisTitle;
+      this.secondXAxisTitle = original.secondXAxisTitle;
+      this.secondYAxisTitle = original.secondYAxisTitle;
+      this.xAxisMinimumAuto = original.xAxisMinimumAuto;
+      this.xAxisMinimumFixedValue = original.xAxisMinimumFixedValue;
+      this.xAxisMaximumAuto = original.xAxisMaximumAuto;
+      this.xAxisMaximumFixedValue = original.xAxisMaximumFixedValue;
+      this.secondXAxisMinimumAuto = original.secondXAxisMinimumAuto;
+      this.secondXAxisMinimumFixedValue = original.secondXAxisMinimumFixedValue;
+      this.secondXAxisMaximumAuto = original.secondXAxisMaximumAuto;
+      this.secondXAxisMaximumFixedValue = original.secondXAxisMaximumFixedValue;
+      this.yAxisMinimumAuto = original.yAxisMinimumAuto;
+      this.yAxisMinimumFixedValue = original.yAxisMinimumFixedValue;
+      this.yAxisMaximumAuto = original.yAxisMaximumAuto;
+      this.yAxisMaximumFixedValue = original.yAxisMaximumFixedValue;
+      this.secondYAxisMinimumAuto = original.secondYAxisMinimumAuto;
+      this.secondYAxisMinimumFixedValue = original.secondYAxisMinimumFixedValue;
+      this.secondYAxisMaximumAuto = original.secondYAxisMaximumAuto;
+      this.secondYAxisMaximumFixedValue = original.secondYAxisMaximumFixedValue;
+      this.xAxisLogScale = original.xAxisLogScale;
+      this.secondXAxisLogScale = original.secondXAxisLogScale;
+      this.yAxisLogScale = original.yAxisLogScale;
+      this.secondYAxisLogScale = original.secondYAxisLogScale;
+    }
+    public DataTableVisualProperties() {
+      this.titleColor = Color.Black;
+      this.axisTitleColor = Color.Black;
+      this.title = string.Empty;
+      this.xAxisTitle = string.Empty;
+      this.yAxisTitle = string.Empty;
+      this.secondXAxisTitle = string.Empty;
+      this.secondYAxisTitle = string.Empty;
+      this.xAxisMinimumAuto = true;
+      this.xAxisMinimumFixedValue = double.NaN;
+      this.xAxisMaximumAuto = true;
+      this.xAxisMaximumFixedValue = double.NaN;
+      this.secondXAxisMinimumAuto = true;
+      this.secondXAxisMinimumFixedValue = double.NaN;
+      this.secondXAxisMaximumAuto = true;
+      this.secondXAxisMaximumFixedValue = double.NaN;
+      this.yAxisMinimumAuto = true;
+      this.yAxisMinimumFixedValue = double.NaN;
+      this.yAxisMaximumAuto = true;
+      this.yAxisMaximumFixedValue = double.NaN;
+      this.secondYAxisMinimumAuto = true;
+      this.secondYAxisMinimumFixedValue = double.NaN;
+      this.secondYAxisMaximumAuto = true;
+      this.secondYAxisMaximumFixedValue = double.NaN;
+      this.xAxisLogScale = false;
+      this.secondXAxisLogScale = false;
+      this.yAxisLogScale = false;
+      this.secondYAxisLogScale = false;
+    }
+    public DataTableVisualProperties(string title)
+      : this() {
+      this.title = title;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DataTableVisualProperties(this, cloner);
+    }
+
+    public event PropertyChangedEventHandler PropertyChanged;
+    protected virtual void OnPropertyChanged(string propertyName) {
+      var handler = PropertyChanged;
+      if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code, remove with 3.4
+      // check if most of the properties that were added in Mai'11 were set to their default values, then we want to reset them to our default values
+      if (xAxisMinimumAuto == default(bool) && xAxisMaximumAuto == default(bool)
+        && yAxisMinimumAuto == default(bool) && yAxisMaximumAuto == default(bool)
+        && secondXAxisMinimumAuto == default(bool) && secondXAxisMaximumAuto == default(bool)
+        && secondYAxisMinimumAuto == default(bool) && secondYAxisMaximumAuto == default(bool)
+        && titleColor == default(Color) && axisTitleColor == default(Color)
+        && secondXAxisTitle == default(string)
+        && xAxisMinimumFixedValue == default(double) && xAxisMaximumFixedValue == default(double)
+        && yAxisMinimumFixedValue == default(double) && yAxisMaximumFixedValue == default(double)
+        && secondXAxisMinimumFixedValue == default(double) && secondXAxisMaximumFixedValue == default(double)
+        && secondYAxisMinimumFixedValue == default(double) && secondYAxisMaximumFixedValue == default(double)) {
+        titleColor = Color.Black;
+        axisTitleColor = Color.Black;
+        this.secondXAxisTitle = string.Empty;
+        this.xAxisMinimumAuto = true;
+        this.xAxisMinimumFixedValue = double.NaN;
+        this.xAxisMaximumAuto = true;
+        this.xAxisMaximumFixedValue = double.NaN;
+        this.secondXAxisMinimumAuto = true;
+        this.secondXAxisMinimumFixedValue = double.NaN;
+        this.secondXAxisMaximumAuto = true;
+        this.secondXAxisMaximumFixedValue = double.NaN;
+        this.yAxisMinimumAuto = true;
+        this.yAxisMinimumFixedValue = double.NaN;
+        this.yAxisMaximumAuto = true;
+        this.yAxisMaximumFixedValue = double.NaN;
+        this.secondYAxisMinimumAuto = true;
+        this.secondYAxisMinimumFixedValue = double.NaN;
+        this.secondYAxisMaximumAuto = true;
+        this.secondYAxisMaximumFixedValue = double.NaN;
+      }
+      #endregion
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/HeatMap.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/HeatMap.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/HeatMap.cs	(revision 12764)
@@ -0,0 +1,159 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  [Item("HeatMap", "Represents a heat map of double values.")]
+  [StorableClass]
+  public class HeatMap : DoubleMatrix {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Gradient; }
+    }
+
+    private string title;
+    public string Title {
+      get { return title; }
+      set {
+        if (value == null) value = string.Empty;
+        if (title != value) {
+          title = value;
+          OnTitleChanged();
+        }
+      }
+    }
+    private double minimum;
+    public double Minimum {
+      get { return minimum; }
+      set {
+        if (minimum != value) {
+          minimum = value;
+          if (minimum >= maximum) Maximum = minimum + 1.0;
+          OnMinimumChanged();
+        }
+      }
+    }
+    private double maximum;
+    public double Maximum {
+      get { return maximum; }
+      set {
+        if (maximum != value) {
+          maximum = value;
+          if (maximum <= minimum) Minimum = maximum - 1.0;
+          OnMaximumChanged();
+        }
+      }
+    }
+
+    #region Storable Properties
+    [Storable(Name = "Title")]
+    private string StorableTitle {
+      get { return title; }
+      set { title = value; }
+    }
+    [Storable(Name = "Minimum")]
+    private double StorableMinimum {
+      get { return minimum; }
+      set { minimum = value; }
+    }
+    [Storable(Name = "Maximum")]
+    private double StorableMaximum {
+      get { return maximum; }
+      set { maximum = value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected HeatMap(bool deserializing) : base(deserializing) { }
+    protected HeatMap(HeatMap original, Cloner cloner)
+      : base(original, cloner) {
+      this.title = original.title;
+      this.minimum = original.minimum;
+      this.maximum = original.maximum;
+    }
+    public HeatMap()
+      : base() {
+      this.title = "Heat Map";
+      this.minimum = 0.0;
+      this.maximum = 1.0;
+    }
+    public HeatMap(int rows, int columns)
+      : base(rows, columns) {
+      this.title = "Heat Map";
+      this.minimum = 0.0;
+      this.maximum = 1.0;
+    }
+    public HeatMap(int rows, int columns, string title)
+      : base(rows, columns) {
+      this.title = title == null ? string.Empty : title;
+      this.minimum = 0.0;
+      this.maximum = 1.0;
+    }
+    public HeatMap(double[,] elements)
+      : base(elements) {
+      this.title = "Heat Map";
+      this.minimum = 0.0;
+      this.maximum = 1.0;
+    }
+    public HeatMap(double[,] elements, string title)
+      : base(elements) {
+      this.title = title == null ? string.Empty : title;
+      this.minimum = 0.0;
+      this.maximum = 1.0;
+    }
+    public HeatMap(double[,] elements, string title, double minimum, double maximum)
+      : base(elements) {
+      this.title = title == null ? string.Empty : title;
+      if (minimum >= maximum) throw new ArgumentException("Minimum is larger than or equal to maximum");
+      this.minimum = minimum;
+      this.maximum = maximum;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new HeatMap(this, cloner);
+    }
+
+    public override string ToString() {
+      return Title;
+    }
+
+    public event EventHandler TitleChanged;
+    protected virtual void OnTitleChanged() {
+      var handler = TitleChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler MinimumChanged;
+    protected virtual void OnMinimumChanged() {
+      var handler = MinimumChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler MaximumChanged;
+    protected virtual void OnMaximumChanged() {
+      var handler = MaximumChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/HeatMapHistory.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/HeatMapHistory.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/HeatMapHistory.cs	(revision 12764)
@@ -0,0 +1,49 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// Represents history values of heat maps.
+  /// </summary>
+  [Item("HeatMapHistory", "Represents history values of heat maps.")]
+  [StorableClass]
+  public class HeatMapHistory : ItemCollection<HeatMap> {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Cab; }
+    }
+
+    [StorableConstructor]
+    protected HeatMapHistory(bool deserializing) : base(deserializing) { }
+    protected HeatMapHistory(HeatMapHistory original, Cloner cloner) : base(original, cloner) { }
+    public HeatMapHistory() : base() { }
+    public HeatMapHistory(IEnumerable<HeatMap> collection) : base(new ItemCollection<HeatMap>(collection)) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new HeatMapHistory(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/IndexedDataTable.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/IndexedDataTable.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/IndexedDataTable.cs	(revision 12764)
@@ -0,0 +1,278 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.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() {
+      EventHandler handler = VisualPropertiesChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    private void VisualProperties_PropertyChanged(object sender, PropertyChangedEventArgs e) {
+      OnVisualPropertiesChanged();
+    }
+
+    protected virtual void RegisterRowsEvents() {
+      rows.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(rows_ItemsAdded);
+      rows.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(rows_ItemsRemoved);
+      rows.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(rows_ItemsReplaced);
+      rows.CollectionReset += new CollectionItemsChangedEventHandler<IndexedDataRow<T>>(rows_CollectionReset);
+    }
+    private void rows_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedDataRow<T>> e) {
+      foreach (var row in e.Items)
+        this.RegisterRowEvents(row);
+
+      this.OnColumnsChanged();
+      this.OnColumnNamesChanged();
+      this.OnReset();
+    }
+    private void rows_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedDataRow<T>> e) {
+      foreach (var row in e.Items)
+        this.DeregisterRowEvents(row);
+
+      this.OnColumnsChanged();
+      this.OnColumnNamesChanged();
+      this.OnReset();
+    }
+    private void rows_ItemsReplaced(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();
+    }
+    private void rows_CollectionReset(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();
+    }
+
+    protected virtual void RegisterRowEvents(IndexedDataRow<T> row) {
+      row.Values.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_ItemsAdded);
+      row.Values.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_ItemsMoved);
+      row.Values.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_ItemsRemoved);
+      row.Values.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_ItemsReplaced);
+      row.Values.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_CollectionReset);
+    }
+    protected virtual void DeregisterRowEvents(IndexedDataRow<T> row) {
+      row.Values.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_ItemsAdded);
+      row.Values.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_ItemsMoved);
+      row.Values.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_ItemsRemoved);
+      row.Values.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_ItemsReplaced);
+      row.Values.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<Tuple<T, double>>>(Values_CollectionReset);
+    }
+
+    private void Values_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<T, double>>> e) {
+      this.OnReset();
+    }
+    private void Values_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<T, double>>> e) {
+      this.OnReset();
+    }
+    private void Values_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<T, double>>> e) {
+      this.OnReset();
+    }
+    private void Values_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<Tuple<T, double>>> e) {
+      this.OnReset();
+    }
+    private void Values_CollectionReset(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/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlot.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlot.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlot.cs	(revision 12764)
@@ -0,0 +1,304 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.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("ScatterPlot", "A scatter plot of 2D data")]
+  [StorableClass]
+  public class ScatterPlot : NamedItem, IStringConvertibleMatrix {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Performance; }
+    }
+
+    private ScatterPlotVisualProperties visualProperties;
+    public ScatterPlotVisualProperties 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<ScatterPlotDataRow> rows;
+    public NamedItemCollection<ScatterPlotDataRow> 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 ScatterPlotVisualProperties StorableVisualProperties {
+      get { return visualProperties; }
+      set {
+        visualProperties = value;
+        visualProperties.PropertyChanged += new PropertyChangedEventHandler(VisualProperties_PropertyChanged);
+      }
+    }
+    [Storable(Name = "Rows")]
+    private IEnumerable<ScatterPlotDataRow> StorableRows {
+      get { return rows; }
+      set { Rows = new NamedItemCollection<ScatterPlotDataRow>(value); }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected ScatterPlot(bool deserializing) : base(deserializing) { }
+    protected ScatterPlot(ScatterPlot original, Cloner cloner)
+      : base(original, cloner) {
+      VisualProperties = cloner.Clone(original.visualProperties);
+      Rows = cloner.Clone(original.rows);
+    }
+    public ScatterPlot()
+      : base() {
+      this.Name = ItemName;
+      this.Description = ItemDescription;
+      VisualProperties = new ScatterPlotVisualProperties();
+      Rows = new NamedItemCollection<ScatterPlotDataRow>();
+    }
+    public ScatterPlot(string name, string description)
+      : base(name, description) {
+      VisualProperties = new ScatterPlotVisualProperties(name);
+      Rows = new NamedItemCollection<ScatterPlotDataRow>();
+    }
+    public ScatterPlot(string name, string description, ScatterPlotVisualProperties visualProperties)
+      : base(name, description) {
+      VisualProperties = visualProperties;
+      Rows = new NamedItemCollection<ScatterPlotDataRow>();
+    }
+
+    // BackwardsCompatibility3.3
+    #region Backwards compatible code, remove with 3.4
+    private ObservableList<PointF> points;
+    [Storable(Name = "points", AllowOneWay = true)]
+    private ObservableList<PointF> StorablePoints {
+      set { points = value; }
+    }
+    private string xAxisName;
+    [Storable(Name = "xAxisName", AllowOneWay = true)]
+    private string StorableXAxisName {
+      set { xAxisName = value; }
+    }
+    private string yAxisName;
+    [Storable(Name = "yAxisName", AllowOneWay = true)]
+    private string StorableYAxisName {
+      set { yAxisName = value; }
+    }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (VisualProperties == null) VisualProperties = new ScatterPlotVisualProperties(name);
+      if (string.IsNullOrEmpty(VisualProperties.XAxisTitle) && !string.IsNullOrEmpty(xAxisName)) VisualProperties.XAxisTitle = xAxisName;
+      if (string.IsNullOrEmpty(VisualProperties.YAxisTitle) && !string.IsNullOrEmpty(yAxisName)) VisualProperties.YAxisTitle = yAxisName;
+      if (rows == null) Rows = new NamedItemCollection<ScatterPlotDataRow>();
+      if ((Rows.Count == 0) && (points != null)) Rows.Add(new ScatterPlotDataRow(name, null, points.Select(p => new Point2D<double>(p.X, p.Y))));
+      if (string.IsNullOrEmpty(this.name)) this.name = ItemName;
+      if (string.IsNullOrEmpty(this.description)) this.description = ItemDescription;
+    }
+    #endregion
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ScatterPlot(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 virtual void RegisterRowsEvents() {
+      rows.ItemsAdded += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(rows_ItemsAdded);
+      rows.ItemsRemoved += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(rows_ItemsRemoved);
+      rows.ItemsReplaced += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(rows_ItemsReplaced);
+      rows.CollectionReset += new CollectionItemsChangedEventHandler<ScatterPlotDataRow>(rows_CollectionReset);
+    }
+    private void rows_ItemsAdded(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
+      foreach (ScatterPlotDataRow row in e.Items)
+        this.RegisterRowEvents(row);
+
+      this.OnColumnsChanged();
+      this.OnColumnNamesChanged();
+      this.OnReset();
+    }
+    private void rows_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
+      foreach (ScatterPlotDataRow row in e.Items)
+        this.DeregisterRowEvents(row);
+
+      this.OnColumnsChanged();
+      this.OnColumnNamesChanged();
+      this.OnReset();
+    }
+    private void rows_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
+      foreach (ScatterPlotDataRow row in e.OldItems)
+        this.DeregisterRowEvents(row);
+      foreach (ScatterPlotDataRow row in e.Items)
+        this.RegisterRowEvents(row);
+
+      this.OnColumnsChanged();
+      this.OnColumnNamesChanged();
+      this.OnReset();
+    }
+    private void rows_CollectionReset(object sender, CollectionItemsChangedEventArgs<ScatterPlotDataRow> e) {
+      foreach (ScatterPlotDataRow row in e.OldItems)
+        this.DeregisterRowEvents(row);
+      foreach (ScatterPlotDataRow row in e.Items)
+        this.RegisterRowEvents(row);
+
+      if (e.OldItems.Count() != e.Items.Count())
+        this.OnColumnsChanged();
+      this.OnColumnNamesChanged();
+      this.OnReset();
+    }
+
+    protected virtual void RegisterRowEvents(ScatterPlotDataRow row) {
+      row.Points.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsAdded);
+      row.Points.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsMoved);
+      row.Points.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsRemoved);
+      row.Points.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsReplaced);
+      row.Points.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_CollectionReset);
+    }
+    protected virtual void DeregisterRowEvents(ScatterPlotDataRow row) {
+      row.Points.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsAdded);
+      row.Points.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsMoved);
+      row.Points.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsRemoved);
+      row.Points.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_ItemsReplaced);
+      row.Points.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<Point2D<double>>>(Points_CollectionReset);
+    }
+
+    private void Points_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
+      this.OnReset();
+    }
+    private void Points_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
+      this.OnReset();
+    }
+    private void Points_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
+      this.OnReset();
+    }
+    private void Points_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
+      this.OnReset();
+    }
+    private void Points_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<Point2D<double>>> e) {
+      this.OnReset();
+    }
+
+    #region IStringConvertibleMatrix Members
+    int IStringConvertibleMatrix.Rows {
+      get { return rows.Count == 0 ? 0 : rows.Max(r => r.Points.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) && rowIndex < rows[columnName].Points.Count)
+          return string.Format("{0};{1}", rows[columnName].Points[rowIndex].X, rows[columnName].Points[rowIndex].Y);
+      }
+      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/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotDataRow.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotDataRow.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotDataRow.cs	(revision 12764)
@@ -0,0 +1,109 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// A row of data values for a scatter plot.
+  /// </summary>
+  [Item("ScatterPlotDataRow", "A row of data values for a scatter plot.")]
+  [StorableClass]
+  public class ScatterPlotDataRow : NamedItem {
+    private ScatterPlotDataRowVisualProperties visualProperties;
+    public ScatterPlotDataRowVisualProperties 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<Point2D<double>> points;
+    public ObservableList<Point2D<double>> Points {
+      get { return points; }
+    }
+
+    #region Persistence Properties
+    [Storable(Name = "VisualProperties")]
+    private ScatterPlotDataRowVisualProperties StorableVisualProperties {
+      get { return visualProperties; }
+      set {
+        visualProperties = value;
+        visualProperties.PropertyChanged += new PropertyChangedEventHandler(VisualProperties_PropertyChanged);
+      }
+    }
+    [Storable(Name = "Points")]
+    private IEnumerable<Point2D<double>> StorablePoints {
+      get { return points; }
+      set { points = new ObservableList<Point2D<double>>(value); }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected ScatterPlotDataRow(bool deserializing) : base(deserializing) { }
+    protected ScatterPlotDataRow(ScatterPlotDataRow original, Cloner cloner)
+      : base(original, cloner) {
+      VisualProperties = cloner.Clone(original.visualProperties);
+      points = new ObservableList<Point2D<double>>(original.points);
+    }
+    public ScatterPlotDataRow()
+      : base() {
+      Name = "ScatterPlotDataRow";
+      VisualProperties = new ScatterPlotDataRowVisualProperties();
+      points = new ObservableList<Point2D<double>>();
+    }
+    public ScatterPlotDataRow(string name, string description, IEnumerable<Point2D<double>> points)
+      : base(name, description) {
+      VisualProperties = new ScatterPlotDataRowVisualProperties(name);
+      this.points = new ObservableList<Point2D<double>>(points);
+    }
+    public ScatterPlotDataRow(string name, string description, IEnumerable<Point2D<double>> points, ScatterPlotDataRowVisualProperties visualProperties)
+      : base(name, description) {
+      VisualProperties = visualProperties;
+      this.points = new ObservableList<Point2D<double>>(points);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ScatterPlotDataRow(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();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotDataRowVisualProperties.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotDataRowVisualProperties.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotDataRowVisualProperties.cs	(revision 12764)
@@ -0,0 +1,164 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// Visual properties of a ScatterPlotDataRow.
+  /// </summary>
+  [StorableClass]
+  public class ScatterPlotDataRowVisualProperties : DeepCloneable, INotifyPropertyChanged {
+    #region PointStyle
+    public enum ScatterPlotDataRowPointStyle {
+      Circle,
+      Cross,
+      Diamond,
+      Square,
+      Star4,
+      Star5,
+      Star6,
+      Star10,
+      Triangle
+    }
+    #endregion
+
+    private Color color;
+    public Color Color {
+      get { return color; }
+      set {
+        if (color != value) {
+          color = value;
+          OnPropertyChanged("Color");
+        }
+      }
+    }
+    private ScatterPlotDataRowPointStyle pointStyle;
+    public ScatterPlotDataRowPointStyle PointStyle {
+      get { return pointStyle; }
+      set {
+        if (pointStyle != value) {
+          pointStyle = value;
+          OnPropertyChanged("PointStyle");
+        }
+      }
+    }
+    private int pointSize;
+    public int PointSize {
+      get { return pointSize; }
+      set {
+        if (pointSize != value) {
+          pointSize = value;
+          OnPropertyChanged("PointSize");
+        }
+      }
+    }
+    private bool isVisibleInLegend;
+    public bool IsVisibleInLegend {
+      get { return isVisibleInLegend; }
+      set {
+        if (isVisibleInLegend != value) {
+          isVisibleInLegend = value;
+          OnPropertyChanged("IsVisibleInLegend");
+        }
+      }
+    }
+    private string displayName;
+    public string DisplayName {
+      get { return displayName == null ? String.Empty : displayName; }
+      set {
+        if (displayName != value) {
+          if (value == null && displayName != String.Empty) {
+            displayName = String.Empty;
+            OnPropertyChanged("DisplayName");
+          } else if (value != null) {
+            displayName = value;
+            OnPropertyChanged("DisplayName");
+          }
+        }
+      }
+    }
+
+    #region Persistence Properties
+    [Storable(Name = "Color")]
+    private Color StorableColor {
+      get { return color; }
+      set { color = value; }
+    }
+    [Storable(Name = "PointStyle")]
+    private ScatterPlotDataRowPointStyle StorablePointStyle {
+      get { return pointStyle; }
+      set { pointStyle = value; }
+    }
+    [Storable(Name = "PointSize")]
+    private int StorablePointSize {
+      get { return pointSize; }
+      set { pointSize = value; }
+    }
+    [Storable(Name = "IsVisibleInLegend")]
+    private bool StorableIsVisibleInLegend {
+      get { return isVisibleInLegend; }
+      set { isVisibleInLegend = value; }
+    }
+    [Storable(Name = "DisplayName")]
+    private string StorableDisplayName {
+      get { return displayName; }
+      set { displayName = value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected ScatterPlotDataRowVisualProperties(bool deserializing) : base() { }
+    protected ScatterPlotDataRowVisualProperties(ScatterPlotDataRowVisualProperties original, Cloner cloner)
+      : base(original, cloner) {
+      this.color = original.color;
+      this.pointStyle = original.pointStyle;
+      this.pointSize = original.pointSize;
+      this.displayName = original.displayName;
+      this.isVisibleInLegend = original.isVisibleInLegend;
+    }
+    public ScatterPlotDataRowVisualProperties() {
+      color = Color.Empty;
+      pointStyle = ScatterPlotDataRowPointStyle.Circle;
+      pointSize = 3;
+      displayName = String.Empty;
+      isVisibleInLegend = true;
+    }
+    public ScatterPlotDataRowVisualProperties(string displayName)
+      : this() {
+      this.displayName = displayName;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ScatterPlotDataRowVisualProperties(this, cloner);
+    }
+
+    public event PropertyChangedEventHandler PropertyChanged;
+    protected virtual void OnPropertyChanged(string propertyName) {
+      PropertyChangedEventHandler handler = PropertyChanged;
+      if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotHistory.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotHistory.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotHistory.cs	(revision 12764)
@@ -0,0 +1,49 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// Represents history values of scatter plots.
+  /// </summary>
+  [Item("ScatterPlotHistory", "Represents history values of scatter plots.")]
+  [StorableClass]
+  public class ScatterPlotHistory : ItemCollection<ScatterPlot> {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Cab; }
+    }
+
+    [StorableConstructor]
+    protected ScatterPlotHistory(bool deserializing) : base(deserializing) { }
+    protected ScatterPlotHistory(ScatterPlotHistory original, Cloner cloner) : base(original, cloner) { }
+    public ScatterPlotHistory() : base() { }
+    public ScatterPlotHistory(IEnumerable<ScatterPlot> scatterPlots) : base(new ItemCollection<ScatterPlot>(scatterPlots)) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ScatterPlotHistory(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotVisualProperties.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotVisualProperties.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotVisualProperties.cs	(revision 12764)
@@ -0,0 +1,365 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.ComponentModel;
+using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// Visual properties of a ScatterPlot.
+  /// </summary>
+  [StorableClass]
+  public class ScatterPlotVisualProperties : DeepCloneable, INotifyPropertyChanged {
+    private Font titleFont;
+    public Font TitleFont {
+      get { return titleFont; }
+      set {
+        if (titleFont == null || value == null
+          || titleFont.Name != value.Name || titleFont.Size != value.Size || titleFont.Style != value.Style) {
+          titleFont = value;
+          OnPropertyChanged("TitleFont");
+        }
+      }
+    }
+    private Color titleColor;
+    public Color TitleColor {
+      get { return titleColor; }
+      set {
+        if (titleColor != value) {
+          titleColor = value;
+          OnPropertyChanged("TitleFontColor");
+        }
+      }
+    }
+    private string title;
+    public string Title {
+      get { return title; }
+      set {
+        if (title != value) {
+          title = value;
+          OnPropertyChanged("Title");
+        }
+      }
+    }
+    private Font axisTitleFont;
+    public Font AxisTitleFont {
+      get { return axisTitleFont; }
+      set {
+        if (axisTitleFont == null || axisTitleFont == null
+          || axisTitleFont.Name != value.Name || axisTitleFont.Size != value.Size || axisTitleFont.Style != value.Style) {
+          axisTitleFont = value;
+          OnPropertyChanged("AxisTitleFont");
+        }
+      }
+    }
+    private Color axisTitleColor;
+    public Color AxisTitleColor {
+      get { return axisTitleColor; }
+      set {
+        if (axisTitleColor != value) {
+          axisTitleColor = value;
+          OnPropertyChanged("AxisTitleColor");
+        }
+      }
+    }
+    private string xAxisTitle;
+    public string XAxisTitle {
+      get { return xAxisTitle; }
+      set {
+        if (value == null) value = string.Empty;
+        if (xAxisTitle != value) {
+          xAxisTitle = value;
+          OnPropertyChanged("XAxisTitle");
+        }
+      }
+    }
+
+    private string yAxisTitle;
+    public string YAxisTitle {
+      get { return yAxisTitle; }
+      set {
+        if (value == null) value = string.Empty;
+        if (yAxisTitle != value) {
+          yAxisTitle = value;
+          OnPropertyChanged("YAxisTitle");
+        }
+      }
+    }
+
+    private bool xAxisGrid;
+    public bool XAxisGrid {
+      get { return xAxisGrid; }
+      set {
+        if (xAxisGrid != value) {
+          xAxisGrid = value;
+          OnPropertyChanged("XAxisGrid");
+        }
+      }
+    }
+
+    private bool yAxisGrid;
+    public bool YAxisGrid {
+      get { return yAxisGrid; }
+      set {
+        if (yAxisGrid != value) {
+          yAxisGrid = value;
+          OnPropertyChanged("YAxisGrid");
+        }
+      }
+    }
+
+    private bool xAxisMinimumAuto;
+    public bool XAxisMinimumAuto {
+      get { return xAxisMinimumAuto; }
+      set {
+        if (xAxisMinimumAuto != value) {
+          xAxisMinimumAuto = value;
+          if (value) xAxisMinimumFixedValue = double.NaN;
+          OnPropertyChanged("XAxisMinimumAuto");
+        }
+      }
+    }
+
+    private bool xAxisMaximumAuto;
+    public bool XAxisMaximumAuto {
+      get { return xAxisMaximumAuto; }
+      set {
+        if (xAxisMaximumAuto != value) {
+          xAxisMaximumAuto = value;
+          if (value) xAxisMaximumFixedValue = double.NaN;
+          OnPropertyChanged("XAxisMaximumAuto");
+        }
+      }
+    }
+
+    private double xAxisMinimumFixedValue;
+    public double XAxisMinimumFixedValue {
+      get { return xAxisMinimumFixedValue; }
+      set {
+        if (xAxisMinimumFixedValue != value) {
+          xAxisMinimumFixedValue = value;
+          OnPropertyChanged("XAxisMinimumFixedValue");
+        }
+      }
+    }
+
+    private double xAxisMaximumFixedValue;
+    public double XAxisMaximumFixedValue {
+      get { return xAxisMaximumFixedValue; }
+      set {
+        if (xAxisMaximumFixedValue != value) {
+          xAxisMaximumFixedValue = value;
+          OnPropertyChanged("XAxisMaximumFixedValue");
+        }
+      }
+    }
+
+    private bool yAxisMinimumAuto;
+    public bool YAxisMinimumAuto {
+      get { return yAxisMinimumAuto; }
+      set {
+        if (yAxisMinimumAuto != value) {
+          yAxisMinimumAuto = value;
+          if (value) yAxisMinimumFixedValue = double.NaN;
+          OnPropertyChanged("YAxisMinimumAuto");
+        }
+      }
+    }
+
+    private bool yAxisMaximumAuto;
+    public bool YAxisMaximumAuto {
+      get { return yAxisMaximumAuto; }
+      set {
+        if (yAxisMaximumAuto != value) {
+          yAxisMaximumAuto = value;
+          if (value) yAxisMaximumFixedValue = double.NaN;
+          OnPropertyChanged("YAxisMaximumAuto");
+        }
+      }
+    }
+
+    private double yAxisMinimumFixedValue;
+    public double YAxisMinimumFixedValue {
+      get { return yAxisMinimumFixedValue; }
+      set {
+        if (yAxisMinimumFixedValue != value) {
+          yAxisMinimumFixedValue = value;
+          OnPropertyChanged("YAxisMinimumFixedValue");
+        }
+      }
+    }
+
+    private double yAxisMaximumFixedValue;
+    public double YAxisMaximumFixedValue {
+      get { return yAxisMaximumFixedValue; }
+      set {
+        if (yAxisMaximumFixedValue != value) {
+          yAxisMaximumFixedValue = value;
+          OnPropertyChanged("YAxisMaximumFixedValue");
+        }
+      }
+    }
+
+    #region Persistence Properties
+    [Storable(Name = "TitleFont")]
+    private Font StorableTitleFont {
+      get { return titleFont; }
+      set { titleFont = value; }
+    }
+    [Storable(Name = "TitleColor")]
+    private Color StorableTitleColor {
+      get { return titleColor; }
+      set { titleColor = value; }
+    }
+    [Storable(Name = "Title")]
+    private string StorableTitle {
+      get { return title; }
+      set { title = value; }
+    }
+    [Storable(Name = "AxisTitleFont")]
+    private Font StorableAxisTitleFont {
+      get { return axisTitleFont; }
+      set { axisTitleFont = value; }
+    }
+    [Storable(Name = "AxisTitleColor")]
+    private Color StorableAxisTitleColor {
+      get { return axisTitleColor; }
+      set { axisTitleColor = value; }
+    }
+    [Storable(Name = "XAxisTitle")]
+    private string StorableXAxisTitle {
+      get { return xAxisTitle; }
+      set { xAxisTitle = value; }
+    }
+    [Storable(Name = "YAxisTitle")]
+    private string StorableYAxisTitle {
+      get { return yAxisTitle; }
+      set { yAxisTitle = value; }
+    }
+    [Storable(Name = "XAxisGrid")]
+    private bool StorableXAxisGrid {
+      get { return xAxisGrid; }
+      set { xAxisGrid = value; }
+    }
+    [Storable(Name = "YAxisGrid")]
+    private bool StorableYAxisGrid {
+      get { return yAxisGrid; }
+      set { yAxisGrid = value; }
+    }
+    [Storable(Name = "XAxisMinimumAuto")]
+    private bool StorableXAxisMinimumAuto {
+      get { return xAxisMinimumAuto; }
+      set { xAxisMinimumAuto = value; }
+    }
+    [Storable(Name = "XAxisMaximumAuto")]
+    private bool StorableXAxisMaximumAuto {
+      get { return xAxisMaximumAuto; }
+      set { xAxisMaximumAuto = value; }
+    }
+    [Storable(Name = "XAxisMinimumFixedValue")]
+    private double StorableXAxisMinimumFixedValue {
+      get { return xAxisMinimumFixedValue; }
+      set { xAxisMinimumFixedValue = value; }
+    }
+    [Storable(Name = "XAxisMaximumFixedValue")]
+    private double StorableXAxisMaximumFixedValue {
+      get { return xAxisMaximumFixedValue; }
+      set { xAxisMaximumFixedValue = value; }
+    }
+    [Storable(Name = "YAxisMinimumAuto")]
+    private bool StorableYAxisMinimumAuto {
+      get { return yAxisMinimumAuto; }
+      set { yAxisMinimumAuto = value; }
+    }
+    [Storable(Name = "YAxisMaximumAuto")]
+    private bool StorableYAxisMaximumAuto {
+      get { return yAxisMaximumAuto; }
+      set { yAxisMaximumAuto = value; }
+    }
+    [Storable(Name = "YAxisMinimumFixedValue")]
+    private double StorableYAxisMinimumFixedValue {
+      get { return yAxisMinimumFixedValue; }
+      set { yAxisMinimumFixedValue = value; }
+    }
+    [Storable(Name = "YAxisMaximumFixedValue")]
+    private double StorableYAxisMaximumFixedValue {
+      get { return yAxisMaximumFixedValue; }
+      set { yAxisMaximumFixedValue = value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected ScatterPlotVisualProperties(bool deserializing) : base() { }
+    protected ScatterPlotVisualProperties(ScatterPlotVisualProperties original, Cloner cloner)
+      : base(original, cloner) {
+      if (original.titleFont != null)
+        this.titleFont = (Font)original.titleFont.Clone();
+      if (original.axisTitleFont != null)
+        this.axisTitleFont = (Font)original.axisTitleFont.Clone();
+      this.title = original.title;
+      this.xAxisTitle = original.xAxisTitle;
+      this.yAxisTitle = original.yAxisTitle;
+      this.xAxisGrid = original.xAxisGrid;
+      this.yAxisGrid = original.yAxisGrid;
+      this.xAxisMinimumAuto = original.xAxisMinimumAuto;
+      this.xAxisMinimumFixedValue = original.xAxisMinimumFixedValue;
+      this.xAxisMaximumAuto = original.xAxisMaximumAuto;
+      this.xAxisMaximumFixedValue = original.xAxisMaximumFixedValue;
+      this.yAxisMinimumAuto = original.yAxisMinimumAuto;
+      this.yAxisMinimumFixedValue = original.yAxisMinimumFixedValue;
+      this.yAxisMaximumAuto = original.yAxisMaximumAuto;
+      this.yAxisMaximumFixedValue = original.yAxisMaximumFixedValue;
+    }
+    public ScatterPlotVisualProperties() {
+      this.titleColor = Color.Black;
+      this.axisTitleColor = Color.Black;
+      this.title = string.Empty;
+      this.xAxisTitle = string.Empty;
+      this.yAxisTitle = string.Empty;
+      this.xAxisGrid = true;
+      this.yAxisGrid = true;
+      this.xAxisMinimumAuto = true;
+      this.xAxisMinimumFixedValue = double.NaN;
+      this.xAxisMaximumAuto = true;
+      this.xAxisMaximumFixedValue = double.NaN;
+      this.yAxisMinimumAuto = true;
+      this.yAxisMinimumFixedValue = double.NaN;
+      this.yAxisMaximumAuto = true;
+      this.yAxisMaximumFixedValue = double.NaN;
+    }
+    public ScatterPlotVisualProperties(string title)
+      : this() {
+      this.title = title;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ScatterPlotVisualProperties(this, cloner);
+    }
+
+    public event PropertyChangedEventHandler PropertyChanged;
+    protected virtual void OnPropertyChanged(string propertyName) {
+      PropertyChangedEventHandler handler = PropertyChanged;
+      if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 12764)
@@ -0,0 +1,282 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{887425B4-4348-49ED-A457-B7D2C26DDBF9}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Analysis</RootNamespace>
+    <AssemblyName>HeuristicLab.Analysis-3.3</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation />
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>
+    </DocumentationFile>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <ItemGroup>
+    <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\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+      <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\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, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core-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.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimization.Operators-3.3.dll</HintPath>
+      <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\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+      <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\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+      <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\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Plugin.cs.frame" />
+    <Compile Include="AlleleFrequencyAnalysis\Allele.cs" />
+    <Compile Include="AlleleFrequencyAnalysis\AlleleFrequency.cs" />
+    <Compile Include="AlleleFrequencyAnalysis\AlleleFrequencyAnalyzer.cs" />
+    <Compile Include="AlleleFrequencyAnalysis\AlleleFrequencyCollection.cs" />
+    <Compile Include="AlleleFrequencyAnalysis\AlleleFrequencyCollectionHistory.cs" />
+    <Compile Include="BestScopeSolutionAnalyzer.cs" />
+    <Compile Include="DataVisualization\IndexedDataRow.cs" />
+    <Compile Include="DataVisualization\IndexedDataTable.cs" />
+    <Compile Include="DataVisualization\ScatterPlotDataRowVisualProperties.cs" />
+    <Compile Include="DataVisualization\ScatterPlotDataRow.cs" />
+    <Compile Include="DataVisualization\ScatterPlotVisualProperties.cs" />
+    <Compile Include="DataVisualization\ScatterPlotHistory.cs" />
+    <Compile Include="DataVisualization\DataRow.cs" />
+    <Compile Include="DataVisualization\DataRowVisualProperties.cs" />
+    <Compile Include="DataVisualization\DataTable.cs" />
+    <Compile Include="DataVisualization\DataTableHistory.cs" />
+    <Compile Include="DataVisualization\DataTableValuesCollector.cs" />
+    <Compile Include="DataVisualization\DataTableVisualProperties.cs" />
+    <Compile Include="DataVisualization\HeatMap.cs" />
+    <Compile Include="DataVisualization\HeatMapHistory.cs" />
+    <Compile Include="DataVisualization\ScatterPlot.cs" />
+    <Compile Include="MultidimensionalScaling\MultidimensionalScaling.cs" />
+    <Compile Include="MultiObjective\RankBasedParetoFrontAnalyzer.cs" />
+    <Compile Include="MultiObjective\ParetoFrontAnalyzer.cs" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="PopulationSimilarityAnalysis\PopulationDiversityAnalyzer.cs" />
+    <Compile Include="PopulationSimilarityAnalysis\PopulationSimilarityAnalyzer.cs" />
+    <Compile Include="PopulationSimilarityAnalysis\SingleObjectivePopulationDiversityAnalyzer.cs" />
+    <Compile Include="QualityAnalysis\BestAverageWorstQualityAnalyzer.cs" />
+    <Compile Include="QualityAnalysis\BestAverageWorstQualityCalculator.cs" />
+    <Compile Include="QualityAnalysis\BestQualityMemorizer.cs" />
+    <Compile Include="QualityAnalysis\QualityAnalyzer.cs" />
+    <Compile Include="QualityAnalysis\QualityDifferenceCalculator.cs" />
+    <Compile Include="MultiAnalyzer.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="QualityAnalysis\QualityDistributionAnalyzer.cs" />
+    <Compile Include="QualityAnalysis\QualityVsEvaluationsAnalyzer.cs" />
+    <Compile Include="QualityAnalysis\ScaledQualityDifferenceAnalyzer.cs" />
+    <Compile Include="Statistics\BonferroniHolm.cs" />
+    <Compile Include="Statistics\EnumerableStatisticsExtension.cs" />
+    <Compile Include="Statistics\Fitting\ExpFitting.cs" />
+    <Compile Include="Statistics\Fitting\IFitting.cs" />
+    <Compile Include="Statistics\KruskalWallisTest.cs" />
+    <Compile Include="Statistics\Fitting\LinearLeastSquaresFitting.cs" />
+    <Compile Include="Statistics\Fitting\LogFitting.cs" />
+    <Compile Include="Statistics\KernelDensityEstimator.cs" />
+    <Compile Include="Statistics\PairwiseTest.cs" />
+    <Compile Include="Statistics\SampleSizeDetermination.cs" />
+    <Compile Include="ValueAnalysis\SingleValueAnalyzer.cs" />
+    <Compile Include="ValueAnalysis\MinAverageMaxValueAnalyzer.cs" />
+    <Compile Include="ValueAnalysis\MinAverageMaxValueCalculator.cs" />
+    <Compile Include="ValueAnalysis\ValueAnalyzer.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
+      <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project>
+      <Name>HeuristicLab.Optimization-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup />
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <PropertyGroup>
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd
+</PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/MultiAnalyzer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/MultiAnalyzer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/MultiAnalyzer.cs	(revision 12764)
@@ -0,0 +1,93 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Collections;
+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 {
+  /// <summary>
+  /// An analyzer which applies arbitrary many other analyzers.
+  /// </summary>
+  [Item("MultiAnalyzer", "An analyzer which applies arbitrary many other analyzers.")]
+  [StorableClass]
+  public class MultiAnalyzer : CheckedMultiOperator<IAnalyzer>, IMultiAnalyzer {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public virtual bool EnabledByDefault {
+      get { return true; }
+    }
+
+    public ValueLookupParameter<IntValue> UpdateIntervalParameter {
+      get { return (ValueLookupParameter<IntValue>)Parameters["UpdateInterval"]; }
+    }
+    public LookupParameter<IntValue> UpdateCounterParameter {
+      get { return (LookupParameter<IntValue>)Parameters["UpdateCounter"]; }
+    }
+
+    public IntValue UpdateInterval {
+      get { return UpdateIntervalParameter.Value; }
+      set { UpdateIntervalParameter.Value = value; }
+    }
+
+    #region Storing & Cloning
+    [StorableConstructor]
+    protected MultiAnalyzer(bool deserializing) : base(deserializing) { }
+    protected MultiAnalyzer(MultiAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MultiAnalyzer(this, cloner);
+    }
+    #endregion
+    public MultiAnalyzer()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<IntValue>("UpdateInterval", "The interval in which the contained analyzers should be applied.", new IntValue(1)));
+      Parameters.Add(new LookupParameter<IntValue>("UpdateCounter", "The value which counts how many times the MultiAnalyzer was called since the last update.", "MultiAnalyzerUpdateCounter"));
+    }
+
+    public override IOperation InstrumentedApply() {
+      IntValue interval = UpdateIntervalParameter.ActualValue;
+      if (interval == null) interval = new IntValue(1);
+
+      IntValue counter = UpdateCounterParameter.ActualValue;
+      if (counter == null) {
+        counter = new IntValue(interval.Value);
+        UpdateCounterParameter.ActualValue = counter;
+      } else counter.Value++;
+
+      if (counter.Value == interval.Value) {
+        counter.Value = 0;
+        OperationCollection next = new OperationCollection();
+        foreach (IndexedItem<IAnalyzer> item in Operators.CheckedItems)
+          next.Add(ExecutionContext.CreateOperation(item.Value));
+        next.Add(base.InstrumentedApply());
+        return next;
+      } else {
+        return base.InstrumentedApply();
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/MultiObjective/ParetoFrontAnalyzer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/MultiObjective/ParetoFrontAnalyzer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/MultiObjective/ParetoFrontAnalyzer.cs	(revision 12764)
@@ -0,0 +1,62 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  [Item("ParetoFrontAnalyzer", "Analyzer for multiobjective problems that collects and presents the current Pareto front as double matrix as well as the solution scopes that lie on the current front.")]
+  [StorableClass]
+  public abstract class ParetoFrontAnalyzer : SingleSuccessorOperator, IAnalyzer, IMultiObjectiveOperator {
+    public virtual bool EnabledByDefault {
+      get { return true; }
+    }
+
+    public IScopeTreeLookupParameter<DoubleArray> QualitiesParameter {
+      get { return (IScopeTreeLookupParameter<DoubleArray>)Parameters["Qualities"]; }
+    }
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+
+    [StorableConstructor]
+    protected ParetoFrontAnalyzer(bool deserializing) : base(deserializing) { }
+    protected ParetoFrontAnalyzer(ParetoFrontAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public ParetoFrontAnalyzer() {
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleArray>("Qualities", "The vector of qualities of each solution."));
+      Parameters.Add(new LookupParameter<ResultCollection>("Results", "The result collection to store the front to."));
+    }
+
+    public override IOperation Apply() {
+      ItemArray<DoubleArray> qualities = QualitiesParameter.ActualValue;
+      ResultCollection results = ResultsParameter.ActualValue;
+      Analyze(qualities, results);
+      return base.Apply();
+    }
+
+    protected abstract void Analyze(ItemArray<DoubleArray> qualities, ResultCollection results);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/MultiObjective/RankBasedParetoFrontAnalyzer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/MultiObjective/RankBasedParetoFrontAnalyzer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/MultiObjective/RankBasedParetoFrontAnalyzer.cs	(revision 12764)
@@ -0,0 +1,97 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  [Item("RankBasedParetoFrontAnalyzer", "Uses the rank value that is computed by e.g. the NSGA2's fast non dominated sort operator to collect all solutions and their qualities of front 0 (the current Pareto front).")]
+  [StorableClass]
+  public class RankBasedParetoFrontAnalyzer : ParetoFrontAnalyzer {
+    public IScopeTreeLookupParameter<IntValue> RankParameter {
+      get { return (IScopeTreeLookupParameter<IntValue>)Parameters["Rank"]; }
+    }
+
+    [StorableConstructor]
+    protected RankBasedParetoFrontAnalyzer(bool deserializing) : base(deserializing) { }
+    protected RankBasedParetoFrontAnalyzer(RankBasedParetoFrontAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public RankBasedParetoFrontAnalyzer() {
+      Parameters.Add(new ScopeTreeLookupParameter<IntValue>("Rank", "The rank of solution [0..N] describes to which front it belongs."));
+    }
+
+    protected override void Analyze(ItemArray<DoubleArray> qualities, ResultCollection results) {
+      ItemArray<IntValue> ranks = RankParameter.ActualValue;
+
+      bool populationLevel = RankParameter.Depth == 1;
+
+      int objectives = qualities[0].Length;
+      int frontSize = ranks.Count(x => x.Value == 0);
+      ItemArray<IScope> paretoArchive = null;
+      if (populationLevel) paretoArchive = new ItemArray<IScope>(frontSize);
+
+      DoubleMatrix front = new DoubleMatrix(frontSize, objectives);
+      int counter = 0;
+      for (int i = 0; i < ranks.Length; i++) {
+        if (ranks[i].Value == 0) {
+          for (int k = 0; k < objectives; k++)
+            front[counter, k] = qualities[i][k];
+          if (populationLevel) {
+            paretoArchive[counter] = (IScope)ExecutionContext.Scope.SubScopes[i].Clone();
+          }
+          counter++;
+        }
+      }
+
+      front.RowNames = GetRowNames(front);
+      front.ColumnNames = GetColumnNames(front);
+
+      if (results.ContainsKey("Pareto Front"))
+        results["Pareto Front"].Value = front;
+      else results.Add(new Result("Pareto Front", front));
+
+      if (populationLevel) {
+        if (results.ContainsKey("Pareto Archive"))
+          results["Pareto Archive"].Value = paretoArchive;
+        else results.Add(new Result("Pareto Archive", paretoArchive));
+      }
+    }
+
+    private IEnumerable<string> GetRowNames(DoubleMatrix front) {
+      for (int i = 1; i <= front.Rows; i++)
+        yield return "Solution " + i.ToString();
+    }
+
+    private IEnumerable<string> GetColumnNames(DoubleMatrix front) {
+      for (int i = 1; i <= front.Columns; i++)
+        yield return "Objective " + i.ToString();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RankBasedParetoFrontAnalyzer(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/MultidimensionalScaling/MultidimensionalScaling.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/MultidimensionalScaling/MultidimensionalScaling.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/MultidimensionalScaling/MultidimensionalScaling.cs	(revision 12764)
@@ -0,0 +1,182 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Analysis {
+  public static class MultidimensionalScaling {
+
+    /// <summary>
+    /// Performs the Kruskal-Shepard algorithm and applies a gradient descent method
+    /// to fit the coordinates such that the difference between the fit distances
+    /// and the dissimilarities becomes minimal.
+    /// </summary>
+    /// <remarks>
+    /// It will initialize the coordinates in a deterministic fashion such that all initial points are equally spaced on a circle.
+    /// </remarks>
+    /// <param name="dissimilarities">A symmetric NxN matrix that specifies the dissimilarities between each element i and j. Diagonal elements are ignored.</param>
+    /// 
+    /// <returns>A Nx2 matrix where the first column represents the x- and the second column the y coordinates.</returns>
+    public static DoubleMatrix KruskalShepard(DoubleMatrix dissimilarities) {
+      if (dissimilarities == null) throw new ArgumentNullException("dissimilarities");
+      if (dissimilarities.Rows != dissimilarities.Columns) throw new ArgumentException("Dissimilarities must be a square matrix.", "dissimilarities");
+
+      int dimension = dissimilarities.Rows;
+      if (dimension == 1) return new DoubleMatrix(new double[,] { { 0, 0 } });
+      else if (dimension == 2) return new DoubleMatrix(new double[,] { { 0, 0 }, { 0, dissimilarities[0, 1] } });
+
+      DoubleMatrix coordinates = new DoubleMatrix(dimension, 2);
+      double rad = (2 * Math.PI) / coordinates.Rows;
+      for (int i = 0; i < dimension; i++) {
+        coordinates[i, 0] = 10 * Math.Cos(rad * i);
+        coordinates[i, 1] = 10 * Math.Sin(rad * i);
+      }
+
+      return KruskalShepard(dissimilarities, coordinates);
+    }
+
+    /// <summary>
+    /// Performs the Kruskal-Shepard algorithm and applies a gradient descent method
+    /// to fit the coordinates such that the difference between the fit distances
+    /// and the dissimilarities is minimal.
+    /// </summary>
+    /// <remarks>
+    /// It will use a pre-initialized x,y-coordinates matrix as a starting point of the gradient descent.
+    /// </remarks>
+    /// <param name="dissimilarities">A symmetric NxN matrix that specifies the dissimilarities between each element i and j. Diagonal elements are ignored.</param>
+    /// <param name="coordinates">The Nx2 matrix of initial coordinates.</param>
+    /// <param name="maximumIterations">The number of iterations for which the algorithm should run.
+    /// In every iteration it tries to find the best location for every item.</param>
+    /// <returns>A Nx2 matrix where the first column represents the x- and the second column the y coordinates.</returns>
+    public static DoubleMatrix KruskalShepard(DoubleMatrix dissimilarities, DoubleMatrix coordinates, int maximumIterations = 10) {
+      int dimension = dissimilarities.Rows;
+      if (dimension != dissimilarities.Columns || coordinates.Rows != dimension) throw new ArgumentException("The number of coordinates and the number of rows and columns in the dissimilarities matrix do not match.");
+
+      double epsg = 1e-7;
+      double epsf = 0;
+      double epsx = 0;
+      int maxits = 0;
+
+      alglib.minlmstate state;
+      alglib.minlmreport rep;
+      for (int iterations = 0; iterations < maximumIterations; iterations++) {
+        bool changed = false;
+        for (int i = 0; i < dimension; i++) {
+          double[] c = new double[] { coordinates[i, 0], coordinates[i, 1] };
+
+          try {
+            alglib.minlmcreatevj(dimension - 1, c, out state);
+            alglib.minlmsetcond(state, epsg, epsf, epsx, maxits);
+            alglib.minlmoptimize(state, StressFitness, StressJacobian, null, new Info(coordinates, dissimilarities, i));
+            alglib.minlmresults(state, out c, out rep);
+          } catch (alglib.alglibexception) { }
+          if (!double.IsNaN(c[0]) && !double.IsNaN(c[1])) {
+            changed = changed || (coordinates[i, 0] != c[0]) || (coordinates[i, 1] != c[1]);
+            coordinates[i, 0] = c[0];
+            coordinates[i, 1] = c[1];
+          }
+        }
+        if (!changed) break;
+      }
+      return coordinates;
+    }
+
+    private static void StressFitness(double[] x, double[] fi, object obj) {
+      Info info = (obj as Info);
+      int idx = 0;
+      for (int i = 0; i < info.Coordinates.Rows; i++) {
+        if (i == info.Row) continue;
+        if (!double.IsNaN(info.Dissimilarities[info.Row, i]))
+          fi[idx++] = Stress(x, info.Dissimilarities[info.Row, i], info.Coordinates[i, 0], info.Coordinates[i, 1]);
+        else fi[idx++] = 0.0;
+      }
+    }
+
+    private static void StressJacobian(double[] x, double[] fi, double[,] jac, object obj) {
+      Info info = (obj as Info);
+      int idx = 0;
+      for (int i = 0; i < info.Coordinates.Rows; i++) {
+        if (i == info.Row) continue;
+        double c = info.Dissimilarities[info.Row, i];
+        double a = info.Coordinates[i, 0];
+        double b = info.Coordinates[i, 1];
+        if (!double.IsNaN(c)) {
+          fi[idx] = Stress(x, c, a, b); ;
+          jac[idx, 0] = 2 * (x[0] - a) * (Math.Sqrt((a - x[0]) * (a - x[0]) + (b - x[1]) * (b - x[1])) - c) / Math.Sqrt((a - x[0]) * (a - x[0]) + (b - x[1]) * (b - x[1]));
+          jac[idx, 1] = 2 * (x[1] - b) * (Math.Sqrt((a - x[0]) * (a - x[0]) + (b - x[1]) * (b - x[1])) - c) / Math.Sqrt((a - x[0]) * (a - x[0]) + (b - x[1]) * (b - x[1]));
+        } else {
+          fi[idx] = jac[idx, 0] = jac[idx, 1] = 0;
+        }
+        idx++;
+      }
+    }
+
+    private static double Stress(double[] x, double distance, double xCoord, double yCoord) {
+      return Stress(x[0], x[1], distance, xCoord, yCoord);
+    }
+
+    private static double Stress(double x, double y, double distance, double otherX, double otherY) {
+      double d = Math.Sqrt((x - otherX) * (x - otherX)
+                         + (y - otherY) * (y - otherY));
+      return (d - distance) * (d - distance);
+    }
+
+    /// <summary>
+    /// This method computes the normalized raw-stress value according to Groenen and van de Velden 2004. "Multidimensional Scaling". Technical report EI 2004-15.
+    /// </summary>
+    /// <remarks>
+    /// Throws an ArgumentException when the <paramref name="dissimilarities"/> matrix is not symmetric.
+    /// </remarks>
+    /// 
+    /// <param name="dissimilarities">The matrix with the dissimilarities.</param>
+    /// <param name="coordinates">The actual location of the points.</param>
+    /// <returns>The normalized raw-stress value that describes the goodness-of-fit between the distances in the points and the size of the dissimilarities. If the value is &lt; 0.1 the fit is generally considered good. If between 0.1 and 0.2 it is considered acceptable, but the usefulness of the scaling with higher values is doubtful.</returns>
+    public static double CalculateNormalizedStress(DoubleMatrix dissimilarities, DoubleMatrix coordinates) {
+      int dimension = dissimilarities.Rows;
+      if (dimension != dissimilarities.Columns || dimension != coordinates.Rows) throw new ArgumentException("The number of coordinates and the number of rows and columns in the dissimilarities matrix do not match.");
+      double stress = 0, normalization = 0;
+      for (int i = 0; i < dimension - 1; i++) {
+        for (int j = i + 1; j < dimension; j++) {
+          if (dissimilarities[i, j] != dissimilarities[j, i] && !(double.IsNaN(dissimilarities[i, j]) && double.IsNaN(dissimilarities[j, i])))
+            throw new ArgumentException("Dissimilarities is not a symmetric matrix.", "dissimilarities");
+          if (!double.IsNaN(dissimilarities[i, j])) {
+            stress += Stress(coordinates[i, 0], coordinates[i, 1], dissimilarities[i, j], coordinates[j, 0], coordinates[j, 1]);
+            normalization += (dissimilarities[i, j] * dissimilarities[i, j]);
+          }
+        }
+      }
+      return stress / normalization;
+    }
+
+    private class Info {
+      public DoubleMatrix Coordinates { get; set; }
+      public DoubleMatrix Dissimilarities { get; set; }
+      public int Row { get; set; }
+
+      public Info(DoubleMatrix c, DoubleMatrix d, int r) {
+        Coordinates = c;
+        Dissimilarities = d;
+        Row = r;
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Plugin.cs.frame
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Plugin.cs.frame	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Plugin.cs.frame	(revision 12764)
@@ -0,0 +1,43 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// Plugin class for HeuristicLab.Analysis plugin.
+  /// </summary>
+  [Plugin("HeuristicLab.Analysis", "3.3.12.$WCREV$")]
+  [PluginFile("HeuristicLab.Analysis-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.ALGLIB", "3.7.0")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  public class HeuristicLabAnalysisPlugin : PluginBase {
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/PopulationDiversityAnalyzer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/PopulationDiversityAnalyzer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/PopulationDiversityAnalyzer.cs	(revision 12764)
@@ -0,0 +1,252 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.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 {
+  // use HeuristicLab.Analysis.SingleObjectivePopulationDiversityAnalyzer instead
+  // BackwardsCompatibility3.3
+  #region Backwards compatible code, remove with 3.4
+  /// <summary>
+  /// An operator for analyzing the solution diversity in a population.
+  /// </summary>
+  [Obsolete]
+  [Item("PopulationDiversityAnalyzer", "An operator for analyzing the solution diversity in a population.")]
+  [StorableClass]
+  public abstract class PopulationDiversityAnalyzer<T> : SingleSuccessorOperator, IAnalyzer, ISingleObjectiveOperator where T : class, IItem {
+    public virtual bool EnabledByDefault {
+      get { return false; }
+    }
+
+    public LookupParameter<BoolValue> MaximizationParameter {
+      get { return (LookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ScopeTreeLookupParameter<T> SolutionParameter {
+      get { return (ScopeTreeLookupParameter<T>)Parameters["Solution"]; }
+    }
+    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ValueLookupParameter<ResultCollection> ResultsParameter {
+      get { return (ValueLookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    public ValueParameter<BoolValue> StoreHistoryParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["StoreHistory"]; }
+    }
+    public ValueParameter<IntValue> UpdateIntervalParameter {
+      get { return (ValueParameter<IntValue>)Parameters["UpdateInterval"]; }
+    }
+    public LookupParameter<IntValue> UpdateCounterParameter {
+      get { return (LookupParameter<IntValue>)Parameters["UpdateCounter"]; }
+    }
+
+    [StorableConstructor]
+    protected PopulationDiversityAnalyzer(bool deserializing) : base(deserializing) { }
+    protected PopulationDiversityAnalyzer(PopulationDiversityAnalyzer<T> original, Cloner cloner) : base(original, cloner) { }
+    public PopulationDiversityAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem."));
+      Parameters.Add(new ScopeTreeLookupParameter<T>("Solution", "The solutions whose diversity should be analyzed."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The qualities of the solutions which should be analyzed."));
+      Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The result collection where the population diversity analysis results should be stored."));
+      Parameters.Add(new ValueParameter<BoolValue>("StoreHistory", "True if the history of the population diversity analysis should be stored.", new BoolValue(false)));
+      Parameters.Add(new ValueParameter<IntValue>("UpdateInterval", "The interval in which the population diversity analysis should be applied.", new IntValue(1)));
+      Parameters.Add(new LookupParameter<IntValue>("UpdateCounter", "The value which counts how many times the operator was called since the last update.", "PopulationDiversityAnalyzerUpdateCounter"));
+
+      MaximizationParameter.Hidden = true;
+      SolutionParameter.Hidden = true;
+      QualityParameter.Hidden = true;
+      ResultsParameter.Hidden = true;
+      UpdateCounterParameter.Hidden = true;
+    }
+
+    public override IOperation Apply() {
+      int updateInterval = UpdateIntervalParameter.Value.Value;
+      IntValue updateCounter = UpdateCounterParameter.ActualValue;
+      // if counter does not yet exist then initialize it with update interval 
+      // to make sure the solutions are analyzed on the first application of this operator
+      if (updateCounter == null) {
+        updateCounter = new IntValue(updateInterval);
+        UpdateCounterParameter.ActualValue = updateCounter;
+      } else updateCounter.Value++;
+
+      //analyze solutions only every 'updateInterval' times
+      if (updateCounter.Value == updateInterval) {
+        updateCounter.Value = 0;
+
+        bool max = MaximizationParameter.ActualValue.Value;
+        ItemArray<T> solutions = SolutionParameter.ActualValue;
+        ItemArray<DoubleValue> qualities = QualityParameter.ActualValue;
+        bool storeHistory = StoreHistoryParameter.Value.Value;
+        int count = solutions.Length;
+
+        if (count > 1) {
+          // sort solutions by quality
+          T[] sortedSolutions = null;
+          if (max)
+            sortedSolutions = solutions
+              .Select((x, index) => new { Solution = x, Quality = qualities[index] })
+              .OrderByDescending(x => x.Quality)
+              .Select(x => x.Solution)
+              .ToArray();
+          else
+            sortedSolutions = solutions
+              .Select((x, index) => new { Solution = x, Quality = qualities[index] })
+              .OrderBy(x => x.Quality)
+              .Select(x => x.Solution)
+              .ToArray();
+
+          // calculate solution similarities
+          double[,] similarities = CalculateSimilarities(sortedSolutions);
+
+          // calculate minimum, average and maximum similarities
+          double similarity;
+          double[] minSimilarities = new double[count];
+          double[] avgSimilarities = new double[count];
+          double[] maxSimilarities = new double[count];
+          for (int i = 0; i < count; i++) {
+            minSimilarities[i] = 1;
+            avgSimilarities[i] = 0;
+            maxSimilarities[i] = 0;
+            for (int j = 0; j < count; j++) {
+              if (i != j) {
+                similarity = similarities[i, j];
+
+                if ((similarity < 0) || (similarity > 1))
+                  throw new InvalidOperationException("Solution similarities have to be in the interval [0;1].");
+
+                if (minSimilarities[i] > similarity) minSimilarities[i] = similarity;
+                avgSimilarities[i] += similarity;
+                if (maxSimilarities[i] < similarity) maxSimilarities[i] = similarity;
+              }
+            }
+            avgSimilarities[i] = avgSimilarities[i] / (count - 1);
+          }
+          double avgMinSimilarity = minSimilarities.Average();
+          double avgAvgSimilarity = avgSimilarities.Average();
+          double avgMaxSimilarity = maxSimilarities.Average();
+
+          // fetch results collection
+          ResultCollection results;
+          if (!ResultsParameter.ActualValue.ContainsKey(Name + " Results")) {
+            results = new ResultCollection();
+            ResultsParameter.ActualValue.Add(new Result(Name + " Results", results));
+          } else {
+            results = (ResultCollection)ResultsParameter.ActualValue[Name + " Results"].Value;
+          }
+
+          // store similarities
+          HeatMap similaritiesHeatMap = new HeatMap(similarities, "Solution Similarities", 0.0, 1.0);
+          if (!results.ContainsKey("Solution Similarities"))
+            results.Add(new Result("Solution Similarities", similaritiesHeatMap));
+          else
+            results["Solution Similarities"].Value = similaritiesHeatMap;
+
+          // store similarities history
+          if (storeHistory) {
+            if (!results.ContainsKey("Solution Similarities History")) {
+              HeatMapHistory history = new HeatMapHistory();
+              history.Add(similaritiesHeatMap);
+              results.Add(new Result("Solution Similarities History", history));
+            } else {
+              ((HeatMapHistory)results["Solution Similarities History"].Value).Add(similaritiesHeatMap);
+            }
+          }
+
+          // store average minimum, average and maximum similarity
+          if (!results.ContainsKey("Average Minimum Solution Similarity"))
+            results.Add(new Result("Average Minimum Solution Similarity", new DoubleValue(avgMinSimilarity)));
+          else
+            ((DoubleValue)results["Average Minimum Solution Similarity"].Value).Value = avgMinSimilarity;
+
+          if (!results.ContainsKey("Average Average Solution Similarity"))
+            results.Add(new Result("Average Average Solution Similarity", new DoubleValue(avgAvgSimilarity)));
+          else
+            ((DoubleValue)results["Average Average Solution Similarity"].Value).Value = avgAvgSimilarity;
+
+          if (!results.ContainsKey("Average Maximum Solution Similarity"))
+            results.Add(new Result("Average Maximum Solution Similarity", new DoubleValue(avgMaxSimilarity)));
+          else
+            ((DoubleValue)results["Average Maximum Solution Similarity"].Value).Value = avgMaxSimilarity;
+
+          // store average minimum, average and maximum solution similarity data table
+          DataTable minAvgMaxSimilarityDataTable;
+          if (!results.ContainsKey("Average Minimum/Average/Maximum Solution Similarity")) {
+            minAvgMaxSimilarityDataTable = new DataTable("Average Minimum/Average/Maximum Solution Similarity");
+            minAvgMaxSimilarityDataTable.VisualProperties.XAxisTitle = "Iteration";
+            minAvgMaxSimilarityDataTable.VisualProperties.YAxisTitle = "Solution Similarity";
+            minAvgMaxSimilarityDataTable.Rows.Add(new DataRow("Average Minimum Solution Similarity", null));
+            minAvgMaxSimilarityDataTable.Rows["Average Minimum Solution Similarity"].VisualProperties.StartIndexZero = true;
+            minAvgMaxSimilarityDataTable.Rows.Add(new DataRow("Average Average Solution Similarity", null));
+            minAvgMaxSimilarityDataTable.Rows["Average Average Solution Similarity"].VisualProperties.StartIndexZero = true;
+            minAvgMaxSimilarityDataTable.Rows.Add(new DataRow("Average Maximum Solution Similarity", null));
+            minAvgMaxSimilarityDataTable.Rows["Average Maximum Solution Similarity"].VisualProperties.StartIndexZero = true;
+            results.Add(new Result("Average Minimum/Average/Maximum Solution Similarity", minAvgMaxSimilarityDataTable));
+          } else {
+            minAvgMaxSimilarityDataTable = (DataTable)results["Average Minimum/Average/Maximum Solution Similarity"].Value;
+          }
+          minAvgMaxSimilarityDataTable.Rows["Average Minimum Solution Similarity"].Values.Add(avgMinSimilarity);
+          minAvgMaxSimilarityDataTable.Rows["Average Average Solution Similarity"].Values.Add(avgAvgSimilarity);
+          minAvgMaxSimilarityDataTable.Rows["Average Maximum Solution Similarity"].Values.Add(avgMaxSimilarity);
+
+          // store minimum, average, maximum similarities data table
+          DataTable minAvgMaxSimilaritiesDataTable = new DataTable("Minimum/Average/Maximum Solution Similarities");
+          minAvgMaxSimilaritiesDataTable.VisualProperties.XAxisTitle = "Solution Index";
+          minAvgMaxSimilaritiesDataTable.VisualProperties.YAxisTitle = "Solution Similarity";
+          minAvgMaxSimilaritiesDataTable.Rows.Add(new DataRow("Minimum Solution Similarity", null, minSimilarities));
+          minAvgMaxSimilaritiesDataTable.Rows["Minimum Solution Similarity"].VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Points;
+          minAvgMaxSimilaritiesDataTable.Rows.Add(new DataRow("Average Solution Similarity", null, avgSimilarities));
+          minAvgMaxSimilaritiesDataTable.Rows["Average Solution Similarity"].VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Points;
+          minAvgMaxSimilaritiesDataTable.Rows.Add(new DataRow("Maximum Solution Similarity", null, maxSimilarities));
+          minAvgMaxSimilaritiesDataTable.Rows["Maximum Solution Similarity"].VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Points;
+          if (!results.ContainsKey("Minimum/Average/Maximum Solution Similarities")) {
+            results.Add(new Result("Minimum/Average/Maximum Solution Similarities", minAvgMaxSimilaritiesDataTable));
+          } else {
+            results["Minimum/Average/Maximum Solution Similarities"].Value = minAvgMaxSimilaritiesDataTable;
+          }
+
+          // store minimum, average, maximum similarities history
+          if (storeHistory) {
+            if (!results.ContainsKey("Minimum/Average/Maximum Solution Similarities History")) {
+              DataTableHistory history = new DataTableHistory();
+              history.Add(minAvgMaxSimilaritiesDataTable);
+              results.Add(new Result("Minimum/Average/Maximum Solution Similarities History", history));
+            } else {
+              ((DataTableHistory)results["Minimum/Average/Maximum Solution Similarities History"].Value).Add(minAvgMaxSimilaritiesDataTable);
+            }
+          }
+        }
+      }
+      return base.Apply();
+    }
+
+    protected abstract double[,] CalculateSimilarities(T[] solutions);
+  }
+  #endregion
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/PopulationSimilarityAnalyzer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/PopulationSimilarityAnalyzer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/PopulationSimilarityAnalyzer.cs	(revision 12764)
@@ -0,0 +1,267 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// An operator for analyzing the solution similarity in a population.
+  /// </summary>
+  [Item("PopulationSimilarityAnalyzer", "An operator for analyzing the solution similarity in a population.")]
+  [StorableClass]
+  public class PopulationSimilarityAnalyzer : SingleSuccessorOperator, IAnalyzer, ISimilarityBasedOperator {
+    private const string DiversityResultNameParameterName = "DiversityResultsName";
+
+    #region Backwards compatible code, remove with 3.4
+    private ISolutionSimilarityCalculator oldSimilarityCalculator;
+    [Storable(AllowOneWay = true, Name = "SimilarityCalculator")]
+    [Obsolete]
+    private ISolutionSimilarityCalculator SimilarityCalculator { set { oldSimilarityCalculator = value; } }
+    #endregion
+
+    public virtual bool EnabledByDefault {
+      get { return false; }
+    }
+    public ScopeParameter CurrentScopeParameter {
+      get { return (ScopeParameter)Parameters["CurrentScope"]; }
+    }
+    public IValueLookupParameter<ResultCollection> ResultsParameter {
+      get { return (IValueLookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    public IConstrainedValueParameter<ISolutionSimilarityCalculator> SimilarityCalculatorParameter {
+      get { return (IConstrainedValueParameter<ISolutionSimilarityCalculator>)Parameters["SimilarityCalculator"]; }
+    }
+    public IValueParameter<BoolValue> StoreHistoryParameter {
+      get { return (IValueParameter<BoolValue>)Parameters["StoreHistory"]; }
+    }
+    public IValueParameter<IntValue> UpdateIntervalParameter {
+      get { return (IValueParameter<IntValue>)Parameters["UpdateInterval"]; }
+    }
+    public ILookupParameter<IntValue> UpdateCounterParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["UpdateCounter"]; }
+    }
+    public IFixedValueParameter<StringValue> DiversityResultNameParameter {
+      get { return (FixedValueParameter<StringValue>)Parameters[DiversityResultNameParameterName]; }
+    }
+
+    public string DiversityResultName {
+      get { return DiversityResultNameParameter.Value.Value; }
+      set { DiversityResultNameParameter.Value.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected PopulationSimilarityAnalyzer(bool deserializing) : base(deserializing) { }
+    protected PopulationSimilarityAnalyzer(PopulationSimilarityAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public PopulationSimilarityAnalyzer(IEnumerable<ISolutionSimilarityCalculator> validSimilarityCalculators)
+      : base() {
+      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope that contains the solutions which should be analyzed."));
+      Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The result collection where the population diversity analysis results should be stored."));
+      Parameters.Add(new ConstrainedValueParameter<ISolutionSimilarityCalculator>("SimilarityCalculator", "The similarity calculator that should be used to calculate population similarity."));
+      Parameters.Add(new ValueParameter<BoolValue>("StoreHistory", "True if the history of the population diversity analysis should be stored.", new BoolValue(false)));
+      Parameters.Add(new ValueParameter<IntValue>("UpdateInterval", "The interval in which the population diversity analysis should be applied.", new IntValue(1)));
+      Parameters.Add(new LookupParameter<IntValue>("UpdateCounter", "The value which counts how many times the operator was called since the last update.", "PopulationDiversityAnalyzerUpdateCounter"));
+      Parameters.Add(new FixedValueParameter<StringValue>(DiversityResultNameParameterName, "Specifies how the diversity results should be named.", new StringValue("PopulationDiversity")));
+
+      var similarityCalculators = SimilarityCalculatorParameter.ValidValues;
+      foreach (var sc in validSimilarityCalculators)
+        similarityCalculators.Add(sc);
+
+
+      ResultsParameter.Hidden = true;
+      UpdateCounterParameter.Hidden = true;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PopulationSimilarityAnalyzer(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code, remove with 3.4
+      if (!Parameters.ContainsKey(DiversityResultNameParameterName))
+        Parameters.Add(new FixedValueParameter<StringValue>(DiversityResultNameParameterName, "Specifies how the diversity results should be named.", new StringValue("PopulationDiversity")));
+
+      if (!Parameters.ContainsKey("SimilarityCalculator"))
+        Parameters.Add(new ConstrainedValueParameter<ISolutionSimilarityCalculator>("SimilarityCalculator", "The similarity calculator that should be used to calculate solution similarity."));
+
+      SimilarityCalculatorParameter.ValidValues.Add(oldSimilarityCalculator);
+      #endregion
+    }
+
+    public override IOperation Apply() {
+      int updateInterval = UpdateIntervalParameter.Value.Value;
+      IntValue updateCounter = UpdateCounterParameter.ActualValue;
+      // if counter does not yet exist then initialize it with update interval
+      // to make sure the solutions are analyzed on the first application of this operator
+      if (updateCounter == null) {
+        updateCounter = new IntValue(updateInterval);
+        UpdateCounterParameter.ActualValue = updateCounter;
+      }
+      //analyze solutions only every 'updateInterval' times
+      if (updateCounter.Value != updateInterval) {
+        updateCounter.Value++;
+        return base.Apply();
+      }
+      updateCounter.Value = 1;
+
+      bool storeHistory = StoreHistoryParameter.Value.Value;
+      int count = CurrentScopeParameter.ActualValue.SubScopes.Count;
+
+      if (count > 1) {
+        var similarityCalculator = SimilarityCalculatorParameter.Value;
+        // calculate solution similarities
+        var similarityMatrix = similarityCalculator.CalculateSolutionCrowdSimilarity(CurrentScopeParameter.ActualValue);
+        double[,] similarities = new double[similarityMatrix.Length, similarityMatrix[0].Length];
+        for (int i = 0; i < similarityMatrix.Length; i++)
+          for (int j = 0; j < similarityMatrix[0].Length; j++)
+            similarities[i, j] = similarityMatrix[i][j];
+
+        // calculate minimum, average and maximum similarities
+        double similarity;
+        double[] minSimilarities = new double[count];
+        double[] avgSimilarities = new double[count];
+        double[] maxSimilarities = new double[count];
+        for (int i = 0; i < count; i++) {
+          minSimilarities[i] = 1;
+          avgSimilarities[i] = 0;
+          maxSimilarities[i] = 0;
+          for (int j = 0; j < count; j++) {
+            if (i != j) {
+              similarity = similarities[i, j];
+
+              if ((similarity < 0) || (similarity > 1))
+                throw new InvalidOperationException("Solution similarities have to be in the interval [0;1].");
+
+              if (minSimilarities[i] > similarity) minSimilarities[i] = similarity;
+              avgSimilarities[i] += similarity;
+              if (maxSimilarities[i] < similarity) maxSimilarities[i] = similarity;
+            }
+          }
+          avgSimilarities[i] = avgSimilarities[i] / (count - 1);
+        }
+        double avgMinSimilarity = minSimilarities.Average();
+        double avgAvgSimilarity = avgSimilarities.Average();
+        double avgMaxSimilarity = maxSimilarities.Average();
+
+        // fetch results collection
+        ResultCollection results;
+        if (!ResultsParameter.ActualValue.ContainsKey(DiversityResultName)) {
+          results = new ResultCollection();
+          ResultsParameter.ActualValue.Add(new Result(DiversityResultName, results));
+        } else {
+          results = (ResultCollection)ResultsParameter.ActualValue[DiversityResultName].Value;
+        }
+
+        // store similarities
+        HeatMap similaritiesHeatMap = new HeatMap(similarities, "Solution Similarities", 0.0, 1.0);
+        if (!results.ContainsKey("Solution Similarities"))
+          results.Add(new Result("Solution Similarities", similaritiesHeatMap));
+        else
+          results["Solution Similarities"].Value = similaritiesHeatMap;
+
+        // store similarities history
+        if (storeHistory) {
+          if (!results.ContainsKey("Solution Similarities History")) {
+            HeatMapHistory history = new HeatMapHistory();
+            history.Add(similaritiesHeatMap);
+            results.Add(new Result("Solution Similarities History", history));
+          } else {
+            ((HeatMapHistory)results["Solution Similarities History"].Value).Add(similaritiesHeatMap);
+          }
+        }
+
+        // store average minimum, average and maximum similarity
+        if (!results.ContainsKey("Average Minimum Solution Similarity"))
+          results.Add(new Result("Average Minimum Solution Similarity", new DoubleValue(avgMinSimilarity)));
+        else
+          ((DoubleValue)results["Average Minimum Solution Similarity"].Value).Value = avgMinSimilarity;
+
+        if (!results.ContainsKey("Average Average Solution Similarity"))
+          results.Add(new Result("Average Average Solution Similarity", new DoubleValue(avgAvgSimilarity)));
+        else
+          ((DoubleValue)results["Average Average Solution Similarity"].Value).Value = avgAvgSimilarity;
+
+        if (!results.ContainsKey("Average Maximum Solution Similarity"))
+          results.Add(new Result("Average Maximum Solution Similarity", new DoubleValue(avgMaxSimilarity)));
+        else
+          ((DoubleValue)results["Average Maximum Solution Similarity"].Value).Value = avgMaxSimilarity;
+
+        // store average minimum, average and maximum solution similarity data table
+        DataTable minAvgMaxSimilarityDataTable;
+        if (!results.ContainsKey("Average Minimum/Average/Maximum Solution Similarity")) {
+          minAvgMaxSimilarityDataTable = new DataTable("Average Minimum/Average/Maximum Solution Similarity");
+          minAvgMaxSimilarityDataTable.VisualProperties.XAxisTitle = "Iteration";
+          minAvgMaxSimilarityDataTable.VisualProperties.YAxisTitle = "Solution Similarity";
+          minAvgMaxSimilarityDataTable.Rows.Add(new DataRow("Average Minimum Solution Similarity", null));
+          minAvgMaxSimilarityDataTable.Rows["Average Minimum Solution Similarity"].VisualProperties.StartIndexZero = true;
+          minAvgMaxSimilarityDataTable.Rows.Add(new DataRow("Average Average Solution Similarity", null));
+          minAvgMaxSimilarityDataTable.Rows["Average Average Solution Similarity"].VisualProperties.StartIndexZero = true;
+          minAvgMaxSimilarityDataTable.Rows.Add(new DataRow("Average Maximum Solution Similarity", null));
+          minAvgMaxSimilarityDataTable.Rows["Average Maximum Solution Similarity"].VisualProperties.StartIndexZero = true;
+          results.Add(new Result("Average Minimum/Average/Maximum Solution Similarity", minAvgMaxSimilarityDataTable));
+        } else {
+          minAvgMaxSimilarityDataTable = (DataTable)results["Average Minimum/Average/Maximum Solution Similarity"].Value;
+        }
+        minAvgMaxSimilarityDataTable.Rows["Average Minimum Solution Similarity"].Values.Add(avgMinSimilarity);
+        minAvgMaxSimilarityDataTable.Rows["Average Average Solution Similarity"].Values.Add(avgAvgSimilarity);
+        minAvgMaxSimilarityDataTable.Rows["Average Maximum Solution Similarity"].Values.Add(avgMaxSimilarity);
+
+        // store minimum, average, maximum similarities data table
+        DataTable minAvgMaxSimilaritiesDataTable = new DataTable("Minimum/Average/Maximum Solution Similarities");
+        minAvgMaxSimilaritiesDataTable.VisualProperties.XAxisTitle = "Solution Index";
+        minAvgMaxSimilaritiesDataTable.VisualProperties.YAxisTitle = "Solution Similarity";
+        minAvgMaxSimilaritiesDataTable.Rows.Add(new DataRow("Minimum Solution Similarity", null, minSimilarities));
+        minAvgMaxSimilaritiesDataTable.Rows["Minimum Solution Similarity"].VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Points;
+        minAvgMaxSimilaritiesDataTable.Rows.Add(new DataRow("Average Solution Similarity", null, avgSimilarities));
+        minAvgMaxSimilaritiesDataTable.Rows["Average Solution Similarity"].VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Points;
+        minAvgMaxSimilaritiesDataTable.Rows.Add(new DataRow("Maximum Solution Similarity", null, maxSimilarities));
+        minAvgMaxSimilaritiesDataTable.Rows["Maximum Solution Similarity"].VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Points;
+        if (!results.ContainsKey("Minimum/Average/Maximum Solution Similarities")) {
+          results.Add(new Result("Minimum/Average/Maximum Solution Similarities", minAvgMaxSimilaritiesDataTable));
+        } else {
+          results["Minimum/Average/Maximum Solution Similarities"].Value = minAvgMaxSimilaritiesDataTable;
+        }
+
+        // store minimum, average, maximum similarities history
+        if (storeHistory) {
+          if (!results.ContainsKey("Minimum/Average/Maximum Solution Similarities History")) {
+            DataTableHistory history = new DataTableHistory();
+            history.Add(minAvgMaxSimilaritiesDataTable);
+            results.Add(new Result("Minimum/Average/Maximum Solution Similarities History", history));
+          } else {
+            ((DataTableHistory)results["Minimum/Average/Maximum Solution Similarities History"].Value).Add(minAvgMaxSimilaritiesDataTable);
+          }
+        }
+      }
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/SingleObjectivePopulationDiversityAnalyzer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/SingleObjectivePopulationDiversityAnalyzer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/SingleObjectivePopulationDiversityAnalyzer.cs	(revision 12764)
@@ -0,0 +1,49 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Analysis {
+  // use HeuristicLab.Analysis.PopulationSimilarityAnalyzer instead
+  // BackwardsCompatibility3.3
+  #region Backwards compatible code, remove with 3.4
+  /// <summary>
+  /// An operator for analyzing the solution diversity in a population.
+  /// </summary>
+  [Obsolete]
+  [NonDiscoverableType]
+  [Item("SingleObjectivePopulationDiversityAnalyzer", "An operator for analyzing the solution diversity in a population.")]
+  [StorableClass]
+  public class SingleObjectivePopulationDiversityAnalyzer : PopulationSimilarityAnalyzer {
+    [StorableConstructor]
+    protected SingleObjectivePopulationDiversityAnalyzer(bool deserializing) : base(deserializing) { }
+    protected SingleObjectivePopulationDiversityAnalyzer(SingleObjectivePopulationDiversityAnalyzer original, Cloner cloner) : base(original, cloner) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SingleObjectivePopulationDiversityAnalyzer(this, cloner);
+    }
+  }
+  #endregion
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Properties/AssemblyInfo.cs.frame	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Properties/AssemblyInfo.cs.frame	(revision 12764)
@@ -0,0 +1,56 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.Analysis")]
+[assembly: AssemblyDescription("HeuristicLab algorithm analysis classes")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2015 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("b987398b-693f-41e6-8a90-10374e9464ba")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.12.$WCREV$")]
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/BestAverageWorstQualityAnalyzer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/BestAverageWorstQualityAnalyzer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/BestAverageWorstQualityAnalyzer.cs	(revision 12764)
@@ -0,0 +1,197 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// An operator which analyzes the best, average and worst quality of solutions in the scope tree.
+  /// </summary>
+  [Item("BestAverageWorstQualityAnalyzer", "An operator which analyzes the best, average and worst quality of solutions in the scope tree.")]
+  [StorableClass]
+  public sealed class BestAverageWorstQualityAnalyzer : AlgorithmOperator, IAnalyzer, ISingleObjectiveOperator {
+    #region Parameter properties
+    public ValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (ValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestKnownQualityParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestQualityParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestQuality"]; }
+    }
+    public ValueLookupParameter<DoubleValue> CurrentBestQualityParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["CurrentBestQuality"]; }
+    }
+    public ValueLookupParameter<DoubleValue> CurrentAverageQualityParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["CurrentAverageQuality"]; }
+    }
+    public ValueLookupParameter<DoubleValue> CurrentWorstQualityParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["CurrentWorstQuality"]; }
+    }
+    public ValueLookupParameter<DataTable> QualitiesParameter {
+      get { return (ValueLookupParameter<DataTable>)Parameters["Qualities"]; }
+    }
+    public ValueLookupParameter<DoubleValue> AbsoluteDifferenceBestKnownToBestParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["AbsoluteDifferenceBestKnownToBest"]; }
+    }
+    public ValueLookupParameter<PercentValue> RelativeDifferenceBestKnownToBestParameter {
+      get { return (ValueLookupParameter<PercentValue>)Parameters["RelativeDifferenceBestKnownToBest"]; }
+    }
+    public ValueLookupParameter<ResultCollection> ResultsParameter {
+      get { return (ValueLookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    #endregion
+
+    #region Properties
+    public bool EnabledByDefault {
+      get { return true; }
+    }
+    private BestQualityMemorizer BestQualityMemorizer {
+      get { return (BestQualityMemorizer)OperatorGraph.InitialOperator; }
+    }
+    private BestAverageWorstQualityCalculator BestAverageWorstQualityCalculator {
+      get { return (BestAverageWorstQualityCalculator)BestQualityMemorizer.Successor; }
+    }
+    #endregion
+
+    #region Storing & Cloning
+    [StorableConstructor]
+    private BestAverageWorstQualityAnalyzer(bool deserializing) : base(deserializing) { }
+    private BestAverageWorstQualityAnalyzer(BestAverageWorstQualityAnalyzer original, Cloner cloner)
+      : base(original, cloner) {
+      Initialize();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BestAverageWorstQualityAnalyzer(this, cloner);
+    }
+    #endregion
+    public BestAverageWorstQualityAnalyzer()
+      : base() {
+      #region Create parameters
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, otherwise false."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The value which represents the quality of a solution."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestKnownQuality", "The best known quality value found so far."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestQuality", "The best quality value found in the current run."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("CurrentBestQuality", "The best quality value found in the current population."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("CurrentAverageQuality", "The average quality value of all solutions in the current population."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("CurrentWorstQuality", "The worst quality value found in the current population."));
+      Parameters.Add(new ValueLookupParameter<DataTable>("Qualities", "The data table to store the current best, current average, current worst, best and best known quality value."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("AbsoluteDifferenceBestKnownToBest", "The absolute difference of the best known quality value to the best quality value."));
+      Parameters.Add(new ValueLookupParameter<PercentValue>("RelativeDifferenceBestKnownToBest", "The relative difference of the best known quality value to the best quality value."));
+      Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The results collection where the analysis values should be stored."));
+
+      BestQualityParameter.Hidden = true;
+      CurrentBestQualityParameter.Hidden = true;
+      CurrentAverageQualityParameter.Hidden = true;
+      CurrentWorstQualityParameter.Hidden = true;
+      QualitiesParameter.Hidden = true;
+      AbsoluteDifferenceBestKnownToBestParameter.Hidden = true;
+      RelativeDifferenceBestKnownToBestParameter.Hidden = true;
+      #endregion
+
+      #region Create operators
+      BestQualityMemorizer bestQualityMemorizer = new BestQualityMemorizer();
+      BestAverageWorstQualityCalculator bestAverageWorstQualityCalculator = new BestAverageWorstQualityCalculator();
+      DataTableValuesCollector dataTableValuesCollector = new DataTableValuesCollector();
+      QualityDifferenceCalculator qualityDifferenceCalculator = new QualityDifferenceCalculator();
+      ResultsCollector resultsCollector = new ResultsCollector();
+
+      bestQualityMemorizer.BestQualityParameter.ActualName = BestQualityParameter.Name;
+      bestQualityMemorizer.MaximizationParameter.ActualName = MaximizationParameter.Name;
+      bestQualityMemorizer.QualityParameter.ActualName = QualityParameter.Name;
+      bestQualityMemorizer.QualityParameter.Depth = QualityParameter.Depth;
+
+      bestAverageWorstQualityCalculator.AverageQualityParameter.ActualName = CurrentAverageQualityParameter.Name;
+      bestAverageWorstQualityCalculator.BestQualityParameter.ActualName = CurrentBestQualityParameter.Name;
+      bestAverageWorstQualityCalculator.MaximizationParameter.ActualName = MaximizationParameter.Name;
+      bestAverageWorstQualityCalculator.QualityParameter.ActualName = QualityParameter.Name;
+      bestAverageWorstQualityCalculator.QualityParameter.Depth = QualityParameter.Depth;
+      bestAverageWorstQualityCalculator.WorstQualityParameter.ActualName = CurrentWorstQualityParameter.Name;
+
+      dataTableValuesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentBestQuality", null, CurrentBestQualityParameter.Name));
+      dataTableValuesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentAverageQuality", null, CurrentAverageQualityParameter.Name));
+      dataTableValuesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentWorstQuality", null, CurrentWorstQualityParameter.Name));
+      dataTableValuesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("BestQuality", null, BestQualityParameter.Name));
+      dataTableValuesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("BestKnownQuality", null, BestKnownQualityParameter.Name));
+      dataTableValuesCollector.DataTableParameter.ActualName = QualitiesParameter.Name;
+
+      qualityDifferenceCalculator.AbsoluteDifferenceParameter.ActualName = AbsoluteDifferenceBestKnownToBestParameter.Name;
+      qualityDifferenceCalculator.FirstQualityParameter.ActualName = BestKnownQualityParameter.Name;
+      qualityDifferenceCalculator.RelativeDifferenceParameter.ActualName = RelativeDifferenceBestKnownToBestParameter.Name;
+      qualityDifferenceCalculator.SecondQualityParameter.ActualName = BestQualityParameter.Name;
+
+      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentBestQuality", null, CurrentBestQualityParameter.Name));
+      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentAverageQuality", null, CurrentAverageQualityParameter.Name));
+      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("CurrentWorstQuality", null, CurrentWorstQualityParameter.Name));
+      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("BestQuality", null, BestQualityParameter.Name));
+      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("BestKnownQuality", null, BestKnownQualityParameter.Name));
+      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("AbsoluteDifferenceBestKnownToBest", null, AbsoluteDifferenceBestKnownToBestParameter.Name));
+      resultsCollector.CollectedValues.Add(new LookupParameter<PercentValue>("RelativeDifferenceBestKnownToBest", null, RelativeDifferenceBestKnownToBestParameter.Name));
+      resultsCollector.CollectedValues.Add(new LookupParameter<DataTable>(QualitiesParameter.Name));
+      resultsCollector.ResultsParameter.ActualName = ResultsParameter.Name;
+      #endregion
+
+      #region Create operator graph
+      OperatorGraph.InitialOperator = bestQualityMemorizer;
+      bestQualityMemorizer.Successor = bestAverageWorstQualityCalculator;
+      bestAverageWorstQualityCalculator.Successor = dataTableValuesCollector;
+      dataTableValuesCollector.Successor = qualityDifferenceCalculator;
+      qualityDifferenceCalculator.Successor = resultsCollector;
+      resultsCollector.Successor = null;
+      #endregion
+
+      Initialize();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      Initialize();
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code, remove with 3.4
+      if (Parameters["Results"] is ValueLookupParameter<VariableCollection>) {
+        Parameters.Remove("Results");
+        Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The results collection where the analysis values should be stored."));
+      }
+      #endregion
+    }
+
+    private void Initialize() {
+      QualityParameter.DepthChanged += new EventHandler(QualityParameter_DepthChanged);
+    }
+
+    private void QualityParameter_DepthChanged(object sender, System.EventArgs e) {
+      BestQualityMemorizer.QualityParameter.Depth = QualityParameter.Depth;
+      BestAverageWorstQualityCalculator.QualityParameter.Depth = QualityParameter.Depth;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/BestAverageWorstQualityCalculator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/BestAverageWorstQualityCalculator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/BestAverageWorstQualityCalculator.cs	(revision 12764)
@@ -0,0 +1,105 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// An operator which calculates the best, average and worst quality of solutions in the scope tree.
+  /// </summary>
+  [Item("BestAverageWorstQualityCalculator", "An operator which calculates the best, average and worst quality of solutions in the scope tree.")]
+  [StorableClass]
+  public sealed class BestAverageWorstQualityCalculator : SingleSuccessorOperator, ISingleObjectiveOperator {
+    public ValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (ValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestQualityParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestQuality"]; }
+    }
+    public ValueLookupParameter<DoubleValue> AverageQualityParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["AverageQuality"]; }
+    }
+    public ValueLookupParameter<DoubleValue> WorstQualityParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["WorstQuality"]; }
+    }
+
+    #region Storing & Cloning
+    [StorableConstructor]
+    private BestAverageWorstQualityCalculator(bool deserializing) : base(deserializing) { }
+    private BestAverageWorstQualityCalculator(BestAverageWorstQualityCalculator original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BestAverageWorstQualityCalculator(this, cloner);
+    }
+    #endregion
+    public BestAverageWorstQualityCalculator()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the current problem is a maximization problem, otherwise false."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The value contained in the scope tree which represents the solution quality."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestQuality", "The quality value of the best solution."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("AverageQuality", "The average quality of all solutions."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("WorstQuality", "The quality value of the worst solution."));
+
+      BestQualityParameter.Hidden = true;
+      AverageQualityParameter.Hidden = true;
+      WorstQualityParameter.Hidden = true;
+    }
+
+
+    public override IOperation Apply() {
+      ItemArray<DoubleValue> qualities = QualityParameter.ActualValue;
+      bool maximization = MaximizationParameter.ActualValue.Value;
+
+      if (qualities.Length > 0) {
+        double min = double.MaxValue, max = double.MinValue, sum = 0.0;
+        for (int i = 0; i < qualities.Length; i++) {
+          if (qualities[i].Value < min) min = qualities[i].Value;
+          if (qualities[i].Value > max) max = qualities[i].Value;
+          sum += qualities[i].Value;
+        }
+        if (!maximization) {
+          double temp = min;
+          min = max;
+          max = temp;
+        }
+
+        DoubleValue best = BestQualityParameter.ActualValue;
+        if (best == null) BestQualityParameter.ActualValue = new DoubleValue(max);
+        else best.Value = max;
+        DoubleValue average = AverageQualityParameter.ActualValue;
+        if (average == null) AverageQualityParameter.ActualValue = new DoubleValue(sum / qualities.Length);
+        else average.Value = sum / qualities.Length;
+        DoubleValue worst = WorstQualityParameter.ActualValue;
+        if (worst == null) WorstQualityParameter.ActualValue = new DoubleValue(min);
+        else worst.Value = min;
+      }
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/BestQualityMemorizer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/BestQualityMemorizer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/BestQualityMemorizer.cs	(revision 12764)
@@ -0,0 +1,80 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// An operator that updates the best quality found so far with those qualities contained in the scope tree.
+  /// </summary>
+  [Item("BestQualityMemorizer", "An operator that updates the best quality found so far with those qualities contained in the scope tree.")]
+  [StorableClass]
+  public class BestQualityMemorizer : SingleSuccessorOperator, ISingleObjectiveOperator {
+    public ValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (ValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestQualityParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestQuality"]; }
+    }
+
+    #region Storing & Cloning
+    [StorableConstructor]
+    protected BestQualityMemorizer(bool deserializing) : base(deserializing) { }
+    protected BestQualityMemorizer(BestQualityMemorizer original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BestQualityMemorizer(this, cloner);
+    }
+    #endregion
+    public BestQualityMemorizer()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the current problem is a maximization problem, otherwise false."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The value contained in the scope tree which represents the solution quality."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestQuality", "The quality value of the best solution."));
+    }
+
+    public override IOperation Apply() {
+      ItemArray<DoubleValue> qualities = QualityParameter.ActualValue;
+      bool maximization = MaximizationParameter.ActualValue.Value;
+      DoubleValue best = BestQualityParameter.ActualValue;
+      double max = (best != null) ? (best.Value) : ((maximization) ? (double.MinValue) : (double.MaxValue));
+
+      foreach (DoubleValue quality in qualities)
+        if (IsBetter(maximization, quality.Value, max)) max = quality.Value;
+
+      if (best == null) BestQualityParameter.ActualValue = new DoubleValue(max);
+      else best.Value = max;
+      return base.Apply();
+    }
+
+    private bool IsBetter(bool maximization, double quality, double max) {
+      return (maximization && quality > max || !maximization && quality < max);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityAnalyzer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityAnalyzer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityAnalyzer.cs	(revision 12764)
@@ -0,0 +1,174 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// An operator which analyzes the quality of solutions in the scope tree.
+  /// </summary>
+  [Item("QualityAnalyzer", "An operator which analyzes the quality of solutions in the scope tree.")]
+  [StorableClass]
+  public sealed class QualityAnalyzer : AlgorithmOperator, IAnalyzer, ISingleObjectiveOperator {
+    #region Parameter properties
+    public ValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (ValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestKnownQualityParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestQualityParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestQuality"]; }
+    }
+    public ValueLookupParameter<DataTable> QualitiesParameter {
+      get { return (ValueLookupParameter<DataTable>)Parameters["Qualities"]; }
+    }
+    public ValueLookupParameter<DoubleValue> AbsoluteDifferenceBestKnownToBestParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["AbsoluteDifferenceBestKnownToBest"]; }
+    }
+    public ValueLookupParameter<PercentValue> RelativeDifferenceBestKnownToBestParameter {
+      get { return (ValueLookupParameter<PercentValue>)Parameters["RelativeDifferenceBestKnownToBest"]; }
+    }
+    public ValueLookupParameter<VariableCollection> ResultsParameter {
+      get { return (ValueLookupParameter<VariableCollection>)Parameters["Results"]; }
+    }
+    #endregion
+
+    #region Properties
+    public bool EnabledByDefault {
+      get { return true; }
+    }
+    private BestQualityMemorizer BestQualityMemorizer {
+      get { return (BestQualityMemorizer)OperatorGraph.InitialOperator; }
+    }
+    private BestQualityMemorizer BestKnownQualityMemorizer {
+      get { return (BestQualityMemorizer)BestQualityMemorizer.Successor; }
+    }
+    private DataTableValuesCollector DataTableValuesCollector {
+      get { return (DataTableValuesCollector)BestKnownQualityMemorizer.Successor; }
+    }
+    private ResultsCollector ResultsCollector {
+      get { return (ResultsCollector)((QualityDifferenceCalculator)DataTableValuesCollector.Successor).Successor; }
+    }
+    #endregion
+
+    #region Storing & Cloning
+    [StorableConstructor]
+    private QualityAnalyzer(bool deserializing) : base(deserializing) { }
+    private QualityAnalyzer(QualityAnalyzer original, Cloner cloner)
+      : base(original, cloner) {
+      Initialize();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new QualityAnalyzer(this, cloner);
+    }
+    #endregion
+    public QualityAnalyzer()
+      : base() {
+      #region Create parameters
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, otherwise false."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The value which represents the quality of a solution."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestKnownQuality", "The best known quality value found so far."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestQuality", "The best quality value found in the current run."));
+      Parameters.Add(new ValueLookupParameter<DataTable>("Qualities", "The data table to store the current best, current average, current worst, best and best known quality value."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("AbsoluteDifferenceBestKnownToBest", "The absolute difference of the best known quality value to the best quality value."));
+      Parameters.Add(new ValueLookupParameter<PercentValue>("RelativeDifferenceBestKnownToBest", "The relative difference of the best known quality value to the best quality value."));
+      Parameters.Add(new ValueLookupParameter<VariableCollection>("Results", "The results collection where the analysis values should be stored."));
+      #endregion
+
+      #region Create operators
+      BestQualityMemorizer bestQualityMemorizer = new BestQualityMemorizer();
+      BestQualityMemorizer bestKnownQualityMemorizer = new BestQualityMemorizer();
+      DataTableValuesCollector dataTableValuesCollector = new DataTableValuesCollector();
+      QualityDifferenceCalculator qualityDifferenceCalculator = new QualityDifferenceCalculator();
+      ResultsCollector resultsCollector = new ResultsCollector();
+
+      bestQualityMemorizer.BestQualityParameter.ActualName = BestQualityParameter.Name;
+      bestQualityMemorizer.MaximizationParameter.ActualName = MaximizationParameter.Name;
+      bestQualityMemorizer.QualityParameter.ActualName = QualityParameter.Name;
+      bestQualityMemorizer.QualityParameter.Depth = QualityParameter.Depth;
+
+      bestKnownQualityMemorizer.BestQualityParameter.ActualName = BestKnownQualityParameter.Name;
+      bestKnownQualityMemorizer.MaximizationParameter.ActualName = MaximizationParameter.Name;
+      bestKnownQualityMemorizer.QualityParameter.ActualName = QualityParameter.Name;
+      bestKnownQualityMemorizer.QualityParameter.Depth = QualityParameter.Depth;
+
+      dataTableValuesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("BestQuality", null, BestQualityParameter.Name));
+      dataTableValuesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("BestKnownQuality", null, BestKnownQualityParameter.Name));
+      dataTableValuesCollector.CollectedValues.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", null, QualityParameter.Name));
+      ((ScopeTreeLookupParameter<DoubleValue>)dataTableValuesCollector.CollectedValues["Quality"]).Depth = QualityParameter.Depth;
+      dataTableValuesCollector.DataTableParameter.ActualName = QualitiesParameter.Name;
+
+      qualityDifferenceCalculator.AbsoluteDifferenceParameter.ActualName = AbsoluteDifferenceBestKnownToBestParameter.Name;
+      qualityDifferenceCalculator.FirstQualityParameter.ActualName = BestKnownQualityParameter.Name;
+      qualityDifferenceCalculator.RelativeDifferenceParameter.ActualName = RelativeDifferenceBestKnownToBestParameter.Name;
+      qualityDifferenceCalculator.SecondQualityParameter.ActualName = BestQualityParameter.Name;
+
+      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("BestQuality", null, BestQualityParameter.Name));
+      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("BestKnownQuality", null, BestKnownQualityParameter.Name));
+      resultsCollector.CollectedValues.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", null, QualityParameter.Name));
+      ((ScopeTreeLookupParameter<DoubleValue>)resultsCollector.CollectedValues["Quality"]).Depth = QualityParameter.Depth;
+      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("AbsoluteDifferenceBestKnownToBest", null, AbsoluteDifferenceBestKnownToBestParameter.Name));
+      resultsCollector.CollectedValues.Add(new LookupParameter<PercentValue>("RelativeDifferenceBestKnownToBest", null, RelativeDifferenceBestKnownToBestParameter.Name));
+      resultsCollector.CollectedValues.Add(new LookupParameter<DataTable>(QualitiesParameter.Name));
+      resultsCollector.ResultsParameter.ActualName = ResultsParameter.Name;
+      #endregion
+
+      #region Create operator graph
+      OperatorGraph.InitialOperator = bestQualityMemorizer;
+      bestQualityMemorizer.Successor = bestKnownQualityMemorizer;
+      bestKnownQualityMemorizer.Successor = dataTableValuesCollector;
+      dataTableValuesCollector.Successor = qualityDifferenceCalculator;
+      qualityDifferenceCalculator.Successor = resultsCollector;
+      resultsCollector.Successor = null;
+      #endregion
+
+      Initialize();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      Initialize();
+    }
+
+    private void Initialize() {
+      QualityParameter.DepthChanged += new EventHandler(QualityParameter_DepthChanged);
+    }
+
+    private void QualityParameter_DepthChanged(object sender, System.EventArgs e) {
+      BestQualityMemorizer.QualityParameter.Depth = QualityParameter.Depth;
+      BestKnownQualityMemorizer.QualityParameter.Depth = QualityParameter.Depth;
+      ((ScopeTreeLookupParameter<DoubleValue>)DataTableValuesCollector.CollectedValues["Quality"]).Depth = QualityParameter.Depth;
+      ((ScopeTreeLookupParameter<DoubleValue>)ResultsCollector.CollectedValues["Quality"]).Depth = QualityParameter.Depth;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityDifferenceCalculator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityDifferenceCalculator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityDifferenceCalculator.cs	(revision 12764)
@@ -0,0 +1,81 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// An operator which calculates the absolute and relative difference of two quality values.
+  /// </summary>
+  [Item("QualityDifferenceCalculator", "An operator which calculates the absolute and relative difference of two quality values.")]
+  [StorableClass]
+  public class QualityDifferenceCalculator : SingleSuccessorOperator {
+    public IValueLookupParameter<DoubleValue> FirstQualityParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["FirstQuality"]; }
+    }
+    public IValueLookupParameter<DoubleValue> SecondQualityParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["SecondQuality"]; }
+    }
+    public IValueLookupParameter<DoubleValue> AbsoluteDifferenceParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["AbsoluteDifference"]; }
+    }
+    public IValueLookupParameter<PercentValue> RelativeDifferenceParameter {
+      get { return (IValueLookupParameter<PercentValue>)Parameters["RelativeDifference"]; }
+    }
+
+    #region Storing & Cloning
+    [StorableConstructor]
+    protected QualityDifferenceCalculator(bool deserializing) : base(deserializing) { }
+    protected QualityDifferenceCalculator(QualityDifferenceCalculator original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new QualityDifferenceCalculator(this, cloner);
+    }
+    #endregion
+    public QualityDifferenceCalculator()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("FirstQuality", "The first quality value from which the difference to the second quality value is calculated."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("SecondQuality", "The second quality value from which the difference from the first quality value is calculated."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("AbsoluteDifference", "The absolute difference of the first and second quality value."));
+      Parameters.Add(new ValueLookupParameter<PercentValue>("RelativeDifference", "The relative difference of the first and second quality value."));
+    }
+
+    public override IOperation Apply() {
+      DoubleValue first = FirstQualityParameter.ActualValue;
+      DoubleValue second = SecondQualityParameter.ActualValue;
+
+      if ((first != null) && (second != null)) {
+        double absolute = second.Value - first.Value;
+        double relative = first.Value == 0 ? double.NaN : absolute / first.Value;
+
+        if (AbsoluteDifferenceParameter.ActualValue == null) AbsoluteDifferenceParameter.ActualValue = new DoubleValue(absolute);
+        else AbsoluteDifferenceParameter.ActualValue.Value = absolute;
+        if (RelativeDifferenceParameter.ActualValue == null) RelativeDifferenceParameter.ActualValue = new PercentValue(relative);
+        else RelativeDifferenceParameter.ActualValue.Value = relative;
+      }
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityDistributionAnalyzer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityDistributionAnalyzer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityDistributionAnalyzer.cs	(revision 12764)
@@ -0,0 +1,139 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.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.QualityAnalysis {
+  [Item("QualityDistributionAnalyzer", "Analyzes the distribution of the quality values in that it adds a Histogram of them into the result collection.")]
+  [StorableClass]
+  public class QualityDistributionAnalyzer : SingleSuccessorOperator, IAnalyzer, IIterationBasedOperator, ISingleObjectiveOperator {
+
+    #region Parameter properties
+    public IScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public IValueLookupParameter<ResultCollection> ResultsParameter {
+      get { return (IValueLookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    private ValueParameter<StringValue> HistogramNameParameter {
+      get { return (ValueParameter<StringValue>)Parameters["HistogramName"]; }
+    }
+    private ValueParameter<BoolValue> StoreHistoryParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["StoreHistory"]; }
+    }
+    public ILookupParameter<IntValue> IterationsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["Iterations"]; }
+    }
+    public IValueLookupParameter<IntValue> MaximumIterationsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+    #endregion
+
+    public virtual bool EnabledByDefault {
+      get { return true; }
+    }
+
+    public string HistogramName {
+      get { return HistogramNameParameter.Value.Value; }
+      set { HistogramNameParameter.Value.Value = value; }
+    }
+
+    public bool StoreHistory {
+      get { return StoreHistoryParameter.Value.Value; }
+      set { StoreHistoryParameter.Value.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected QualityDistributionAnalyzer(bool deserializing) : base(deserializing) { }
+    protected QualityDistributionAnalyzer(QualityDistributionAnalyzer original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public QualityDistributionAnalyzer()
+      : base() {
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The value which represents the quality of a solution."));
+      Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The results collection where the analysis values should be stored."));
+      Parameters.Add(new FixedValueParameter<StringValue>("HistogramName", "The name of the histogram that gets injected in to the results collection.", new StringValue("Quality Distribution")));
+      Parameters.Add(new FixedValueParameter<BoolValue>("StoreHistory", "True if the history should be stored in addition to the current distribution", new BoolValue(false)));
+      Parameters.Add(new LookupParameter<IntValue>("Iterations", "Optional: A value indicating the current iteration."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "Unused", new IntValue(-1)));
+
+      QualityParameter.Hidden = true;
+      ResultsParameter.Hidden = true;
+      IterationsParameter.Hidden = true;
+      MaximumIterationsParameter.Hidden = true;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new QualityDistributionAnalyzer(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      DataTable qualityDistribution = null;
+      ResultCollection results = ResultsParameter.ActualValue;
+      string description = "Shows the quality distributions in the current population.";
+      if (results.ContainsKey(HistogramName)) {
+        qualityDistribution = results[HistogramName].Value as DataTable;
+      } else {
+        qualityDistribution = new DataTable("Population Quality Distribution", description);
+        qualityDistribution.VisualProperties.XAxisTitle = QualityParameter.ActualName;
+        qualityDistribution.VisualProperties.YAxisTitle = "Frequency";
+        results.Add(new Result(HistogramName, description, qualityDistribution));
+      }
+      DataRow row;
+      if (!qualityDistribution.Rows.TryGetValue("QualityDistribution", out row)) {
+        row = new DataRow("QualityDistribution");
+        row.VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Histogram;
+        qualityDistribution.Rows.Add(row);
+      }
+      var qualities = QualityParameter.ActualValue;
+      row.Values.Replace(qualities.Select(x => x.Value));
+
+      if (StoreHistory) {
+        string historyResultName = HistogramName + " History";
+        DataTableHistory qdHistory = null;
+        if (results.ContainsKey(historyResultName)) {
+          qdHistory = results[historyResultName].Value as DataTableHistory;
+        } else {
+          qdHistory = new DataTableHistory();
+          results.Add(new Result(historyResultName, qdHistory));
+        }
+        DataTable table = (DataTable)qualityDistribution.Clone();
+        IntValue iteration = IterationsParameter.ActualValue;
+        if (iteration != null) {
+          string iterationName = IterationsParameter.ActualName;
+          if (iterationName.EndsWith("s")) iterationName = iterationName.Remove(iterationName.Length - 1);
+          string appendix = " at " + iterationName + " " + iteration.Value.ToString();
+          table.Name += appendix;
+          table.Rows["QualityDistribution"].VisualProperties.DisplayName += appendix;
+        }
+        qdHistory.Add(table);
+      }
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityVsEvaluationsAnalyzer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityVsEvaluationsAnalyzer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityVsEvaluationsAnalyzer.cs	(revision 12764)
@@ -0,0 +1,76 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using 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("QualityVsEvaluationsAnalyzer", @"Creates a plot of the solution quality with respect to the number of evaluated solutions.")]
+  [StorableClass]
+  public class QualityVsEvaluationsAnalyzer : 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 IResultParameter<IndexedDataTable<int>> QualityVsEvaluationsParameter {
+      get { return (IResultParameter<IndexedDataTable<int>>)Parameters["QualityVsEvaluations"]; }
+    }
+
+    [StorableConstructor]
+    protected QualityVsEvaluationsAnalyzer(bool deserializing) : base(deserializing) { }
+    protected QualityVsEvaluationsAnalyzer(QualityVsEvaluationsAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public QualityVsEvaluationsAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleValue>("BestQuality", "The quality value that should be compared."));
+      Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The quality value that should be compared."));
+      Parameters.Add(new ResultParameter<IndexedDataTable<int>>("QualityVsEvaluations", "Data table containing the first hitting graph with evaluations as the x-axis."));
+      QualityVsEvaluationsParameter.DefaultValue = new IndexedDataTable<int>("Quality vs Evaluations") {
+        Rows = { new IndexedDataRow<int>("First-hit Graph") { VisualProperties = { ChartType = DataRowVisualProperties.DataRowChartType.StepLine } } }
+      };
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new QualityVsEvaluationsAnalyzer(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var bestQuality = BestQualityParameter.ActualValue.Value;
+      var evaluations = EvaluatedSolutionsParameter.ActualValue.Value;
+
+      var dataTable = QualityVsEvaluationsParameter.ResultValue;
+      dataTable.Rows["First-hit Graph"].Values.Add(Tuple.Create(evaluations, bestQuality));
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/ScaledQualityDifferenceAnalyzer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/ScaledQualityDifferenceAnalyzer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/QualityAnalysis/ScaledQualityDifferenceAnalyzer.cs	(revision 12764)
@@ -0,0 +1,102 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis.QualityAnalysis {
+  [Item("ScaledQualityDifferenceAnalyzer", @"Calculates the quality value relative to a certain range given with a minimum and a maximum value.
+The difference lies in the interval [0;1] if the range [min;max] is as large as the observed quality values, otherwise the difference will become < 0 or > 1.
+A value towards 0 always means that it's closer to the better fitness value, while a value towards 1 means that it's closer to the worse fitness value.")]
+  [StorableClass]
+  public class ScaledQualityDifferenceAnalyzer : SingleSuccessorOperator, IAnalyzer, ISingleObjectiveOperator {
+    public virtual bool EnabledByDefault {
+      get { return true; }
+    }
+
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ILookupParameter<DoubleValue> ScaledDifferenceParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["ScaledDifference"]; }
+    }
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    public IValueLookupParameter<DoubleValue> MinimumQualityParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["MinimumQuality"]; }
+    }
+    public IValueLookupParameter<DoubleValue> MaximumQualityParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["MaximumQuality"]; }
+    }
+
+    [StorableConstructor]
+    protected ScaledQualityDifferenceAnalyzer(bool deserializing) : base(deserializing) { }
+    protected ScaledQualityDifferenceAnalyzer(ScaledQualityDifferenceAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public ScaledQualityDifferenceAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value that should be compared."));
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, false otherwise."));
+      Parameters.Add(new LookupParameter<DoubleValue>("ScaledDifference", "The value that describes whether the quality value lies towards the better quality in the range (<=0.5) or more towards the worse quality (> 0.5)."));
+      Parameters.Add(new LookupParameter<ResultCollection>("Results", "The result collection where the difference will be stored (in addition to the scope)."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("MinimumQuality", "The lower bound of the quality range to which the quality is compared."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("MaximumQuality", "The upper bound of the quality range to which the quality is compared."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ScaledQualityDifferenceAnalyzer(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      bool maximization = MaximizationParameter.ActualValue.Value;
+      double quality = QualityParameter.ActualValue.Value, max = MaximumQualityParameter.ActualValue.Value, min = MinimumQualityParameter.ActualValue.Value;
+      double difference;
+
+      difference = ((quality - min) / (max - min));
+      if (maximization) difference = 1.0 - difference;
+
+      DoubleValue differenceValue = ScaledDifferenceParameter.ActualValue;
+      if (differenceValue == null) {
+        differenceValue = new DoubleValue(difference);
+        ScaledDifferenceParameter.ActualValue = differenceValue;
+      } else differenceValue.Value = difference;
+
+      ResultCollection results = ResultsParameter.ActualValue;
+      if (results != null) {
+        IResult r;
+        if (!results.TryGetValue(ScaledDifferenceParameter.TranslatedName, out r)) {
+          r = new Result(ScaledDifferenceParameter.TranslatedName, differenceValue);
+          results.Add(r);
+        }
+      }
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/BonferroniHolm.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/BonferroniHolm.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/BonferroniHolm.cs	(revision 12764)
@@ -0,0 +1,66 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace HeuristicLab.Analysis.Statistics {
+  public static class BonferroniHolm {
+    /// <summary>
+    /// Based on David Groppe's MATLAB implementation 
+    /// (BSD licensed, see 
+    /// http://www.mathworks.com/matlabcentral/fileexchange/28303-bonferroni-holm-correction-for-multiple-comparisons)
+    /// </summary>
+    public static double[] Calculate(double globalAlpha, double[] pValues, out bool[] h) {
+      int k = pValues.Length;
+      double[] alphaNiveau = new double[k];
+      double[] adjustedPValues = new double[k];
+      bool[] decision = new bool[k];
+      Dictionary<int, double> pValuesIndizes = new Dictionary<int, double>();
+
+      for (int i = 0; i < k; i++) {
+        pValuesIndizes.Add(i, pValues[i]);
+      }
+      var sortedPValues = pValuesIndizes.OrderBy(x => x.Value).ToArray();
+
+      for (int i = 1; i < k + 1; i++) {
+        alphaNiveau[i - 1] = globalAlpha / (k - i + 1);
+        int idx = sortedPValues[i - 1].Key;
+
+        if (i == 1) {
+          //true means reject
+          decision[idx] = sortedPValues[i - 1].Value < alphaNiveau[i - 1];
+          adjustedPValues[idx] = sortedPValues[i - 1].Value * (k - i + 1);
+        } else {
+          decision[idx] = decision[sortedPValues[i - 2].Key] && (sortedPValues[i - 1].Value < alphaNiveau[i - 1]);
+          adjustedPValues[idx] = Math.Max(adjustedPValues[sortedPValues[i - 2].Key], sortedPValues[i - 1].Value * (k - i + 1));
+        }
+        if (adjustedPValues[idx] > 1.0) {
+          adjustedPValues[idx] = 1.0;
+        }
+      }
+
+      h = decision;
+      return adjustedPValues;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/EnumerableStatisticsExtension.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/EnumerableStatisticsExtension.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/EnumerableStatisticsExtension.cs	(revision 12764)
@@ -0,0 +1,48 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Analysis.Statistics {
+  public static class EnumerableStatisticExtensions {
+    public static Tuple<double, double> ConfidenceIntervals(this IEnumerable<double> values, double alpha) {
+      return ConfidenceIntervals(values.ToArray(), alpha);
+    }
+
+    public static Tuple<double, double> ConfidenceIntervals(this double[] values, double alpha) {
+      double lower, upper;
+      int n = values.Length;
+      if (n <= 1) return new Tuple<double, double>(double.NaN, double.NaN);
+
+      double s = values.StandardDeviation();
+      double x = values.Average();
+      double t = alglib.invstudenttdistribution(n - 1, (1.0 - alpha) / 2.0);
+
+      lower = x + t * (s / Math.Sqrt(n));
+      upper = x - t * (s / Math.Sqrt(n));
+
+      return new Tuple<double, double>(lower, upper);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/Fitting/ExpFitting.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/Fitting/ExpFitting.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/Fitting/ExpFitting.cs	(revision 12764)
@@ -0,0 +1,97 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+
+namespace HeuristicLab.Analysis.Statistics {
+  public class ExpFitting : IFitting {
+    private void ExpFunc(double[] c, double[] x, ref double func, object obj) {
+      func = Math.Exp(-c[0] * Math.Pow(x[0], 2));
+    }
+
+    private double[] GetDefaultXValues(int n) {
+      var stdX = Enumerable.Range(1, n).Select(x => (double)x).ToArray();
+      return stdX;
+    }
+
+    public void Calculate(double[] dataPoints, out double p0) {
+      var stdX = GetDefaultXValues(dataPoints.Count());
+      Calculate(dataPoints, stdX, out p0);
+    }
+
+    public void Calculate(double[] y, double[] x, out double p0) {
+      if (y.Count() != x.Count()) {
+        throw new ArgumentException("The lenght of x and y needs do be equal. ");
+      }
+
+      double[] c = new double[] { 0.3 };
+      double epsf = 0;
+      double epsx = 0.000001;
+      int maxits = 0;
+      int info;
+      alglib.lsfitstate state;
+      alglib.lsfitreport rep;
+      double diffstep = 0.0001;
+      double[,] xx = new double[x.Count(), 1];
+
+      for (int i = 0; i < x.Count(); i++) {
+        xx[i, 0] = x[i];
+      }
+
+      alglib.lsfitcreatef(xx, y, c, diffstep, out state);
+      alglib.lsfitsetcond(state, epsf, epsx, maxits);
+      alglib.lsfitfit(state, ExpFunc, null, null);
+      alglib.lsfitresults(state, out info, out c, out rep);
+
+      p0 = c[0];
+    }
+
+    public DataRow CalculateFittedLine(double[] dataPoints) {
+      DataRow newRow = new DataRow();
+      double c0;
+      Calculate(dataPoints, out c0);
+      var stdX = GetDefaultXValues(dataPoints.Count());
+
+      for (int i = 0; i < stdX.Count(); i++) {
+        newRow.Values.Add(Math.Exp(-c0 * Math.Pow(stdX[i], 2)));
+      }
+
+      return newRow;
+    }
+
+    public DataRow CalculateFittedLine(double[] y, double[] x) {
+      DataRow newRow = new DataRow();
+      double c0;
+      Calculate(y, x, out c0);
+
+      for (int i = 0; i < x.Count(); i++) {
+        newRow.Values.Add(Math.Exp(-c0 * Math.Pow(x[i], 2)));
+      }
+
+      return newRow;
+    }
+
+    public override string ToString() {
+      return "Exponential Fitting";
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/Fitting/IFitting.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/Fitting/IFitting.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/Fitting/IFitting.cs	(revision 12764)
@@ -0,0 +1,27 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Analysis.Statistics {
+  public interface IFitting {
+    DataRow CalculateFittedLine(double[] dataPoints);
+    DataRow CalculateFittedLine(double[] y, double[] x);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/Fitting/LinearLeastSquaresFitting.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/Fitting/LinearLeastSquaresFitting.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/Fitting/LinearLeastSquaresFitting.cs	(revision 12764)
@@ -0,0 +1,98 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+
+namespace HeuristicLab.Analysis.Statistics {
+  public class LinearLeastSquaresFitting : IFitting {
+    public void Calculate(double[] dataPoints, out double slope, out double intercept) {
+      var stdX = Enumerable.Range(0, dataPoints.Count()).Select(x => (double)x).ToArray();
+      Calculate(dataPoints, stdX, out slope, out intercept);
+    }
+
+    public void Calculate(double[] y, double[] x, out double slope, out double intercept) {
+      if (y.Count() != x.Count()) {
+        throw new ArgumentException("The lenght of x and y needs do be equal. ");
+      }
+
+      double sxy = 0.0;
+      double sxx = 0.0;
+      int n = y.Count();
+      double sy = y.Sum();
+      double sx = ((n - 1) * n) / 2.0;
+      double avgy = sy / n;
+      double avgx = sx / n;
+
+      for (int i = 0; i < n; i++) {
+        sxy += x[i] * y[i];
+        sxx += x[i] * x[i];
+      }
+
+      slope = (sxy - (n * avgx * avgy)) / (sxx - (n * avgx * avgx));
+      intercept = avgy - slope * avgx;
+    }
+
+    public double CalculateError(double[] dataPoints, double slope, double intercept) {
+      double r;
+      double avgy = dataPoints.Average();
+      double sstot = 0.0;
+      double sserr = 0.0;
+
+      for (int i = 0; i < dataPoints.Count(); i++) {
+        double y = slope * i + intercept;
+        sstot += Math.Pow(dataPoints[i] - avgy, 2);
+        sserr += Math.Pow(dataPoints[i] - y, 2);
+      }
+
+      r = 1.0 - (sserr / sstot);
+      return r;
+    }
+
+    public DataRow CalculateFittedLine(double[] y, double[] x) {
+      double slope, intercept;
+      Calculate(y, x, out slope, out intercept);
+
+      DataRow newRow = new DataRow();
+      for (int i = 0; i < x.Count(); i++) {
+        newRow.Values.Add(slope * x[i] + intercept);
+      }
+      return newRow;
+    }
+
+    public DataRow CalculateFittedLine(double[] dataPoints) {
+      DataRow newRow = new DataRow();
+      double slope, intercept;
+      Calculate(dataPoints, out slope, out intercept);
+      var stdX = Enumerable.Range(0, dataPoints.Count()).Select(x => (double)x).ToArray();
+
+      for (int i = 0; i < stdX.Count(); i++) {
+        newRow.Values.Add(slope * stdX[i] + intercept);
+      }
+
+      return newRow;
+    }
+
+    public override string ToString() {
+      return "Linear Fitting";
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/Fitting/LogFitting.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/Fitting/LogFitting.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/Fitting/LogFitting.cs	(revision 12764)
@@ -0,0 +1,98 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+
+namespace HeuristicLab.Analysis.Statistics {
+  public class LogFitting : IFitting {
+    private void LogFunc(double[] c, double[] x, ref double func, object obj) {
+      func = c[0] * Math.Exp(c[1] / x[0]);
+    }
+
+    private double[] GetDefaultXValues(int n) {
+      var stdX = Enumerable.Range(1, n).Select(x => (double)x).ToArray();
+      return stdX;
+    }
+
+    public void Calculate(double[] dataPoints, out double p0, out double p1) {
+      var stdX = GetDefaultXValues(dataPoints.Count());
+      Calculate(dataPoints, stdX, out p0, out p1);
+    }
+
+    public void Calculate(double[] y, double[] x, out double p0, out double p1) {
+      if (y.Count() != x.Count()) {
+        throw new ArgumentException("The lenght of x and y needs do be equal. ");
+      }
+
+      double[] c = new double[] { 0.3, 0.3 };
+      double epsf = 0;
+      double epsx = 0.000001;
+      int maxits = 0;
+      int info;
+      alglib.lsfitstate state;
+      alglib.lsfitreport rep;
+      double diffstep = 0.0001;
+      double[,] xx = new double[x.Count(), 1];
+
+      for (int i = 0; i < x.Count(); i++) {
+        xx[i, 0] = x[i];
+      }
+
+      alglib.lsfitcreatef(xx, y, c, diffstep, out state);
+      alglib.lsfitsetcond(state, epsf, epsx, maxits);
+      alglib.lsfitfit(state, LogFunc, null, null);
+      alglib.lsfitresults(state, out info, out c, out rep);
+
+      p0 = c[0];
+      p1 = c[1];
+    }
+
+    public DataRow CalculateFittedLine(double[] dataPoints) {
+      DataRow newRow = new DataRow();
+      double c0, c1;
+      Calculate(dataPoints, out c0, out c1);
+      var stdX = GetDefaultXValues(dataPoints.Count());
+
+      for (int i = 0; i < stdX.Count(); i++) {
+        newRow.Values.Add(c0 * Math.Exp(c1 / stdX[i]));
+      }
+
+      return newRow;
+    }
+
+    public DataRow CalculateFittedLine(double[] y, double[] x) {
+      DataRow newRow = new DataRow();
+      double c0, c1;
+      Calculate(y, x, out c0, out c1);
+
+      for (int i = 0; i < x.Count(); i++) {
+        newRow.Values.Add(c0 * Math.Exp(c1 / x[i]));
+      }
+
+      return newRow;
+    }
+
+    public override string ToString() {
+      return "Logarithmic Fitting";
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/KernelDensityEstimator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/KernelDensityEstimator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/KernelDensityEstimator.cs	(revision 12764)
@@ -0,0 +1,69 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Analysis.Statistics {
+  public static class KernelDensityEstimator {
+    public static double[] Density(double[] x, double mean, double stdDev) {
+      return x.Select(xi => Density(xi, mean, stdDev)).ToArray();
+    }
+
+    public static double Density(double x, double mean, double stdDev) {
+      return (1.0 / (stdDev * Math.Sqrt(2.0 * Math.PI))) *
+                  Math.Exp(-((Math.Pow(x - mean, 2.0)) /
+                             (2.0 * Math.Pow(stdDev, 2.0))));
+    }
+
+    // the scale (sigma) of the kernel is a parameter
+    public static List<Tuple<double, double>> Density(double[] x, int nrOfPoints, double stepWidth, double sigma = 1.0) {
+      // calculate grid for which to estimate the density
+      double[] newX = new double[nrOfPoints];
+      double margin = stepWidth * 2;
+
+      double dataMin = x.Min() - margin;
+      double dataMax = x.Max() + margin;
+      double diff = (dataMax - dataMin) / nrOfPoints;
+      double cur = dataMin;
+      newX[0] = cur;
+      for (int i = 1; i < nrOfPoints; i++) {
+        cur += diff;
+        newX[i] = cur;
+      }
+
+      // for each of the points for which we want to calculate the density
+      // we sum up all the densities of the observed points assuming they are at the center of a normal distribution
+      var y = from xi in newX
+              select (from obsX in x
+                      select Density(xi, obsX, sigma)).Sum();
+
+      return newX.Zip(y, Tuple.Create).ToList();
+    }
+
+    //Silverman's rule of thumb for bandwidth estimation (sigma)
+    public static double EstimateBandwidth(double[] x) {
+      return 1.06 * x.StandardDeviation() * Math.Pow(x.Length, -0.2);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/KruskalWallisTest.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/KruskalWallisTest.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/KruskalWallisTest.cs	(revision 12764)
@@ -0,0 +1,151 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Analysis.Statistics {
+  public static class KruskalWallisTest {
+    /// <summary>
+    /// Performs the Kruskal-Wallis test and returns the p-Value. 
+    /// (source based on R's kruskal.test(), GNU GPL)
+    /// </summary>
+    public static double Test(double[][] data) {
+      double[] g;
+      double[] x = FlattenArray(data, out g);
+      int n = x.Length;
+      int parameter = data.Length - 1;
+
+      int[] r = Rank(x);
+      double[][] ties = CountDuplicates(x);
+      double statistic = CalculateStatistic(r, g);
+      double tiesCorrection = CalculateTiesCorrection(ties);
+      statistic = ((12 * statistic / (n * (n + 1)) - 3 * (n + 1)) /
+                  (1 - tiesCorrection / (Math.Pow(n, 3) - n)));
+
+      return alglib.chisquarecdistribution(parameter, statistic);
+    }
+
+    private static double CalculateStatistic(int[] r, double[] g) {
+      double result = 0.0;
+      double lastG = g[0];
+      double curSum = 0.0;
+      int cnt = 0;
+      for (int i = 0; i < r.Length; i++) {
+        if (lastG.IsAlmost(g[i])) {
+          curSum += r[i];
+          cnt++;
+        } else {
+          double sum = Math.Pow(curSum, 2);
+          sum /= cnt;
+          result += sum;
+
+          lastG = g[i];
+          curSum = r[i];
+          cnt = 1;
+        }
+      }
+
+      double lastSum = Math.Pow(curSum, 2);
+      lastSum /= cnt;
+      result += lastSum;
+
+      return result;
+    }
+
+    private static double CalculateTiesCorrection(double[][] ties) {
+      double sum = 0.0;
+      for (int i = 0; i < ties[1].Length; i++) {
+        double tic = Math.Pow(ties[1][i], 3) - ties[1][i];
+        sum += tic;
+      }
+      return sum;
+    }
+
+    private static double[] FlattenArray(double[][] x, out double[] indizes) {
+      int compLenght = 0;
+      for (int i = 0; i < x.Length; i++) {
+        compLenght += x[i].Length;
+      }
+
+      double[] result = new double[compLenght];
+      indizes = new double[compLenght];
+
+      int resultPos = 0;
+      for (int i = 0; i < x.Length; i++) {
+        Array.Copy(x[i], 0, result, resultPos, x[i].Length);
+
+        for (int j = resultPos; j < resultPos + x[i].Length; j++) {
+          indizes[j] = i;
+        }
+        resultPos += x[i].Length;
+      }
+
+      return result;
+    }
+
+    private static double[][] CountDuplicates(double[] x) {
+      List<double> number = new List<double>();
+      List<double> cnt = new List<double>();
+      double[] sortedX = new double[x.Length];
+
+      Array.Copy(x, sortedX, x.Length);
+      Array.Sort(sortedX);
+
+      double last = x[0];
+      number.Add(x[0]);
+      cnt.Add(1);
+
+      for (int i = 1; i < x.Length; i++) {
+        if (!last.IsAlmost(x[i])) {
+          number.Add(x[i]);
+          last = x[i];
+          cnt.Add(1);
+        } else {
+          cnt[cnt.Count - 1] += 1;
+        }
+      }
+
+      double[][] result = new double[2][];
+      result[0] = number.ToArray();
+      result[1] = cnt.ToArray();
+
+      return result;
+    }
+
+    private static int[] Rank(double[] x) {
+      double[] keys = new double[x.Length];
+      int[] items = new int[x.Length];
+      int[] ranks = new int[x.Length];
+
+      Array.Copy(x, keys, x.Length);
+      for (int i = 0; i < x.Length; i++) items[i] = i;
+
+      Array.Sort(keys, items);
+
+      for (int i = 0; i < x.Length; i++) {
+        ranks[items[i]] = i + 1;
+      }
+      return ranks;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/PairwiseTest.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/PairwiseTest.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/PairwiseTest.cs	(revision 12764)
@@ -0,0 +1,37 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+
+namespace HeuristicLab.Analysis.Statistics {
+  public class PairwiseTest {
+    public static double TTest(double[] group1, double[] group2) {
+      double left, right, both;
+      alglib.unequalvariancettest(group1, group1.Length, group2, group2.Length, out both, out left, out right);
+      return both;
+    }
+
+    public static double MannWhitneyUTest(double[] group1, double[] group2) {
+      double mwuBothtails, mwuLefttail, mwuRighttail;
+      alglib.mannwhitneyutest(group1, group1.Length, group2, group2.Length, out mwuBothtails, out mwuLefttail, out mwuRighttail);
+      return mwuBothtails;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/SampleSizeDetermination.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/SampleSizeDetermination.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/Statistics/SampleSizeDetermination.cs	(revision 12764)
@@ -0,0 +1,95 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Analysis.Statistics {
+  public static class SampleSizeDetermination {
+    /// <summary>
+    /// Determines for a given sample the required sample size as described in 
+    /// Göran Kauermann, Helmut Küchenhoff: Stichproben: Methoden und praktische Umsetzung mit R, section 2.27. 
+    /// </summary>
+    /// <param name="samples">The pilot sample.</param>
+    /// <param name="conf">Confidence Interval.</param>
+    /// <returns>Number of required samples for the given confidence interval. </returns>
+    public static int DetermineSampleSizeByEstimatingMean(double[] samples, double conf = 0.95) {
+      if (conf < 0.0 || conf > 1.0) throw new ArgumentException("The confidence interval must be between zero and one.");
+
+      var confInterval = samples.ConfidenceIntervals(conf);
+      double e = (confInterval.Item2 - confInterval.Item1) / 2;
+      double s = samples.StandardDeviation();
+      double z = alglib.invnormaldistribution((conf + 1) / 2);
+      double n = samples.Count();
+
+      double result = Math.Pow(s, 2) / ((Math.Pow(e, 2) / Math.Pow(z, 2)) + (Math.Pow(s, 2) / n));
+
+      result = Math.Ceiling(result);
+      if (result > int.MaxValue)
+        return int.MaxValue;
+      else
+        return (int)result;
+    }
+
+    /// <summary>
+    /// Calculates Cohen's d.
+    /// </summary>
+    /// <returns>Cohen's d. 
+    /// d = 0.2 means small effect
+    /// d = 0.5 means medium effect
+    /// d = 0.8 means big effect
+    /// According to Wikipedia this means: "A lower Cohen's d indicates a necessity of larger sample sizes, and vice versa."
+    /// </returns>
+    public static double CalculateCohensD(double[] d1, double[] d2) {
+      double x1, x2, s1, s2;
+
+      x1 = d1.Average();
+      x2 = d2.Average();
+      s1 = d1.Variance();
+      s2 = d2.Variance();
+
+      return Math.Abs(x1 - x2) / Math.Sqrt((s1 + s2) / 2);
+    }
+
+    /// <summary>
+    /// Calculates Hedges' g. 
+    /// Hedges' g works like Cohen's d but corrects for bias. 
+    /// </summary>
+    /// <returns>Hedges' g</returns>
+    public static double CalculateHedgesG(double[] d1, double[] d2) {
+      double x1, x2, s1, s2, n1, n2, s, g, c;
+
+      x1 = d1.Average();
+      x2 = d2.Average();
+      s1 = d1.Variance();
+      s2 = d2.Variance();
+      n1 = d1.Count();
+      n2 = d2.Count();
+
+      s = Math.Sqrt(((n1 - 1) * s1 + (n2 - 1) * s2) / (n1 + n2 - 2));
+      g = Math.Abs(x1 - x2) / s;
+      c = (1 - (3 / (4 * (n1 + n2) - 9))) * g;
+
+      return c;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/ValueAnalysis/MinAverageMaxValueAnalyzer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/ValueAnalysis/MinAverageMaxValueAnalyzer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/ValueAnalysis/MinAverageMaxValueAnalyzer.cs	(revision 12764)
@@ -0,0 +1,228 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// An operator which analyzes the minimum, average and maximum of a value in the scope tree.
+  /// </summary>
+  [Item("MinAverageMaxValueAnalyzer", "An operator which analyzes the minimum, average and maximum of a value in the scope tree.")]
+  [StorableClass]
+  public sealed class MinAverageMaxValueAnalyzer : AlgorithmOperator, IAnalyzer {
+    #region Parameter properties
+    public ScopeTreeLookupParameter<DoubleValue> ValueParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Value"]; }
+    }
+    public ValueLookupParameter<DoubleValue> MinValueParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["MinValue"]; }
+    }
+    public ValueLookupParameter<DoubleValue> AverageValueParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["AverageValue"]; }
+    }
+    public ValueLookupParameter<DoubleValue> MaxValueParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["MaxValue"]; }
+    }
+    public ValueLookupParameter<DataTable> ValuesParameter {
+      get { return (ValueLookupParameter<DataTable>)Parameters["Values"]; }
+    }
+    public ValueLookupParameter<VariableCollection> ResultsParameter {
+      get { return (ValueLookupParameter<VariableCollection>)Parameters["Results"]; }
+    }
+    public ValueParameter<BoolValue> CollectMinValueInResultsParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["CollectMinValueInResults"]; }
+    }
+    public ValueParameter<BoolValue> CollectMaxValueInResultsParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["CollectMaxValueInResults"]; }
+    }
+    public ValueParameter<BoolValue> CollectAverageValueInResultsParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["CollectAverageValueInResults"]; }
+    }
+    #endregion
+
+    #region Properties
+    public bool EnabledByDefault {
+      get { return true; }
+    }
+    private MinAverageMaxValueCalculator MinAverageMaxValueCalculator {
+      get { return (MinAverageMaxValueCalculator)OperatorGraph.InitialOperator; }
+    }
+    private BoolValue CollectMinValueInResults {
+      get { return CollectMinValueInResultsParameter.Value; }
+    }
+    private BoolValue CollectMaxValueInResults {
+      get { return CollectMaxValueInResultsParameter.Value; }
+    }
+    private BoolValue CollectAverageValueInResults {
+      get { return CollectAverageValueInResultsParameter.Value; }
+    }
+    #endregion
+
+    [Storable]
+    private ResultsCollector resultsCollector;
+
+    #region Storing & Cloning
+    [StorableConstructor]
+    private MinAverageMaxValueAnalyzer(bool deserializing) : base(deserializing) { }
+    private MinAverageMaxValueAnalyzer(MinAverageMaxValueAnalyzer original, Cloner cloner)
+      : base(original, cloner) {
+      resultsCollector = cloner.Clone(original.resultsCollector);
+      RegisterEventHandlers();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MinAverageMaxValueAnalyzer(this, cloner);
+    }
+    #endregion
+    public MinAverageMaxValueAnalyzer()
+      : base() {
+      #region Create parameters
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Value", "The value contained in the scope tree which should be analyzed."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("MinValue", "The minimum of the value."));
+      Parameters.Add(new ValueParameter<BoolValue>("CollectMinValueInResults", "Determines if the minimum of the value should also be stored in the results.", new BoolValue(true)));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("AverageValue", "The average of the value."));
+      Parameters.Add(new ValueParameter<BoolValue>("CollectAverageValueInResults", "Determines if the average of the value should also be stored in the results.", new BoolValue(true)));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("MaxValue", "The maximum of the value."));
+      Parameters.Add(new ValueParameter<BoolValue>("CollectMaxValueInResults", "Determines if the maximum of the value should also be stored in the results.", new BoolValue(true)));
+      Parameters.Add(new ValueLookupParameter<DataTable>("Values", "The data table to store the minimum, average and maximum of the value."));
+      Parameters.Add(new ValueLookupParameter<VariableCollection>("Results", "The results collection where the analysis values should be stored."));
+      #endregion
+
+      #region Create operators
+      MinAverageMaxValueCalculator minAverageMaxValueCalculator = new MinAverageMaxValueCalculator();
+      DataTableValuesCollector dataTableValuesCollector = new DataTableValuesCollector();
+      resultsCollector = new ResultsCollector();
+
+      minAverageMaxValueCalculator.AverageValueParameter.ActualName = AverageValueParameter.Name;
+      minAverageMaxValueCalculator.MaxValueParameter.ActualName = MaxValueParameter.Name;
+      minAverageMaxValueCalculator.MinValueParameter.ActualName = MinValueParameter.Name;
+      minAverageMaxValueCalculator.ValueParameter.ActualName = ValueParameter.Name;
+      minAverageMaxValueCalculator.ValueParameter.Depth = ValueParameter.Depth;
+
+      dataTableValuesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("MinValue", null, MinValueParameter.Name));
+      dataTableValuesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("AverageValue", null, AverageValueParameter.Name));
+      dataTableValuesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("MaxValue", null, MaxValueParameter.Name));
+      dataTableValuesCollector.DataTableParameter.ActualName = ValuesParameter.Name;
+
+      if (CollectMinValueInResults.Value)
+        resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("MinValue", null, MinValueParameter.Name));
+      if (CollectAverageValueInResults.Value)
+        resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("AverageValue", null, AverageValueParameter.Name));
+      if (CollectMaxValueInResults.Value)
+        resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("MaxValue", null, MaxValueParameter.Name));
+      resultsCollector.CollectedValues.Add(new LookupParameter<DataTable>(ValuesParameter.Name));
+      resultsCollector.ResultsParameter.ActualName = ResultsParameter.Name;
+      #endregion
+
+      #region Create operator graph
+      OperatorGraph.InitialOperator = minAverageMaxValueCalculator;
+      minAverageMaxValueCalculator.Successor = dataTableValuesCollector;
+      dataTableValuesCollector.Successor = resultsCollector;
+      resultsCollector.Successor = null;
+      #endregion
+
+      RegisterEventHandlers();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEventHandlers();
+    }
+
+    private void RegisterEventHandlers() {
+      ValueParameter.DepthChanged += new EventHandler(ValueParameter_DepthChanged);
+      CollectMinValueInResultsParameter.ValueChanged += new EventHandler(CollectMinValueInResultsParameter_ValueChanged);
+      CollectMinValueInResultsParameter.Value.ValueChanged += new EventHandler(CollectMinValueInResultsParameter_Value_ValueChanged);
+      CollectMaxValueInResultsParameter.ValueChanged += new EventHandler(CollectMaxValueInResultsParameter_ValueChanged);
+      CollectMaxValueInResultsParameter.Value.ValueChanged += new EventHandler(CollectMaxValueInResultsParameter_Value_ValueChanged);
+      CollectAverageValueInResultsParameter.ValueChanged += new EventHandler(CollectAverageValueInResultsParameter_ValueChanged);
+      CollectAverageValueInResultsParameter.Value.ValueChanged += new EventHandler(CollectAverageValueInResultsParameter_Value_ValueChanged);
+    }
+
+    private void CollectAverageValueInResultsParameter_ValueChanged(object sender, EventArgs e) {
+      IParameter avgValueParameter;
+      resultsCollector.CollectedValues.TryGetValue("AverageValue", out avgValueParameter);
+      if (CollectAverageValueInResults.Value && avgValueParameter == null)
+        resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("AverageValue", null, AverageValueParameter.Name));
+      else if (!CollectAverageValueInResults.Value && avgValueParameter != null)
+        resultsCollector.CollectedValues.Remove(avgValueParameter);
+      CollectAverageValueInResultsParameter.Value.ValueChanged += new EventHandler(CollectAverageValueInResultsParameter_Value_ValueChanged);
+    }
+
+    private void CollectAverageValueInResultsParameter_Value_ValueChanged(object sender, EventArgs e) {
+      IParameter avgValueParameter;
+      resultsCollector.CollectedValues.TryGetValue("AverageValue", out avgValueParameter);
+      if (CollectAverageValueInResults.Value && avgValueParameter == null)
+        resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("AverageValue", null, AverageValueParameter.Name));
+      else if (!CollectAverageValueInResults.Value && avgValueParameter != null)
+        resultsCollector.CollectedValues.Remove(avgValueParameter);
+    }
+
+    private void CollectMaxValueInResultsParameter_ValueChanged(object sender, EventArgs e) {
+      IParameter maxValueParameter;
+      resultsCollector.CollectedValues.TryGetValue("MaxValue", out maxValueParameter);
+      if (CollectMaxValueInResults.Value && maxValueParameter == null)
+        resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("MaxValue", null, MaxValueParameter.Name));
+      else if (!CollectMaxValueInResults.Value && maxValueParameter != null)
+        resultsCollector.CollectedValues.Remove(maxValueParameter);
+      CollectMaxValueInResultsParameter.Value.ValueChanged += new EventHandler(CollectMaxValueInResultsParameter_Value_ValueChanged);
+    }
+
+    private void CollectMaxValueInResultsParameter_Value_ValueChanged(object sender, EventArgs e) {
+      IParameter maxValueParameter;
+      resultsCollector.CollectedValues.TryGetValue("MaxValue", out maxValueParameter);
+      if (CollectMaxValueInResults.Value && maxValueParameter == null)
+        resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("MaxValue", null, MaxValueParameter.Name));
+      else if (!CollectMaxValueInResults.Value && maxValueParameter != null)
+        resultsCollector.CollectedValues.Remove(maxValueParameter);
+    }
+
+    private void CollectMinValueInResultsParameter_ValueChanged(object sender, EventArgs e) {
+      IParameter minValueParameter;
+      resultsCollector.CollectedValues.TryGetValue("MinValue", out minValueParameter);
+      if (CollectMinValueInResults.Value && minValueParameter == null)
+        resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("MinValue", null, MinValueParameter.Name));
+      else if (!CollectMinValueInResults.Value && minValueParameter != null)
+        resultsCollector.CollectedValues.Remove(minValueParameter);
+      CollectMinValueInResultsParameter.Value.ValueChanged += new EventHandler(CollectMinValueInResultsParameter_Value_ValueChanged);
+    }
+
+    private void CollectMinValueInResultsParameter_Value_ValueChanged(object sender, EventArgs e) {
+      IParameter minValueParameter;
+      resultsCollector.CollectedValues.TryGetValue("MinValue", out minValueParameter);
+      if (CollectMinValueInResults.Value && minValueParameter == null)
+        resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("MinValue", null, MinValueParameter.Name));
+      else if (!CollectMinValueInResults.Value && minValueParameter != null)
+        resultsCollector.CollectedValues.Remove(minValueParameter);
+    }
+
+    private void ValueParameter_DepthChanged(object sender, System.EventArgs e) {
+      MinAverageMaxValueCalculator.ValueParameter.Depth = ValueParameter.Depth;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/ValueAnalysis/MinAverageMaxValueCalculator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/ValueAnalysis/MinAverageMaxValueCalculator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/ValueAnalysis/MinAverageMaxValueCalculator.cs	(revision 12764)
@@ -0,0 +1,89 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// An operator which calculates the minimum, average and maximum of a value in the scope tree.
+  /// </summary>
+  [Item("MinAverageMaxValueCalculator", "An operator which calculates the minimum, average and maximum of a value in the scope tree.")]
+  [StorableClass]
+  public sealed class MinAverageMaxValueCalculator : SingleSuccessorOperator {
+    public ScopeTreeLookupParameter<DoubleValue> ValueParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Value"]; }
+    }
+    public ValueLookupParameter<DoubleValue> MinValueParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["MinValue"]; }
+    }
+    public ValueLookupParameter<DoubleValue> AverageValueParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["AverageValue"]; }
+    }
+    public ValueLookupParameter<DoubleValue> MaxValueParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["MaxValue"]; }
+    }
+
+    #region Storing & Cloning
+    [StorableConstructor]
+    private MinAverageMaxValueCalculator(bool deserializing) : base(deserializing) { }
+    private MinAverageMaxValueCalculator(MinAverageMaxValueCalculator original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MinAverageMaxValueCalculator(this, cloner);
+    }
+    #endregion
+    public MinAverageMaxValueCalculator()
+      : base() {
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Value", "The value contained in the scope tree for which the minimum, average and maximum should be calculated."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("MinValue", "The minimum of the value."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("AverageValue", "The average of the value."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("MaxValue", "The maximum of the value."));
+    }
+
+    public override IOperation Apply() {
+      ItemArray<DoubleValue> values = ValueParameter.ActualValue;
+
+      if (values.Length > 0) {
+        double min = double.MaxValue, max = double.MinValue, sum = 0.0;
+        for (int i = 0; i < values.Length; i++) {
+          if (values[i].Value < min) min = values[i].Value;
+          if (values[i].Value > max) max = values[i].Value;
+          sum += values[i].Value;
+        }
+
+        DoubleValue minValue = MinValueParameter.ActualValue;
+        if (minValue == null) MinValueParameter.ActualValue = new DoubleValue(min);
+        else minValue.Value = min;
+        DoubleValue averageValue = AverageValueParameter.ActualValue;
+        if (averageValue == null) AverageValueParameter.ActualValue = new DoubleValue(sum / values.Length);
+        else averageValue.Value = sum / values.Length;
+        DoubleValue maxValue = MaxValueParameter.ActualValue;
+        if (maxValue == null) MaxValueParameter.ActualValue = new DoubleValue(max);
+        else maxValue.Value = max;
+      }
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/ValueAnalysis/SingleValueAnalyzer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/ValueAnalysis/SingleValueAnalyzer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/ValueAnalysis/SingleValueAnalyzer.cs	(revision 12764)
@@ -0,0 +1,97 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// An operator which analyzes a value in the scope tree (current scope and parents).
+  /// </summary>
+  [Item("SingleValueAnalyzer", "An operator which analyzes a value in the scope tree (current scope and parents).")]
+  [StorableClass]
+  public sealed class SingleValueAnalyzer : AlgorithmOperator, IAnalyzer {
+    #region Parameter properties
+    public ILookupParameter<DoubleValue> ValueParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Value"]; }
+    }
+    public IValueLookupParameter<DataTable> ValuesParameter {
+      get { return (IValueLookupParameter<DataTable>)Parameters["Values"]; }
+    }
+    public IValueLookupParameter<VariableCollection> ResultsParameter {
+      get { return (IValueLookupParameter<VariableCollection>)Parameters["Results"]; }
+    }
+    #endregion
+
+    #region Properties
+    public bool EnabledByDefault {
+      get { return true; }
+    }
+    private DataTableValuesCollector DataTableValuesCollector {
+      get { return (DataTableValuesCollector)OperatorGraph.InitialOperator; }
+    }
+    private ResultsCollector ResultsCollector {
+      get { return (ResultsCollector)DataTableValuesCollector.Successor; }
+    }
+    #endregion
+
+    #region Storing & Cloning
+    [StorableConstructor]
+    private SingleValueAnalyzer(bool deserializing) : base(deserializing) { }
+    private SingleValueAnalyzer(SingleValueAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SingleValueAnalyzer(this, cloner);
+    }
+    #endregion
+    public SingleValueAnalyzer()
+      : base() {
+      #region Create parameters
+      Parameters.Add(new LookupParameter<DoubleValue>("Value", "The value contained in the scope tree which should be analyzed."));
+      Parameters.Add(new ValueLookupParameter<DataTable>("Values", "The data table to store the values."));
+      Parameters.Add(new ValueLookupParameter<VariableCollection>("Results", "The results collection where the analysis values should be stored."));
+      #endregion
+
+      #region Create operators
+      DataTableValuesCollector dataTableValuesCollector = new DataTableValuesCollector();
+      ResultsCollector resultsCollector = new ResultsCollector();
+
+      dataTableValuesCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("Value", null, ValueParameter.Name));
+      dataTableValuesCollector.DataTableParameter.ActualName = ValuesParameter.Name;
+
+      resultsCollector.CollectedValues.Add(new LookupParameter<DoubleValue>("Value", null, ValueParameter.Name));
+      resultsCollector.CollectedValues.Add(new LookupParameter<DataTable>(ValuesParameter.Name));
+      resultsCollector.ResultsParameter.ActualName = ResultsParameter.Name;
+      #endregion
+
+      #region Create operator graph
+      OperatorGraph.InitialOperator = dataTableValuesCollector;
+      dataTableValuesCollector.Successor = resultsCollector;
+      resultsCollector.Successor = null;
+      #endregion
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/ValueAnalysis/ValueAnalyzer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/ValueAnalysis/ValueAnalyzer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Analysis/3.3/ValueAnalysis/ValueAnalyzer.cs	(revision 12764)
@@ -0,0 +1,119 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// An operator which analyzes a value in the scope tree.
+  /// </summary>
+  [Item("ValueAnalyzer", "An operator which analyzes a value in the scope tree (current scope and children).")]
+  [StorableClass]
+  public sealed class ValueAnalyzer : AlgorithmOperator, IAnalyzer {
+    #region Parameter properties
+    public ScopeTreeLookupParameter<DoubleValue> ValueParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Value"]; }
+    }
+    public ValueLookupParameter<DataTable> ValuesParameter {
+      get { return (ValueLookupParameter<DataTable>)Parameters["Values"]; }
+    }
+    public ValueLookupParameter<VariableCollection> ResultsParameter {
+      get { return (ValueLookupParameter<VariableCollection>)Parameters["Results"]; }
+    }
+    #endregion
+
+    #region Properties
+    public bool EnabledByDefault {
+      get { return true; }
+    }
+    private DataTableValuesCollector DataTableValuesCollector {
+      get { return (DataTableValuesCollector)OperatorGraph.InitialOperator; }
+    }
+    private ResultsCollector ResultsCollector {
+      get { return (ResultsCollector)DataTableValuesCollector.Successor; }
+    }
+    #endregion
+
+    #region Storing & Cloning
+    [StorableConstructor]
+    private ValueAnalyzer(bool deserializing) : base(deserializing) { }
+    private ValueAnalyzer(ValueAnalyzer original, Cloner cloner)
+      : base(original, cloner) {
+      Initialize();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ValueAnalyzer(this, cloner);
+    }
+    #endregion
+    public ValueAnalyzer()
+      : base() {
+      #region Create parameters
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Value", "The value contained in the scope tree which should be analyzed."));
+      Parameters.Add(new ValueLookupParameter<DataTable>("Values", "The data table to store the values."));
+      Parameters.Add(new ValueLookupParameter<VariableCollection>("Results", "The results collection where the analysis values should be stored."));
+      #endregion
+
+      #region Create operators
+      DataTableValuesCollector dataTableValuesCollector = new DataTableValuesCollector();
+      ResultsCollector resultsCollector = new ResultsCollector();
+
+      dataTableValuesCollector.CollectedValues.Add(new ScopeTreeLookupParameter<DoubleValue>("Value", null, ValueParameter.Name));
+      ((ScopeTreeLookupParameter<DoubleValue>)dataTableValuesCollector.CollectedValues["Value"]).Depth = ValueParameter.Depth;
+      dataTableValuesCollector.DataTableParameter.ActualName = ValuesParameter.Name;
+
+      resultsCollector.CollectedValues.Add(new ScopeTreeLookupParameter<DoubleValue>("Value", null, ValueParameter.Name));
+      ((ScopeTreeLookupParameter<DoubleValue>)resultsCollector.CollectedValues["Value"]).Depth = ValueParameter.Depth;
+      resultsCollector.CollectedValues.Add(new LookupParameter<DataTable>(ValuesParameter.Name));
+      resultsCollector.ResultsParameter.ActualName = ResultsParameter.Name;
+      #endregion
+
+      #region Create operator graph
+      OperatorGraph.InitialOperator = dataTableValuesCollector;
+      dataTableValuesCollector.Successor = resultsCollector;
+      resultsCollector.Successor = null;
+      #endregion
+
+      Initialize();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      Initialize();
+    }
+
+    private void Initialize() {
+      ValueParameter.DepthChanged += new EventHandler(ValueParameter_DepthChanged);
+    }
+
+    private void ValueParameter_DepthChanged(object sender, System.EventArgs e) {
+      ((ScopeTreeLookupParameter<DoubleValue>)DataTableValuesCollector.CollectedValues["Value"]).Depth = ValueParameter.Depth;
+      ((ScopeTreeLookupParameter<DoubleValue>)ResultsCollector.CollectedValues["Value"]).Depth = ValueParameter.Depth;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/AlgorithmView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/AlgorithmView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/AlgorithmView.Designer.cs	(revision 12764)
@@ -0,0 +1,310 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class AlgorithmView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    #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() {
+      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AlgorithmView));
+      this.tabControl = new HeuristicLab.MainForm.WindowsForms.DragOverTabControl();
+      this.problemTabPage = new System.Windows.Forms.TabPage();
+      this.problemViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.openProblemButton = new System.Windows.Forms.Button();
+      this.newProblemButton = new System.Windows.Forms.Button();
+      this.parametersTabPage = new System.Windows.Forms.TabPage();
+      this.parameterCollectionView = new HeuristicLab.Core.Views.ParameterCollectionView();
+      this.resultsTabPage = new System.Windows.Forms.TabPage();
+      this.resultsView = new HeuristicLab.Optimization.Views.ResultCollectionView();
+      this.runsTabPage = new System.Windows.Forms.TabPage();
+      this.storeAlgorithmInEachRunCheckBox = new System.Windows.Forms.CheckBox();
+      this.runsView = new HeuristicLab.Optimization.Views.RunCollectionView();
+      this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.tabControl.SuspendLayout();
+      this.problemTabPage.SuspendLayout();
+      this.parametersTabPage.SuspendLayout();
+      this.resultsTabPage.SuspendLayout();
+      this.runsTabPage.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // startButton
+      // 
+      this.startButton.Location = new System.Drawing.Point(0, 458);
+      this.toolTip.SetToolTip(this.startButton, "Start/Resume Algorithm");
+      // 
+      // executionTimeTextBox
+      // 
+      this.executionTimeTextBox.Location = new System.Drawing.Point(542, 462);
+      // 
+      // executionTimeLabel
+      // 
+      this.executionTimeLabel.Location = new System.Drawing.Point(453, 465);
+      // 
+      // pauseButton
+      // 
+      this.pauseButton.Location = new System.Drawing.Point(30, 458);
+      this.toolTip.SetToolTip(this.pauseButton, "Pause Algorithm");
+      // 
+      // stopButton
+      // 
+      this.stopButton.Location = new System.Drawing.Point(60, 458);
+      this.toolTip.SetToolTip(this.stopButton, "Stop Algorithm");
+      // 
+      // resetButton
+      // 
+      this.resetButton.Location = new System.Drawing.Point(90, 458);
+      this.toolTip.SetToolTip(this.resetButton, "Reset Algorithm");
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      this.nameTextBox.Location = new System.Drawing.Point(60, 0);
+      this.nameTextBox.Size = new System.Drawing.Size(594, 20);
+      // 
+      // infoLabel
+      // 
+      this.infoLabel.Location = new System.Drawing.Point(660, 3);
+      // 
+      // tabControl
+      // 
+      this.tabControl.AllowDrop = true;
+      this.tabControl.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.tabControl.Controls.Add(this.problemTabPage);
+      this.tabControl.Controls.Add(this.parametersTabPage);
+      this.tabControl.Controls.Add(this.resultsTabPage);
+      this.tabControl.Controls.Add(this.runsTabPage);
+      this.tabControl.Location = new System.Drawing.Point(0, 26);
+      this.tabControl.Name = "tabControl";
+      this.tabControl.SelectedIndex = 0;
+      this.tabControl.Size = new System.Drawing.Size(679, 430);
+      this.tabControl.TabIndex = 3;
+      // 
+      // problemTabPage
+      // 
+      this.problemTabPage.AllowDrop = true;
+      this.problemTabPage.Controls.Add(this.problemViewHost);
+      this.problemTabPage.Controls.Add(this.openProblemButton);
+      this.problemTabPage.Controls.Add(this.newProblemButton);
+      this.problemTabPage.Location = new System.Drawing.Point(4, 22);
+      this.problemTabPage.Name = "problemTabPage";
+      this.problemTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.problemTabPage.Size = new System.Drawing.Size(671, 404);
+      this.problemTabPage.TabIndex = 0;
+      this.problemTabPage.Text = "Problem";
+      this.problemTabPage.UseVisualStyleBackColor = true;
+      this.problemTabPage.DragDrop += new System.Windows.Forms.DragEventHandler(this.problemTabPage_DragDrop);
+      this.problemTabPage.DragEnter += new System.Windows.Forms.DragEventHandler(this.problemTabPage_DragEnterOver);
+      this.problemTabPage.DragOver += new System.Windows.Forms.DragEventHandler(this.problemTabPage_DragEnterOver);
+      // 
+      // problemViewHost
+      // 
+      this.problemViewHost.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.problemViewHost.Caption = "View";
+      this.problemViewHost.Content = null;
+      this.problemViewHost.Enabled = false;
+      this.problemViewHost.Location = new System.Drawing.Point(6, 36);
+      this.problemViewHost.Name = "problemViewHost";
+      this.problemViewHost.ReadOnly = false;
+      this.problemViewHost.Size = new System.Drawing.Size(659, 362);
+      this.problemViewHost.TabIndex = 3;
+      this.problemViewHost.ViewsLabelVisible = true;
+      this.problemViewHost.ViewType = null;
+      // 
+      // openProblemButton
+      // 
+      this.openProblemButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Open;
+      this.openProblemButton.Location = new System.Drawing.Point(36, 6);
+      this.openProblemButton.Name = "openProblemButton";
+      this.openProblemButton.Size = new System.Drawing.Size(24, 24);
+      this.openProblemButton.TabIndex = 1;
+      this.toolTip.SetToolTip(this.openProblemButton, "Open Problem");
+      this.openProblemButton.UseVisualStyleBackColor = true;
+      this.openProblemButton.Click += new System.EventHandler(this.openProblemButton_Click);
+      // 
+      // newProblemButton
+      // 
+      this.newProblemButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.NewDocument;
+      this.newProblemButton.Location = new System.Drawing.Point(6, 6);
+      this.newProblemButton.Name = "newProblemButton";
+      this.newProblemButton.Size = new System.Drawing.Size(24, 24);
+      this.newProblemButton.TabIndex = 0;
+      this.toolTip.SetToolTip(this.newProblemButton, "New Problem");
+      this.newProblemButton.UseVisualStyleBackColor = true;
+      this.newProblemButton.Click += new System.EventHandler(this.newProblemButton_Click);
+      // 
+      // parametersTabPage
+      // 
+      this.parametersTabPage.Controls.Add(this.parameterCollectionView);
+      this.parametersTabPage.Location = new System.Drawing.Point(4, 22);
+      this.parametersTabPage.Name = "parametersTabPage";
+      this.parametersTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.parametersTabPage.Size = new System.Drawing.Size(671, 400);
+      this.parametersTabPage.TabIndex = 1;
+      this.parametersTabPage.Text = "Algorithm";
+      this.parametersTabPage.UseVisualStyleBackColor = true;
+      // 
+      // parameterCollectionView
+      // 
+      this.parameterCollectionView.AllowEditingOfHiddenParameters = true;
+      this.parameterCollectionView.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.parameterCollectionView.Caption = "ParameterCollection View";
+      this.parameterCollectionView.Content = null;
+      this.parameterCollectionView.Location = new System.Drawing.Point(6, 6);
+      this.parameterCollectionView.Name = "parameterCollectionView";
+      this.parameterCollectionView.ReadOnly = false;
+      this.parameterCollectionView.Size = new System.Drawing.Size(659, 388);
+      this.parameterCollectionView.TabIndex = 0;
+      // 
+      // resultsTabPage
+      // 
+      this.resultsTabPage.Controls.Add(this.resultsView);
+      this.resultsTabPage.Location = new System.Drawing.Point(4, 22);
+      this.resultsTabPage.Name = "resultsTabPage";
+      this.resultsTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.resultsTabPage.Size = new System.Drawing.Size(671, 400);
+      this.resultsTabPage.TabIndex = 2;
+      this.resultsTabPage.Text = "Results";
+      this.resultsTabPage.UseVisualStyleBackColor = true;
+      // 
+      // resultsView
+      // 
+      this.resultsView.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.resultsView.Caption = "ResultCollection View";
+      this.resultsView.Content = null;
+      this.resultsView.Location = new System.Drawing.Point(6, 6);
+      this.resultsView.Name = "resultsView";
+      this.resultsView.ReadOnly = true;
+      this.resultsView.Size = new System.Drawing.Size(659, 388);
+      this.resultsView.TabIndex = 0;
+      // 
+      // runsTabPage
+      // 
+      this.runsTabPage.Controls.Add(this.storeAlgorithmInEachRunCheckBox);
+      this.runsTabPage.Controls.Add(this.runsView);
+      this.runsTabPage.Location = new System.Drawing.Point(4, 22);
+      this.runsTabPage.Name = "runsTabPage";
+      this.runsTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.runsTabPage.Size = new System.Drawing.Size(671, 400);
+      this.runsTabPage.TabIndex = 3;
+      this.runsTabPage.Text = "Runs";
+      this.runsTabPage.UseVisualStyleBackColor = true;
+      // 
+      // storeAlgorithmInEachRunCheckBox
+      // 
+      this.storeAlgorithmInEachRunCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.storeAlgorithmInEachRunCheckBox.AutoSize = true;
+      this.storeAlgorithmInEachRunCheckBox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
+      this.storeAlgorithmInEachRunCheckBox.Checked = true;
+      this.storeAlgorithmInEachRunCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.storeAlgorithmInEachRunCheckBox.Location = new System.Drawing.Point(503, 6);
+      this.storeAlgorithmInEachRunCheckBox.Name = "storeAlgorithmInEachRunCheckBox";
+      this.storeAlgorithmInEachRunCheckBox.Size = new System.Drawing.Size(161, 17);
+      this.storeAlgorithmInEachRunCheckBox.TabIndex = 1;
+      this.storeAlgorithmInEachRunCheckBox.Text = "&Store Algorithm in each Run:";
+      this.toolTip.SetToolTip(this.storeAlgorithmInEachRunCheckBox, "Check to store a copy of the algorithm in each run.");
+      this.storeAlgorithmInEachRunCheckBox.UseVisualStyleBackColor = true;
+      this.storeAlgorithmInEachRunCheckBox.CheckedChanged += new System.EventHandler(this.storeAlgorithmInEachRunCheckBox_CheckedChanged);
+      // 
+      // runsView
+      // 
+      this.runsView.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.runsView.Caption = "RunCollection View";
+      this.runsView.Content = null;
+      this.runsView.Location = new System.Drawing.Point(6, 6);
+      this.runsView.Name = "runsView";
+      this.runsView.ReadOnly = false;
+      this.runsView.Size = new System.Drawing.Size(659, 388);
+      this.runsView.TabIndex = 0;
+      // 
+      // openFileDialog
+      // 
+      this.openFileDialog.DefaultExt = "hl";
+      this.openFileDialog.FileName = "Problem";
+      this.openFileDialog.Filter = "HeuristicLab Files|*.hl|All Files|*.*";
+      this.openFileDialog.Title = "Open Problem";
+      // 
+      // AlgorithmView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.tabControl);
+      this.Name = "AlgorithmView";
+      this.Size = new System.Drawing.Size(679, 482);
+      this.Controls.SetChildIndex(this.executionTimeLabel, 0);
+      this.Controls.SetChildIndex(this.executionTimeTextBox, 0);
+      this.Controls.SetChildIndex(this.resetButton, 0);
+      this.Controls.SetChildIndex(this.tabControl, 0);
+      this.Controls.SetChildIndex(this.stopButton, 0);
+      this.Controls.SetChildIndex(this.pauseButton, 0);
+      this.Controls.SetChildIndex(this.startButton, 0);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.tabControl.ResumeLayout(false);
+      this.problemTabPage.ResumeLayout(false);
+      this.parametersTabPage.ResumeLayout(false);
+      this.resultsTabPage.ResumeLayout(false);
+      this.runsTabPage.ResumeLayout(false);
+      this.runsTabPage.PerformLayout();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    protected HeuristicLab.MainForm.WindowsForms.DragOverTabControl tabControl;
+    protected System.Windows.Forms.TabPage parametersTabPage;
+    protected System.Windows.Forms.TabPage problemTabPage;
+    protected HeuristicLab.Core.Views.ParameterCollectionView parameterCollectionView;
+    protected HeuristicLab.MainForm.WindowsForms.ViewHost problemViewHost;
+    protected System.Windows.Forms.Button newProblemButton;
+    protected System.Windows.Forms.Button openProblemButton;
+    protected System.Windows.Forms.OpenFileDialog openFileDialog;
+    protected System.Windows.Forms.TabPage resultsTabPage;
+    protected HeuristicLab.Optimization.Views.ResultCollectionView resultsView;
+    protected System.Windows.Forms.TabPage runsTabPage;
+    protected RunCollectionView runsView;
+    protected System.Windows.Forms.CheckBox storeAlgorithmInEachRunCheckBox;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/AlgorithmView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/AlgorithmView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/AlgorithmView.cs	(revision 12764)
@@ -0,0 +1,217 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("Algorithm View")]
+  [Content(typeof(Algorithm), true)]
+  [Content(typeof(IAlgorithm), false)]
+  public partial class AlgorithmView : IOptimizerView {
+    private TypeSelectorDialog problemTypeSelectorDialog;
+    public AlgorithmView() {
+      InitializeComponent();
+    }
+
+    public new IAlgorithm Content {
+      get { return (IAlgorithm)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (problemTypeSelectorDialog != null) problemTypeSelectorDialog.Dispose();
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    protected override void OnInitialized(EventArgs e) {
+      // Set order of tab pages according to z order.
+      // NOTE: This is required due to a bug in the VS designer.
+      List<Control> tabPages = new List<Control>();
+      for (int i = 0; i < tabControl.Controls.Count; i++) {
+        tabPages.Add(tabControl.Controls[i]);
+      }
+      tabControl.Controls.Clear();
+      foreach (Control control in tabPages)
+        tabControl.Controls.Add(control);
+
+      base.OnInitialized(e);
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.ProblemChanged -= new EventHandler(Content_ProblemChanged);
+      Content.StoreAlgorithmInEachRunChanged -= new EventHandler(Content_StoreAlgorithmInEachRunChanged);
+      base.DeregisterContentEvents();
+    }
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ProblemChanged += new EventHandler(Content_ProblemChanged);
+      Content.StoreAlgorithmInEachRunChanged += new EventHandler(Content_StoreAlgorithmInEachRunChanged);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        parameterCollectionView.Content = null;
+        problemViewHost.Content = null;
+        resultsView.Content = null;
+        runsView.Content = null;
+        storeAlgorithmInEachRunCheckBox.Checked = true;
+      } else {
+        parameterCollectionView.Content = Content.Parameters;
+        problemViewHost.ViewType = null;
+        problemViewHost.Content = Content.Problem;
+        resultsView.Content = Content.Results.AsReadOnly();
+        runsView.Content = Content.Runs;
+        storeAlgorithmInEachRunCheckBox.Checked = Content.StoreAlgorithmInEachRun;
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      parameterCollectionView.Enabled = Content != null;
+      newProblemButton.Enabled = Content != null && !ReadOnly;
+      openProblemButton.Enabled = Content != null && !ReadOnly;
+      problemViewHost.Enabled = Content != null;
+      resultsView.Enabled = Content != null;
+      runsView.Enabled = Content != null;
+      storeAlgorithmInEachRunCheckBox.Enabled = Content != null && !ReadOnly;
+    }
+
+    protected override void OnClosed(FormClosedEventArgs e) {
+      if ((Content != null) && (Content.ExecutionState == ExecutionState.Started)) {
+        //The content must be stopped if no other view showing the content is available
+        var optimizers = MainFormManager.MainForm.Views.OfType<IContentView>().Where(v => v != this).Select(v => v.Content).OfType<IOptimizer>();
+        if (!optimizers.Contains(Content)) {
+          var nestedOptimizers = optimizers.SelectMany(opt => opt.NestedOptimizers);
+          if (!nestedOptimizers.Contains(Content)) Content.Stop();
+        }
+      }
+      base.OnClosed(e);
+    }
+
+    #region Content Events
+    protected override void Content_Prepared(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_Prepared), sender, e);
+      else {
+        base.Content_Prepared(sender, e);
+        resultsView.Content = Content.Results.AsReadOnly();
+      }
+    }
+
+    protected virtual void Content_ProblemChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_ProblemChanged), sender, e);
+      else {
+        problemViewHost.ViewType = null;
+        problemViewHost.Content = Content.Problem;
+      }
+    }
+    protected virtual void Content_StoreAlgorithmInEachRunChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_StoreAlgorithmInEachRunChanged), sender, e);
+      else
+        storeAlgorithmInEachRunCheckBox.Checked = Content.StoreAlgorithmInEachRun;
+    }
+    #endregion
+
+    #region Control Events
+    protected virtual void newProblemButton_Click(object sender, EventArgs e) {
+      if (problemTypeSelectorDialog == null) {
+        problemTypeSelectorDialog = new TypeSelectorDialog();
+        problemTypeSelectorDialog.Caption = "Select Problem";
+        problemTypeSelectorDialog.TypeSelector.Caption = "Available Problems";
+        problemTypeSelectorDialog.TypeSelector.Configure(Content.ProblemType, false, true);
+      }
+      if (problemTypeSelectorDialog.ShowDialog(this) == DialogResult.OK) {
+        try {
+          Content.Problem = (IProblem)problemTypeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
+        }
+        catch (Exception ex) {
+          ErrorHandling.ShowErrorDialog(this, ex);
+        }
+      }
+    }
+    protected virtual void openProblemButton_Click(object sender, EventArgs e) {
+      openFileDialog.Title = "Open Problem";
+      if (openFileDialog.ShowDialog(this) == DialogResult.OK) {
+        newProblemButton.Enabled = openProblemButton.Enabled = false;
+        problemViewHost.Enabled = false;
+
+        ContentManager.LoadAsync(openFileDialog.FileName, delegate(IStorableContent content, Exception error) {
+          try {
+            if (error != null) throw error;
+            IProblem problem = content as IProblem;
+            if (problem == null)
+              Invoke(new Action(() =>
+                MessageBox.Show(this, "The selected file does not contain a problem.", "Invalid File", MessageBoxButtons.OK, MessageBoxIcon.Error)));
+            else if (!Content.ProblemType.IsInstanceOfType(problem))
+              Invoke(new Action(() =>
+                MessageBox.Show(this, "The selected file contains a problem type which is not supported by this algorithm.", "Invalid Problem Type", MessageBoxButtons.OK, MessageBoxIcon.Error)));
+            else
+              Content.Problem = problem;
+          }
+          catch (Exception ex) {
+            Invoke(new Action(() => ErrorHandling.ShowErrorDialog(this, ex)));
+          }
+          finally {
+            Invoke(new Action(delegate() {
+              problemViewHost.Enabled = true;
+              newProblemButton.Enabled = openProblemButton.Enabled = true;
+            }));
+          }
+        });
+      }
+    }
+    protected virtual void storeAlgorithmInEachRunCheckBox_CheckedChanged(object sender, EventArgs e) {
+      if (Content != null) Content.StoreAlgorithmInEachRun = storeAlgorithmInEachRunCheckBox.Checked;
+    }
+    protected virtual void problemTabPage_DragEnterOver(object sender, DragEventArgs e) {
+      e.Effect = DragDropEffects.None;
+      if (!ReadOnly && (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) != null) && Content.ProblemType.IsAssignableFrom(e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat).GetType())) {
+        if ((e.KeyState & 32) == 32) e.Effect = DragDropEffects.Link;  // ALT key
+        else if ((e.KeyState & 4) == 4) e.Effect = DragDropEffects.Move;  // SHIFT key
+        else if (e.AllowedEffect.HasFlag(DragDropEffects.Copy)) e.Effect = DragDropEffects.Copy;
+        else if (e.AllowedEffect.HasFlag(DragDropEffects.Move)) e.Effect = DragDropEffects.Move;
+        else if (e.AllowedEffect.HasFlag(DragDropEffects.Link)) e.Effect = DragDropEffects.Link;
+      }
+    }
+    protected virtual void problemTabPage_DragDrop(object sender, DragEventArgs e) {
+      if (e.Effect != DragDropEffects.None) {
+        IProblem problem = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as IProblem;
+        if (e.Effect.HasFlag(DragDropEffects.Copy)) problem = (IProblem)problem.Clone();
+        Content.Problem = problem;
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/BasicAlgorithmView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/BasicAlgorithmView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/BasicAlgorithmView.Designer.cs	(revision 12764)
@@ -0,0 +1,32 @@
+﻿namespace HeuristicLab.Optimization.Views {
+  partial class BasicAlgorithmView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+    }
+
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/BasicAlgorithmView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/BasicAlgorithmView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/BasicAlgorithmView.cs	(revision 12764)
@@ -0,0 +1,46 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("Basic Algorithm View")]
+  [Content(typeof(BasicAlgorithm), true)]
+  public partial class BasicAlgorithmView : AlgorithmView {
+    public BasicAlgorithmView() {
+      InitializeComponent();
+    }
+    public new BasicAlgorithm Content {
+      get { return (BasicAlgorithm)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      pauseButton.Enabled = false;
+    }
+
+    protected override void SetEnabledStateOfExecutableButtons() {
+      base.SetEnabledStateOfExecutableButtons();
+      pauseButton.Enabled = false;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/BatchRunView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/BatchRunView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/BatchRunView.Designer.cs	(revision 12764)
@@ -0,0 +1,272 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class BatchRunView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    #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() {
+      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(BatchRunView));
+      this.tabControl = new HeuristicLab.MainForm.WindowsForms.DragOverTabControl();
+      this.optimizerTabPage = new System.Windows.Forms.TabPage();
+      this.optimizerViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.openOptimizerButton = new System.Windows.Forms.Button();
+      this.newOptimizerButton = new System.Windows.Forms.Button();
+      this.runsTabPage = new System.Windows.Forms.TabPage();
+      this.runsView = new HeuristicLab.Optimization.Views.RunCollectionView();
+      this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
+      this.repetitionsLabel = new System.Windows.Forms.Label();
+      this.repetitionsNumericUpDown = new System.Windows.Forms.NumericUpDown();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.tabControl.SuspendLayout();
+      this.optimizerTabPage.SuspendLayout();
+      this.runsTabPage.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.repetitionsNumericUpDown)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // startButton
+      // 
+      this.startButton.Location = new System.Drawing.Point(0, 459);
+      this.toolTip.SetToolTip(this.startButton, "Start/Resume Batchrun");
+      // 
+      // executionTimeTextBox
+      // 
+      this.executionTimeTextBox.Location = new System.Drawing.Point(542, 462);
+      // 
+      // executionTimeLabel
+      // 
+      this.executionTimeLabel.Location = new System.Drawing.Point(453, 465);
+      // 
+      // pauseButton
+      // 
+      this.pauseButton.Location = new System.Drawing.Point(30, 459);
+      this.toolTip.SetToolTip(this.pauseButton, "Pause Batchrun");
+      // 
+      // stopButton
+      // 
+      this.stopButton.Location = new System.Drawing.Point(60, 459);
+      this.toolTip.SetToolTip(this.stopButton, "Stop Batchrun");
+      // 
+      // resetButton
+      // 
+      this.resetButton.Location = new System.Drawing.Point(90, 458);
+      this.toolTip.SetToolTip(this.resetButton, "Reset Batchrun");
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      this.nameTextBox.Location = new System.Drawing.Point(72, 0);
+      this.nameTextBox.Size = new System.Drawing.Size(582, 20);
+      // 
+      // infoLabel
+      // 
+      this.infoLabel.Location = new System.Drawing.Point(660, 3);
+      // 
+      // tabControl
+      // 
+      this.tabControl.AllowDrop = true;
+      this.tabControl.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.tabControl.Controls.Add(this.optimizerTabPage);
+      this.tabControl.Controls.Add(this.runsTabPage);
+      this.tabControl.Location = new System.Drawing.Point(0, 52);
+      this.tabControl.Name = "tabControl";
+      this.tabControl.SelectedIndex = 0;
+      this.tabControl.Size = new System.Drawing.Size(679, 401);
+      this.tabControl.TabIndex = 5;
+      // 
+      // optimizerTabPage
+      // 
+      this.optimizerTabPage.AllowDrop = true;
+      this.optimizerTabPage.Controls.Add(this.optimizerViewHost);
+      this.optimizerTabPage.Controls.Add(this.openOptimizerButton);
+      this.optimizerTabPage.Controls.Add(this.newOptimizerButton);
+      this.optimizerTabPage.Location = new System.Drawing.Point(4, 22);
+      this.optimizerTabPage.Name = "optimizerTabPage";
+      this.optimizerTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.optimizerTabPage.Size = new System.Drawing.Size(671, 375);
+      this.optimizerTabPage.TabIndex = 1;
+      this.optimizerTabPage.Text = "Optimizer";
+      this.optimizerTabPage.UseVisualStyleBackColor = true;
+      this.optimizerTabPage.DragDrop += new System.Windows.Forms.DragEventHandler(this.optimizerTabPage_DragDrop);
+      this.optimizerTabPage.DragEnter += new System.Windows.Forms.DragEventHandler(this.optimizerTabPage_DragEnterOver);
+      this.optimizerTabPage.DragOver += new System.Windows.Forms.DragEventHandler(this.optimizerTabPage_DragEnterOver);
+      // 
+      // optimizerViewHost
+      // 
+      this.optimizerViewHost.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.optimizerViewHost.Caption = "View";
+      this.optimizerViewHost.Content = null;
+      this.optimizerViewHost.Enabled = false;
+      this.optimizerViewHost.Location = new System.Drawing.Point(6, 36);
+      this.optimizerViewHost.Name = "optimizerViewHost";
+      this.optimizerViewHost.ReadOnly = false;
+      this.optimizerViewHost.Size = new System.Drawing.Size(659, 333);
+      this.optimizerViewHost.TabIndex = 3;
+      this.optimizerViewHost.ViewsLabelVisible = true;
+      this.optimizerViewHost.ViewType = null;
+      // 
+      // openOptimizerButton
+      // 
+      this.openOptimizerButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Open;
+      this.openOptimizerButton.Location = new System.Drawing.Point(36, 6);
+      this.openOptimizerButton.Name = "openOptimizerButton";
+      this.openOptimizerButton.Size = new System.Drawing.Size(24, 24);
+      this.openOptimizerButton.TabIndex = 1;
+      this.toolTip.SetToolTip(this.openOptimizerButton, "Open Optimizer");
+      this.openOptimizerButton.UseVisualStyleBackColor = true;
+      this.openOptimizerButton.Click += new System.EventHandler(this.openOptimizerButton_Click);
+      // 
+      // newOptimizerButton
+      // 
+      this.newOptimizerButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.NewDocument;
+      this.newOptimizerButton.Location = new System.Drawing.Point(6, 6);
+      this.newOptimizerButton.Name = "newOptimizerButton";
+      this.newOptimizerButton.Size = new System.Drawing.Size(24, 24);
+      this.newOptimizerButton.TabIndex = 0;
+      this.toolTip.SetToolTip(this.newOptimizerButton, "New Optimizer");
+      this.newOptimizerButton.UseVisualStyleBackColor = true;
+      this.newOptimizerButton.Click += new System.EventHandler(this.newOptimizerButton_Click);
+      // 
+      // runsTabPage
+      // 
+      this.runsTabPage.Controls.Add(this.runsView);
+      this.runsTabPage.Location = new System.Drawing.Point(4, 22);
+      this.runsTabPage.Name = "runsTabPage";
+      this.runsTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.runsTabPage.Size = new System.Drawing.Size(671, 374);
+      this.runsTabPage.TabIndex = 2;
+      this.runsTabPage.Text = "Runs";
+      this.runsTabPage.UseVisualStyleBackColor = true;
+      // 
+      // runsView
+      // 
+      this.runsView.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.runsView.Caption = "RunCollection View";
+      this.runsView.Content = null;
+      this.runsView.Location = new System.Drawing.Point(6, 6);
+      this.runsView.Name = "runsView";
+      this.runsView.ReadOnly = false;
+      this.runsView.Size = new System.Drawing.Size(659, 362);
+      this.runsView.TabIndex = 0;
+      // 
+      // openFileDialog
+      // 
+      this.openFileDialog.DefaultExt = "hl";
+      this.openFileDialog.FileName = "Optimizer";
+      this.openFileDialog.Filter = "HeuristicLab Files|*.hl|All Files|*.*";
+      this.openFileDialog.Title = "Open Optimizer";
+      // 
+      // repetitionsLabel
+      // 
+      this.repetitionsLabel.AutoSize = true;
+      this.repetitionsLabel.Location = new System.Drawing.Point(3, 28);
+      this.repetitionsLabel.Name = "repetitionsLabel";
+      this.repetitionsLabel.Size = new System.Drawing.Size(63, 13);
+      this.repetitionsLabel.TabIndex = 3;
+      this.repetitionsLabel.Text = "&Repetitions:";
+      // 
+      // repetitionsNumericUpDown
+      // 
+      this.repetitionsNumericUpDown.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.repetitionsNumericUpDown.Location = new System.Drawing.Point(72, 26);
+      this.repetitionsNumericUpDown.Maximum = new decimal(new int[] {
+            1000000,
+            0,
+            0,
+            0});
+      this.repetitionsNumericUpDown.Minimum = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+      this.repetitionsNumericUpDown.Name = "repetitionsNumericUpDown";
+      this.repetitionsNumericUpDown.Size = new System.Drawing.Size(607, 20);
+      this.repetitionsNumericUpDown.TabIndex = 4;
+      this.repetitionsNumericUpDown.ThousandsSeparator = true;
+      this.repetitionsNumericUpDown.Value = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+      this.repetitionsNumericUpDown.ValueChanged += new System.EventHandler(this.repetitionsNumericUpDown_ValueChanged);
+      this.repetitionsNumericUpDown.Validated += new System.EventHandler(this.repetitionsNumericUpDown_Validated);
+      // 
+      // BatchRunView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.repetitionsNumericUpDown);
+      this.Controls.Add(this.repetitionsLabel);
+      this.Controls.Add(this.tabControl);
+      this.Name = "BatchRunView";
+      this.Size = new System.Drawing.Size(679, 482);
+      this.Controls.SetChildIndex(this.tabControl, 0);
+      this.Controls.SetChildIndex(this.resetButton, 0);
+      this.Controls.SetChildIndex(this.stopButton, 0);
+      this.Controls.SetChildIndex(this.executionTimeLabel, 0);
+      this.Controls.SetChildIndex(this.pauseButton, 0);
+      this.Controls.SetChildIndex(this.executionTimeTextBox, 0);
+      this.Controls.SetChildIndex(this.startButton, 0);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      this.Controls.SetChildIndex(this.repetitionsLabel, 0);
+      this.Controls.SetChildIndex(this.repetitionsNumericUpDown, 0);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.tabControl.ResumeLayout(false);
+      this.optimizerTabPage.ResumeLayout(false);
+      this.runsTabPage.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.repetitionsNumericUpDown)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+    #endregion
+
+    private HeuristicLab.MainForm.WindowsForms.DragOverTabControl tabControl;
+    private System.Windows.Forms.TabPage optimizerTabPage;
+    private HeuristicLab.MainForm.WindowsForms.ViewHost optimizerViewHost;
+    private System.Windows.Forms.Button newOptimizerButton;
+    private System.Windows.Forms.Button openOptimizerButton;
+    private System.Windows.Forms.OpenFileDialog openFileDialog;
+    private System.Windows.Forms.TabPage runsTabPage;
+    private System.Windows.Forms.Label repetitionsLabel;
+    private System.Windows.Forms.NumericUpDown repetitionsNumericUpDown;
+    private RunCollectionView runsView;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/BatchRunView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/BatchRunView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/BatchRunView.cs	(revision 12764)
@@ -0,0 +1,193 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Optimization.Views {
+  /// <summary>
+  /// The base class for visual representations of items.
+  /// </summary>
+  [View("BatchRun View")]
+  [Content(typeof(BatchRun), true)]
+  public sealed partial class BatchRunView : IOptimizerView {
+    private TypeSelectorDialog optimizerTypeSelectorDialog;
+
+    public new BatchRun Content {
+      get { return (BatchRun)base.Content; }
+      set { base.Content = value; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of <see cref="ItemBaseView"/>.
+    /// </summary>
+    public BatchRunView() {
+      InitializeComponent();
+    }
+
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (optimizerTypeSelectorDialog != null) optimizerTypeSelectorDialog.Dispose();
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.OptimizerChanged -= new EventHandler(Content_OptimizerChanged);
+      Content.RepetitionsChanged -= new EventHandler(Content_RepetitionsChanged);
+      base.DeregisterContentEvents();
+    }
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.OptimizerChanged += new EventHandler(Content_OptimizerChanged);
+      Content.RepetitionsChanged += new EventHandler(Content_RepetitionsChanged);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        repetitionsNumericUpDown.Value = 1;
+        optimizerViewHost.Content = null;
+        runsView.Content = null;
+      } else {
+        repetitionsNumericUpDown.Value = Content.Repetitions;
+        optimizerViewHost.Content = Content.Optimizer;
+        runsView.Content = Content.Runs;
+      }
+    }
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      repetitionsNumericUpDown.Enabled = Content != null && !ReadOnly;
+      newOptimizerButton.Enabled = Content != null && !ReadOnly;
+      openOptimizerButton.Enabled = Content != null && !ReadOnly;
+      optimizerViewHost.Enabled = Content != null;
+      runsView.Enabled = Content != null;
+    }
+
+    protected override void OnClosed(FormClosedEventArgs e) {
+      if ((Content != null) && (Content.ExecutionState == ExecutionState.Started)) {
+        //The content must be stopped if no other view showing the content is available
+        var optimizers = MainFormManager.MainForm.Views.OfType<IContentView>().Where(v => v != this).Select(v => v.Content).OfType<IOptimizer>();
+        if (!optimizers.Contains(Content)) {
+          var nestedOptimizers = optimizers.SelectMany(opt => opt.NestedOptimizers);
+          if (!nestedOptimizers.Contains(Content)) Content.Stop();
+        }
+      }
+      base.OnClosed(e);
+    }
+
+    #region Content Events
+    private void Content_OptimizerChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_OptimizerChanged), sender, e);
+      else {
+        optimizerViewHost.Content = Content.Optimizer;
+      }
+    }
+    private void Content_RepetitionsChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_RepetitionsChanged), sender, e);
+      else
+        repetitionsNumericUpDown.Value = Content.Repetitions;
+    }
+    #endregion
+
+    #region Control events
+    private void repetitionsNumericUpDown_Validated(object sender, System.EventArgs e) {
+      if (repetitionsNumericUpDown.Text == string.Empty)
+        repetitionsNumericUpDown.Text = repetitionsNumericUpDown.Value.ToString();
+    }
+    private void repetitionsNumericUpDown_ValueChanged(object sender, EventArgs e) {
+      if (Content != null)
+        Content.Repetitions = (int)repetitionsNumericUpDown.Value;
+    }
+    private void newOptimizerButton_Click(object sender, EventArgs e) {
+      if (optimizerTypeSelectorDialog == null) {
+        optimizerTypeSelectorDialog = new TypeSelectorDialog();
+        optimizerTypeSelectorDialog.Caption = "Select Optimizer";
+        optimizerTypeSelectorDialog.TypeSelector.Caption = "Available Optimizers";
+        optimizerTypeSelectorDialog.TypeSelector.Configure(typeof(IOptimizer), false, true);
+      }
+      if (optimizerTypeSelectorDialog.ShowDialog(this) == DialogResult.OK) {
+        try {
+          Content.Optimizer = (IOptimizer)optimizerTypeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
+        }
+        catch (Exception ex) {
+          ErrorHandling.ShowErrorDialog(this, ex);
+        }
+      }
+    }
+    private void openOptimizerButton_Click(object sender, EventArgs e) {
+      openFileDialog.Title = "Open Optimizer";
+      if (openFileDialog.ShowDialog(this) == DialogResult.OK) {
+        newOptimizerButton.Enabled = openOptimizerButton.Enabled = false;
+        optimizerViewHost.Enabled = false;
+
+        ContentManager.LoadAsync(openFileDialog.FileName, delegate(IStorableContent content, Exception error) {
+          try {
+            if (error != null) throw error;
+            IOptimizer optimizer = content as IOptimizer;
+            if (optimizer == null)
+              MessageBox.Show(this, "The selected file does not contain an optimizer.", "Invalid File", MessageBoxButtons.OK, MessageBoxIcon.Error);
+            else
+              Content.Optimizer = optimizer;
+          }
+          catch (Exception ex) {
+            ErrorHandling.ShowErrorDialog(this, ex);
+          }
+          finally {
+            Invoke(new Action(delegate() {
+              optimizerViewHost.Enabled = true;
+              newOptimizerButton.Enabled = openOptimizerButton.Enabled = true;
+            }));
+          }
+        });
+      }
+    }
+
+    private void optimizerTabPage_DragEnterOver(object sender, DragEventArgs e) {
+      e.Effect = DragDropEffects.None;
+      if (!ReadOnly && (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IOptimizer)) {
+        if ((e.KeyState & 32) == 32) e.Effect = DragDropEffects.Link;  // ALT key
+        else if ((e.KeyState & 4) == 4) e.Effect = DragDropEffects.Move;  // SHIFT key
+        else if (e.AllowedEffect.HasFlag(DragDropEffects.Copy)) e.Effect = DragDropEffects.Copy;
+        else if (e.AllowedEffect.HasFlag(DragDropEffects.Move)) e.Effect = DragDropEffects.Move;
+        else if (e.AllowedEffect.HasFlag(DragDropEffects.Link)) e.Effect = DragDropEffects.Link;
+      }
+    }
+    private void optimizerTabPage_DragDrop(object sender, DragEventArgs e) {
+      if (e.Effect != DragDropEffects.None) {
+        IOptimizer optimizer = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as IOptimizer;
+        if (e.Effect.HasFlag(DragDropEffects.Copy)) optimizer = (IOptimizer)optimizer.Clone();
+        Content.Optimizer = optimizer;
+      }
+    }
+    #endregion
+
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/CreateNewSingleEncodingDialog.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/CreateNewSingleEncodingDialog.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/CreateNewSingleEncodingDialog.Designer.cs	(revision 12764)
@@ -0,0 +1,149 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class CreateNewSingleEncodingDialog {
+    /// <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() {
+      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CreateNewSingleEncodingDialog));
+      this.label1 = new System.Windows.Forms.Label();
+      this.encodingTypeComboBox = new System.Windows.Forms.ComboBox();
+      this.label2 = new System.Windows.Forms.Label();
+      this.encodingNameTextBox = new System.Windows.Forms.TextBox();
+      this.okButton = new System.Windows.Forms.Button();
+      this.cancelButton = new System.Windows.Forms.Button();
+      this.SuspendLayout();
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(22, 20);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(34, 13);
+      this.label1.TabIndex = 0;
+      this.label1.Text = "Type:";
+      // 
+      // encodingTypeComboBox
+      // 
+      this.encodingTypeComboBox.DisplayMember = "Name";
+      this.encodingTypeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.encodingTypeComboBox.FormattingEnabled = true;
+      this.encodingTypeComboBox.Location = new System.Drawing.Point(66, 17);
+      this.encodingTypeComboBox.Name = "encodingTypeComboBox";
+      this.encodingTypeComboBox.Size = new System.Drawing.Size(232, 21);
+      this.encodingTypeComboBox.TabIndex = 1;
+      this.encodingTypeComboBox.SelectedIndexChanged += new System.EventHandler(this.encodingTypeComboBox_SelectedIndexChanged);
+      // 
+      // label2
+      // 
+      this.label2.AutoSize = true;
+      this.label2.Location = new System.Drawing.Point(22, 47);
+      this.label2.Name = "label2";
+      this.label2.Size = new System.Drawing.Size(38, 13);
+      this.label2.TabIndex = 2;
+      this.label2.Text = "Name:";
+      // 
+      // encodingNameTextBox
+      // 
+      this.encodingNameTextBox.Location = new System.Drawing.Point(66, 44);
+      this.encodingNameTextBox.Name = "encodingNameTextBox";
+      this.encodingNameTextBox.Size = new System.Drawing.Size(232, 20);
+      this.encodingNameTextBox.TabIndex = 3;
+      this.encodingNameTextBox.TextChanged += new System.EventHandler(this.encodingNameTextBox_TextChanged);
+      // 
+      // okButton
+      // 
+      this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.okButton.Location = new System.Drawing.Point(142, 70);
+      this.okButton.Name = "okButton";
+      this.okButton.Size = new System.Drawing.Size(75, 23);
+      this.okButton.TabIndex = 4;
+      this.okButton.Text = "&OK";
+      this.okButton.UseVisualStyleBackColor = true;
+      this.okButton.Click += new System.EventHandler(this.okButton_Click);
+      // 
+      // 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(223, 70);
+      this.cancelButton.Name = "cancelButton";
+      this.cancelButton.Size = new System.Drawing.Size(75, 23);
+      this.cancelButton.TabIndex = 4;
+      this.cancelButton.Text = "&Cancel";
+      this.cancelButton.UseVisualStyleBackColor = true;
+      this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
+      // 
+      // CreateNewSingleEncodingDialog
+      // 
+      this.AcceptButton = this.okButton;
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.CancelButton = this.cancelButton;
+      this.ClientSize = new System.Drawing.Size(320, 105);
+      this.Controls.Add(this.cancelButton);
+      this.Controls.Add(this.okButton);
+      this.Controls.Add(this.encodingNameTextBox);
+      this.Controls.Add(this.label2);
+      this.Controls.Add(this.encodingTypeComboBox);
+      this.Controls.Add(this.label1);
+      this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+      this.MaximizeBox = false;
+      this.MinimizeBox = false;
+      this.Name = "CreateNewSingleEncodingDialog";
+      this.ShowInTaskbar = false;
+      this.Text = "Create new encoding";
+      this.Load += new System.EventHandler(this.CreateNewSingleEncodingDialog_Load);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.ComboBox encodingTypeComboBox;
+    private System.Windows.Forms.Label label2;
+    private System.Windows.Forms.TextBox encodingNameTextBox;
+    private System.Windows.Forms.Button okButton;
+    private System.Windows.Forms.Button cancelButton;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/CreateNewSingleEncodingDialog.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/CreateNewSingleEncodingDialog.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/CreateNewSingleEncodingDialog.cs	(revision 12764)
@@ -0,0 +1,84 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Windows.Forms;
+using HeuristicLab.Optimization;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Optimization.Views {
+  public partial class CreateNewSingleEncodingDialog : Form {
+    private HashSet<string> forbiddenNames;
+    public IEnumerable<string> ForbiddenNames {
+      get { return forbiddenNames; }
+      set { forbiddenNames = new HashSet<string>(value); }
+    }
+
+    public Type EncodingType { get; private set; }
+    public string EncodingName { get; private set; }
+
+    public CreateNewSingleEncodingDialog() {
+      InitializeComponent();
+      forbiddenNames = new HashSet<string>();
+    }
+
+    private void CreateNewSingleEncodingDialog_Load(object sender, EventArgs e) {
+      encodingTypeComboBox.Items.Clear();
+      var encodings = ApplicationManager.Manager.GetTypes(typeof(IEncoding));
+      foreach (var enc in encodings) {
+        if (enc != typeof(MultiEncoding))
+          encodingTypeComboBox.Items.Add(enc);
+      }
+      if (encodingTypeComboBox.Items.Count > 0)
+        encodingTypeComboBox.SelectedIndex = 0;
+      else encodingTypeComboBox.SelectedIndex = -1;
+    }
+
+    private void encodingNameTextBox_TextChanged(object sender, EventArgs e) {
+      EncodingName = encodingNameTextBox.Text;
+      SetEnabledStateOfControls();
+    }
+
+    private void encodingTypeComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      if (encodingTypeComboBox.SelectedIndex >= 0)
+        EncodingType = (Type)encodingTypeComboBox.SelectedItem;
+      else EncodingType = null;
+      SetEnabledStateOfControls();
+    }
+
+    private void SetEnabledStateOfControls() {
+      okButton.Enabled = EncodingType != null
+                         && !string.IsNullOrEmpty(EncodingName)
+                         && !forbiddenNames.Contains(EncodingName);
+    }
+
+    private void okButton_Click(object sender, EventArgs e) {
+      DialogResult = DialogResult.OK;
+      Close();
+    }
+
+    private void cancelButton_Click(object sender, EventArgs e) {
+      DialogResult = DialogResult.Cancel;
+      Close();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/CreateNewSingleEncodingDialog.resx
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/CreateNewSingleEncodingDialog.resx	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/CreateNewSingleEncodingDialog.resx	(revision 12764)
@@ -0,0 +1,1787 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+  <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        AAABAAUAEBAAAAEAIABoBAAAVgAAACAgAAABACAAqBAAAL4EAAAwMAAAAQAgAKglAABmFQAAQEAAAAEA
+        IAAoQgAADjsAAICAAAABACAAKAgBADZ9AAAoAAAAEAAAACAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAABuR/gAbk/YAAAAAABuS9gAAAAAAGpD2AAAAAAAAAAAAAAAAABuQ
+        9QAAAAAAAAAAAByS9QAAAAAAAAAAAAAAAAAakfUAAAAAABuR9QIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHJD2QAAAAAAAAAAAGo/4CBuR9f8akPVCAAAAABuT9gAAAAAAG5H1/xuR9YEbkPYUG5H1/xqR
+        9v8bkfX/G5H1/xuS9P8bkfX/GpH1QwAAAAAbkfX/G5H1eQAAAAAAAAAAAAAAABuR9cgbkPSjAAAAABuR
+        9f8dkfWZG5H1QRyR9kAbkfWrG5L1TwAAAAAAAAAAHJH1zhuR9p4AAAAAAAAAAAAAAAAckvaHG5H15QAA
+        AAAbkfXkHJH2hgAAAAAAAAAAAAAAAAAAAAAbkvUAAAAAABuS9YwbkfXiGpHzJhuS9TQbkfQwG5H1fhuR
+        9f8AAAAAG5L1qhuR9cUAAAAAHJD2AAAAAAAbkfYAAAAAAAAAAAAbkfVqG5H1/xuR9f8akfX/G5H1/xuR
+        9f8bkfX/GpLzFhuQ9n0bkfX/AAAAABiQ9gAAAAAAAAAAAAAAAAAAAAAAG5H2KRuR9f8ckfYcI5D3Ax+U
+        /AUAAAAAG5H1/xyR9VEckvVBG5H1/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckfX/GpH1TgAA
+        AAAAAAAAAAAAABuR9esakfWBGI7xBhyR9f8akfQwAAAAAAAAAAAAAAAAAAAAABuS9QAAAAAAG5L1+huR
+        9YAAAAAAGpH1AAAAAAAbkfalG5H0ugAAAAAbkfX/HJL1bwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByR
+        9ccbkfXIAAAAAAAAAAAAAAAAG5L17BuR9f8dkvMXG5H17BqR9Z0AAAAAAAAAAAAAAAAAAAAAAAAAABuR
+        9QEAAAAAAAAAABuR9QEbkfQAAAAAAB6P9w8akfXwAAAAAAAAAAAAAAAAG5H1AAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAByR9gAAAAAAAAAAABqR9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG5L1AAAAAAAckvQAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAP//AAD//wAA//8AALyBAAC8mwAAnJ8AAJ6fAADA3wAA3t8AAN5fAADOXwAAzk8AAP9/
+        AAD//wAA//8AAP//AAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABqQ
+        9gAAAAAAAAAAABuT9wAAAAAAAAAAAAAAAAAckvYAAAAAAAAAAAAAAAAAAAAAAByS9wAAAAAAAAAAAAAA
+        AAAAAAAAHZb2ABuP9QAAAAAAAAAAAAAAAAAckvUAHJH2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAABuQ9QIAAAAAAAAAAByS9gAAAAAAAAAAAAAAAAAckfQDGpr/AxqS+Qcckf8BAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAHJP2AQAAAAAAAAAAAAAAABuR9gEckfYAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAByR9v8ckvU/AAAAAAAAAAAbk/QAAAAAABuR9lkckvX/HJL1/xuR
+        9ocAAAAAAAAAAAAAAAAAAAAAAAAAAB2W9wAAAAAAHJH1/xuS9v8ckfXvAAAAAAAAAAAbkfZwG5L1/xyS
+        9v8bkvb/G5L2/xuR9v8bkvb/G5H1/xyS9v8bkvX/G5L1/ByR9f8bkvbBHJjtBgAAAAAAAAAAHpL3BxuR
+        9f8bkfb/G5H1owAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckfXIG5H2/xuS9v8AAAAAAAAAAByS
+        9SMbkfb/G5H1/huR9v8bkfb/HJH1/xuS9v8ckfb/G5L2/xyS9f8bkvX+G5H2/hyR9v8bkfb/AAAAABuS
+        9QAAAAAAHJL2/xuS9f8ckvbjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABuS9ogckvX/HJH1/xqT
+        9hgAAAAAAAAAAByR9v8bkvX/HZH17h2S95UbkfWdHJL2nBuR9podkvaaG5L2ihyR9f8ckvb/G5L1YgAA
+        AAAbkvYAAAAAAAAAAAAbkfXSG5H1/xuR9f8AAAAAG5L2AAAAAAAAAAAAAAAAAAAAAAAAAAAAG5H2YhyR
+        9f8bkfX/HJH1XAAAAAAAAAAAHJL2+BuR9f8ckvX/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG5L13QAA
+        AAAAAAAAG5L1AAAAAAAAAAAAAAAAABuR948dkvX/HJL2/xyR9xMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAbk/UgHJL2/xyR9v8ckfWIAAAAAAAAAAAckfa+HJL1/xyS9v8AAAAAAAAAAAAAAAAAAAAAAAAAAByR
+        9gEAAAAAAAAAAByS9gAAAAAAAAAAAAAAAAAAAAAAG5H1bhyS9f8ckvb/G5H1UgAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHZHyAAAAAAAckvb/G5L1/xuS9cAAAAAAAAAAABuR9Ycckvb/HJL2/x2R9SIAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckfQtG5L2/xuS9f8bkfV9AAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS9egbkfb/HJL2/wAAAAAAAAAAHJL2YhuS9v8bkvX/G5H1XAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckvX/HJL2/xyS
+        980bkfV6G5L1fxyS9n8bkvV/HJL1fxuR9X8bkfV6G5L20ByS9v8bkfX/AAAAAAAAAAAakvYlHJL1/xyS
+        9v8bkfaDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbkfQAAAAAAByR
+        9vkckfX/HJL1/xuR9v8ckfb/G5H1/xuS9f8bkfb/HJL2/xyR9f8ckvX/G5H1/huS9v8bkfU6AAAAAAAA
+        AAAckfb/HJH1/xuR9rQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAG5L1thuR9v8ckvb9G5H1/xuS9v8bkfb/G5L2/xuR9f8bkvX/G5L2/xuS9v8bkfX9HJH2/xuS
+        9XMAAAAAAAAAABuR9vcbkfb/G5L18AAAAAAfkvYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAckfaFG5L1/xyR9f8ckvZdHZL3LRyS9i8ckfYvHJP2LxyR9y8ckvcvHJH2JxyR
+        9f8bkvb/HJH1lgAAAAAAAAAAHJL2txuS9f8ckfb/AAAAAACK9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAABuS9lQbkfb/HJL1/xuR9XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAG5L2/xuR9f8ckvbYAAAAAAAAAAAckvWGG5H2/xyS9f8ZkPYmAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJL1EhyR9f8ckvb/G5L2kAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAbkfXLHJL2/xuR9f8AAAAAAAAAABuR9V4ckfX/HJL2/xyR9WkAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+R+gAAAAAAG5H1/x2S9v8bkfXLAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAByR9pEckvb/G5L2/xyQ8QgAAAAAHZL1HRyS9v8dkvb/G5L1iAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG5P0AAAAAAAckvblG5L1/xyS
+        9v8AAAAAHJH2AAAAAAAAAAAAAAAAAAAAAAAAAAAAG5H1cxuS9v8ckfX/G5H2SQAAAAAAAAAAHJH1/xuS
+        9f8ckvbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABuS
+        9qMckvb/G5H1/wAAAAAAAAAAAAAAAAAAAAAAAAAAHJL1AAAAAAAbkfckHJL2/xuS9f8bkvV2AAAAAAAA
+        AAAbkvXyHJL2/xyS9f4AAAAAG5H3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHJH2eByS9f8bkfb/G5L0MAAAAAAAAAAAAAAAAAAAAAAAAAAAG5H1ChyS9e8ckvb/G5H1/xuS
+        9vAckvWPAAAAABuS9rMckfX/G5H1/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAbkvVFHJL2/xuS9f8ckvZ0AAAAAAAAAAAAAAAAAAAAAByS9QAAAAAAHJH1QhuS
+        9v8ckfb+G5L2/x2S9SgAAAAAG5H1ghyS9v8bkvb/HJL2LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAHJL1AAAAAAAAAAAAAAAAAAAAAAAckvYAAAAAAAAAAAAAAAAAAAAAAByR
+        9QAAAAAAHJH2oRuS9f8bkfXWAAAAABuS9QAAAAAAAAAAAAAAAAAAAAAAHJL2AAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbkvYAAAAAAByS9gAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAByS9gAAAAAAG5H26xuS9lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckvUVAAAAABqR9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJL2AAAAAAAbkfYAJZTtAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAP//////////////////////////////78fxwAPH8cABx/HAB8f5x+/H+Mf/5/jH/+f4
+        5//j+OP/4ADj/+AA4//j/GP/8/xj//H8c//x/HH/8f5x//H+cf/5/BH/+f4x///+P////3//////////
+        ////////////////////////KAAAADAAAABgAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGpD2AByX+AAAAAAAAAAAABuT9wAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAByS9gAAAAAAHJL2AByT9gAbkvcAHJL2AByS9wAAAAAAHJL3AAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAB2W9wAAAAAAHJT1ABuR9gAckvcAHJH2ABuR9gAqnu0AAAAAAByS9gAAAAAAHJH2ABuQ
+        9QAckvYAHJL2AByR9QAckvYAHZH2AByT9wAbk/YAHJH1AByT9wAbkfYAHJL2ABuR9QIAAAAAAAAAAByS
+        9QMbkfUAAAAAAAAAAAAAAAAAAAAAAAAAAAAckvYAAAAAAAAAAAAAAAAAAAAAAAAAAAAckvYAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckvYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGpL1AAAA
+        AAAckvYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAbkvVNG5H1VQAAAAAAAAAAAAAAABuS9QAfkfgAAAAAAByS9QAAAAAAHJL1HRuS9iYbkvYmHJL2LByS
+        9hsAAAAAHJL3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByW9wAAAAAAHJP1ARuR9hQckvYQHJL3ERyR
+        9g0AAAAAHIX5ABuS9QAAAAAAHJH1EBuR9hIdkvYQHJP3EByT9xAckvcQHJL3EByS9xAbkvcQHJL1EByT
+        9hAckfcQHJD2EQAAAAAckvaQHJH2/xuR9Z4bkfUMAAAAAAAAAAAbkvUBAAAAABuR9gMAAAAAG5H2lhyS
+        9v8bkfb/HJL2/xyS9sEAAAAAG5H1BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2W9wAAAAAAHJL1AhuS
+        9vUbkfX/HJL2/xyR9fEakfU+AAAAAByR9gMAAAAAHJL2rBuS9f8ckfb+HJL2/RuS9v0ckfb9HJL2/RyR
+        9v0bkfb9HJL2/RuR9f0ckvb9HJH2/RuR9f0bkvb7HJL2/xuR9f8ckvX1G5L1YwAAAAAAAAAAG5L2AhuR
+        9wEAAAAAG5H3VxyS9v8bkfX/G5H2/xyR9soAAAAAG5H1AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAByR9cgbkvb/G5H2/xuR9v8ckfVsAAAAABuS9gIAAAAAG5H2dhuR9f8bkfX/G5H1/xuR
+        9v8bkvb/G5H2/xuR9f8ckfX/G5H2/xyR9v8bkvb/G5H2/xyR9v8ckvX/G5H2/RuR9v8bkvb/HJL2/xyS
+        9tAckfVMAAAAAByS9QAAAAAAHJL1HRuR9f8ckvb/HJL1/xuS9dsakvUWAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAABuS9Y0ckfb/G5L2+xyS9v8ckvWCAAAAAByS9QEAAAAAHJL1QhyS
+        9v8ckvb/G5L1/hyS9v8ckfb/HJL2/xuR9v8bkfX/HJL2/xuR9v8ckvb/HJL2/xuR9f8ckvX/G5L1/ByS
+        9v0bkfb/HJH2/xyR9vMckfVAAAAAAAAAAAAAAAAAAAAAAByR9fYckvb/G5L1/xyS9fYckvZEAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABuS9k8ckfX/HJL1+RyS9f8ckfakAAAAAAAA
+        AAAAAAAAGZH1DByR9f4ckvb/G5L1/x2R9fwckfbbHJL20ByR9dMbkfbSHJL20hyS9dEckvbQHJL20RyR
+        9cobkfbjHJL1/xyS9f8bkfb3G5L1fgAAAAAAAAAAGpP2AAAAAAAAAAAAAAAAABuR9c8bkfX/G5L2/xuR
+        9v8bkfVuAAAAABqS9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckvYAAAAAABuR9TYckvb/HJH1+xuR
+        9v8bkfXQHJP0FQAAAAAAAAAAAAAAAByS9vMckfX/G5H2/xyS9v0bk/VSAAAAAB2R9AcekfsGHZT5BiGU
+        9wQTjP0DFpf7BAAAAAAbkfaAHJH2/xyR9bgbkvYrAAAAAAAAAAAAAAAAHJL2AAAAAAAAAAAAAAAAAByR
+        9Zockfb/HJL1/ByS9f8bkvaAAAAAACCR+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABuS
+        9igckvbwHJH1/xuR9v8bkvX9HJH1LQAAAAAAAAAAAAAAAByR9c0ckvb/HJH1/hyS9f8bkvZ1AAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckvV8G5L1eQAAAAAAAAAAHJH1BBqT+AAAAAAAAAAAAAAA
+        AAAAAAAAAAAAABuS9l0ckfb/HZL1+hyS9v8bkfagAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAABuU9QwckvXAHJL2/xyR9vkckfb/G5H1QQAAAAAAAAAAAAAAAByS9ZcckfX/HZL2+xyS
+        9v8bkfWEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckvYAAAAAAAAAAAAckvYBAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAckfUAAAAAABuS9jkckfb/HJL2+RyS9v8ckfbJGpL3EQAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbkfWUHJL2/xyS9vsckfX/G5L1ZAAAAAAAAAAAAAAAAByS
+        9mcckfb/HJL2+xyS9v8bkfaeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS9gAAAAAAAAAAABuR
+        9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABuR9S8ckfX8HJL2/xyS9v8ckfXxG5L1KAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJDyAAAAAAAbkfV/HJL2/xyS9vwbkfX/HJL1mwAA
+        AAAAAAAAAAAAABqR9UAckfX/HZL2+hyS9v8bkfXAH5L2DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByP9BMbkvXNG5L2/xyS
+        9vobkfX/G5H1PAAAAAAckfYEHJL2BByS9QQbkfUEHJL2BByS9QQbkfUEG5L2BAAAAAAckfViHJL2/xuR
+        9f8bkfb/HJL12AAAAAAAAAAAAAAAABuR9S8bkfX/G5L2/huS9v8ckfbqHJL2JAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAckfWjHJL1/xyS9fkbkvb/HJL2PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAek/YVHJL15BuR9f8ckfb/G5L1/QAAAAAAAAAAAAAAABqS9hsckfbbHJL1/xyS9fsbkfX/HJL1NgAA
+        AAAckvYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAckfWFHJL2/xyS9v0ckvb/HJL32huR9b4bkfXBHJL1wRyR9cEbkfbBHJH2wRuR
+        9sEckvXBHJH2wRyR9sEbkvXCHJL18xyR9v8bkfb/HJH2/xyR9SIAAAAAAAAAABaW+gQckvayHJL2/xyS
+        9vobkfb/HJL2RAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAG5H1AAAAAAAbkvZqHJH1/xyR9f8bkfX8HJH1/xyR9v8bkfX/HJH2/xyR
+        9f8bkfX/HJH1/xuR9f8ckvb/HJL1/xyS9f8bkvX/HJH1/xyR9v0bkfX/HJL2/xyR9V4AAAAAHZL2AAAA
+        AAAbkfWMHJH2/xyR9fsbkfb/HJH2dQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckvVBG5L29BuR9v8bkvb9G5H2/RuR
+        9v8ckfX/G5L2/xuR9v8bkvb/G5H2/xyR9v8bkvX/G5H2/xuR9v8ckvb/G5H2/xuR9v4ckfX/G5L2/xuS
+        9pEAAAAAHJL2AwAAAAAbkvV5G5H2/xuR9vwbkvX/G5L1pgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAakvUWG5H22xyR
+        9v8bkfb9HJL2/RyR9v8bkfb/HJL2/xyR9v8ckvb/HJL2/xyR9v8ckfb/HJL2/xyS9v8ckfb/HJL2/xyR
+        9v4bkfX/HJL2/xyS9roAAAAAG5H1BAAAAAAbkfZYHJL2/xyR9v8ckvb/HJL11wAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABuS
+        9gIAAAAAHJL1yBuS9f8ckfb/HJL1/xyS9pockfdSHJL2XhyS9lwckfZcHJL2XByT9lwdkvdcHJL2XByS
+        9l0ckvZXHJL2bByS9f4bkfX/HJL2/xyS9swAAAAAG5L0AQAAAAAckfYrHJH15xuS9f8ckfb/HJH2/heS
+        9gEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAABuR9gQAAAAAHJL2tRuS9v8ckfX/HJL1/xuS9YYAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAABuR9v8ckfb/G5H2/xyS9uIdkvUiAAAAAAAAAAAckvoCG5H20RuR
+        9v8ckvX/HJH1/xuS9SAAAAAAG5L2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAABuR9QIAAAAAG5H1fhuR9f8ckfb/HJL1/xyS9bkAAAAAHJL2BhyS
+        9gEckfYBHJL2ARyT9gEdkvcBHJH2ARyS9wEAAAAAHI33ARyS9uMbkfX/G5H1/xyS9fockvZMAAAAAByS
+        9gMAAAAAHJL2xhuS9f8ckfX/HJL2/xuR9l4AAAAAG5H2AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS9QEAAAAAHJL1QxyS9f8ckfX/HJL2/xyS
+        9skAAAAAHJP3AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABuR9agbkvX/HJL2/RyR
+        9v8bkfVzAAAAABuR9QMAAAAAG5H1oxuR9v8ckfX/HJL2/xyS9pwAAAAAHJH1AwAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2T9wAAAAAAHJP3EhyR
+        9v8ckvX/HJL2/xyS9twbkPQXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS
+        9XYckfX/HJL2+hyS9v8bkvaGAAAAAByP9AEAAAAAHJH1bRyS9f8ckvX/HJL2/xyS9r0AAAAAHJH2BAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAG4/vARuR9vYckvX/HZL2/xyR9vIbkvY9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAByS9kwckfX/HJL2+hyS9v8bkfWoAAAAAAAAAAAAAAAAHJL2OhyS9v8ckvX/HZL2/xyS
+        9soAAAAAG5X1AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAABuS9skckfX/G5L2/xyS9v8bkfVpAAAAABeK9gAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAakvYAAAAAABuS9TcbkfX/G5L2+xuS9f8ckvXWG5L4GQAAAAAAAAAAGpL4ChyR
+        9v4bkfX/G5L2/xuS9uIckPYhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABuS9ZYckfb/HJL1+xyS9f8bkfaAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckvYAAAAAAByR9iIbkfbsHJL1/xyS9v0bkfb/HJH1LgAA
+        AAAAAAAAAAAAABuS9fEbkvb/HJL1/xyS9vgckvZIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABuR9l4ckfX/HJL2+xuR
+        9v8ckvaUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS9gAAAAAAAAAAABuT+QYbkva8HJL2/xyR
+        9vobkfX/G5L1NwAAAAAhoP8AAAAAABuS9sMckvX/HJL2/xyR9v8bkvVvAAAAABqS9gAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAclPUAAAAAAByR
+        9jgckvX/HJH1+hyR9v8bkvW9HJL0CgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS9gEAAAAAG5H2NByS
+        9rockvXcHJH2/xyR9f0bkfX/G5L1zBuS9ZUck/gTAAAAAByS9osckfX/HJH1+huR9f8bkvWEAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAbkfcAAAAAABuR9S4bkfb/G5H2/xuR9v8ckvXtG5P1IwAAAAAbkvYAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAByR9asckvX/G5H2+RuR9v4bkvb9HJL1/x2R9rwAAAAAAAAAABuR9VYbkfb/G5H2/xuS
+        9v8bkfakAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAByT9RQckvbCHJL28ByS9eMbkvb1G5L2MwAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAByS9QAbkvYAAAAAAAAAAAAbkfXGHJL2/xyR9v4ckvb/HJL2/xyS9TQAAAAAAAAAABuR
+        9TYbkvb8HJL24hyS9vEbkva4HJT2DwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFo/2AAAAAAAAAAAAKKHgAQAAAAAbjvYDHI/1AgAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgjfEAG5L2AQAAAAAckfgeHJL27xuS9f8bkvX/G5H2xQAA
+        AAAAAAAAAAAAAAAAAAAYpvkAZf+2AAAAAAAbk/UDG5T6AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZL1AAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAByS9gAbkvYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJH2AByS9gIAAAAAHJH1TRuS
+        9v8bkfb/G5H1TgAAAAAAAAAAHJH2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByT9wAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAByS9gAAAAAAHJL2AByS9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAek/YAAAAAABuR9ocbkvXlGpL2DgAAAAAakPQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAckvUAAAAAABuR9hEbkvUuAAAAAByR9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAakfgAHJL1AQAAAAAAAAAAHZH2ABuS9QAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABuR9gAckvUBAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////wAA////////AAD///////8AAP//
+        /////wAA////////AAD///////8AAP///////wAA////////AAD//////x8AAMH/w8AADwAA4f/D4AAD
+        AADh/8HgAAMAAOH/4eAADwAA4f/h4f8fAADg/+Hh//8AAPD/4eD//wAA8P/h8P//AADw//Dw//8AAPD/
+        8PD//wAA8P/w8P//AADwAADw//8AAPgAAPD//wAA+AAAeH//AAD4AAB4f/8AAPg/+Hh//wAA+D/4eH//
+        AAD8P/h4f/8AAPw/+Hg//wAA/D/8PD//AAD8P/w8P/8AAPw//Dw//wAA/B/8PD//AAD+H/w8P/8AAP4f
+        +Awf/wAA/h/4Dh//AAD+H/weH/8AAP///h///wAA////P///AAD///8///8AAP///////wAA////////
+        AAD///////8AAP///////wAA////////AAD///////8AAP///////wAA////////AAD///////8AACgA
+        AABAAAAAgAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAdk/YAAAAAAB2T9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAbkvcAAAAAAAAAAAAbk/cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABqQ9gQbk/cUAAAAAEac7AAckvYAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2T9wAckvYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJL3AByS
+        9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2U9wAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAHZP2AAAAAAAAAAAAAAAAAByS9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJL2/xyR
+        9oEAAAAAAAAAAByS9gAfkPcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS9ikdk/crG5P3LhyS
+        9zEck/c0HJL3LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHZb3ARyS9hQckvcSHZP3Eh2R9hIbkfcTIJX0BAAAAAAck/cAAAAAAAAAAAAAAAAAHJL2ExyQ
+        9hIckvUSHZP3EhyS9hIdkvYSHJL2Eh2T9xIdkfYSHZP3EhyU9xIck/YSHZH2EhyT9xIck/cSG5D2EhyT
+        9xIckfYSG5r9AhyS9/8ckvb/HJL2+hyS9kAAAAAAAAAAAByS9gAAAAAAAAAAAAAAAAAAAAAAHZP2AAAA
+        AAAckvbSHJL2/xyS9v8ckvb/HZP2/xyS9v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckvb/HJL2/xyS9v8ck/f/HZL2/xuS9ooAAAAAAAAAAAAA
+        AAAAAAAAAAAAAByS9u4ck/b/HJL2/x2S9/8ck/f/HJP3/xyS9/8ckvb/HJP3/xyS9v8ckff/HJL2/xyT
+        9/8ckvb/HJL2/x2T9/8ckfb/HJL2/xyS9v8ckvb9HJL2/xyS9v0ckvb/HJL2xR+R+AcAAAAAAAAAAByS
+        9wAAAAAAAAAAAByS9gAAAAAAG5H3hh2T9v8ckvb+HJL2/hyS9v4ckvb/IZ3/AQAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByT9gAAAAAAHJL2zRyS9v8ckvb+HJL2/hyS
+        9v8ckfbAAAAAAAAAAAAAAAAAG5H1AAAAAAAckvevHJL1/xyS9v4ckvb+HJL2/hyS9v4ckvb+HJL2/hyS
+        9v4ckvb+HJL2/hyS9v4ckvf+HJL2/hyS9v4ck/b9HJL2/hyS9v4ckvb+HJL2/hyS9v4ckvb+HJL2/hyT
+        9v8ckvb/HJP1ggAAAAAAAAAAHZL2AAAAAAAAAAAAAAAAAB2S91Yckvb/HJL2/hyS9v4ckvb/HJL2/xyS
+        9ikAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdlPQAAAAAAByS
+        9pYckvb/HJL3/hyS9/4ckvf/HJL29AAAAAAAAAAAAAAAAAAAAAAAAAAAHJL2fByS9v8ckvb+HJL2/hyS
+        9v8ckvf/HJL2/hyS9/4ckvf+HJL2/xyR9v8ckvb/HJL3/hyS9v8ckvf/HJP2/hyR9/8ckvb/HJL2/hyS
+        9v4ckvb/HJL3/xyS9v4ckvf+HZL2/hyS9/8ckvb/HZH1IQAAAAAAAAAAHJL2AAAAAAAakvQYHJL2/xyS
+        9v8ckvb+HJL2/xyS9v8bkvZXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAckvZhHJL2/xyS9v4ckvb+HJL2/hyS9v8dk/cJAAAAAAAAAAAAAAAAAAAAAB2S
+        9kwckvb/HJL2/hyS9v4ckvb/HJL2/xyS9v4ckvb+HJL2/hyS9v8ckfb/HJL2/xyS9/4ckvb/HJL2/xyT
+        9/4ckvb/HJL2/xyS9v4ckvb+HJL2/xyS9v8ckvb+HJL2/hyS9v8ckvb+HJL2RgAAAAAckvUAAAAAAAAA
+        AAAAAAAAAAAAAByS9v8dkvb+HJP2/hyS9f8ckvb/HZP2kQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6U9QAAAAAAHJP2IxyS9v8dkvb+HJP2/hyS9v8dkvb/G5L2NAAA
+        AAAAAAAAG5L2AAAAAAAbkvUVHJL2/x2S9v4ck/b+HJL1/x2S9v4dkvb/HZL3/x2T9/8ckvb/HJH2/xyS
+        9v8dk/b/HJL2/xyS9v8dk/b/HZL2/xyS9v8ckvb/HJL2/RyS9f8dk/b/HJL2/xyS9v8ckvWRAAAAAAAA
+        AAAckvYAH5L4AAAAAAAAAAAAHZP2AAAAAAAckvbXHJL2/xyS9v4ckvb/HJL2/xyS9sIAAAAAHJP2AAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckvb/HZL2/hyS
+        9v4ckvb/HJH2/xyT9m8AAAAAAAAAAAAAAAAAAAAAAAAAAByS9v8dkvb+HJL2/hyS9v8dkvb/HJL2rxyT
+        9SsdkvY0HJL1NB2R9zEckvcxHZP3MR2T9jAckfcsG5P3LRyT9y0dk/csHJL2GxyS9/8dkvb/HJL2/xyS
+        9uQbk/gZAAAAAAAAAAAbkvcAAAAAAAAAAAAAAAAAAAAAABuS9wAAAAAAHJL2qhyR9v8ckvb+HJL2/xyS
+        9v8ckvb7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHJL24hyS9v8ckvb+HJH2/xuS9v8ckvWjAAAAAByS9gAAAAAAAAAAAAAAAAAckvbfHJL2/xyS
+        9v4ckvb/HJL2/xyT9soAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAckvb/HJL2/xyS9moAAAAAAAAAABuS9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS
+        9m0ckvb/HJL2/hyS9f8ckvX/HJL2//8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAckfcAAAAAAByS9rQdkvb/HJL2/hyS9v8ckvb/HJL24AAAAAAAAAAAAAAAAByT
+        9QAAAAAAHJL2tx2S9v8ckvb+HJL1/x2S9v8ckvb4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAHJL20QAAAAAAAAAAHJP2AAAAAAAdkvYAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAckvU+HJL3/x2S9v4dk/b+HZP3/hyS9v8bkvYzAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAck/Z3HJL2/x2T9/4ckvb+HJL3/hyS
+        9v8AAAAAAAAAAAAAAAAckvYAAAAAAByS9oEckvb/HZL2/h2T9v4dk/f+HJL2/wAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZk/UAIZD3AAAAAAAAAAAAG5L3AAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEoX0AByS9/8dkvb+HZP2/h2T9/4ckvb/HZL3XwAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJL1RhyS
+        9v8dk/f+HJL2/h2R9v4ckvb/HZH1IQAAAAAAAAAAAAAAAAAAAAAckvZVHZL2/xyS9v4dk/b+HZP3/hyS
+        9v8ckvchAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHpD5AAAAAAAAAAAAG5P3AAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbkvYAHJL2AAAAAAAckvb7HZL2/xyT
+        9v8ck/b/HZL2/xuS9psAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAABuT9wgbkvb/HZP2/hyT9v8ckfb/HJL1/xyT91AAAAAAAAAAAAAAAAAAAAAAHJL2HxyS
+        9v8dkvb+HJP2/x2T9v8bkvb/HJL2TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHJL2wh2S9v8dk/b/HZP3/xyS9v8ckvbGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAG5P2AAAAAAAAAAAAHJL2/x2T9/8ckvb+HJL2/hyS9v8ckvWNAAAAAAAA
+        AAAckvYAAAAAAAAAAAAbkfX/HZL2/x2T9v4dk/f+HJL2/x2S9ngAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAByR9ZMck/b/HJL2/xyT9v8ckvb/HJL2/QAAAAAbkvYAG5P2AAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdkvYAAAAAAByS9sock/b/HJL2/xyR
+        9v8ckvb/HJL2vQAAAAAAAAAAAAAAAByS9gAAAAAAHJL25ByS9v8ck/b/HJP2/xyS9v8ckvasAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAck/ZXHJL2/xyT9v4ck/b+HJL2/huS
+        9v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfmPkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAdkvadHJL2/xyS9v4ckfb+HJL2/xyS9vkAAAAAHJL3AAAAAAAAAAAAAAAAAByS9rMckvb/HJP2/hyT
+        9v4ckvb/HJL22AAAAAAalPcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG5H1KB2S
+        9v8dk/b+HZP2/hyS9v4dk/f/HZL3KwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAHJP2SxyS9v8ckvb+HJL2/hyS9v4ckvb/AAAAAAAAAAAAAAAAAAAAAAAA
+        AAAbkvaCHZL2/x2T9v4dk/b+HJL2/hyS9v8AAAAAAAAAAByS9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAckvb/HJL2/xyS9/8ckvb/HZL3/RyS9/8ckvb/HJH2/xyS9v8ckvb/HJL2/xyS
+        9v8ckvb/HJL2/xyS9v8ckvb/HJL2/xyS9v8ckvb/HJL2/xyS9v8ckvb+HJL2/xyS9v8ckvb/HJL2/xyS
+        9j0AAAAAAAAAAAAAAAAAAAAAHZP3TB2S9v8ckvb/HJL3/xyS9v8ckvf/HJL2DwAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJL26R2S9v8dkvb/HJL2/hyS9v4dkvb+HJH2/hyR
+        9v8ckfb/HZL2/hyR9v8ckfb/HJL2/hyR9v8ckfb/HJL2/h2S9v4dkvb/HZL2/xyS9v4ckvb+HZL2/hyR
+        9v8ckfb/HJH2/xyT9/8ckfVrAAAAAAAAAAAAAAAAAAAAABuR9R8ckvb/HZL2/x2S9v8ckvb+HJL2/xyS
+        9kUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckvYAAAAAAByS9q0ckvb/HJL2/hyS
+        9v4ckvb+HJL2/hyS9v4ckvb+HJL2/hyS9/4ckvb+HJL2/hyT9v0ckvb+HJL2/hyS9v4ckvb+HJL2/hyS
+        9v4ckvb+HJL2/hyS9v4ckvb+HJL2/hyS9v4ck/f/HJL2pwAAAAAAAAAAAAAAAAAAAAAAAAAAHJL2/xyS
+        9v4ckvb+HJL2/hyS9v8ckvdwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAckvZ+HJL2/xyS9/8ckvb+HJL3/hyS9/4ckvb/HJH2/xyS9v8ckvf+HJL2/xyS9/8ck/b+HJH3/xyS
+        9v8ckvb+HJL2/hyS9v8ckvf/HJL2/hyS9/4ckvf+HJL2/xyR9v8ckvb/HJL3/xyS9tIAAAAAHJL2AAAA
+        AAAAAAAAAAAAAByS9uYckvb/HJL3/xyS9v4ck/b/HJL1qAAAAAAdkvYAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAG5L2QByS9v8ckvb/HJL2/hyS9v4dk/b+HJL2/xyR9v8ckvb/HJP2/xyS
+        9v8ckvb/HJP2/xyS9v8ckvb/HJL2/xyS9v8ck/b/HJP2/xyS9v8ckvb/HJP3/xyS9v0ckfb/HJL2/xyS
+        9/8ckvb/AAAAAAAAAAAdk/YAHJP3AAAAAAAckvesHJL2/xyS9v8ckvb+HJL2/xyS9tMAAAAAHJL2AAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2S9hUckvb/HJL1/xyS9v4dkvb+HJL2/x2S
+        9rYckvd1HZL3eB2T93gck/Z4HZL3eByS9ngdkvd4HJP2eB2T93gdkvd4HJL3eByT93gdkvd4HJP2dx2R
+        944dk/b/HJH1/xyS9v8ck/f+HJL2/x6V+A0AAAAAAAAAAAAAAAAAAAAAHJL2fxyS9v8ckvX/HJL2/h2S
+        9v8ckvb/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJL2/xyT
+        9v8ckvb+HZL2/hyS9v8ckvagAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAdlfcHHJL2/xyR9v8ckvb/HJL3/hyS9v8ckfZJAAAAAAAAAAAAAAAAAAAAAByS
+        90Mckvb/HJL2/xyS9v4dkvb+HJL2/x+S9g0AAAAAHJL2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAByS9tIckvb/HJL2/hyS9v4ck/b/HJL21QAAAAAdkPUAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS9v8ckvb/HJH2/xyS9v4ckvb/HZP2eQAA
+        AAAAAAAAAAAAAAAAAAAckvUbHJL2/xyS9v8ckvb+HJL2/hyS9v8bkvZMAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckvaXHJL2/xyS9v4dkvb+HZP2/xyS9vgAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckvbPHJL2/xyS
+        9v8ckvb+HJL2/xyS9rQAAAAAHZH2AAAAAAAAAAAAAAAAAByS9v8ckvb/HJL2/h2S9v4dk/b/G5H2hAAA
+        AAAckvYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS9gAAAAAAHJL1YxyS9v8ckvb+HZL2/h2T
+        9/4ckvb/HJH2CgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHJH2mhyS9v8ckvb+HZP3/hyS9v8ckvbhAAAAAByS9gAAAAAAAAAAAAAAAAAckvbhHJL2/xyS
+        9v4dkvb+HJL3/x2S9sAAAAAAHpL4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2T
+        9y0ckvb/HZL2/hyS9v4dk/f+HJP3/xyR9TYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAck/YAAAAAAByS9Wgckvb/HJL2/h2T9/4ckvb+HJL2/wAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHJH1pxyS9v8dkvb+HJL2/h2T9/8ckvbsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAbk/QGHJL2/xyS9v4dk/b+HZP2/hyS9v8ckvZpAAAAAByS9gAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbkvY0HZL2/xyS9v8dk/b+HJP2/xyS
+        9v8clPYcAAAAAAAAAAAdkvYAAAAAAB2T9nUdk/b/HJL2/h2T9v4dk/b+HJL2/xKU7AIAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS9vEckvb/HZL2/x2T9/8ckvb/HJL2mQAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJL2DhyS
+        9v8ckvb/HZP3/xyS9v8ckvb/HJH1VAAAAAAAAAAAAAAAAAAAAAAckfZAHJL3/xyS9v8dkvb/HZP3/xyT
+        9v8dkfcjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGpP2AAAAAAAckvbFHJL2/xyS
+        9v4ck/b+HZL3/xyS9s4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAckvb5HJL2/xyT9/4ckvb/HJL1/xyT94gAAAAAAAAAAAAAAAAAAAAAGpT4Eh2S
+        9v8ckvb+HJL2/hyT9v4ckvb/HJL2VgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABuS
+        9gAAAAAAG5P2kB2S9v8ckvb+HJP2/hyT9v8ckvb4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAByT9gAAAAAAHJL21ByS9v8ck/b+HJL2/hyS9v8ckfa+AAAAAAAA
+        AAAAAAAAAAAAAAAAAAAckvb9HJL2/xyS9v4ck/b+HJP2/x2R94cAAAAAHJP2AAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAByT9l0ckvb/HJL2/h2T9v4ckvb+HJL2/xuQ9goAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByR954ckvb/HZP2/hyS
+        9v4ckvb/HJL28AAAAAAck/YAAAAAAByS9gAAAAAAHJL22xyT9v8ckvb+HZP2/h2S9v8ck/a6AAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG5L2AAAAAAAckfciHJL2/x2S9v8ckvf/HJL2/xyS
+        9v8dk/YvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckvYAAAAAAAAA
+        AAAck/ZkHJL2/xyS9/8ckvb/HJL2/xyS9v8AAAAAAAAAAAAAAAAck/cAAAAAAByS9qcckvb/HZL2/xyS
+        9/8ckvb/HJL27gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS
+        9v8ckvb/HZL2/hyR9v8ckvb/HJL2XgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAByS9lkckvaVHJL2qxyS9v8dkvb+HJH2/xyR9v8ckvb/HJL2mhuS9ZUck/dRAAAAAAAA
+        AAAck/Z0HJL2/xyS9v4dkvb+HJH2/xyS9v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAckvblHJL2/xyS9v4ckvb+HJL2/xyT9ZQAAAAAHJP2AAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJL28B2S9v8ckvb+HJL3/hyS9v4ckvb+HJP2/hyS
+        9v8dkvb/HZD3CQAAAAAAAAAAHJL2PhyS9v8ckvb+HJL2/hyS9v4ckvb/G5L3IQAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS9gAAAAAAG5L2vByS9/8ckvf/HJL2/xyS9v8ck/bEAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckvcAAAAAACGN8Qgckvb/HJL2/hyS
+        9/4ckvb/HJL3/xyT9v4ckvb/HZL2uAAAAAAdkfYAAAAAABmQ9wockvb/HJL3/xyS9/8ckvb/HJL3/xyS
+        9UwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2T9nUckvbqHZP24hyT
+        9uIckvbjHJL24wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2S
+        9gAAAAAAHJH2QRyS9v8ck/f9HJL2/xyS9v8ck/f+HJL2/xuT9ScAAAAAAAAAAAAAAAAAAAAAHJL25ByT
+        9+Mdk/biHJP24hyS9ucck/d8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2T
+        9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckvYBHY/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAHJL2AAAAAAAckveKHJL2/xyS9f4ckvX/HJL2/xyS9tQAAAAAG5XzAAAA
+        AAAckvUAHJL3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByT9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbk/YAAAAAAByS9tcckvb/G5L2/hyS
+        9v8bkfVEAAAAAByS9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAII34AAAA
+        AAAAAAAAHJL2/xyS9v8ckvbyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAdkvcAAAAAABqR+CIckvb/G5L2agAAAAAck/cAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZL2ABqS+AAAAAAAHJL2cCWU7gEAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdk/YAHJL2AAAA
+        AAAAAAAAHJL2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////////////////
+        ////////////////////////////////////////////////////////////////////////////////
+        ///////////8//////////x/4H//A+AAAB/gf/8D4AAAB/B//wPwAAAD8H//g/AAAAfwP/+D8AAAD/A/
+        /4PwP/w/8D//gfA//P/4P/+B8D/9//g//8HwP///+D//wfg////4H//B+D////gf/8D4P///+B//wPgf
+        ///8H//A+B////wf/+D4H////AAAAPwf///8AAAA/B////wAAAB8H////gAAAHwP///+AAAAfA////4H
+        /+B+D////gf/8H4P///+B//wfg////4H//A+B////wf/8D4H////B//4Pgf///8H//g/B////wP/+D8H
+        ////A//4Hwf///8D//gfA////4P/+B8D////g//8HwP///+D//AHg////4H/8AeD////gf/4B4P////B
+        //wPg////////A/////////+H/////////8f/////////7//////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////////////
+        //////////////////8oAAAAgAAAAAABAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAIJX1AB2T9gIclvsAHYvvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOY9AAAAAAAAAAAAAAAAAAAAAAAHZL3AAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAABuS9xgck/d9HZT4BwAAAAAAAAAAHJH2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG5P2ExyT9v8dkvfnHJP2VQAA
+        AAAAAAAAHZP2ARqR9gAdkvgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAbkvYSHJL39R2T9v8dkvf/HZL3shyS9yQAAAAAAAAAAB2S9wAdk/YAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHI3xAB2T
+        9wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdk/cBAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZT2AAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABuR9wAdk/YAAID/AAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAByV9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABeT9wYck/f2HZL3/x2T
+        9/8dk/b/HJL3/xyT9oEck/UKAAAAAB+R9wEbk/YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS9kQdk/d5HZP3bh2T93Ick/d0HJP3dx2T
+        93kckvd8HZP3fhyT94AckveLHZP4RQAAAAAckvgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAHZT3Cx2T90AckvZHHJP3RR2S90Udk/dFHZP3RR2S90Udk/dFHZP3RRyS
+        90cdk/Y4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByn7QAck/Y0HZL3SRyS
+        9kUdkvdFHJL2RR2T9kUdk/dFHZP3RR2T90Uck/dFHZP3RR2T90Uck/dFHZL3RR2T90Udk/dFHZL3RR2T
+        90Udk/dFHZP3RRyT90Udk/dFHJP2RR2T90UdkvdFHZP3RRyT90Udk/dFHJP3RR2T90UdkvdFHJL3RR2S
+        90Uck/dFHJL2RR2S90Udk/dCHJP3UxyT9/kdk/f/HZP2/hyS9/8dk/b/HZL3/x2S990ck/ZWAAAAAAAA
+        AAAAAAAAHJL2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHJL2jR2T9/8dk/f/HZP2/x2T9v8dkvb/HZP3/x2T9/8dk/b/HZP3/xyS9/8dk/e0AAAAAByS
+        9wUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAck/YXHJP21h2S
+        9/8ckvb6HZP3+h2T9/ockvb6HZP3+hyT9/odk/f6HZP3/RyS9u8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2T9qsckvf/HJP2+h2T9/odk/f6HJL2+h2S9/odk/f6HZP3+hyT
+        9/odk/f6HJP3+hyS9/odk/f6HZP3+hyS9vodk/f6HJP3+h2T9/ockvb6HJL3+h2S9/ock/b6HZL3+h2T
+        9/ock/f6HJL2+h2T9/ockvb6HZP3+h2T9/odk/f6HZL2+hyS9/ockvb6HZP3+hyT9/odkvb7HZP3/hyT
+        9/8dk/f/HJL2/x2S9/4ck/b6HZL2/xyT9/8ck/ezHJL2IgAAAAAAAAAAHpL3ABuT9wAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHI3xAAAAAAAdk/dZHJP2/xyS9/8dk/b/HJP3/xyS
+        9v8dkvf/HJP2/x2T9v8dk/b/HZP3/xyS9tMAAAAAHpT3AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckvbBHZP3/x2S9/8dk/f/HZP3/x2S9v8dk/f/HZP3/x2T
+        9/8dkvb/HJP3/xyT9yMAAAAAHJP3AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACue8QAAAAAAHJL3jh2T
+        9v8dk/f/HZP3/x2T9/8dkvb/HZL3/x2T9/8dk/f/HZP3/x2T9/8dk/f/HZL3/x2T9/8dk/f/HZL2/x2T
+        9/8dk/f/HZP3/xyS9v8dkvf/HZL3/x2T9/8dkvf/HZP3/x2T9/8ckvb/HZP3/xyS9v8dk/f/HZP3/x2T
+        9/8dkvb/HZL3/x2S9/8dk/f/HJP2/xyS9v8dkvf/HZP2/h2S9v8dkvb/HZL2/xyT9/8ck/f+HZL2/x2S
+        9v8ckvf/HZL3gBuT9ggAAAAAAAAAAAAAAAAckvYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAByS9y4ckvf8HZP2/x2T9/8dk/f+HJL2/x2T9/4ckvb/HJL2/xyS9v8dkvb/HJP34xyU
+        +BYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2S
+        95wck/b/HJL2/x2T9/4dk/f+HJL2/x2T9/4ckvb/HJL3/xyT9v8dkvf/HZL3VAAAAAAdkvcCAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdk/ZlHJL3/x2T9v8ckvb/HZP3/hyS9v8dk/f+HJL2/xyS
+        9v8ckvb/HJL2/xyS9v8ckvb/HZP3/h2T9/4ckvb/HZP3/hyS9v8ckvf/HJL2/xyS9v8ckvb/HJL2/xyS
+        9/8dk/f+HJL3/xyS9v8ckvb/HJL2/xyS9v8dk/f+HZP3/hyS9v8ckvb/HJL3/xyS9v8dk/f+HJL2/x2T
+        9/4ckvb/HJL2/xyS9v8ckvb/HJL2/xyS9v8dk/f/HZP3/RyT9v8dk/b/HJL32xyT9lMAAAAAAAAAAAAA
+        AAAck/cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxmNYAAH7/AByS9/Adk/b/HZP2/xyT
+        9v4dk/f/HZP3/h2T9v4dk/b+HZP3/hyS9v8dk/f2HZP3PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2S9QAAAAAAHZP3ax2T9v8dkvf/HJP3/h2T9/4dk/f/HZP3/h2T
+        9/4dk/f+HZP3/xyS9v8dk/aIAAAAAByT9gQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2T
+        9zsdk/f/HJL2/xyS9v4ck/b+HZP3/x2T9/4dk/b+HZP2/h2T9/4dk/f+HZP3/h2T9v4ck/f+HZP3/h2T
+        9/8dk/f+HZP3/h2T9/4dk/b/HJP3/h2T9v4ck/b+HZL3/x2T9/4dk/f+HJP2/x2T9/4dk/f/HZP3/hyT
+        9/4ck/b+HZP3/x2T9/4dk/f/HZP2/hyT9v4dk/f/HZP3/h2T9v4dk/b+HZP3/h2T9/4dk/f+HZP2/hyT
+        9/4dk/f+HZP2/hyS9v8dkvf/HZP2/x2T9rYdkvcrAAAAAAAAAAAek/cAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAByS9gIAAAAAHZP30RyS9v8dkvf+HZP2/x2S9/8dkvf/HZP2/x2T9v8dk/f/HZP3/x2S
+        9v8ck/ZdAAAAAB2S9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAdkvZAHZL2/xyT9/8dk/f/HZP3/x2S9/8dk/f/HZP3/x2T9/8dk/f/HZP2/xyT97YAAAAAHZP2BQAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJL2FRyS9vYdk/f/HZL2/x2T9v8dkvf/HZL3/x2T
+        9v8dk/b/HZP3/x2T9/8dk/f/HZL2/x2T9/8dk/f/HZL3/x2T9/8dk/f/HZP3/xyS9v8dkvf/HZL2/x2T
+        9v8dkvf/HZP3/x2T9/8ckvb/HZP3/xyS9/8dk/f/HZP3/x2T9v8dkvf/HZL3/x2S9/8dk/b/HZP2/x2S
+        9/8dkvf/HZP2/x2T9v8dk/f/HZP3/x2T9/8dkvb/HZP3/x2T9/8dkvf/HZP3/x2T9v4ckvf/HZP3/xyS
+        9vwdk/eEH5L2EAAAAAAWmP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZP3AQAAAAAdkvefHJP2/x2S
+        9/0ck/f+HJL3/x2T9/4ckvb/HJP2/xyS9/8ckvb/HJP2/x2S938AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByT9xIck/f8HZL2/xyT9/8dk/f+HJL3/x2T
+        9/4ckvf/HJL3/xyT9/4dkvb/HJP30gqT+AAgkvYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByR
+        9QEAAAAAHZP36RyS9v8ckvb+HJP3/hyS9/8dk/f+HJL2/xyT9v8ckvf/HJL3/xyT9/8ckvb/HJP3/h2T
+        9/4ckvf/HZP3/hyS9/8ckvf/HJL2/xyS9/8ckvb/HJL2/xyS9/8dk/f+HJL3/xyS9v8ckvf/HJL3/xyS
+        9/8ck/f+HJP3/hyS9/8ckvf/HJL3/xyS9v8ck/f+HJL3/x2T9/4ckvb/HJP2/xyS9/8ckvf/HJP3/xyS
+        9v8ck/f+HZP3/hyS9/8dk/f+HZL3/x2T9/8ckvf7HJP3/x2T9v8dkvaOAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAck/YAAAAAAByT9modkvf/HJP2/ByT9/8dk/f/HZL3/x2T9/8dk/f/HZP3/xyT
+        9v4dkvf/HJP2pgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAelPUBAAAAAByS9+Mdk/b/HJL3/h2T9/8dk/f/HZP3/x2T9/8dk/f/HZP3/h2S9/8ck/bpHJL2JgAA
+        AAAAqv4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJP3AgAAAAAdkva+HJP3/x2T9v0ck/f/HZP3/x2S
+        9/8dk/f/HZP3/x2T9/8dk/f/HZP3/x2S9/8ck/f/HZP3/x2T9/8dk/f/HZP3/x2T9/8dk/f/HJL3/x2S
+        9/8ck/f/HZL3/x2T9/8dk/f/HJP3/x2T9/8dk/f/HZP3/xyT9/8ck/f/HZP3/x2S9/8dk/f/HZP3/xyT
+        9/8dk/f/HZL3/x2T9/8dk/f/HZP3/x2T9/8dk/f/HZL3/xyT9/8dk/f/HZP3/x2T9v4dk/f+HZL2/xyT
+        9/8dk/fkHJL2VQAAAAAolP8AHZH2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABuS9gAAAAAAHJL2Ox2T
+        9/8ckvb6HZP3/hyS9v8dk/f+HJL2/xyT9v8ckvb/HJL2/x2T9v8ckvfJHJL3CwAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS9wAAAAAAHZP2sxyS9/8dk/f9HZP3/hyS
+        9v8dk/f+HJL2/xyS9/8ckvb/HJP3/x2S9v8dk/dIAAAAAByR9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAckvYBAAAAAB2T95Mckvb/HZL3/B2T9/4ckvb/HZP3/hyS9v8ck/b/HJL2/xyS9v8ck/b/HJL2/x2T
+        9/4dk/f+HJL2/x2T9/4ckvb/HJL3/xyS9v8ckvb/HJL2/xyS9v8ckvb/HZP3/hyS9/8ckvb/HJL2/xyS
+        9v8ckvb/HZP3/h2T9/4ckvb/HJL2/xyS9v8ckvb/HZP3/hyS9v8dk/f+HJL2/xyT9v8ckvb/HJL2/xyT
+        9v8ckvb/HZP3/h2T9/8ckvb+HJL3/x2T9/8ck/f/HZL2kR2S9hIAAAAAH5L4AQBVuAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdkvcbHJL2+x2T9/4dk/f+HZL2/x2T9/4dk/b/HZP2/x2T
+        9v8dk/b/HJP3/x2T9vEdk/ccAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHZP2AAAAAAAdk/Z9HJL3/x2T9vsdk/f+HZL2/x2T9/4dk/b/HZP3/xyS9v8dk/f/HZL2/xyT
+        924AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS9wAAAAAAHJL2Yx2T9/8ckvb7HZP3/h2S
+        9v8dk/f+HZP2/x2T9v8dk/b/HZP2/x2T9/4dkvf/HZP3/R2T9/0dk/f9HZP3/R2T9/0dk/f9HZP3/R2S
+        9/0dkvf9HJP2/R2S9/0dk/f9HZP2/RyS9/0dk/b9HZL3/R2T9/0dk/f9HZP3/R2S9/0dkvf9HZP3/R2T
+        9/0dk/b9HZP2/R2S9/4dk/b/HZP2/x2T9v8dk/b/HZP2/x2S9/8ck/b/HZP3/RyS9/8dkvb/HJL2yRyS
+        9zcAAAAAAAAAAB+V9gAakfcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2U
+        9g4dk/bUHJL3/x2T9/4dk/b/HZP3/hyT9v8dkvb/HJP2/x2T9v8ckvb6HZP3/xyT9i4AAAAAGpP2AAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAck/cAAAAAAByT904dkvb/HJP3+h2T
+        9/4dk/b/HZP3/hyT9v8dk/f/HJP2/x2S9v4dk/f/HJL2lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHZT3AAAAAAAdk/c4HJL3/x2T9vodk/f+HZP2/x2T9/4ck/b/HZL2/xyT9v8dk/b/HZL3/x2T
+        9v0dkvf/HZL3/x2S9/8dk/f/HZP3/x2T9/8ckvb/HJL2/x2S9v8dk/b/HJL3/x2T9/8dk/f/HJP2/xyT
+        9/8ck/b/HJP2/x2T9v8dk/b/HZP2/x2S9v8ck/b/HZL2/xyT9/8dkvb/HZP3/xyT9v4dkvb/HJP2/x2T
+        9v8dk/f/HJP3/h2S9/8dkvb/HJP3+hyT928AAAAAAAAAAB+V+gAAAAAAHpH2AAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByT96kdkvb/HJP3/x2S9/8dk/f+HJL2/x2T
+        9v8ckvf/HZL3/xyT9/odkvb/HJP3WwAAAAAck/cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAHZP3KByS9v8dk/f8HZP3/h2S9/8dk/f+HJL3/x2S9/8ckvb/HJL3/x2S
+        9/8ck/bBHJP3BwAAAAAclPkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2T9xwckvb9HZP3/h2T
+        9/4dkvf/HZP3/hyS9v8dk/b/HJL3/x2S9/8dk/b8HZL3/x2T9pcck/Z5HZP2gB2T94Adk/aAHZP2gByS
+        9oAdkvd7HZL3eh2T93ockvd6HZP3eh2T93odk/d6HZP2eByS93MdkvdzHJP3cxyT93Mck/dzHZP3cx2T
+        93Qdk/dvHZL2ahyT93ockvf7HZP3/x2T9v8dkvf/HZP3/hyS9vock/b/HJP2/xyT96wckvgbAAAAAAAA
+        AAAdk/cAGpL1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHJL3gx2T9v8ck/b+HZP2/x2S9/4ck/b/HZP2/xyT9v8dk/b/HZP2/ByT9/8dkvaKAAAAAB2T
+        9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckvYXHZP24ByS
+        9/8dk/f+HZP2/x2T9/4ck/b/HZP3/xyT9v8ckvb/HJL2/x2T9+odkvYUAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAHJL2EB2T99kckvf/HZP3/h2T9v8dkvf+HJP2/x2T9v8ck/b/HZP2/x2T
+        9vockvf/HJP2OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFpP3BRyS9/Ydk/f/HZP2/h2T
+        9/8ckvb/HZP3/x2S9+AckvdVAAAAAAAAAAAAAAAAHJP4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF4zzAAAAAAAdk/ZgHJL2/xyS9/8ckvb/HZL2/xyS
+        9v8ck/b/HJL2/xyS9v8ck/f9HJP2/x2T97cAAAAAHJP2AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2S9wUdkve8HJP2/x2S9v4ckvb/HZP2/xyS9v8ckvb/HJL2/xyS
+        9v8ck/f7HZL2/xyT9yUAAAAAGpT6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdk/YDHZP2txyS
+        9/8ck/b/HJL2/x2S9v8ckvb/HJP2/xyS9v8ckvb/HZL3+x2T9v8ckvdsAAAAAB2S9wIdk/cCHZP3Ah2T
+        9wIck/YCHJL2ARyS9wEdk/cBHZP3AR2T9wEdk/cBHZP3AR2T9gEckvcBHZL4AR2T+AEdk/gBHZP3AR2T
+        9wEdk/gBHJP3AQAAAAAbk/YTHJP39x2S9v8dk/b/HJP3/x2S9/8ck/aLHJH2CwAAAAAdkvYBG5P5AAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAimf8AAAAAAByS9zkdk/f1HJL2/x2S9/8dk/f+HJL2/x2T9v8ckvf/HZL3/x2T9/4dkvf/HJL25wAA
+        AAAek/cBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS
+        95Qdk/b/HZP3/h2S9/8dk/f+HJL3/x2S9/8ckvb/HJL3/xyT9/sdkvb/HJP3VgAAAAAck/cAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckveQHZP2/xyT9v4dkvf/HZP3/hyS9v8dk/b/HJL3/x2S
+        9/8dk/f8HZP3/x2T9pMAAAAAHZP2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABuT9hIck/f1HZP3/x2S
+        9/8ckvbDHZP3MQAAAAAAAAAAHZf3AByS9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJL4FxyS9+Idk/b/HZP2/x2T
+        9/4ckvb/HZP2/xyS9v8dkvb/HJP2/x2T9/8ckvb5HJP2EgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6W/wAAAAAAHJL2cB2T9/8dk/f/HZL2/x2T9/4ckvb/HZL2/xyS
+        9v8ckvb/HZL2/RyS9/8dk/aHAAAAAByS9wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS
+        928dk/b/HZP3/x2S9v8dk/f+HJL2/x2T9v8ckvb/HZL2/x2T9v0dkvf/HJP2twAAAAAdkvcBAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAG5P2EhyT9/8dk/b7HJL3bgAAAAAAAAAAHJP3AB6T9wAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAABuS9wMAAAAAHZP2zByS9/8dk/f+HZP3/h2T9v8dk/b/HZP2/x2T9v8dk/b/HJP2/x2S
+        9/8dkvdBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG43wAAAA
+        AAAdkvdGHJL3+x2T9v8dkvb/HZP3/h2T9v8dk/f/HJL2/x2S9v8dk/f+HZP3/xyS9r4AAAAAHZP3AgAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAABuR+wAAAAAAHZP2TRyS9/8dk/b/HZL2/x2T9/4dk/b/HZP2/x2T
+        9v8dk/b/HZP3/hyS9v8dk/fgAAAAAByS9gEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbkvcYHJL2nx2T
+        9xoAAAAAAAAAAB2R9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZP2BQAAAAAdkvanHZP3/x2T
+        9/4dkvf/HZP2/x2T9v8dk/f/HZP3/x2T9/8dk/f/HZL2/xyT9mkAAAAAH5L4AAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2T+CEdk/fqHZL2/xyT9v8dk/f/HZP3/x2T
+        9/8dk/b/HJL3/x2T9/4dk/b/HJL35wAAAAAdk/UCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAck/ctHZP37h2S9v8dk/f/HZL3/x2T9v8dk/b/HZP3/x2T9/8dk/f/HZP2/xyS9/Uajf8DAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6Q+QEAAAAAAAAAAAAAAAAdk/cAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAckvYDAAAAAByT9ngckvf/HJP3/h2T9/4dk/f+HZP3/h2T9/4dk/f+HZP3/hyS
+        9v8dk/f/HJL3kQAAAAAdk/YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAdkPgBAAAAAByT9tsckvf/HZL2/x2T9/4dk/f+HZP3/hyS9v8dk/f+HZL3/xyT9v8dkvf1HZH3HAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByR9g4dkvbeHZP3/x2S9v8dk/f+HZP3/h2T
+        9/4dk/f+HZP3/h2T9/4dk/b/HJL3+xyR9yYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAekPkAAAAAAByT
+        9wIdkvYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS9wEAAAAAHJL3QxyS
+        9/8ckvf+HZL3/h2T9/4dk/f+HZP3/h2T9/4dk/f+HJL3/hyT9v8dkve2AAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByT9wQAAAAAHJL2thyT9/8ckvb+HZP3/h2T
+        9/4dk/f+HJL2/x2S9/4dkvf+HJP3/xyS9v8dkvZLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAdk/cEAAAAAB2S9sgdk/f/HZL2/h2S9/4dk/f+HZP3/h2T9/4dk/f+HZP3/hyS9/8dk/b/HZP2TQAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAHZP2AAAAAAAdk/YVHZP3/x2T9/4dkvf/HZP2/x2T9v8dk/f/HZP3/x2T
+        9/8dkvb/HJL2/x2T99Adk/kOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHZL3AgAAAAAdk/aFHZL3/x2S9v4dk/f/HZP3/x2T9/8dk/b+HZL3/x2S9v8dk/b/HJP3/x2S
+        9nQAAAAAHJT3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS9gQAAAAAHJP3pR2S9v8dk/f+HZL3/x2T
+        9v8dk/b/HZP3/x2T9/8dk/f/HZP2/xyS9v8ckvdxAAAAAB2T9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAdk/bmHZP3/x2S9/8dk/f/HZP3/x2T9/8dk/f/HZP3/x2S9/8dkvb/HJP37hyS9yoAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAck/cBAAAAAByT91Ack/f/HJP3/R2T
+        9/8dk/f/HZP3/xyT9v8ckvf/HZL3/xyT9v4ckvb/HZP3nwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHJL2AwAAAAAckvZzHJL2/xyS9v4dkvf/HZP3/x2T9/8dk/f/HZP3/x2T9/8ckvb/HJP3/x2T
+        9poAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS97gckvb/HZL3/h2T9v8dk/b/HZP2/x2T
+        9v8dk/b/HZL2/x2T9/8ckvb/HZP3QQAAAAAZkfYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAByS9gAAAAAAHJL2IByS9v8ckvb9HZP3/h2T9v8dk/b/HZP2/x2S9v8dkvb/HZP2/h2S
+        9v8ck/e/HJb6AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdk/cBAAAAAB2T90cdk/f/HZP3/h2S
+        9/4dk/b/HZP2/x2T9v8dk/b/HZP2/xyS9v4ckvb/HJL3tgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHZL2jByT9/8dk/f+HZP3/x2T9/8dk/f/HZP3/x2T9/8dk/f/HJL2/hyS9v8dk/dhAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdkvYHHZL28x2S
+        9v8dk/f/HZP3/x2T9/8dk/f/HZP3/x2T9/8dk/f/HJP3/x2S9t8ckvYaAAAAADOZ/wAAAAAAAAAAAAAA
+        AAAAAAAAAAAAABuS9gAAAAAAHJL2GRyS9v8ckvb+HZP3/x2T9/8dk/f/HZP3/x2T9/8dk/f/HZP3/xyT
+        9v8dkvfOHZP3DQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAck/dbHZL2/x2S9/8dk/b/HZP2/x2T
+        9/8dk/f/HZP3/x2S9v8ck/f+HZP2/xyS95EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdkvfCHJP2/x2T9/8dk/f/HZP3/xyS9v8ckvf/HZL2/xyT
+        9v8dkvf/HJP2/x2S9zMAAAAAGZP0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJL27hyS
+        9v8dkvf/HZP2/x2T9v8dk/f/HZP3/x2T9/8dkvb/HZP3/x2T9ukdkvYlAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAij/UAAAAAAByT9z0dkvb/HZP3/xyT9v8dk/b/HJP3/x2T9/8ck/f/HJL2/x2T9/4dk/f/HZP2ugAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2S
+        95gck/b/HZP3/hyT9/8dk/f/HJP2/xyS9/8dkvb/HJP2/x2T9/4ckvf/HZP2UQAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAakvYAAAAAAAAAAAAck/bDHJL3/x2T9/4ck/b/HZP2/xyT9/8dk/f/HJP3/xyS
+        9v8dk/f/HJP2/x2S9zsAAAAAHZP2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACq/gAAAAAAHZL2IByS9uQdk/f/HZP2/x2T
+        9v8dk/b/HZP2/x2T9v8dkvb/HZP3/hyS9/8ckvfqF4T/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZL3aByT9v8ck/b/HZP2/x2T9/8ckvb/HZL2/x2S
+        9v8dk/b/HJL3/h2S9/8ck/aFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2S
+        95Qck/b/HZL3/x2T9v8dk/b/HZP2/x2T9v8dk/b/HZL2/x2T9/4ck/b/HZL3WwAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAdlfkGHZP3yByS9v8dk/b+HZP2/xyT9v8dk/b/HJP2/xyS9v8ck/f+HJL3/hyS
+        9/8bkvcSAAAAABqR9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZL3AAAA
+        AAAck/ZHHZL3/x2T9/8ck/b/HZP2/xyS9v8ckvb/HZL2/xyT9v8ckvb/HZP2/xyS97QAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJL3ah2T9v8dk/f+HJP2/x2T9v8ck/b/HZP2/xyT
+        9v8ckvb/HJP3/h2S9v8ck/eDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAck/asHZL3/x2S
+        9v4dk/f+HZP3/h2T9/4dk/f+HZL3/hyT9/4ck/b+HJP2/xyT9j8AAAAAHJP2AQAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2T9ysdk/btHJL3/x2T9/4dk/f+HJL2/xyS
+        9/4dkvf+HJP3/h2S9/8ck/f/HZL25QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAck/ZHHZL3/x2S9/8dk/f+HZP3/h2T9/4dk/f+HZP3/h2S9/4ck/f/HZP2/xyS96sAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAdk/gAAAAAAByS9oEdk/f/HZP2/x2T9v8dk/b/HZP2/x2T9v8dkvb/HJP2/x2T
+        9/4dk/f/HZL3cQAAAAAdk/cDHZP3AByT9wAdk/YAHJL3AB+V8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAGpn2BxyT9s8dkvf/HZP2/x2T9/8dk/b/HJL2/x2S9v8ck/b/HZL3/xyS9v8dk/f/HpP3EgAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAakvgAAAAAAB2T9iwckvfxHZL3/x2T9v8dk/b/HZP2/x2T
+        9v8dk/b/HZL2/xyT9v8ckvf/HZL22QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJL2Vh2S
+        9/8dk/f/HZP3/h2T9/4dk/f+HZP3/h2T9/4dk/f+HZP3/h2T9/8dk/ecAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfmPkEH5v5BB+a+QQfmvkEH5r5BCCd
+        +gQdkfcIHo/zCx6P8wsej/MLHo/zCx6P8woekPQLHpL4EB6Q+A84hP8AHZP3uxyS9v8dk/f+HZP3/hyS
+        9v8dk/f+HZP3/h2T9/4ckvf/HZP2/xyS9/8ckvdCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHZP2FByT9tYdkvf/HZP3/h2T9/4dk/f+HZP3/h2T9/4dk/f+HZP3/hyT9/8ck/f/GpT3BgAA
+        AAAPmvcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdk/YnHZP2/ByS9/8dk/f/HZP3/x2T9/8dk/f/HZP3/xyT
+        9/8dk/f/HZP3/x2T9/4dk/fxHZP3+B2T9/kckvf4HZL2+B2T9vgckvf4HJL2+R2T9vkdk/b5HZP2+R2T
+        9vkdk/b5HZP2+R2T9/odk/f6HZP3+h2T9/odk/f6HZP3+h2S9/sdkvb7HZL2+x2S9vsdkvb7HZL2+x2S
+        9vsdkvf8HZL3/B2S9/odkvf8HJP2/x2T9/8dk/f/HJL2/xyT9/8dk/f/HJP3/x2S9/8ck/f/HZL2/xyS
+        9nUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZP3uB2S9v8dk/f+HZP3/x2T
+        9/8dk/f/HZP3/x2T9/8ck/f/HJP3/hyT9/8ck/YtAAAAAByT9gEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJZHvAAAA
+        AAAck/fyHZL2/x2T9v8ckvf/HZL3/xyT9/8ckvb/HJL3/x2S9/8dkvf+HZP3/xyS9/8ckvb/HZP3/xyS
+        9/8dkvb/HJL3/x2T9v8dk/f/HJL3/xyS9/8ckvf/HJL3/xyS9/8ckvf/HJL2/xyS9v8ckvb/HJL2/xyS
+        9v8ckvb/HJP2/xyT9/8ck/f/HJP3/xyT9/8ck/f/HJP3/xyT9v8ck/b/HJP2/xyS9v8dkvf+HJL3/x2S
+        9/8ckvb/HJL3/x2S9v8ckvb/HZL3/x2S9/8ckvb/HZP3pQAAAAAbjfMAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAdk/eaHZL2/x2S9v8dk/b/HJL3/x2S9/8ck/f/HJL2/xyS9/8dkvf+HZL3/x2S
+        91kAAAAAHZL3AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdk/YBAAAAAByS980dk/b/HZP3/h2S9/8dkvf/HZP3/x2S
+        9/8dk/f+HZP3/hyS9v8dk/f+HZL3/h2S9/4ckvb/HZL3/x2S9/8dkvf/HJL3/x2T9/4dkvf/HJL2/x2S
+        9/8ckvb/HZL3/x2T9/4dk/f+HJL2/x2S9/8ckvf/HZL3/x2T9/4ckvb/HZP3/h2S9/8dk/f/HZL3/x2S
+        9/8dk/f/HZL3/x2T9/4dk/f+HJL2/x2T9/4dkvf/HZL3/xyS9v8dkvf/HZL3/x2S9/8ckvf/HZP3/hyT
+        9/8dkvbHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdm/8AAAAAAByS9nMdk/f/HJP2/x2T
+        9/8dkvf/HZL3/x2T9/8dkvf/HZP3/h2T9v4ck/b/HZL3gwAAAAAck/YDAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS
+        9wEAAAAAHZP2mByS9/8dk/f8HZL2/x2S9v8dkvb/HZL2/xyS9v8dkvb/HJL2/x2S9v8dkvb/HZL3/xyS
+        9v8ckvb/HZL2/xyS9v8ckvf/HZL2/x2S9/8ckvb/HZL2/xyS9v8dkvb/HJL2/xyS9v8ckvb/HZL2/xyS
+        9v8dkvb/HJL2/xyS9v8dkvb/HZL2/x2S9v8dkvb/HZL2/x2S9v8dkvb/HJL2/x2S9v8ckvb/HZL2/x2S
+        9v8dkvf/HJL2/xyS9v8dkvb/HJL2/xyS9/8dk/f+HZP3/xyS9t8ckvYYAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAHZL2Rh2S9v8ck/f/HZL2/x2S9v8dkvb/HZL2/x2S9v8ckvb/HZP3/h2S
+        9/8ck/a0AAAAAB2S9wUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJL2AAAAAAAckvZpHZP3/xyS9vsckvb/HJL2/xyS
+        9v8ckvb/HZP3/h2T9/4ckvb/HZP3/hyS9v8ckvf/HJL2/xyS9v8ckvb/HJL2/xyS9/8dk/f+HJL3/xyS
+        9v8ckvb/HJL2/xyS9v8dk/f+HZP3/hyS9v8ckvb/HJL3/xyS9v8dk/f+HJL2/x2T9/4ckvb/HJL2/xyS
+        9v8ckvb/HJL2/xyS9v8dk/f+HZP3/hyS9v8dk/f+HJL2/xyS9/8ckvb/HJL2/xyS9v8ckvb/HJL3/x2T
+        9/4dk/f/HJP29B2S9zYAAAAAHJf2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAck/cdHJP3+x2S
+        9v8ck/b/HJL2/xyS9v8ckvb/HJL2/x2T9/4dk/b/HZL2/xyT99AAAAAAHZL2AgAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAaj/UAAAAAAByS9jYdk/f/HJL2+h2T9/4dk/f+HZP3/h2T9v4ck/f+HZP3/h2T9/8dk/f+HZP3/h2T
+        9/4dk/b/HJP3/h2T9v4ck/b+HZL3/x2T9/4dk/f+HJP2/x2T9/4dk/f/HZP3/hyT9/4ck/b+HZP3/x2T
+        9/4dk/f/HZP2/hyT9v4dk/f/HZP3/h2T9v4dk/b+HZP3/h2T9/4dk/f+HZP2/hyT9/4dk/f+HZP3/x2T
+        9/4dk/f+HZP3/h2T9v8ck/f+HZP2/hyT9v4dkvf/HZP3/hyT9/8ckvf/HZP2WAAAAAAbjPcAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAH5H1AQAAAAAck/fsHZL2/x2T9v4dk/f+HZP3/h2T9/4dk/b+HJP3/h2T
+        9/8ck/b/HZL35B2S9xsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZP3HhyS9vgdk/f/HZP3/x2T
+        9/8dk/f/HZL2/x2T9/8dk/f/HZL3/x2T9/8dk/f/HZP3/xyS9v8dkvf/HZL2/x2T9v8dkvf/HZP3/x2T
+        9/8ckvb/HZP3/xyS9/8dk/f/HZP3/x2T9v8dkvf/HZL3/x2S9/8dk/b/HZP2/x2S9/8dkvf/HZP2/x2T
+        9v8dk/f/HZP3/x2T9/8dkvb/HZP3/x2T9/8dkvf/HZP3/x2T9/8dk/f/HJL2/x2S9/8dkvb/HZP2/x2S
+        9/8dk/f/HJL3/h2S9/8ck/Z6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAck/cBAAAAAB2S
+        9sQck/f/HZP2/R2T9/8dk/f/HZP3/x2S9v8dk/f/HZP3/x2T9/8ck/b1HZL2OgAAAAAVlf8AAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAGo/2AAAAAAAdkvYPHZP30RyS9v8ckvf/HJL3/xyT9/8ckvb/HJP3/h2T9/4ckvf/HZP3/hyS
+        9/8ckvf/HJL2/xyS9/8ckvb/HJL2/xyS9/8dk/f+HJL3/xyS9v8ckvf/HJL3/xyS9/8ck/f+HJP3/hyS
+        9/8ckvf/HJL3/xyS9v8ck/f+HJL3/x2T9/4ckvb/HJP2/xyS9/8ckvf/HJP3/xyS9v8ck/f+HZP3/hyS
+        9/8dk/f+HJL3/xyS9/8ckvb/HJL3/xyS9v8ckvb/HJL3/x2T9/4dk/f/HZP2/xyS96IAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2S9gAAAAAAHJL3lR2T9v8ckvb8HJL3/xyS9/8ck/f/HJL2/xyT
+        9/4dk/f+HJP2/x2S9v8ck/dZAAAAAB+S9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckveoHZP2/xyT
+        9/4dk/f/HZP3/x2S9/8ck/f/HZP3/x2T9/8dk/f/HZP3/x2T9/8dk/f/HJL3/x2S9/8ck/f/HZL3/x2T
+        9/8dk/f/HJP3/x2T9/8dk/f/HZP3/xyT9/8ck/f/HZP3/x2S9/8dk/f/HZP3/xyT9/8dk/f/HZL3/x2T
+        9/8dk/f/HZP3/x2T9/8dk/f/HZL3/xyT9/8dk/f/HZP3/x2T9/8dk/f/HZP3/x2T9/8ckvf/HZL3/xyT
+        9/8dkvf/HZP3/x2T9/8ckvf/HZP2zh2S9gQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZP3AAAA
+        AAAdk/dkHJL3/x2T9/sdk/f/HZP3/x2T9/8dkvf/HJP3/x2T9/8dk/f/HJL3/x2T9n0AAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAByT9oQdkvf/HJP3/hyS9v8ck/b/HJL2/x2T9/4dk/f+HJL2/x2T
+        9/4dk/b+HZP3/xyS9v8ckvb/HZL2/xyT9v8ckvb/HZP3/xyT9v8ckvb/HJP2/xyS9v8ck/b/HZP3/x2T
+        9v8ckvb/HJL2/xyS9v8dk/b/HZP2/xyS9v8dkvf/HJP2/x2T9v8ck/b/HZP2/xyT9v8ckvb/HZP3/x2T
+        9/8ckvb/HZP3/xyT9/8dkvf+HJP2/hyS9v8ckvb/HJL2/xyS9v8dk/f+HJL3/xyS9v8dk/f2HJL2DQAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbk/cAAAAAAByT9jgdkvf/HJP2+hyS9v8ckvb/HJP2/xyS
+        9v8dk/f+HZP3/hyS9v4ck/f/HZL2nwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS9wAAAAAAHZP3XByT
+        9/8dkvb/HZP2/x2T9v8dkvb/HZP3/h2T9/4dkvb/HZP3/h2T9/8dkvb8HZL22x2T990dkvfdHZP33R2S
+        990dk/fdHZP33RyT9t0dk/fdHZP33R2T990dk/fdHZP33R2T990dkvfdHZP23R2T990dk/fdHZP33R2S
+        990dk/fdHZP33R2T990dk/fdHZP33R2S990dk/fdHZP33R2T9t0dkvfaHZL38R2T9v8dk/f+HJL2/x2S
+        9v8ck/b/HZL3/x2T9/4dk/f/HZP3+xyS9v8dk/cpAAAAAB2U9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHJL2Hh2T9/gckvb/HZP2/x2T9v8dk/b/HZL2/x2T9/4dk/f+HZL2/x2S9v8ck/fGHJL3CQAA
+        AAAkkv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAHJf2AAAAAAAdkvY5HZL29RyT9/8dk/b/HJL2/xyS9v8dk/f+HZP3/h2T
+        9v8dk/f+HJL2/x2T9/Mck/ceHJL2FRyT9xYckvcWHJP2Fh2T9xYck/YWHZP3FhyT9hYckvYWHJL2Fh2S
+        9hYckvYWHJP3FhyS9hYck/cWHJL2Fh2T9hYdk/YWHJP2Fh2T9xYckvYWHJP2FhyT9xYckvcWHZP3FhyS
+        9hYckvYWHJP2Fh2O9wMdkveEHZP3/x2T9/8ckvb/HZL2/xyT9v8dkvf/HZP3/hyT9/8dk/f8HJL2/x2T
+        91gAAAAAHZP3AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdk/YQHJL21B2T9/8ck/b/HZP2/xyS
+        9v8ckvb/HZP3/h2T9/4dk/b/HJP2/x2S9+ock/YWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABqV
+        +BEck/fhHZL2/x2T9/8ck/f/HJL2/x2T9/4dk/f+HZL3/x2T9/4ck/f/HZL2/ByR9SgAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2T90wckvb/HJL3/xyS
+        9/8dkvb/HJL2/x2S9/8dk/f+HJL3/xyS9v0dk/f/HJL2igAAAAAckvYCAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAdk/etHJL2/x2T9/8dkvf/HJP3/xyS9v8dk/f+HZP3/h2S9/8dkvf7HJP2/x2S
+        9yoAAAAAIpL+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdkvYDAAAAAByT980dkvb/HZP3/hyT9v8ckvb/HZP3/h2T
+        9/4dk/b/HZP3/hyS9v8ck/f/HZP3WAAAAAAZlfcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAHJL2LByS9vAdk/f/HJL3/x2S9v8ck/b/HZL3/x2T9/4ck/f/HJP2/h2T
+        9/8dkve7AAAAAByT9wMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS94odk/b/HZP3/h2T
+        9v8ck/b/HJL2/x2T9/4dk/f+HZP2/x2T9vsckvf/HZP2WAAAAAAdk/YAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2T
+        9gQAAAAAHJL3ph2T9v8dkvf+HJP2/xyS9v8ck/b/HZP2/xyS9v8dk/b/HJP3/x2S9v8ckvZ9AAAAAB2S
+        9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdk/cIHZP35ByS
+        9v8ckvf/HJL2/xyS9v8ckvb/HZP2/xyS9v8dk/b+HZL3/x2T994AAAAAHZH3AgAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAACGT/QAAAAAAHJL2aB2T9/8dk/f/HJL2/xyT9v8ckvb/HJP2/x2T9v8ckvb/HJL2/B2S
+        9/8ck/aLAAAAAByS9gEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJL3AgAAAAAdk/dwHZL3/x2T9/4ck/f/HJL2/x2T
+        9/4dk/f+HZL3/x2T9/4ck/b+HZL2/xyT96QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAHJL2BAAAAAAdk/fLHJL2/xyT9/4dkvb/HJL2/x2S9/8dk/f+HJL3/xyS
+        9v8ckvb/HZP27hyU9h8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGJHyAAAAAAAdk/dCHJL2+R2T
+        9/8dkvf/HJP3/xyS9v8dk/f+HZP3/h2S9/8dk/f+HZP2/xyS98UAAAAAHZP2AgAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAckvYBAAAAAByS9kEckvb/HJL2/hyT9v8ckvb/HZP3/h2T9/4dkvb/HZP3/h2T9/4ck/f/HZL3vx2E
+        9gEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdk/cDAAAAAByS
+        9qAdk/f/HJP2/h2S9v8ckvb/HZL3/x2T9/4ckvb/HJL2/x2T9/8dkvf6HJL2RgAAAAAkkv8AAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2T9iEdk/bpHJL3/x2S9/8ck/b/HJL2/x2T9/4dk/f+HZL2/x2T
+        9/4dk/b/HJL37QAAAAAhlvYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6V+gAAAAAAHZP4EB2T9/8ckvf+HZP2/x2S
+        9v8dk/f+HZP3/h2S9v8dk/f+HZP2/xyT9v8ckvfdHZL2GgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2S9wIAAAAAHZL3bhyT9v8dkvf9HZL2/x2T9v8dkvf/HZP3/h2T
+        9/8ckvb/HZP3/xyT9v8dkvdxAAAAABmV8gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdk/YBAAAAAByS
+        99Ydk/b/HZP2/x2T9v8dkvb/HZP3/h2T9/4dkvb/HZP3/x2T9/8ckvb7HJL2KQAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAckfYBHJL25B2T9v8dk/f/HZL2/xyT9/8dk/f/HZP3/x2T9/8dk/f/HZL3/x2T
+        9vkck/cvAAAAAB2R9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJP2AQAA
+        AAAck/ZCHZL3/xyT9vwdkvb/HJP2/x2S9/8dk/f/HZP3/xyT9v8dk/f/HZL3/xyT9pUAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2T9gUAAAAAHJL3uh2T9v8ckvb+HZP3/x2S9v8ck/f/HZP3/x2T
+        9/8dk/f/HJL3/x2T9/8dk/ZWAAAAAB6U9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAglfkAAAAAAAAAAAAdk/a5HJL3/x2T
+        9/4dk/f+HZP3/h2T9/4dkvb/HZP3/h2T9/4ckvf/HJP3/x2S9kUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdlvkAAAAAAB2T9xkckvb/HZP3/B2T9/4dk/f+HZL3/x2T
+        9/4dk/f+HJL2/x2T9/4dkvf/HJP2tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJL3AwAA
+        AAAdk/eNHJL3/xyT9/4dk/f+HZP3/h2T9/4dk/f+HZL2/x2T9/4ck/f/HZL3/xyT9oMAAAAAHpL4AAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2T94ockvb/HZP3/h2S9/4dk/f+HZP3/hyS9v8dk/f+HZP3/h2T
+        9/4ck/f/HZL2bwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHZL3BxyT9ugdkvf/HZL3/h2T9/4ckvb/HZP3/h2T9/4ckvb/HZP3/h2T9v8ckvfZHJL3FQAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdkvYCAAAAAB2S9lsdkvb/HZL2/h2T9/4dkvf+HZP3/h2T
+        9/4ckvb/HZP3/h2T9/4ckvb/HZP3qwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZP3YRyS
+        9v8dk/b+HZL2/x2T9/8dk/f/HZP3/h2T9/8dk/f/HZP3/x2T9/8ckvaXAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIZn+AAAAAAAAAAAAHZL2wByT9/8dkvb/HZP2/x2T
+        9/4dk/f/HZP3/x2T9v4dk/f/HZL2/xyT9/kdkvYoAAAAAByT9wAAAAAAAAAAAAAAAAAAAAAAAAAAAByS
+        9gAAAAAAHJL2LhyS9v8ckvb9HZP3/x2S9v8dk/f/HZP3/x2T9/4dk/f/HZP3/xyT9v8dkvfFHpL4BwAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAHZL5AAAAAAAck/Y/HJL3/x2T9v8dkvf/HJP3/x2T9/8dk/b/HZP3/x2T
+        9/8dk/f/HZL3/xyT9sQAAAAAAAAAABad8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAckvaVHZP3/x2S9/8ck/f/HZL3/x2T9/8dk/f/HJP2/x2T9/8dk/b5HJL3/x2T
+        9kQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdk/kHHZP3/x2T9/8dk/f/HZL3/xyT
+        9/8dk/f/HZP2/x2T9/8dk/f/HZP3/xyT9uQckvYgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAglfQAAAAAAB2S
+        9yYdkvfpHJP2/x2S9v8dk/f+HZP3/h2T9v8dk/f+HZP2/x2T9v8ck/b/HZL37wAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByT924dkvb/HZL2/h2T
+        9v8dkvf/HZP3/h2T9v8dk/b/HZP2/xyT9/odkvb/HJP3bwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAB2U2AAdk/bWHZP2/x2T9v8dkvb/HZP3/h2T9/4dk/b/HZP3/h2T9v8dk/f/HZL3/xyT
+        9jQAAAAAHZH4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGpP2CxyT9s8dkvf/HZL2/h2T9/8dk/f/HZP3/x2T
+        9/8dk/f/HZP3/xyS9v8dk/f/HZP3FQAAAAAdk/cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAABaO8QAAAAAAHZP3TxyS9v8dk/f/HZP3/x2T9/8dk/f/HZP3/x2T9/8dk/f/HZL2/ByT
+        9/8dkvacAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACSS/gAAAAAAAAAAAB2S96wckvf/HZP3/x2T
+        9/8dk/f/HZP3/x2T9/8dk/f/HZP3/x2T9/8ck/b/HZL3TgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHZP2sRyS9/8dk/b+HJP3/x2T9/8dkvb/HZP3/x2T9/8dk/f/HZP3/xyS9v8ckvZDAAAAAByS
+        9gEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIpn/AAAAAAAckvYwHZP38B2S
+        9/8ck/b/HZL3/x2T9/8dk/f/HJL2/x2T9/8dkvb9HZP3/xyS9s8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAHJL2fh2T9/8dkvf+HZL2/xyT9/8dk/f/HZL2/x2T9/8dk/f/HZP3/hyT
+        9v8dkvd6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGpTyAAAAAAAdkveOHJL2/xyT9/8dk/f+HZP3/h2T
+        9/8dk/f+HJP3/x2T9/8dkvf/HZP2/x2T9m0AAAAAHZP2AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAByT9hQck/baHZL3/x2T9/4dkvf/HZP3/hyT9/8ck/b/HJP3/xyT
+        9v4ckvb/HZP39wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAck/dYHZL2/x2T
+        9/8ckvb/HZP3/h2T9/4dk/f/HZP3/hyT9/8dk/f/HJP2/x2S96IAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAkkv8AAAAAAB2T918dk/f/HJL2/x2T9/4dk/f+HJL2/x2T9/4dk/b/HZP3/x2T9/8ck/f/HZL2nAAA
+        AAAck/cEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS
+        98Idk/b/HZP2/hyS9/8dk/f+HZP3/xyS9v8dk/b/HJP2/x2S9v8ck/f/HJP3JwAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAdkfYAAAAAAByT9zkdkvb+HZP2/x2S9v8dk/f+HZP3/hyS9v8dk/f+HZP2/x2T
+        9/8dkvb/HJP20AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJP3NRyT9/8dkvb/HZP3/x2T
+        9/4ckvb/HZP3/hyT9v8dk/b/HZP2/x2S9v8ck/fBAAAAAB2S9gQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAABSU7gAAAAAAHZL3oxyT9v8ck/f/HJL2/x2T9/4ck/b/HJL2/xyT
+        9v8ckvb/HJP3/x2S9v8dkvZVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACq/wAAAAAAHZL2IB2S
+        9+Mck/f/HJL2/xyT9/4dk/f+HJL2/x2T9/4ck/b/HZP2/xyT9v8dkvf5IIH3AQAAAAA9APYAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAYk/YJHJP2+h2S9/8dk/f/HZP3/h2S9/8dk/f+HZP3/h2T9/4ck/b+HJP2/x2S
+        99Ygj/gHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAck/Z5HZP3/xyS9/8dkvf/HZP3/h2T9/4ckvb/HZP3/hyS9/8dk/b/HZL2/xyT94EAAAAAIJL2AAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAck/YFHJP3yh2S9v8dkvf+HJP3/h2T9/4dkvf/HZP3/h2T
+        9/4dk/f+HJP2/x2S9/8dkvYgAAAAAB2S9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJL2AQAAAAAdk/fcHJL2/xyS
+        9v4dk/b/HZP2/x2T9v8dk/b/HZP3/x2T9v8ck/b/HZL36x2S9ykAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2S90odkvf/HJP2/xyS9v4dk/b/HZP3/xyT
+        9v8dk/b/HZP2/x2T9/8ck/f/HZL2rwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAck/asHZL2/x2T9v8ck/b/HZP2/x2T9v8dk/b/HZP2/x2T9/8dkvf/HJP3/xyT91AAAAAAHJP3AgAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAdkvYAAAAAAByT9q0dkvf/HZP2/R2T9/4ckvf/HZP3/h2T9/4dk/f+HJL2/xyT
+        9/8dkvb+HJL2RgAAAAAelPQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHJL3HxyS9/8dk/b/HJL3/x2T9/4dk/f+HJL2/x2T9/4ckvf/HZP3/hyT9/8dkvbKAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAalfcAAAAAAB2S94gck/f/HZP2/x2T9/4dk/f+HJL3/x2T
+        9/4dk/f+HZP3/h2S9v8dk/b/HJL3eQAAAAAdk/YDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2S9wAAAAAAHZL3exyT
+        9v8dkvf7HZP3/x2S9v8dk/f/HZP3/x2T9/8ckvb/HZP3/xyS9/8dk/ZoAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAXi/8AAAAAABuR+gAelvcAHZX4AAAAAAAAAAAAHZP38xyS9v8dk/f+HZP3/x2T
+        9/8ckvb/HZP3/xyS9v8dk/f/HZL2/xyT9+QclPcgAAAAAB6W+AAdlfcAHpb4AB+X+gAAAAAAAAAAAAAA
+        AAAAAAAAHJP2WRyT9v8dkvf/HJP3/x2T9/8dkvb/HZP3/x2T9/8dk/f/HJL2/xyS9/8dk/apAAAAAByS
+        9wUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAHJH4AAAAAAAckvdMHZP2/xyS9/kdkvf/HZL3/xyS9/8ckvf/HZL3/xyS
+        9v8dkvf+HJL2/x2T94kAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdk/YAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAck/bEHZP3/x2T9/0ckvf/HJL3/xyS9v8ckvf/HJL3/xyS9/8dk/f/HJL3/B2S
+        9jgAAAAAAAAAAAAAAAAAAAAAAAAAAB2T9wAAAAAAAAAAAAAAAAAdkvcwHZL3/xyT9v8dkvf/HZL3/x2S
+        9/8ckvf/HJL3/x2S9/8dk/b+HJL2/x2T98kAAAAAHJH2AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS
+        9isdk/f/HJL2/B2T9/4ckvb/HZP3/h2S9/8dkvf/HJL2/xyS9v8dk/b/HJL3rRuR/wAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAGoz+AAAAAAAckvgMHZT3Kx2U9x4dlPcfHZT3Fh2T964ckvb/HZL2/B2T
+        9/4dkvf/HJL2/x2S9/8ckvb/HZL3/x2S9v8dk/b/HJL3bx2W+AsdlPcgHZT3IB2U9yIdlPgJAAAAAAAA
+        AAAAAAAAAAAAABuT9QYck/b5HZL3/x2T9/8dk/f+HJL2/x2T9/4dkvf/HZL3/xyS9v8dk/b/HJL32xyR
+        9xEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZP2GByS9+Idk/b/HZL2/xyS9v8dkvb/HZL2/x2S
+        9/8ckvb/HJL2/x2S9/8dk/bVHZP2DQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkkv8AAAAAAB2S
+        9xMckvbjHZP3/xyS9v8ckvb/HJL2/x2T9/4ckvf/HZL2/x2S9/8ckvb/HZL2/xyS9v8dkvb/HJP3/hyS
+        9/4dk/b/HJL2/xyS9v8ck/b/HJP35ByT9w4AAAAAAAAAAAAAAAAckvYBAAAAAB2T99kckvb/HZL3/h2S
+        9v8ckvb/HZL2/x2S9v8dkvf/HJL2/xyT9/8ckvbxHZL2MgAAAAAVlP4AAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAckvYHHJL3wB2T9v8dk/f+HJL2/x2T9/4ckvb/HJL3/xyS9v8ckvb/HJP3/x2T9vock/cYAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdk/YAAAAAAByS9yQdkvb1HZP3/x2T9/sdk/f+HJL2/xyS
+        9/4dk/f+HJL3/xyS9v8ckvb/HJL2/xyS9v8dk/f/HZP2/xyS9/0dk/f8HZP3/R2S9v8dkvd2AAAAAByR
+        9QAAAAAAAAAAAB2S9wAAAAAAHJP2qh2S9/8ck/b8HZP3/hyS9v8dk/f+HJL2/xyS9/8ckvb/HZP3/x2S
+        9v8ckvdPAAAAAB6T9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdkvaZHJP3/x2T9/4dk/f/HZP3/h2T
+        9/4dk/f+HZP2/xyT9/4dk/f7HJP2/x2T9zIAAAAAHZL4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS
+        9wAdk/cCAAAAAByS91Eck/f/HZL2/h2S9v4ck/b/HZL3/x2T9/4dk/f+HJP2/x2T9/4dk/f/HZP3/hyT
+        9/4ck/b+HZP3/xyS9v4dk/f/HZL39B2R9gcAAAAAHZT4AAAAAAAAAAAAHZL3AAAAAAAdkvd5HJP2/x2S
+        9/sdk/f+HZP3/x2T9/4dk/f+HZP3/h2T9v8ckvf/HZL2/xyT93IAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAUc/YAAAAAAB2T9ncckvf/HZL3/x2S9/8dk/f/HZP3/x2T9/8ckvb/HZL3/x2S9vwck/f/HZP2XQAA
+        AAAdk/YBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2S9pAck/f/HZL2/xyT
+        9v4dkvf/HZP3/x2T9/8ckvb/HZP3/xyS9/8dk/f/HZP3/x2T9v8dkvf/HJL3+x2S9v8dk/eOAAAAAByS
+        9wAAAAAAAAAAAAAAAAAbkfgAAAAAAByS90wdk/b/HJL3+R2T9/8dkvf/HZP3/x2T9/8dk/f/HJL2/x2S
+        9/4ckvf/HZP2lQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJL3UxyS9/8dk/f/HJL3/x2T
+        9/4ckvf/HJL3/xyS9v8ckvf/HJP3/R2T9v8ck/eJAAAAAByT9wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHpP2ABuT+AAAAAAAAAAAAByT98Ick/f/HJP3/hyS9/8dk/f+HJL3/xyS9v8ckvf/HJL3/xyS
+        9/8ck/f+HJP3/hyT9/4ck/b+HZL3/x2S9yoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJL2Kx2T
+        9/8ckvb8HZP3/hyS9/8dk/f+HJL3/xyS9/8ckvb/HJL3/x2T9/8ckva5HJL2BAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAdk/YrHZP2+hyS9/8dk/f/HZP3/x2T9/8dk/f/HZP2/xyS9/8dkvb/HJP3/x2S
+        9sUAAAAAHJP3AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZH1AByT9wAAAAAAHJL2FByS
+        9+wdk/b/HJL3/R2T9/4dk/f/HJP3/x2T9/8dk/f/HZP3/xyT9/8dk/f/HZP3/h2S9/8ck/ajAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdk/YYHZP37ByS9v8dk/f/HZP3/x2T9/8dk/f/HZP3/x2T
+        9v8ckvf/HZL2/x2T9+8dk/cTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACGW+Agdk/eUHJL2rx2T
+        96gdk/eoHZP2qB2T96gck/eoHJP2qB2S96gdkvauHJP3kgAAAAAejvYCAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS9wAAAAAAHZP2RxyS9v8dk/b/HZP3/hyT9/8ckvb/HJL2/xyS
+        9v8ckvb/HZP3/h2T9/8ckvb/HZL3/xyT9kMAAAAAHZH4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABuR
+        9gYckveCHZP3rhyT96gdk/eoHZP3qB2T9qgdk/eoHJP3qByT9qgckvanHJP3qR2T9hIAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAdlPYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAGpr3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJL3AAAA
+        AAAAAAAAHJL3cx2S9/8ck/b/HZL3/xyS9v8dk/b/HJL2/x2T9v8dk/f+HJP3/hyS9v8dk/fCAAAAAByS
+        9wMamfIAAAAAAAAAAAAAAAAAAAAAAAAAAAAdk/cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2T9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACua/gAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfivYAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAglfQAHJL2ABuS0QAAAAAAHJP3rB2S9v8ck/f9HJP2/hyT
+        9v8ck/b/HJP2/x2T9/4dkvb8HZP3/xyT9kwAAAAAHZP2AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByS
+        9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHJP3AAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAHZL4AAAAAAAgjfgEHJP32x2T9v8ckvb+HJP3/xyS9/8ckvf/HJP3/h2T9/8ckvbVAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZL1AAAAAAAdkvcvHJL2+xyT
+        9v8dk/b+HJP2/xyT9/4dkvb/HJP3/xyS9mwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAACuA/wAAAAAAHZX2AAAAAAAdkvdhHZP2/xyT9/8ckvb+HZL3/hyT9/8dkvbmHZP3GAAA
+        AAAdkfUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAckvYAAAAAAAAA
+        AAAck/eZHZL2/xyT9/4ck/b/HJP3/x2S9owAAAAAG5T6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdkvYAAAAAABWU/AIckvfMHZP2/x2S9v8ck/f/HJP2GgAA
+        AAAekPIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABuU
+        +AAdkvYBAAAAAByT9xockvbuHZL3/xyS9qIAAAAAHpL3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABuS9wAdk/YBAAAAAB2T904ck/f/HZP2NgAA
+        AAAZlPoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2S9kYckvYOAAAAAByS8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByT9wAAAAAAAAAAAAAA
+        AAAdk/cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2S/wAdkvYAHJL1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+        AAAAAAAAAAAAAP//////////////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////////////
+        //////////////////////////////////////////////////////////P////////////////////w
+        ////////////////////8D////5///////////////Af//wAP////wAf/AAAAAAAB//+AD////8AH/wA
+        AAAAAAH//gA/////AB/+AAAAAAAA//4AP////4AP/gAAAAAAAD/+AD////+AD/4AAAAAAAAP/gA/////
+        gA/+AAAAAAAAB/8AH////4AP/gAAAAAAAB//AB////+AD/4AAAAAAAA//wAf////wA//AAAAAAAA//8A
+        H////8AH/wAAAAAAA///AB/////AB/8ACD//8Af//wAP////wAf/AB////Af//+AD////8AH/wAf///w
+        P///gA/////AB/8AD///8P///4AP////4AP/gA////P///+AD////+AD/4AP///3////gA/////gA/+A
+        D////////8AH////4AP/gA/////////AB////+AD/4AP////////wAf////gA/+AD////////8AH////
+        8AH/wAf////////AB/////AB/8AH////////wAf////wAf/AB////////+AD////8AH/wAf////////g
+        A/////AB/8AH////////4AP////4AP/AB////////+AD////+AD/4AP////////gA/////gA/+AD////
+        ////4AP////4AP/gA/////////AB////+AD/4AP////////wAAAAAAAA/+AD////////8AAAAAAAAH/g
+        A/////////AAAAAAAAB/8AH////////wAAAAAAAAf/AB////////+AAAAAAAAH/wAf////////gAAAAA
+        AAB/8AH////////4AAAAAAAAf/AB////////+AAAAAAAAD/wAf////////gAAAAAAAA/+AH////////4
+        AAAAAAAAP/gA/////////AAAAAAAAD/4AP////////wAf////gA/+AD////////8AH////8AH/gA////
+        /////AB/////AB/4AP////////wAf////wAf/AB////////+AD////8AH/wAf////////gA/////AB/8
+        AH////////4AP////4Af/AB////////+AD////+AD/wAf////////gA/////gA/8AD////////4AP///
+        /4AP/gA/////////AB////+AD/4AP////////wAf////gA/+AD////////8AH////8AP/gA/////////
+        AB/////AB/4AP////////wAf////wAf/AD////////8AH////8AH/wAf////////gA/////AB/8AH///
+        /////4AP////wAf/AB////////+AD////+AD/wAf////////gA/////gA/8AH////////4AP////4AP/
+        AB/////////AD////+AD/4AP////////wAf////gA/+AD////////8AH////4AP/gA/////////AB///
+        /gAAH4AP////////wAf///8AAD+AD////////8AH////gAA/wA/////////gB////4AAP8AH////////
+        4AP////AAH/AB////////+AD////4AB/wAf////////gA/////AA/8AH///////////////4AP//////
+        ////////////+AH///////////////////wB///////////////////+A////////////////////wP/
+        //////////////////8D////////////////////h////////////////////8f/////////////////
+        ///v////////////////////////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////////////////////////
+        ////////////////////////
+</value>
+  </data>
+</root>
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/EngineAlgorithmView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/EngineAlgorithmView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/EngineAlgorithmView.Designer.cs	(revision 12764)
@@ -0,0 +1,302 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class EngineAlgorithmView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.engineLabel = new System.Windows.Forms.Label();
+      this.engineComboBox = new System.Windows.Forms.ComboBox();
+      this.engineTabPage = new System.Windows.Forms.TabPage();
+      this.engineViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.operatorGraphTabPage = new System.Windows.Forms.TabPage();
+      this.openOperatorGraphButton = new System.Windows.Forms.Button();
+      this.newOperatorGraphButton = new System.Windows.Forms.Button();
+      this.operatorGraphViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.tabControl.SuspendLayout();
+      this.parametersTabPage.SuspendLayout();
+      this.problemTabPage.SuspendLayout();
+      this.resultsTabPage.SuspendLayout();
+      this.runsTabPage.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.engineTabPage.SuspendLayout();
+      this.operatorGraphTabPage.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // tabControl
+      // 
+      this.tabControl.Controls.Add(this.operatorGraphTabPage);
+      this.tabControl.Controls.Add(this.engineTabPage);
+      this.tabControl.Location = new System.Drawing.Point(0, 26);
+      this.tabControl.Size = new System.Drawing.Size(713, 493);
+      this.tabControl.TabIndex = 3;
+      this.tabControl.Controls.SetChildIndex(this.engineTabPage, 0);
+      this.tabControl.Controls.SetChildIndex(this.operatorGraphTabPage, 0);
+      this.tabControl.Controls.SetChildIndex(this.runsTabPage, 0);
+      this.tabControl.Controls.SetChildIndex(this.resultsTabPage, 0);
+      this.tabControl.Controls.SetChildIndex(this.parametersTabPage, 0);
+      this.tabControl.Controls.SetChildIndex(this.problemTabPage, 0);
+      // 
+      // parametersTabPage
+      // 
+      this.parametersTabPage.Size = new System.Drawing.Size(705, 467);
+      // 
+      // problemTabPage
+      // 
+      this.problemTabPage.Size = new System.Drawing.Size(705, 467);
+      // 
+      // parameterCollectionView
+      // 
+      this.parameterCollectionView.Size = new System.Drawing.Size(693, 455);
+      // 
+      // problemViewHost
+      // 
+      this.problemViewHost.Size = new System.Drawing.Size(693, 425);
+      // 
+      // newProblemButton
+      // 
+      this.toolTip.SetToolTip(this.newProblemButton, "New Problem");
+      // 
+      // openProblemButton
+      // 
+      this.toolTip.SetToolTip(this.openProblemButton, "Open Problem");
+      // 
+      // startButton
+      // 
+      this.startButton.Location = new System.Drawing.Point(0, 525);
+      this.startButton.TabIndex = 4;
+      this.toolTip.SetToolTip(this.startButton, "Start/Resume Algorithm");
+      // 
+      // pauseButton
+      // 
+      this.pauseButton.Location = new System.Drawing.Point(30, 525);
+      this.pauseButton.TabIndex = 5;
+      this.toolTip.SetToolTip(this.pauseButton, "Pause Algorithm");
+      // 
+      // resetButton
+      // 
+      this.resetButton.Location = new System.Drawing.Point(90, 525);
+      this.resetButton.TabIndex = 7;
+      this.toolTip.SetToolTip(this.resetButton, "Reset Algorithm");
+      // 
+      // executionTimeLabel
+      // 
+      this.executionTimeLabel.Location = new System.Drawing.Point(487, 532);
+      this.executionTimeLabel.TabIndex = 8;
+      // 
+      // executionTimeTextBox
+      // 
+      this.executionTimeTextBox.Location = new System.Drawing.Point(576, 529);
+      this.executionTimeTextBox.TabIndex = 9;
+      // 
+      // resultsTabPage
+      // 
+      this.resultsTabPage.Size = new System.Drawing.Size(705, 467);
+      // 
+      // resultsView
+      // 
+      this.resultsView.Size = new System.Drawing.Size(693, 455);
+      // 
+      // stopButton
+      // 
+      this.stopButton.Location = new System.Drawing.Point(60, 525);
+      this.stopButton.TabIndex = 6;
+      this.toolTip.SetToolTip(this.stopButton, "Stop Algorithm");
+      // 
+      // runsTabPage
+      // 
+      this.runsTabPage.Size = new System.Drawing.Size(705, 467);
+      // 
+      // runsView
+      // 
+      this.runsView.Size = new System.Drawing.Size(693, 455);
+      // 
+      // storeAlgorithmInEachRunCheckBox
+      // 
+      this.storeAlgorithmInEachRunCheckBox.Location = new System.Drawing.Point(530, 6);
+      this.toolTip.SetToolTip(this.storeAlgorithmInEachRunCheckBox, "Check to store a copy of the algorithm in each run.");
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      this.nameTextBox.Location = new System.Drawing.Point(60, 0);
+      this.nameTextBox.Size = new System.Drawing.Size(628, 20);
+      // 
+      // infoLabel
+      // 
+      this.infoLabel.Location = new System.Drawing.Point(694, 3);
+      // 
+      // engineLabel
+      // 
+      this.engineLabel.AutoSize = true;
+      this.engineLabel.Location = new System.Drawing.Point(6, 9);
+      this.engineLabel.Name = "engineLabel";
+      this.engineLabel.Size = new System.Drawing.Size(43, 13);
+      this.engineLabel.TabIndex = 0;
+      this.engineLabel.Text = "&Engine:";
+      // 
+      // engineComboBox
+      // 
+      this.engineComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.engineComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.engineComboBox.FormattingEnabled = true;
+      this.engineComboBox.Location = new System.Drawing.Point(55, 6);
+      this.engineComboBox.Name = "engineComboBox";
+      this.engineComboBox.Size = new System.Drawing.Size(644, 21);
+      this.engineComboBox.TabIndex = 1;
+      this.engineComboBox.SelectedIndexChanged += new System.EventHandler(this.engineComboBox_SelectedIndexChanged);
+      // 
+      // engineTabPage
+      // 
+      this.engineTabPage.Controls.Add(this.engineViewHost);
+      this.engineTabPage.Controls.Add(this.engineComboBox);
+      this.engineTabPage.Controls.Add(this.engineLabel);
+      this.engineTabPage.Location = new System.Drawing.Point(4, 22);
+      this.engineTabPage.Name = "engineTabPage";
+      this.engineTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.engineTabPage.Size = new System.Drawing.Size(705, 467);
+      this.engineTabPage.TabIndex = 5;
+      this.engineTabPage.Text = "Engine";
+      this.engineTabPage.UseVisualStyleBackColor = true;
+      // 
+      // engineViewHost
+      // 
+      this.engineViewHost.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.engineViewHost.Caption = "View";
+      this.engineViewHost.Content = null;
+      this.engineViewHost.Enabled = false;
+      this.engineViewHost.Location = new System.Drawing.Point(6, 33);
+      this.engineViewHost.Name = "engineViewHost";
+      this.engineViewHost.ReadOnly = false;
+      this.engineViewHost.Size = new System.Drawing.Size(693, 428);
+      this.engineViewHost.TabIndex = 2;
+      this.engineViewHost.ViewsLabelVisible = true;
+      this.engineViewHost.ViewType = null;
+      // 
+      // operatorGraphTabPage
+      // 
+      this.operatorGraphTabPage.Controls.Add(this.openOperatorGraphButton);
+      this.operatorGraphTabPage.Controls.Add(this.newOperatorGraphButton);
+      this.operatorGraphTabPage.Controls.Add(this.operatorGraphViewHost);
+      this.operatorGraphTabPage.Location = new System.Drawing.Point(4, 22);
+      this.operatorGraphTabPage.Name = "operatorGraphTabPage";
+      this.operatorGraphTabPage.Size = new System.Drawing.Size(705, 467);
+      this.operatorGraphTabPage.TabIndex = 4;
+      this.operatorGraphTabPage.Text = "Operator Graph";
+      this.operatorGraphTabPage.UseVisualStyleBackColor = true;
+      // 
+      // openOperatorGraphButton
+      // 
+      this.openOperatorGraphButton.Enabled = false;
+      this.openOperatorGraphButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Open;
+      this.openOperatorGraphButton.Location = new System.Drawing.Point(33, 3);
+      this.openOperatorGraphButton.Name = "openOperatorGraphButton";
+      this.openOperatorGraphButton.Size = new System.Drawing.Size(24, 24);
+      this.openOperatorGraphButton.TabIndex = 1;
+      this.toolTip.SetToolTip(this.openOperatorGraphButton, "Open Operator Graph");
+      this.openOperatorGraphButton.UseVisualStyleBackColor = true;
+      // 
+      // newOperatorGraphButton
+      // 
+      this.newOperatorGraphButton.Enabled = false;
+      this.newOperatorGraphButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.NewDocument;
+      this.newOperatorGraphButton.Location = new System.Drawing.Point(3, 3);
+      this.newOperatorGraphButton.Name = "newOperatorGraphButton";
+      this.newOperatorGraphButton.Size = new System.Drawing.Size(24, 24);
+      this.newOperatorGraphButton.TabIndex = 1;
+      this.toolTip.SetToolTip(this.newOperatorGraphButton, "New Operator Graph");
+      this.newOperatorGraphButton.UseVisualStyleBackColor = true;
+      // 
+      // operatorGraphViewHost
+      // 
+      this.operatorGraphViewHost.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.operatorGraphViewHost.Caption = "View";
+      this.operatorGraphViewHost.Content = null;
+      this.operatorGraphViewHost.Enabled = false;
+      this.operatorGraphViewHost.Location = new System.Drawing.Point(3, 33);
+      this.operatorGraphViewHost.Name = "operatorGraphViewHost";
+      this.operatorGraphViewHost.ReadOnly = true;
+      this.operatorGraphViewHost.Size = new System.Drawing.Size(699, 431);
+      this.operatorGraphViewHost.TabIndex = 0;
+      this.operatorGraphViewHost.ViewsLabelVisible = true;
+      this.operatorGraphViewHost.ViewType = null;
+      // 
+      // EngineAlgorithmView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Name = "EngineAlgorithmView";
+      this.Size = new System.Drawing.Size(713, 549);
+      this.tabControl.ResumeLayout(false);
+      this.parametersTabPage.ResumeLayout(false);
+      this.problemTabPage.ResumeLayout(false);
+      this.resultsTabPage.ResumeLayout(false);
+      this.runsTabPage.ResumeLayout(false);
+      this.runsTabPage.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.engineTabPage.ResumeLayout(false);
+      this.engineTabPage.PerformLayout();
+      this.operatorGraphTabPage.ResumeLayout(false);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    protected System.Windows.Forms.Label engineLabel;
+    protected System.Windows.Forms.ComboBox engineComboBox;
+    protected System.Windows.Forms.TabPage engineTabPage;
+    protected HeuristicLab.MainForm.WindowsForms.ViewHost engineViewHost;
+    protected System.Windows.Forms.TabPage operatorGraphTabPage;
+    protected HeuristicLab.MainForm.WindowsForms.ViewHost operatorGraphViewHost;
+    protected System.Windows.Forms.Button openOperatorGraphButton;
+    protected System.Windows.Forms.Button newOperatorGraphButton;
+
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/EngineAlgorithmView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/EngineAlgorithmView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/EngineAlgorithmView.cs	(revision 12764)
@@ -0,0 +1,137 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.MainForm;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Optimization.Views {
+  /// <summary>
+  /// The base class for visual representations of items.
+  /// </summary>
+  [View("EngineAlgorithm View")]
+  [Content(typeof(EngineAlgorithm), true)]
+  public partial class EngineAlgorithmView : AlgorithmView {
+    private List<Type> engineTypes;
+
+    public new EngineAlgorithm Content {
+      get { return (EngineAlgorithm)base.Content; }
+      set { base.Content = value; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of <see cref="ItemBaseView"/>.
+    /// </summary>
+    public EngineAlgorithmView() {
+      InitializeComponent();
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.EngineChanged -= new EventHandler(Content_EngineChanged);
+      Content.OperatorGraphChanged -= new EventHandler(Content_OperatorGraphChanged);
+      base.DeregisterContentEvents();
+    }
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.EngineChanged += new EventHandler(Content_EngineChanged);
+      Content.OperatorGraphChanged += new EventHandler(Content_OperatorGraphChanged);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+
+      if (engineTypes == null) {
+        engineTypes = ApplicationManager.Manager.GetTypes(typeof(IEngine)).
+                      OrderBy(x => {
+                        string name = ItemAttribute.GetName(x);
+                        if (name != null) return name;
+                        else return x.GetPrettyName();
+                      }).ToList();
+        foreach (Type t in engineTypes) {
+          string name = ItemAttribute.GetName(t);
+          if (name == null) name = t.GetPrettyName();
+          engineComboBox.Items.Add(name);
+        }
+      }
+
+      if (Content == null) {
+        engineViewHost.Content = null;
+        operatorGraphViewHost.Content = null;
+      } else {
+        if (Content.Engine == null)
+          engineComboBox.SelectedIndex = -1;
+        else
+          engineComboBox.SelectedIndex = engineTypes.IndexOf(Content.Engine.GetType());
+        engineViewHost.ViewType = null;
+        engineViewHost.Content = Content.Engine;
+        operatorGraphViewHost.ViewType = null;
+        operatorGraphViewHost.Content = Content.OperatorGraph;
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      engineViewHost.Enabled = Content != null;
+      newOperatorGraphButton.Enabled = false;
+      openOperatorGraphButton.Enabled = false;
+      operatorGraphViewHost.Enabled = Content != null;
+      operatorGraphViewHost.ReadOnly = true;
+      engineComboBox.Enabled = Content != null && !ReadOnly;
+    }
+
+    protected virtual void Content_EngineChanged(object sender, System.EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_EngineChanged), sender, e);
+      else {
+        if (Content.Engine == null)
+          engineComboBox.SelectedIndex = -1;
+        else
+          engineComboBox.SelectedIndex = engineTypes.IndexOf(Content.Engine.GetType());
+        engineViewHost.ViewType = null;
+        engineViewHost.Content = Content.Engine;
+      }
+    }
+    private void Content_OperatorGraphChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_OperatorGraphChanged), sender, e);
+      else {
+        operatorGraphViewHost.ViewType = null;
+        operatorGraphViewHost.Content = Content.OperatorGraph;
+      }
+    }
+
+    protected virtual void engineComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      if (Content != null) {
+        if (engineComboBox.SelectedIndex == -1)
+          Content.Engine = null;
+        else {
+          Type t = engineTypes[engineComboBox.SelectedIndex];
+          if ((Content.Engine == null) || (Content.Engine.GetType() != t))
+            Content.Engine = (IEngine)Activator.CreateInstance(t);
+        }
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ExperimentListView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ExperimentListView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ExperimentListView.Designer.cs	(revision 12764)
@@ -0,0 +1,196 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class ExperimentListView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.tabControl = new HeuristicLab.MainForm.WindowsForms.DragOverTabControl();
+      this.optimizersTabPage = new System.Windows.Forms.TabPage();
+      this.optimizerListView = new HeuristicLab.Optimization.Views.OptimizerListView();
+      this.runsTabPage = new System.Windows.Forms.TabPage();
+      this.runsViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.tabControl.SuspendLayout();
+      this.optimizersTabPage.SuspendLayout();
+      this.runsTabPage.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // startButton
+      // 
+      this.startButton.Location = new System.Drawing.Point(0, 458);
+      this.toolTip.SetToolTip(this.startButton, "Start/Resume Experiment");
+      // 
+      // executionTimeTextBox
+      // 
+      this.executionTimeTextBox.Location = new System.Drawing.Point(542, 461);
+      // 
+      // executionTimeLabel
+      // 
+      this.executionTimeLabel.Location = new System.Drawing.Point(453, 464);
+      // 
+      // pauseButton
+      // 
+      this.pauseButton.Location = new System.Drawing.Point(30, 458);
+      this.toolTip.SetToolTip(this.pauseButton, "Pause Experiment");
+      // 
+      // stopButton
+      // 
+      this.stopButton.Location = new System.Drawing.Point(60, 458);
+      this.toolTip.SetToolTip(this.stopButton, "Stop Experiment");
+      // 
+      // resetButton
+      // 
+      this.resetButton.Location = new System.Drawing.Point(90, 458);
+      this.toolTip.SetToolTip(this.resetButton, "Reset Experiment");
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      this.nameTextBox.Location = new System.Drawing.Point(60, 0);
+      this.nameTextBox.Size = new System.Drawing.Size(594, 20);
+      // 
+      // infoLabel
+      // 
+      this.infoLabel.Location = new System.Drawing.Point(660, 3);
+      // 
+      // tabControl
+      // 
+      this.tabControl.AllowDrop = true;
+      this.tabControl.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.tabControl.Controls.Add(this.optimizersTabPage);
+      this.tabControl.Controls.Add(this.runsTabPage);
+      this.tabControl.Location = new System.Drawing.Point(0, 26);
+      this.tabControl.Name = "tabControl";
+      this.tabControl.SelectedIndex = 0;
+      this.tabControl.Size = new System.Drawing.Size(679, 427);
+      this.tabControl.TabIndex = 3;
+      // 
+      // optimizersTabPage
+      // 
+      this.optimizersTabPage.Controls.Add(this.optimizerListView);
+      this.optimizersTabPage.Location = new System.Drawing.Point(4, 22);
+      this.optimizersTabPage.Name = "optimizersTabPage";
+      this.optimizersTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.optimizersTabPage.Size = new System.Drawing.Size(671, 401);
+      this.optimizersTabPage.TabIndex = 1;
+      this.optimizersTabPage.Text = "Optimizers";
+      this.optimizersTabPage.UseVisualStyleBackColor = true;
+      // 
+      // optimizerListView
+      // 
+      this.optimizerListView.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.optimizerListView.Caption = "OptimizerList View";
+      this.optimizerListView.Content = null;
+      this.optimizerListView.Location = new System.Drawing.Point(6, 6);
+      this.optimizerListView.Name = "optimizerListView";
+      this.optimizerListView.ReadOnly = false;
+      this.optimizerListView.Size = new System.Drawing.Size(659, 389);
+      this.optimizerListView.TabIndex = 0;
+      // 
+      // runsTabPage
+      // 
+      this.runsTabPage.Controls.Add(this.runsViewHost);
+      this.runsTabPage.Location = new System.Drawing.Point(4, 22);
+      this.runsTabPage.Name = "runsTabPage";
+      this.runsTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.runsTabPage.Size = new System.Drawing.Size(671, 401);
+      this.runsTabPage.TabIndex = 2;
+      this.runsTabPage.Text = "Runs";
+      this.runsTabPage.UseVisualStyleBackColor = true;
+      // 
+      // runsViewHost
+      // 
+      this.runsViewHost.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.runsViewHost.Caption = "View";
+      this.runsViewHost.Content = null;
+      this.runsViewHost.Enabled = false;
+      this.runsViewHost.Location = new System.Drawing.Point(2, 6);
+      this.runsViewHost.Name = "runsViewHost";
+      this.runsViewHost.ReadOnly = false;
+      this.runsViewHost.Size = new System.Drawing.Size(657, 389);
+      this.runsViewHost.TabIndex = 0;
+      this.runsViewHost.ViewsLabelVisible = true;
+      this.runsViewHost.ViewType = null;
+      // 
+      // ExperimentView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.tabControl);
+      this.Name = "ExperimentView";
+      this.Size = new System.Drawing.Size(679, 482);
+      this.Controls.SetChildIndex(this.resetButton, 0);
+      this.Controls.SetChildIndex(this.stopButton, 0);
+      this.Controls.SetChildIndex(this.pauseButton, 0);
+      this.Controls.SetChildIndex(this.tabControl, 0);
+      this.Controls.SetChildIndex(this.executionTimeLabel, 0);
+      this.Controls.SetChildIndex(this.executionTimeTextBox, 0);
+      this.Controls.SetChildIndex(this.startButton, 0);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.tabControl.ResumeLayout(false);
+      this.optimizersTabPage.ResumeLayout(false);
+      this.runsTabPage.ResumeLayout(false);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+    #endregion
+
+    private HeuristicLab.MainForm.WindowsForms.DragOverTabControl tabControl;
+    private System.Windows.Forms.TabPage optimizersTabPage;
+    private OptimizerListView optimizerListView;
+    private System.Windows.Forms.TabPage runsTabPage;
+    private HeuristicLab.MainForm.WindowsForms.ViewHost runsViewHost;
+
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ExperimentListView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ExperimentListView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ExperimentListView.cs	(revision 12764)
@@ -0,0 +1,69 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("Experiment List View")]
+  [Content(typeof(Experiment), false)]
+  public sealed partial class ExperimentListView : IOptimizerView {
+    public ExperimentListView() {
+      InitializeComponent();
+    }
+
+    public new Experiment Content {
+      get { return (Experiment)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        optimizerListView.Content = null;
+        runsViewHost.Content = null;
+      } else {
+        optimizerListView.Content = Content.Optimizers;
+        runsViewHost.Content = Content.Runs;
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      optimizerListView.Enabled = Content != null;
+      runsViewHost.Enabled = Content != null;
+    }
+
+    protected override void OnClosed(FormClosedEventArgs e) {
+      if ((Content != null) && (Content.ExecutionState == ExecutionState.Started)) {
+        //The content must be stopped if no other view showing the content is available
+        var optimizers = MainFormManager.MainForm.Views.OfType<IContentView>().Where(v => v != this).Select(v => v.Content).OfType<IOptimizer>();
+        if (!optimizers.Contains(Content)) {
+          var nestedOptimizers = optimizers.SelectMany(opt => opt.NestedOptimizers);
+          if (!nestedOptimizers.Contains(Content)) Content.Stop();
+        }
+      }
+      base.OnClosed(e);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.Designer.cs	(revision 12764)
@@ -0,0 +1,305 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class ExperimentTreeView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ExperimentTreeView));
+      this.optimizersGroupBox = new System.Windows.Forms.GroupBox();
+      this.splitContainer = new System.Windows.Forms.SplitContainer();
+      this.showDetailsCheckBox = new System.Windows.Forms.CheckBox();
+      this.removeButton = new System.Windows.Forms.Button();
+      this.moveUpButton = new System.Windows.Forms.Button();
+      this.moveDownButton = new System.Windows.Forms.Button();
+      this.addButton = new System.Windows.Forms.Button();
+      this.treeView = new HeuristicLab.Optimization.Views.ExperimentTreeView.CustomTreeView();
+      this.imageList = new System.Windows.Forms.ImageList(this.components);
+      this.detailsGroupBox = new System.Windows.Forms.GroupBox();
+      this.detailsViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
+      this.ExpandToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.ExpandAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.CollapseToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.CollapseAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.EditNodeLabelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.toolTip = new System.Windows.Forms.ToolTip(this.components);
+      this.optimizersGroupBox.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.detailsGroupBox.SuspendLayout();
+      this.contextMenuStrip.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // optimizersGroupBox
+      // 
+      this.optimizersGroupBox.Controls.Add(this.splitContainer);
+      this.optimizersGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.optimizersGroupBox.Location = new System.Drawing.Point(0, 0);
+      this.optimizersGroupBox.Name = "optimizersGroupBox";
+      this.optimizersGroupBox.Size = new System.Drawing.Size(627, 458);
+      this.optimizersGroupBox.TabIndex = 16;
+      this.optimizersGroupBox.TabStop = false;
+      this.optimizersGroupBox.Text = "Optimizers";
+      // 
+      // splitContainer
+      // 
+      this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.splitContainer.Location = new System.Drawing.Point(3, 16);
+      this.splitContainer.Name = "splitContainer";
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.showDetailsCheckBox);
+      this.splitContainer.Panel1.Controls.Add(this.removeButton);
+      this.splitContainer.Panel1.Controls.Add(this.moveUpButton);
+      this.splitContainer.Panel1.Controls.Add(this.moveDownButton);
+      this.splitContainer.Panel1.Controls.Add(this.addButton);
+      this.splitContainer.Panel1.Controls.Add(this.treeView);
+      // 
+      // splitContainer.Panel2
+      // 
+      this.splitContainer.Panel2.Controls.Add(this.detailsGroupBox);
+      this.splitContainer.Size = new System.Drawing.Size(621, 439);
+      this.splitContainer.SplitterDistance = 198;
+      this.splitContainer.TabIndex = 0;
+      // 
+      // showDetailsCheckBox
+      // 
+      this.showDetailsCheckBox.Appearance = System.Windows.Forms.Appearance.Button;
+      this.showDetailsCheckBox.Checked = true;
+      this.showDetailsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.showDetailsCheckBox.Image = HeuristicLab.Common.Resources.VSImageLibrary.Properties;
+      this.showDetailsCheckBox.Location = new System.Drawing.Point(124, 4);
+      this.showDetailsCheckBox.Name = "showDetailsCheckBox";
+      this.showDetailsCheckBox.Size = new System.Drawing.Size(24, 24);
+      this.showDetailsCheckBox.TabIndex = 15;
+      this.toolTip.SetToolTip(this.showDetailsCheckBox, "Show/Hide Details");
+      this.showDetailsCheckBox.UseVisualStyleBackColor = true;
+      this.showDetailsCheckBox.CheckedChanged += new System.EventHandler(this.showDetailsCheckBox_CheckedChanged);
+      // 
+      // removeButton
+      // 
+      this.removeButton.Enabled = false;
+      this.removeButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Remove;
+      this.removeButton.Location = new System.Drawing.Point(94, 4);
+      this.removeButton.Name = "removeButton";
+      this.removeButton.Size = new System.Drawing.Size(24, 24);
+      this.removeButton.TabIndex = 14;
+      this.toolTip.SetToolTip(this.removeButton, "Remove");
+      this.removeButton.UseVisualStyleBackColor = true;
+      this.removeButton.Click += new System.EventHandler(this.removeButton_Click);
+      // 
+      // moveUpButton
+      // 
+      this.moveUpButton.Enabled = false;
+      this.moveUpButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.ArrowUp;
+      this.moveUpButton.Location = new System.Drawing.Point(34, 4);
+      this.moveUpButton.Name = "moveUpButton";
+      this.moveUpButton.Size = new System.Drawing.Size(24, 24);
+      this.moveUpButton.TabIndex = 12;
+      this.toolTip.SetToolTip(this.moveUpButton, "Move Up");
+      this.moveUpButton.UseVisualStyleBackColor = true;
+      this.moveUpButton.Click += new System.EventHandler(this.moveUpButton_Click);
+      // 
+      // moveDownButton
+      // 
+      this.moveDownButton.Enabled = false;
+      this.moveDownButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.ArrowDown;
+      this.moveDownButton.Location = new System.Drawing.Point(64, 4);
+      this.moveDownButton.Name = "moveDownButton";
+      this.moveDownButton.Size = new System.Drawing.Size(24, 24);
+      this.moveDownButton.TabIndex = 13;
+      this.toolTip.SetToolTip(this.moveDownButton, "Move Down");
+      this.moveDownButton.UseVisualStyleBackColor = true;
+      this.moveDownButton.Click += new System.EventHandler(this.moveDownButton_Click);
+      // 
+      // addButton
+      // 
+      this.addButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Add;
+      this.addButton.Location = new System.Drawing.Point(4, 4);
+      this.addButton.Name = "addButton";
+      this.addButton.Size = new System.Drawing.Size(24, 24);
+      this.addButton.TabIndex = 11;
+      this.toolTip.SetToolTip(this.addButton, "Add");
+      this.addButton.UseVisualStyleBackColor = true;
+      this.addButton.Click += new System.EventHandler(this.addButton_Click);
+      // 
+      // optimizerTreeView
+      // 
+      this.treeView.AllowDrop = true;
+      this.treeView.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.treeView.HideSelection = false;
+      this.treeView.ImageIndex = 0;
+      this.treeView.ImageList = this.imageList;
+      this.treeView.LabelEdit = true;
+      this.treeView.Location = new System.Drawing.Point(4, 34);
+      this.treeView.Name = "optimizerTreeView";
+      this.treeView.SelectedImageIndex = 0;
+      this.treeView.Size = new System.Drawing.Size(191, 402);
+      this.treeView.TabIndex = 10;
+      this.treeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(treeView_AfterSelect);
+      this.treeView.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.optimizerTreeView_ItemDrag);
+      this.treeView.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeview_NodeMouseClick);
+      this.treeView.NodeMouseDoubleClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeView_NodeMouseDoubleClick);
+      this.treeView.DragDrop += new System.Windows.Forms.DragEventHandler(this.optimizerTreeView_DragDrop);
+      this.treeView.DragEnter += new System.Windows.Forms.DragEventHandler(this.optimizerTreeView_DragEnter);
+      this.treeView.DragOver += new System.Windows.Forms.DragEventHandler(this.optimizerTreeView_DragOver);
+      this.treeView.KeyDown += new System.Windows.Forms.KeyEventHandler(this.treeView_KeyDown);
+      this.treeView.MouseDown += new System.Windows.Forms.MouseEventHandler(this.treeView_MouseDown);
+      this.treeView.RightClick += new System.EventHandler(treeView_RightClick);
+      // 
+      // imageList
+      // 
+      this.imageList.ColorDepth = System.Windows.Forms.ColorDepth.Depth8Bit;
+      this.imageList.ImageSize = new System.Drawing.Size(16, 16);
+      this.imageList.TransparentColor = System.Drawing.Color.Transparent;
+      // 
+      // detailsGroupBox
+      // 
+      this.detailsGroupBox.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.detailsGroupBox.Controls.Add(this.detailsViewHost);
+      this.detailsGroupBox.Location = new System.Drawing.Point(3, 34);
+      this.detailsGroupBox.Name = "detailsGroupBox";
+      this.detailsGroupBox.Size = new System.Drawing.Size(413, 405);
+      this.detailsGroupBox.TabIndex = 1;
+      this.detailsGroupBox.TabStop = false;
+      this.detailsGroupBox.Text = "Details";
+      // 
+      // detailsViewHost
+      // 
+      this.detailsViewHost.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.detailsViewHost.Caption = "View";
+      this.detailsViewHost.Content = null;
+      this.detailsViewHost.Enabled = false;
+      this.detailsViewHost.Location = new System.Drawing.Point(6, 19);
+      this.detailsViewHost.Name = "detailsViewHost";
+      this.detailsViewHost.ReadOnly = false;
+      this.detailsViewHost.Size = new System.Drawing.Size(401, 380);
+      this.detailsViewHost.TabIndex = 0;
+      this.detailsViewHost.ViewsLabelVisible = true;
+      this.detailsViewHost.ViewType = null;
+      // 
+      // contextMenuStrip
+      // 
+      this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.EditNodeLabelToolStripMenuItem,
+            this.ExpandToolStripMenuItem,
+            this.ExpandAllToolStripMenuItem,
+            this.CollapseToolStripMenuItem,
+            this.CollapseAllToolStripMenuItem});
+      this.contextMenuStrip.Name = "contextMenuStrip";
+      this.contextMenuStrip.Size = new System.Drawing.Size(120, 48);
+      // 
+      // ExpandToolStripMenuItem
+      // 
+      this.ExpandToolStripMenuItem.Name = "ExpandToolStripMenuItem";
+      this.ExpandToolStripMenuItem.Size = new System.Drawing.Size(119, 22);
+      this.ExpandToolStripMenuItem.Text = "Expand";
+      this.ExpandToolStripMenuItem.Click += new System.EventHandler(this.ExpandToolStripMenuItem_Click);
+      // 
+      // ExpandAllToolStripMenuItem
+      // 
+      this.ExpandAllToolStripMenuItem.Name = "ExpandAllToolStripMenuItem";
+      this.ExpandAllToolStripMenuItem.Size = new System.Drawing.Size(119, 22);
+      this.ExpandAllToolStripMenuItem.Text = "Expand All";
+      this.ExpandAllToolStripMenuItem.Click += new System.EventHandler(this.ExpandAllToolStripMenuItem_Click);
+      // 
+      // CollapseToolStripMenuItem
+      // 
+      this.CollapseToolStripMenuItem.Name = "CollapseToolStripMenuItem";
+      this.CollapseToolStripMenuItem.Size = new System.Drawing.Size(119, 22);
+      this.CollapseToolStripMenuItem.Text = "Collapse";
+      this.CollapseToolStripMenuItem.Click += new System.EventHandler(this.CollapseToolStripMenuItem_Click);
+      // 
+      // CollapseAllToolStripMenuItem
+      // 
+      this.CollapseAllToolStripMenuItem.Name = "CollapseAllToolStripMenuItem";
+      this.CollapseAllToolStripMenuItem.Size = new System.Drawing.Size(119, 22);
+      this.CollapseAllToolStripMenuItem.Text = "Collapse All";
+      this.CollapseAllToolStripMenuItem.Click += new System.EventHandler(this.CollapseAllToolStripMenuItem_Click);
+      //
+      // EditNodeLabelToolStripMenuItem
+      //
+      this.EditNodeLabelToolStripMenuItem.Name = "EditNodeLabelToolStripMenuItem";
+      this.EditNodeLabelToolStripMenuItem.Size = new System.Drawing.Size(119, 22);
+      this.EditNodeLabelToolStripMenuItem.Text = "Edit Name";
+      this.EditNodeLabelToolStripMenuItem.Click += new System.EventHandler(this.EditNodeLabelToolStripMenuItem_Click);
+
+      // 
+      // ExperimentTreeView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.optimizersGroupBox);
+      this.Name = "ExperimentTreeView";
+      this.Size = new System.Drawing.Size(627, 458);
+      this.optimizersGroupBox.ResumeLayout(false);
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.detailsGroupBox.ResumeLayout(false);
+      this.contextMenuStrip.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+    #endregion
+
+    private System.Windows.Forms.GroupBox optimizersGroupBox;
+    private System.Windows.Forms.SplitContainer splitContainer;
+    private HeuristicLab.Optimization.Views.ExperimentTreeView.CustomTreeView treeView;
+    private System.Windows.Forms.GroupBox detailsGroupBox;
+    private MainForm.WindowsForms.ViewHost detailsViewHost;
+    private System.Windows.Forms.ToolTip toolTip;
+    private System.Windows.Forms.CheckBox showDetailsCheckBox;
+    private System.Windows.Forms.Button removeButton;
+    private System.Windows.Forms.Button moveUpButton;
+    private System.Windows.Forms.Button moveDownButton;
+    private System.Windows.Forms.Button addButton;
+    private System.Windows.Forms.ImageList imageList;
+    private System.Windows.Forms.ContextMenuStrip contextMenuStrip;
+    private System.Windows.Forms.ToolStripMenuItem ExpandToolStripMenuItem;
+    private System.Windows.Forms.ToolStripMenuItem ExpandAllToolStripMenuItem;
+    private System.Windows.Forms.ToolStripMenuItem CollapseToolStripMenuItem;
+    private System.Windows.Forms.ToolStripMenuItem CollapseAllToolStripMenuItem;
+    private System.Windows.Forms.ToolStripMenuItem EditNodeLabelToolStripMenuItem;
+
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.cs	(revision 12764)
@@ -0,0 +1,931 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Optimization.Views {
+  public sealed partial class ExperimentTreeView : ItemView {
+    private TypeSelectorDialog typeSelectorDialog;
+    private Dictionary<INamedItem, List<TreeNode>> treeNodeTagMapping;
+
+    public ExperimentTreeView() {
+      InitializeComponent();
+      treeNodeTagMapping = new Dictionary<INamedItem, List<TreeNode>>();
+    }
+
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (typeSelectorDialog != null) typeSelectorDialog.Dispose();
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region necessary code to handle dock correctly regarding the expanded nodes
+    bool[] expandendedState;
+    protected override void OnHandleCreated(EventArgs e) {
+      base.OnHandleCreated(e);
+      if (expandendedState == null) return;
+      var nodes = IterateTreeNodes().ToList();
+      for (int i = 0; i < nodes.Count; i++)
+        if (expandendedState[i]) nodes[i].Expand();
+    }
+    protected override void OnHandleDestroyed(EventArgs e) {
+      base.OnHandleDestroyed(e);
+      var nodes = IterateTreeNodes().ToList();
+      expandendedState = new bool[nodes.Count];
+      for (int i = 0; i < nodes.Count; i++)
+        expandendedState[i] = nodes[i].IsExpanded;
+    }
+    #endregion
+
+    public new Experiment Content {
+      get { return (Experiment)base.Content; }
+      set { base.Content = value; }
+    }
+
+    #region events registration
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ExecutionStateChanged += new EventHandler(Content_ExecutionStateChanged);
+      Content.Optimizers.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
+      Content.Optimizers.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsMoved);
+      Content.Optimizers.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsRemoved);
+      Content.Optimizers.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
+      Content.Optimizers.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_CollectionReset);
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.ExecutionStateChanged -= new EventHandler(Content_ExecutionStateChanged);
+      Content.Optimizers.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
+      Content.Optimizers.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsMoved);
+      Content.Optimizers.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsRemoved);
+      Content.Optimizers.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
+      Content.Optimizers.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_CollectionReset);
+      foreach (var optimizer in treeNodeTagMapping.Keys)
+        DeregisterNamedItemEvents(optimizer);
+      base.DeregisterContentEvents();
+    }
+
+    private void RegisterNamedItemEvents(INamedItem namedItem) {
+      namedItem.ToStringChanged += new EventHandler(namedItem_ToStringChanged);
+      namedItem.ItemImageChanged += new EventHandler(namedItem_ItemImageChanged);
+
+      var algorithm = namedItem as IAlgorithm;
+      var batchRun = namedItem as BatchRun;
+      var experiment = namedItem as Experiment;
+
+      if (algorithm != null) {
+        algorithm.Prepared += new EventHandler(algorithm_Prepared);
+        algorithm.ProblemChanged += new EventHandler(algorithm_ProblemChanged);
+      } else if (batchRun != null) {
+        batchRun.OptimizerChanged += new EventHandler(batchRun_OptimizerChanged);
+        batchRun.RepetetionsCounterChanged += new EventHandler(batchRun_RepetitionsCounterChanged);
+        batchRun.RepetitionsChanged += new EventHandler(batchRun_RepetitionsChanged);
+      } else if (experiment != null) {
+        experiment.Optimizers.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
+        experiment.Optimizers.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsMoved);
+        experiment.Optimizers.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsRemoved);
+        experiment.Optimizers.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
+        experiment.Optimizers.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_CollectionReset);
+      }
+    }
+
+    private void DeregisterNamedItemEvents(INamedItem namedItem) {
+      namedItem.ToStringChanged -= new EventHandler(namedItem_ToStringChanged);
+      namedItem.ItemImageChanged -= new EventHandler(namedItem_ItemImageChanged);
+
+      var algorithm = namedItem as IAlgorithm;
+      var batchRun = namedItem as BatchRun;
+      var experiment = namedItem as Experiment;
+
+      if (algorithm != null) {
+        algorithm.Prepared -= new EventHandler(algorithm_Prepared);
+        algorithm.ProblemChanged -= new EventHandler(algorithm_ProblemChanged);
+      } else if (batchRun != null) {
+        batchRun.OptimizerChanged -= new EventHandler(batchRun_OptimizerChanged);
+        batchRun.RepetetionsCounterChanged -= new EventHandler(batchRun_RepetitionsCounterChanged);
+        batchRun.RepetitionsChanged += new EventHandler(batchRun_RepetitionsChanged);
+      } else if (experiment != null) {
+        experiment.Optimizers.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
+        experiment.Optimizers.ItemsMoved -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsMoved);
+        experiment.Optimizers.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsRemoved);
+        experiment.Optimizers.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
+        experiment.Optimizers.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_CollectionReset);
+      }
+    }
+    #endregion
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        treeView.Nodes.Clear();
+      } else {
+        UpdateOptimizerTreeView();
+        treeView.ExpandAll();
+      }
+    }
+
+    #region content events
+    private void Content_ExecutionStateChanged(object sender, EventArgs e) {
+      if (InvokeRequired) {
+        Invoke((Action<object, EventArgs>)Content_ExecutionStateChanged, sender, e);
+        return;
+      }
+      SetEnabledStateOfControls();
+    }
+
+    private void algorithm_Prepared(object sender, EventArgs e) {
+      var algorithm = (IAlgorithm)sender;
+      foreach (TreeNode node in treeNodeTagMapping[algorithm]) {
+        TreeNode resultsNode = node.Nodes.OfType<TreeNode>().Where(x => x.Tag is ResultCollection).Single();
+        if (detailsViewHost.Content == resultsNode.Tag)
+          detailsViewHost.Content = algorithm.Results;
+        resultsNode.Tag = algorithm.Results;
+      }
+    }
+
+    private void algorithm_ProblemChanged(object sender, EventArgs e) {
+      if (InvokeRequired) {
+        Invoke((Action<object, EventArgs>)algorithm_ProblemChanged, sender, e);
+        return;
+      }
+
+      var algorithm = (IAlgorithm)sender;
+      foreach (TreeNode node in treeNodeTagMapping[algorithm]) {
+        foreach (TreeNode childNode in node.Nodes.OfType<TreeNode>().ToList()) {
+          DisposeTreeNode(childNode);
+          childNode.Remove();
+        }
+        List<TreeNode> nodes;
+        foreach (TreeNode childNode in CreateAlgorithmChildNodes(algorithm)) {
+          node.Nodes.Add(childNode);
+          INamedItem namedItem = childNode.Tag as INamedItem;
+          if (namedItem != null) {
+            if (!treeNodeTagMapping.TryGetValue(namedItem, out nodes)) {
+              nodes = new List<TreeNode>();
+              treeNodeTagMapping.Add(namedItem, nodes);
+              RegisterNamedItemEvents(namedItem);
+            }
+            nodes.Add(childNode);
+          }
+        }
+
+        node.Expand();
+      }
+
+      RebuildImageList();
+      UpdateDetailsViewHost();
+    }
+
+    private void batchRun_OptimizerChanged(object sender, EventArgs e) {
+      if (InvokeRequired) {
+        Invoke((Action<object, EventArgs>)batchRun_OptimizerChanged, sender, e);
+        return;
+      }
+      var batchRun = (BatchRun)sender;
+      foreach (TreeNode node in treeNodeTagMapping[batchRun]) {
+        foreach (TreeNode childNode in node.Nodes.OfType<TreeNode>().ToList()) {
+          DisposeTreeNode(childNode);
+          childNode.Remove();
+        }
+
+        if (batchRun.Optimizer != null) {
+          UpdateChildTreeNodes(node.Nodes, batchRun);
+          node.Expand();
+        }
+      }
+      RebuildImageList();
+      UpdateDetailsViewHost();
+    }
+
+    private void batchRun_RepetitionsCounterChanged(object sender, EventArgs e) {
+      namedItem_ToStringChanged(sender, e);
+    }
+    private void batchRun_RepetitionsChanged(object sender, EventArgs e) {
+      namedItem_ToStringChanged(sender, e);
+    }
+
+    private void Optimizers_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
+      if (InvokeRequired) {
+        Invoke((Action<object, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>>>)Optimizers_ItemsAdded, sender, e);
+        return;
+      }
+
+      var optimizerList = (OptimizerList)sender;
+      IEnumerable<TreeNodeCollection> parentNodes;
+      if (optimizerList == Content.Optimizers) parentNodes = new List<TreeNodeCollection>() { treeView.Nodes };
+      else {
+        Experiment experiment = treeNodeTagMapping.Keys.OfType<Experiment>().Where(exp => exp.Optimizers == optimizerList).First();
+        parentNodes = treeNodeTagMapping[experiment].Select(node => node.Nodes);
+      }
+
+      foreach (TreeNodeCollection parentNode in parentNodes) {
+        foreach (var childOptimizer in e.Items) {
+          TreeNode childNode = CreateTreeNode(childOptimizer.Value);
+          UpdateChildTreeNodes(childNode.Nodes, childOptimizer.Value);
+          parentNode.Insert(childOptimizer.Index, childNode);
+          childNode.ExpandAll();
+          if (childNode.Parent != null) childNode.Parent.ExpandAll();
+        }
+      }
+      RebuildImageList();
+    }
+    private void Optimizers_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
+      if (InvokeRequired) {
+        Invoke((Action<object, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>>>)Optimizers_ItemsMoved, sender, e);
+        return;
+      }
+
+      var optimizerList = (OptimizerList)sender;
+      IEnumerable<TreeNodeCollection> parentNodes;
+      if (optimizerList == Content.Optimizers) parentNodes = new List<TreeNodeCollection>() { treeView.Nodes };
+      else {
+        Experiment experiment = treeNodeTagMapping.Keys.OfType<Experiment>().Where(exp => exp.Optimizers == optimizerList).First();
+        parentNodes = treeNodeTagMapping[experiment].Select(node => node.Nodes);
+      }
+
+      foreach (TreeNodeCollection parentNode in parentNodes) {
+        var backup = parentNode.OfType<TreeNode>().ToList();
+        foreach (var indexedItem in e.Items) {
+          var node = backup.Where(n => n.Tag == indexedItem.Value).First();
+          node.Remove();
+          parentNode.Insert(indexedItem.Index, node);
+        }
+      }
+    }
+    private void Optimizers_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
+      if (InvokeRequired) {
+        Invoke((Action<object, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>>>)Optimizers_ItemsRemoved, sender, e);
+        return;
+      }
+
+      var optimizerList = (OptimizerList)sender;
+      IEnumerable<TreeNodeCollection> parentNodes;
+      if (optimizerList == Content.Optimizers) parentNodes = new List<TreeNodeCollection>() { treeView.Nodes };
+      else {
+        Experiment experiment = treeNodeTagMapping.Keys.OfType<Experiment>().Where(exp => exp.Optimizers == optimizerList).First();
+        parentNodes = treeNodeTagMapping[experiment].Select(node => node.Nodes);
+      }
+
+      foreach (TreeNodeCollection parentNode in parentNodes) {
+        foreach (var childOptimizer in e.Items) {
+          TreeNode childNode = parentNode[childOptimizer.Index];
+          DisposeTreeNode(childNode);
+          childNode.Remove();
+        }
+      }
+      RebuildImageList();
+      UpdateDetailsViewHost();
+    }
+    private void Optimizers_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
+      if (InvokeRequired) {
+        Invoke((Action<object, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>>>)Optimizers_ItemsReplaced, sender, e);
+        return;
+      }
+
+      var optimizerList = (OptimizerList)sender;
+      IEnumerable<TreeNodeCollection> parentNodes;
+      if (optimizerList == Content.Optimizers) parentNodes = new List<TreeNodeCollection>() { treeView.Nodes };
+      else {
+        Experiment experiment = treeNodeTagMapping.Keys.OfType<Experiment>().Where(exp => exp.Optimizers == optimizerList).First();
+        parentNodes = treeNodeTagMapping[experiment].Select(node => node.Nodes);
+      }
+
+      foreach (TreeNodeCollection parentNode in parentNodes) {
+        foreach (var childOptimizer in e.OldItems) {
+          TreeNode childNode = parentNode.Cast<TreeNode>().Where(n => n.Tag == childOptimizer.Value && n.Index == childOptimizer.Index).First();
+          DisposeTreeNode(childNode);
+          childNode.Remove();
+        }
+        foreach (var childOptimizer in e.Items) {
+          TreeNode childNode = CreateTreeNode(childOptimizer.Value);
+          UpdateChildTreeNodes(childNode.Nodes, childOptimizer.Value);
+          parentNode.Insert(childOptimizer.Index, childNode);
+        }
+      }
+      RebuildImageList();
+      UpdateDetailsViewHost();
+    }
+    private void Optimizers_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
+      if (InvokeRequired) {
+        Invoke((Action<object, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>>>)Optimizers_CollectionReset, sender, e);
+        return;
+      }
+
+      var optimizerList = (OptimizerList)sender;
+      IEnumerable<TreeNodeCollection> parentNodes;
+      if (optimizerList == Content.Optimizers) parentNodes = new List<TreeNodeCollection>() { treeView.Nodes };
+      else {
+        Experiment experiment = treeNodeTagMapping.Keys.OfType<Experiment>().Where(exp => exp.Optimizers == optimizerList).First();
+        parentNodes = treeNodeTagMapping[experiment].Select(node => node.Nodes);
+      }
+
+      foreach (TreeNodeCollection parentNode in parentNodes) {
+        foreach (var childOptimizer in e.OldItems) {
+          TreeNode childNode = parentNode.Cast<TreeNode>().Where(n => n.Tag == childOptimizer.Value && n.Index == childOptimizer.Index).First();
+          DisposeTreeNode(childNode);
+          childNode.Remove();
+        }
+        foreach (var childOptimizer in e.Items) {
+          TreeNode childNode = CreateTreeNode(childOptimizer.Value);
+          UpdateChildTreeNodes(childNode.Nodes, childOptimizer.Value);
+          parentNode.Insert(childOptimizer.Index, childNode);
+        }
+      }
+      RebuildImageList();
+      UpdateDetailsViewHost();
+    }
+
+    private void namedItem_ToStringChanged(object sender, EventArgs e) {
+      if (InvokeRequired) {
+        Invoke((Action<object, EventArgs>)namedItem_ToStringChanged, sender, e);
+        return;
+      }
+      var namedItem = (INamedItem)sender;
+      foreach (TreeNode node in treeNodeTagMapping[namedItem]) {
+        node.Text = namedItem.ToString();
+        var batchRun = namedItem as BatchRun;
+        if (batchRun != null)
+          node.Text += string.Format(" {0}/{1}", batchRun.RepetitionsCounter, batchRun.Repetitions);
+      }
+    }
+
+    private void namedItem_ItemImageChanged(object sender, EventArgs e) {
+      if (InvokeRequired) {
+        Invoke((Action<object, EventArgs>)namedItem_ItemImageChanged, sender, e);
+        return;
+      }
+      INamedItem namedItem = (INamedItem)sender;
+      foreach (TreeNode node in treeNodeTagMapping[namedItem]) {
+        treeView.ImageList.Images[node.ImageIndex] = namedItem.ItemImage;
+        node.ImageIndex = node.ImageIndex;
+      }
+      SetEnabledStateOfControls();
+    }
+    #endregion
+
+    protected override void PropagateStateChanges(Control control, Type type, System.Reflection.PropertyInfo propertyInfo) {
+      return;
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      IOptimizer optimizer = null;
+      IAlgorithm algorithm = null;
+      BatchRun batchRun = null;
+      Experiment experiment = null;
+
+      IOptimizer parentOptimizer = null;
+      Experiment parentExperiment = null;
+
+      if (treeView.SelectedNode != null) {
+        optimizer = treeView.SelectedNode.Tag as IOptimizer;
+        algorithm = optimizer as IAlgorithm;
+        batchRun = optimizer as BatchRun;
+        experiment = optimizer as Experiment;
+
+        if (treeView.SelectedNode.Parent != null) parentOptimizer = treeView.SelectedNode.Parent.Tag as IOptimizer;
+        else parentOptimizer = Content;
+
+        parentExperiment = parentOptimizer as Experiment;
+      }
+
+      treeView.Enabled = Content != null;
+      if (parentOptimizer != null) {
+        detailsViewHost.ReadOnly = parentOptimizer.ExecutionState == ExecutionState.Started;
+        detailsViewHost.Locked = parentOptimizer.ExecutionState == ExecutionState.Started;
+      }
+
+      addButton.Enabled = Content != null && !Locked && !ReadOnly &&
+        (treeView.SelectedNode == null || experiment != null || batchRun != null || algorithm != null);
+      moveUpButton.Enabled = Content != null && !Locked && !ReadOnly &&
+        treeView.SelectedNode != null && treeView.SelectedNode.PrevNode != null && parentExperiment != null;
+      moveDownButton.Enabled = Content != null && !Locked && !ReadOnly &&
+        treeView.SelectedNode != null && treeView.SelectedNode.NextNode != null && parentExperiment != null;
+      removeButton.Enabled = Content != null && !Locked && !ReadOnly && optimizer != null;
+    }
+
+    private void UpdateOptimizerTreeView() {
+      treeView.Nodes.Clear();
+      UpdateChildTreeNodes(treeView.Nodes, Content);
+      RebuildImageList();
+    }
+
+    private void UpdateChildTreeNodes(TreeNodeCollection collection, IOptimizer optimizer) {
+      var batchRun = optimizer as BatchRun;
+      var experiment = optimizer as Experiment;
+
+      if (batchRun != null && batchRun.Optimizer != null) UpdateChildTreeNodes(collection, new List<IOptimizer>() { batchRun.Optimizer });
+      else if (experiment != null) UpdateChildTreeNodes(collection, experiment.Optimizers);
+    }
+    private void UpdateChildTreeNodes(TreeNodeCollection collection, IEnumerable<IOptimizer> optimizers) {
+      foreach (IOptimizer optimizer in optimizers) {
+        var node = CreateTreeNode(optimizer);
+        collection.Add(node);
+        UpdateChildTreeNodes(node.Nodes, optimizer);
+      }
+    }
+
+
+    #region drag & drop
+    private void optimizerTreeView_ItemDrag(object sender, ItemDragEventArgs e) {
+      if (Locked) return;
+
+      TreeNode selectedNode = (TreeNode)e.Item;
+      var item = (IItem)selectedNode.Tag;
+      if (item == null) return;
+
+      DataObject data = new DataObject();
+      data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, item);
+      validDragOperation = true;
+
+      if (ReadOnly || !(item is IOptimizer)) {
+        DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link);
+      } else {
+        DragDropEffects result = DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link | DragDropEffects.Move);
+        if ((result & DragDropEffects.Move) == DragDropEffects.Move) {
+          var optimizer = (IOptimizer)item;
+          if (selectedNode.Parent == null) Content.Optimizers.Remove(optimizer);
+          else {
+            var parentOptimizer = (IOptimizer)selectedNode.Parent.Tag;
+            var parentBatchRun = parentOptimizer as BatchRun;
+            var parentExperiment = parentOptimizer as Experiment;
+            if (parentBatchRun != null) parentBatchRun.Optimizer = null;
+            else if (parentExperiment != null) parentExperiment.Optimizers.Remove(optimizer);
+            else throw new NotSupportedException("Handling for specific type not implemented" + parentOptimizer.GetType());
+          }
+        }
+      }
+    }
+
+    private bool validDragOperation = false;
+    private void optimizerTreeView_DragEnter(object sender, DragEventArgs e) {
+      validDragOperation = false;
+      if (!ReadOnly) {
+        var data = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+        if (data is IOptimizer) validDragOperation = true;
+        else if (data is IProblem) validDragOperation = true;
+        else if (data is IEnumerable) {
+          IEnumerable items = (IEnumerable)data;
+          validDragOperation = true;
+          foreach (object item in items)
+            validDragOperation = validDragOperation && (item is IOptimizer);
+        }
+      }
+    }
+    private void optimizerTreeView_DragOver(object sender, DragEventArgs e) {
+      e.Effect = DragDropEffects.None;
+      if (!validDragOperation) return;
+      Point coordinates = treeView.PointToClient(new Point(e.X, e.Y));
+      TreeNode node = treeView.GetNodeAt(coordinates);
+      Experiment experiment = null;
+      BatchRun batchRun = null;
+      Algorithm algorithm = null;
+
+      if (node == null) experiment = Content;
+      else {
+        experiment = node.Tag as Experiment;
+        batchRun = node.Tag as BatchRun;
+        algorithm = node.Tag as Algorithm;
+      }
+
+      if (batchRun == null && experiment == null && algorithm == null) return;
+
+      var data = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+
+      if (algorithm != null) {
+        var problem = data as IProblem;
+        if (problem == null) return;
+        if (!algorithm.ProblemType.IsAssignableFrom(problem.GetType())) return;
+      } else if (batchRun != null) {
+        var optimizer = data as IOptimizer;
+        if (optimizer == null) return;
+        if (batchRun == optimizer) return;
+        if (optimizer.NestedOptimizers.Contains(batchRun)) return;
+      } //do not allow recursive nesting of contents
+      else if (experiment != null) {
+        var optimizer = data as IOptimizer;
+        IEnumerable<IOptimizer> optimizers = null;
+        var enumerable = data as IEnumerable;
+        if (enumerable != null) optimizers = enumerable.Cast<IOptimizer>();
+        if (experiment == optimizer) return;
+        if (optimizer != null && optimizer.NestedOptimizers.Contains(experiment)) return;
+        if (optimizers != null && optimizers.Any(x => x.NestedOptimizers.Contains(experiment))) return;
+      }
+
+      if ((e.KeyState & 32) == 32 && e.AllowedEffect.HasFlag(DragDropEffects.Link)) e.Effect = DragDropEffects.Link;  // ALT key
+      else if ((e.KeyState & 4) == 4 && e.AllowedEffect.HasFlag(DragDropEffects.Move)) e.Effect = DragDropEffects.Move;  // SHIFT key
+      else if (e.AllowedEffect.HasFlag(DragDropEffects.Copy)) e.Effect = DragDropEffects.Copy;
+      else if (e.AllowedEffect.HasFlag(DragDropEffects.Move)) e.Effect = DragDropEffects.Move;
+      else if (e.AllowedEffect.HasFlag(DragDropEffects.Link)) e.Effect = DragDropEffects.Link;
+    }
+
+    private void optimizerTreeView_DragDrop(object sender, DragEventArgs e) {
+      Point coordinates = treeView.PointToClient(new Point(e.X, e.Y));
+      TreeNode node = treeView.GetNodeAt(coordinates);
+      Algorithm algorithm = null;
+      BatchRun batchRun = null;
+      Experiment experiment = null;
+
+      if (node == null) experiment = Content;
+      else {
+        algorithm = node.Tag as Algorithm;
+        batchRun = node.Tag as BatchRun;
+        experiment = node.Tag as Experiment;
+      }
+
+      var data = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+      if (data is IProblem) {
+        var problem = (IProblem)data;
+        if (e.Effect.HasFlag(DragDropEffects.Copy)) problem = (IProblem)problem.Clone();
+        algorithm.Problem = problem;
+      } else if (data is IOptimizer) {
+        IOptimizer optimizer = (IOptimizer)data;
+        if (e.Effect.HasFlag(DragDropEffects.Copy)) optimizer = (IOptimizer)optimizer.Clone();
+        if (batchRun != null) batchRun.Optimizer = optimizer;
+        else if (experiment != null) experiment.Optimizers.Add(optimizer);
+        else throw new NotSupportedException("Handling for specific type not implemented" + node.Tag.GetType());
+      } else if (data is IEnumerable) {
+        IEnumerable<IOptimizer> optimizers = ((IEnumerable)data).Cast<IOptimizer>();
+        if (e.Effect.HasFlag(DragDropEffects.Copy)) {
+          Cloner cloner = new Cloner();
+          optimizers = optimizers.Select(o => cloner.Clone(o));
+        }
+        if (experiment != null) experiment.Optimizers.AddRange(optimizers);
+        else throw new NotSupportedException("Handling for specific type not implemented" + node.Tag.GetType());
+      }
+    }
+    #endregion
+
+    #region control events
+    private void treeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) {
+      if (rightClickOccured) return;
+      if (e.X < e.Node.Bounds.Left - treeView.ImageList.Images[e.Node.ImageIndex].Width || e.X > e.Node.Bounds.Right) return;
+      e.Node.Toggle();
+      IContent optimizer = (IContent)e.Node.Tag;
+      MainFormManager.MainForm.ShowContent(optimizer);
+    }
+    private void treeview_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) {
+      if (e.X < e.Node.Bounds.Left - treeView.ImageList.Images[e.Node.ImageIndex].Width || e.X > e.Node.Bounds.Right) return;
+      treeView.SelectedNode = e.Node;
+      detailsViewHost.Content = (IContent)e.Node.Tag;
+      SetEnabledStateOfControls();
+    }
+    private void treeView_MouseDown(object sender, MouseEventArgs e) {
+      // enables deselection of treeNodes
+      if (e.Button != MouseButtons.Right) rightClickOccured = false;
+      if (treeView.SelectedNode == null) return;
+      Point coordinates = new Point(e.X, e.Y);
+      TreeNode node = treeView.GetNodeAt(coordinates);
+      if (node == null || coordinates.X < node.Bounds.Left - treeView.ImageList.Images[node.ImageIndex].Width || coordinates.X > node.Bounds.Right) {
+        treeView.SelectedNode = null;
+        detailsViewHost.Content = null;
+        SetEnabledStateOfControls();
+      }
+    }
+
+
+    private void treeView_KeyDown(object sender, KeyEventArgs e) {
+      if (Locked || ReadOnly) return;
+      if (treeView.SelectedNode == null) return;
+      if (!(treeView.SelectedNode.Tag is INamedItem)) return;
+
+      var treeNode = treeView.SelectedNode;
+      var namedItem = (INamedItem)treeNode.Tag;
+      var optimizer = namedItem as IOptimizer;
+
+      if (e.KeyCode == Keys.Delete && optimizer != null) {
+        if (treeNode.Parent == null)
+          Content.Optimizers.Remove(optimizer);
+        else {
+          var batchRun = treeNode.Parent.Tag as BatchRun;
+          var experiment = treeNode.Parent.Tag as Experiment;
+          if (batchRun != null) batchRun.Optimizer = null;
+          else if (experiment != null) experiment.Optimizers.Remove(optimizer);
+          else throw new NotSupportedException("Handling for specific type not implemented" + treeView.SelectedNode.Tag.GetType());
+        }
+        SetEnabledStateOfControls();
+        UpdateDetailsViewHost();
+        RebuildImageList();
+      }
+    }
+
+
+    private void treeView_AfterSelect(object sender, TreeViewEventArgs e) {
+      if (e.Action == TreeViewAction.ByKeyboard) {
+        UpdateDetailsViewHost();
+        //NOTE: necessary because algorithm view steals the focus
+        treeView.Focus();
+      }
+    }
+
+    private bool rightClickOccured = true;
+    private TreeNode toolStripMenuNode = null;
+    private void treeView_RightClick(object sender, EventArgs e) {
+      rightClickOccured = true;
+      Point coordinates = treeView.PointToClient(Cursor.Position);
+      toolStripMenuNode = treeView.GetNodeAt(coordinates);
+
+      if (toolStripMenuNode != null && coordinates.X >= toolStripMenuNode.Bounds.Left && coordinates.X <= toolStripMenuNode.Bounds.Right) {
+        treeView.SelectedNode = toolStripMenuNode;
+        detailsViewHost.Content = (IContent)toolStripMenuNode.Tag;
+        SetEnabledStateOfControls();
+
+        ExpandToolStripMenuItem.Enabled = ExpandToolStripMenuItem.Visible = !toolStripMenuNode.IsExpanded && toolStripMenuNode.Nodes.Count > 0;
+        CollapseToolStripMenuItem.Enabled = CollapseToolStripMenuItem.Visible = toolStripMenuNode.IsExpanded;
+        EditNodeLabelToolStripMenuItem.Enabled = EditNodeLabelToolStripMenuItem.Visible = !Locked && !ReadOnly && toolStripMenuNode.Tag != null && toolStripMenuNode.Tag is INamedItem && ((INamedItem)toolStripMenuNode.Tag).CanChangeName;
+      } else {
+        ExpandToolStripMenuItem.Enabled = ExpandToolStripMenuItem.Visible = false;
+        CollapseToolStripMenuItem.Enabled = CollapseToolStripMenuItem.Visible = false;
+        EditNodeLabelToolStripMenuItem.Enabled = EditNodeLabelToolStripMenuItem.Visible = false;
+      }
+      ExpandAllToolStripMenuItem.Enabled = ExpandAllToolStripMenuItem.Visible = !treeView.Nodes.OfType<TreeNode>().All(x => TreeNodeIsFullyExpanded(x));
+      CollapseAllToolStripMenuItem.Enabled = CollapseAllToolStripMenuItem.Visible = treeView.Nodes.OfType<TreeNode>().Any(x => x.IsExpanded);
+      if (contextMenuStrip.Items.Cast<ToolStripMenuItem>().Any(item => item.Enabled))
+        contextMenuStrip.Show(Cursor.Position);
+    }
+
+    private void ExpandToolStripMenuItem_Click(object sender, EventArgs e) {
+      if (toolStripMenuNode != null) toolStripMenuNode.ExpandAll();
+    }
+    private void ExpandAllToolStripMenuItem_Click(object sender, EventArgs e) {
+      treeView.ExpandAll();
+    }
+    private void CollapseToolStripMenuItem_Click(object sender, EventArgs e) {
+      if (toolStripMenuNode != null) toolStripMenuNode.Collapse();
+    }
+    private void CollapseAllToolStripMenuItem_Click(object sender, EventArgs e) {
+      treeView.CollapseAll();
+    }
+    private void EditNodeLabelToolStripMenuItem_Click(object sender, EventArgs e) {
+      if (toolStripMenuNode != null) {
+        if (!toolStripMenuNode.IsEditing) toolStripMenuNode.BeginEdit();
+      }
+    }
+
+    private void addButton_Click(object sender, System.EventArgs e) {
+      if (typeSelectorDialog == null) typeSelectorDialog = new TypeSelectorDialog();
+
+      IAlgorithm algorithm = null;
+      if (treeView.SelectedNode != null && (treeView.SelectedNode.Tag is IAlgorithm))
+        algorithm = (IAlgorithm)treeView.SelectedNode.Tag;
+
+      if (algorithm == null) {
+        typeSelectorDialog.Caption = "Select Optimizer";
+        typeSelectorDialog.TypeSelector.Caption = "Available Optimizers";
+        typeSelectorDialog.TypeSelector.Configure(typeof(IOptimizer), false, true);
+      } else {
+        typeSelectorDialog.Caption = "Select Problem";
+        typeSelectorDialog.TypeSelector.Caption = "Available Problems";
+        typeSelectorDialog.TypeSelector.Configure(algorithm.ProblemType, false, true);
+      }
+
+      if (typeSelectorDialog.ShowDialog(this) == DialogResult.OK) {
+        try {
+          if (algorithm == null) {
+            IOptimizer optimizer = (IOptimizer)typeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
+            if (treeView.SelectedNode == null) Content.Optimizers.Add(optimizer);
+            else {
+              var batchRun = treeView.SelectedNode.Tag as BatchRun;
+              var experiment = treeView.SelectedNode.Tag as Experiment;
+              if (batchRun != null) batchRun.Optimizer = optimizer;
+              else if (experiment != null) experiment.Optimizers.Add(optimizer);
+              else throw new NotSupportedException("Handling for specific type not implemented" + treeView.SelectedNode.Tag.GetType());
+            }
+          } else {
+            IProblem problem = (IProblem)typeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
+            algorithm.Problem = problem;
+          }
+        }
+        catch (Exception ex) {
+          ErrorHandling.ShowErrorDialog(this, ex);
+        }
+      }
+    }
+
+    private void moveUpButton_Click(object sender, EventArgs e) {
+      var optimizer = (IOptimizer)treeView.SelectedNode.Tag;
+      Experiment experiment = null;
+      if (treeView.SelectedNode.Parent == null) experiment = Content;
+      else experiment = (Experiment)treeView.SelectedNode.Parent.Tag;
+
+      var selectedNode = treeView.SelectedNode;
+      int index = treeView.SelectedNode.Index;
+      experiment.Optimizers.Reverse(index - 1, 2);
+      treeView.SelectedNode = selectedNode;
+      SetEnabledStateOfControls();
+    }
+    private void moveDownButton_Click(object sender, EventArgs e) {
+      var optimizer = (IOptimizer)treeView.SelectedNode.Tag;
+      Experiment experiment = null;
+      if (treeView.SelectedNode.Parent == null) experiment = Content;
+      else experiment = (Experiment)treeView.SelectedNode.Parent.Tag;
+
+      var selectedNode = treeView.SelectedNode;
+      int index = treeView.SelectedNode.Index;
+      experiment.Optimizers.Reverse(index, 2);
+      treeView.SelectedNode = selectedNode;
+      SetEnabledStateOfControls();
+    }
+
+    private void removeButton_Click(object sender, EventArgs e) {
+      var treeNode = treeView.SelectedNode;
+      var optimizer = treeNode.Tag as IOptimizer;
+
+      if (treeNode.Parent == null)
+        Content.Optimizers.Remove(optimizer);
+      else {
+        var batchRun = treeNode.Parent.Tag as BatchRun;
+        var experiment = treeNode.Parent.Tag as Experiment;
+        if (batchRun != null) batchRun.Optimizer = null;
+        else if (experiment != null) experiment.Optimizers.Remove(optimizer);
+        else throw new NotSupportedException("Handling for specific type not implemented" + treeView.SelectedNode.Tag.GetType());
+      }
+      SetEnabledStateOfControls();
+      UpdateDetailsViewHost();
+      RebuildImageList();
+    }
+
+    private void showDetailsCheckBox_CheckedChanged(object sender, System.EventArgs e) {
+      if (showDetailsCheckBox.Checked) {
+        splitContainer.Panel2Collapsed = false;
+        detailsGroupBox.Enabled = treeView.SelectedNode != null;
+        detailsViewHost.Content = treeView.SelectedNode != null ? (IContent)treeView.SelectedNode.Tag : null;
+      } else {
+        splitContainer.Panel2Collapsed = true;
+        detailsViewHost.Content = null;
+      }
+    }
+    #endregion
+
+    #region helpers
+    private void UpdateDetailsViewHost() {
+      if (treeView.SelectedNode != null)
+        detailsViewHost.Content = (IContent)treeView.SelectedNode.Tag;
+      else
+        detailsViewHost.Content = null;
+    }
+
+    private TreeNode CreateTreeNode(IOptimizer optimizer) {
+      TreeNode node = new TreeNode(optimizer.ToString());
+      node.Tag = optimizer;
+
+      var algorithm = optimizer as IAlgorithm;
+      if (algorithm != null) {
+        foreach (TreeNode childNode in CreateAlgorithmChildNodes(algorithm))
+          node.Nodes.Add(childNode);
+      }
+      var batchRun = optimizer as BatchRun;
+      if (batchRun != null) {
+        node.Text += string.Format(" {0}/{1}", batchRun.RepetitionsCounter, batchRun.Repetitions);
+      }
+
+      List<TreeNode> nodes;
+      if (!treeNodeTagMapping.TryGetValue(optimizer, out nodes)) {
+        nodes = new List<TreeNode>();
+        treeNodeTagMapping.Add(optimizer, nodes);
+        RegisterNamedItemEvents(optimizer);
+      }
+      nodes.Add(node);
+
+      foreach (TreeNode childNode in node.Nodes) {
+        INamedItem namedItem = childNode.Tag as INamedItem;
+        if (namedItem != null) {
+          if (!treeNodeTagMapping.TryGetValue(namedItem, out nodes)) {
+            nodes = new List<TreeNode>();
+            treeNodeTagMapping.Add(namedItem, nodes);
+            RegisterNamedItemEvents(namedItem);
+          }
+          nodes.Add(childNode);
+        }
+      }
+      return node;
+    }
+
+    private IEnumerable<TreeNode> CreateAlgorithmChildNodes(IAlgorithm algorithm) {
+      TreeNode problemNode;
+      if (algorithm.Problem != null) {
+        problemNode = new TreeNode(algorithm.Problem.Name);
+        problemNode.Tag = algorithm.Problem;
+      } else {
+        problemNode = new TreeNode("No Problem");
+        problemNode.Tag = null;
+      }
+      TreeNode parametersNode = new TreeNode("Parameters");
+      parametersNode.Tag = algorithm.Parameters;
+      TreeNode resultsNode = new TreeNode("Results");
+      resultsNode.Tag = algorithm.Results;
+
+      yield return problemNode;
+      yield return parametersNode;
+      yield return resultsNode;
+    }
+
+    private void DisposeTreeNode(TreeNode node) {
+      var namedItem = node.Tag as INamedItem;
+      if (namedItem == null) return;
+
+      List<TreeNode> nodes;
+      if (!treeNodeTagMapping.TryGetValue(namedItem, out nodes))
+        throw new ArgumentException();
+      nodes.Remove(node);
+      if (nodes.Count == 0) {
+        treeNodeTagMapping.Remove(namedItem);
+        DeregisterNamedItemEvents(namedItem);
+      }
+    }
+
+    private IEnumerable<TreeNode> IterateTreeNodes(TreeNode node = null) {
+      TreeNodeCollection nodes;
+      if (node == null)
+        nodes = treeView.Nodes;
+      else {
+        nodes = node.Nodes;
+        yield return node;
+      }
+
+      foreach (var childNode in nodes.OfType<TreeNode>())
+        foreach (var n in IterateTreeNodes(childNode))
+          yield return n;
+    }
+
+    private bool TreeNodeIsFullyExpanded(TreeNode node) {
+      return (node.Nodes.Count == 0) || (node.IsExpanded && node.Nodes.OfType<TreeNode>().All(x => TreeNodeIsFullyExpanded(x)));
+    }
+
+    private void RebuildImageList() {
+      if (InvokeRequired) {
+        Invoke((Action)RebuildImageList);
+        return;
+      }
+
+      treeView.BeginUpdate();
+
+      treeView.ImageList.Images.Clear();
+      var topLevelNodes = treeView.Nodes.OfType<TreeNode>().ToArray();
+      var nodes = IterateTreeNodes().ToList();
+      var selectedNode = treeView.SelectedNode;
+      treeView.Nodes.Clear();
+
+      foreach (TreeNode treeNode in nodes) {
+        var item = (IItem)treeNode.Tag;
+        treeView.ImageList.Images.Add(item == null ? HeuristicLab.Common.Resources.VSImageLibrary.Nothing : item.ItemImage);
+        treeNode.ImageIndex = treeView.ImageList.Images.Count - 1;
+        treeNode.SelectedImageIndex = treeNode.ImageIndex;
+      }
+      treeView.Nodes.AddRange(topLevelNodes);
+      treeView.SelectedNode = selectedNode;
+      treeView.EndUpdate();
+    }
+    #endregion
+
+
+    public sealed class CustomTreeView : System.Windows.Forms.TreeView {
+      protected override void WndProc(ref System.Windows.Forms.Message m) {
+        const int WM_RBUTTONDOWN = 0x204;
+        if (m.Msg == WM_RBUTTONDOWN) {
+          //Raise your custom event right click event to prevent node highlighting
+          OnRightClick();
+          return;
+        }
+        base.WndProc(ref m);
+      }
+
+      public event EventHandler RightClick;
+      private void OnRightClick() {
+        var handler = RightClick;
+        if (handler != null) RightClick(this, EventArgs.Empty);
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ExperimentView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ExperimentView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ExperimentView.Designer.cs	(revision 12764)
@@ -0,0 +1,194 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class ExperimentView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.tabControl = new HeuristicLab.MainForm.WindowsForms.DragOverTabControl();
+      this.optimizersTabPage = new System.Windows.Forms.TabPage();
+      this.runsTabPage = new System.Windows.Forms.TabPage();
+      this.runsViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.experimentTreeView = new HeuristicLab.Optimization.Views.ExperimentTreeView();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.tabControl.SuspendLayout();
+      this.optimizersTabPage.SuspendLayout();
+      this.runsTabPage.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // startButton
+      // 
+      this.startButton.Location = new System.Drawing.Point(0, 458);
+      this.toolTip.SetToolTip(this.startButton, "Start/Resume Experiment");
+      // 
+      // executionTimeTextBox
+      // 
+      this.executionTimeTextBox.Location = new System.Drawing.Point(542, 461);
+      // 
+      // executionTimeLabel
+      // 
+      this.executionTimeLabel.Location = new System.Drawing.Point(453, 464);
+      // 
+      // pauseButton
+      // 
+      this.pauseButton.Location = new System.Drawing.Point(30, 458);
+      this.toolTip.SetToolTip(this.pauseButton, "Pause Experiment");
+      // 
+      // stopButton
+      // 
+      this.stopButton.Location = new System.Drawing.Point(60, 458);
+      this.toolTip.SetToolTip(this.stopButton, "Stop Experiment");
+      // 
+      // resetButton
+      // 
+      this.resetButton.Location = new System.Drawing.Point(90, 458);
+      this.toolTip.SetToolTip(this.resetButton, "Reset Experiment");
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      this.nameTextBox.Location = new System.Drawing.Point(60, 0);
+      this.nameTextBox.Size = new System.Drawing.Size(594, 20);
+      // 
+      // infoLabel
+      // 
+      this.infoLabel.Location = new System.Drawing.Point(660, 3);
+      // 
+      // tabControl
+      // 
+      this.tabControl.AllowDrop = true;
+      this.tabControl.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.tabControl.Controls.Add(this.optimizersTabPage);
+      this.tabControl.Controls.Add(this.runsTabPage);
+      this.tabControl.Location = new System.Drawing.Point(0, 26);
+      this.tabControl.Name = "tabControl";
+      this.tabControl.SelectedIndex = 0;
+      this.tabControl.Size = new System.Drawing.Size(679, 427);
+      this.tabControl.TabIndex = 3;
+      // 
+      // optimizersTabPage
+      // 
+      this.optimizersTabPage.Controls.Add(this.experimentTreeView);
+      this.optimizersTabPage.Location = new System.Drawing.Point(4, 22);
+      this.optimizersTabPage.Name = "optimizersTabPage";
+      this.optimizersTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.optimizersTabPage.Size = new System.Drawing.Size(671, 401);
+      this.optimizersTabPage.TabIndex = 1;
+      this.optimizersTabPage.Text = "Optimizers";
+      this.optimizersTabPage.UseVisualStyleBackColor = true;
+      // 
+      // runsTabPage
+      // 
+      this.runsTabPage.Controls.Add(this.runsViewHost);
+      this.runsTabPage.Location = new System.Drawing.Point(4, 22);
+      this.runsTabPage.Name = "runsTabPage";
+      this.runsTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.runsTabPage.Size = new System.Drawing.Size(671, 401);
+      this.runsTabPage.TabIndex = 2;
+      this.runsTabPage.Text = "Runs";
+      this.runsTabPage.UseVisualStyleBackColor = true;
+      // 
+      // runsViewHost
+      // 
+      this.runsViewHost.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.runsViewHost.Caption = "View";
+      this.runsViewHost.Content = null;
+      this.runsViewHost.Enabled = false;
+      this.runsViewHost.Location = new System.Drawing.Point(2, 6);
+      this.runsViewHost.Name = "runsViewHost";
+      this.runsViewHost.ReadOnly = false;
+      this.runsViewHost.Size = new System.Drawing.Size(657, 389);
+      this.runsViewHost.TabIndex = 0;
+      this.runsViewHost.ViewsLabelVisible = true;
+      this.runsViewHost.ViewType = null;
+      // 
+      // experimentTreeView
+      // 
+      this.experimentTreeView.Caption = "Experiment View";
+      this.experimentTreeView.Content = null;
+      this.experimentTreeView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.experimentTreeView.Location = new System.Drawing.Point(3, 3);
+      this.experimentTreeView.Name = "experimentTreeView";
+      this.experimentTreeView.ReadOnly = false;
+      this.experimentTreeView.Size = new System.Drawing.Size(665, 395);
+      this.experimentTreeView.TabIndex = 0;
+      // 
+      // ExperimentView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.tabControl);
+      this.Name = "ExperimentView";
+      this.Size = new System.Drawing.Size(679, 482);
+      this.Controls.SetChildIndex(this.resetButton, 0);
+      this.Controls.SetChildIndex(this.stopButton, 0);
+      this.Controls.SetChildIndex(this.pauseButton, 0);
+      this.Controls.SetChildIndex(this.tabControl, 0);
+      this.Controls.SetChildIndex(this.executionTimeLabel, 0);
+      this.Controls.SetChildIndex(this.executionTimeTextBox, 0);
+      this.Controls.SetChildIndex(this.startButton, 0);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.tabControl.ResumeLayout(false);
+      this.optimizersTabPage.ResumeLayout(false);
+      this.runsTabPage.ResumeLayout(false);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+    #endregion
+
+    private HeuristicLab.MainForm.WindowsForms.DragOverTabControl tabControl;
+    private System.Windows.Forms.TabPage optimizersTabPage;
+    private System.Windows.Forms.TabPage runsTabPage;
+    private HeuristicLab.MainForm.WindowsForms.ViewHost runsViewHost;
+    private ExperimentTreeView experimentTreeView;
+
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ExperimentView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ExperimentView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ExperimentView.cs	(revision 12764)
@@ -0,0 +1,69 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("Experiment View")]
+  [Content(typeof(Experiment), true)]
+  public sealed partial class ExperimentView : IOptimizerView {
+    public ExperimentView() {
+      InitializeComponent();
+    }
+
+    public new Experiment Content {
+      get { return (Experiment)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        experimentTreeView.Content = null;
+        runsViewHost.Content = null;
+      } else {
+        experimentTreeView.Content = Content;
+        runsViewHost.Content = Content.Runs;
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      experimentTreeView.Enabled = Content != null;
+      runsViewHost.Enabled = Content != null;
+    }
+
+    protected override void OnClosed(FormClosedEventArgs e) {
+      if ((Content != null) && (Content.ExecutionState == ExecutionState.Started)) {
+        //The content must be stopped if no other view showing the content is available
+        var optimizers = MainFormManager.MainForm.Views.OfType<IContentView>().Where(v => v != this).Select(v => v.Content).OfType<IOptimizer>();
+        if (!optimizers.Contains(Content)) {
+          var nestedOptimizers = optimizers.SelectMany(opt => opt.NestedOptimizers);
+          if (!nestedOptimizers.Contains(Content)) Content.Stop();
+        }
+      }
+      base.OnClosed(e);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/HeuristicLab.Optimization.Views-3.3.csproj
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/HeuristicLab.Optimization.Views-3.3.csproj	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/HeuristicLab.Optimization.Views-3.3.csproj	(revision 12764)
@@ -0,0 +1,462 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{662B4B15-8F4D-4AE5-B3EB-D91C215F5AF2}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Optimization.Views</RootNamespace>
+    <AssemblyName>HeuristicLab.Optimization.Views-3.3</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation />
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>
+    </DocumentationFile>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <ItemGroup>
+    <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, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <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, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <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.Data.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Data.Views-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.MainForm-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.MainForm-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.MainForm.WindowsForms-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.MainForm.WindowsForms-3.3.dll</HintPath>
+      <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\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Parameters.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Parameters.Views-3.3.dll</HintPath>
+      <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\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <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\sources\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.Instances.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.Instances.Views-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="Microsoft.CSharp" />
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Windows.Forms.DataVisualization" />
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Plugin.cs.frame" />
+    <Compile Include="AlgorithmView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="AlgorithmView.Designer.cs">
+      <DependentUpon>AlgorithmView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="BasicAlgorithmView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="BasicAlgorithmView.Designer.cs">
+      <DependentUpon>BasicAlgorithmView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="BatchRunView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="BatchRunView.Designer.cs">
+      <DependentUpon>BatchRunView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="CreateNewSingleEncodingDialog.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="CreateNewSingleEncodingDialog.Designer.cs">
+      <DependentUpon>CreateNewSingleEncodingDialog.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ISolutionSimilarityCalculatorView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ISolutionSimilarityCalculatorView.Designer.cs">
+      <DependentUpon>ISolutionSimilarityCalculatorView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ExperimentListView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ExperimentListView.Designer.cs">
+      <DependentUpon>ExperimentListView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ResultParameterView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ResultParameterView.Designer.cs">
+      <DependentUpon>ResultParameterView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="MultiEncodingView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="MultiEncodingView.Designer.cs">
+      <DependentUpon>MultiEncodingView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Plugin.cs" />
+    <Compile Include="ProblemView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ProblemView.Designer.cs">
+      <DependentUpon>ProblemView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="RunCollectionModifierListView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="RunCollectionModifierListView.Designer.cs">
+      <DependentUpon>RunCollectionModifierListView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="RunCollectionConstraintViews\RunCollectionContentConstraintView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="RunCollectionConstraintViews\RunCollectionContentConstraintView.Designer.cs">
+      <DependentUpon>RunCollectionContentConstraintView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ExperimentTreeView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ExperimentTreeView.Designer.cs">
+      <DependentUpon>ExperimentTreeView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="IOptimizerView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="IOptimizerView.Designer.cs">
+      <DependentUpon>IOptimizerView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ResultValueView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ResultValueView.Designer.cs">
+      <DependentUpon>ResultValueView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="RunCollectionViews\RunCollectionBoxPlotView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="RunCollectionViews\RunCollectionBoxPlotView.Designer.cs">
+      <DependentUpon>RunCollectionBoxPlotView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="RunCollectionConstraintViews\RunCollectionComparisonConstraintView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="RunCollectionConstraintViews\RunCollectionComparisonConstraintView.Designer.cs">
+      <DependentUpon>RunCollectionComparisonConstraintView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="RunCollectionConstraintViews\RunCollectionTypeCompatibilityConstraintView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="RunCollectionConstraintViews\RunCollectionTypeCompatibilityConstraintView.Designer.cs">
+      <DependentUpon>RunCollectionTypeCompatibilityConstraintView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="RunCollectionConstraintViews\RunCollectionConstraintCollectionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="RunCollectionConstraintViews\RunCollectionConstraintCollectionView.Designer.cs">
+      <DependentUpon>RunCollectionConstraintCollectionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="RunCollectionConstraintViews\RunCollectionColumnConstraintView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="RunCollectionConstraintViews\RunCollectionColumnConstraintView.Designer.cs">
+      <DependentUpon>RunCollectionColumnConstraintView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="OptimizerListView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="OptimizerListView.Designer.cs">
+      <DependentUpon>OptimizerListView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ExperimentView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ExperimentView.Designer.cs">
+      <DependentUpon>ExperimentView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="RunCollectionViews\RunCollectionBubbleChartView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="RunCollectionViews\RunCollectionBubbleChartView.Designer.cs">
+      <DependentUpon>RunCollectionBubbleChartView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="RunCollectionConstraintViews\RunCollectionEqualityConstraintView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="RunCollectionConstraintViews\RunCollectionEqualityConstraintView.Designer.cs">
+      <DependentUpon>RunCollectionEqualityConstraintView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="RunCollectionViews\RunCollectionTableView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="RunCollectionViews\RunCollectionTableView.Designer.cs">
+      <DependentUpon>RunCollectionTableView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="RunCollectionViews\RunCollectionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="RunCollectionViews\RunCollectionView.Designer.cs">
+      <DependentUpon>RunCollectionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="RunView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="RunView.Designer.cs">
+      <DependentUpon>RunView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="RunCollectionViews\RunCollectionChartAggregationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="RunCollectionViews\RunCollectionChartAggregationView.Designer.cs">
+      <DependentUpon>RunCollectionChartAggregationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="TimeLimitRunView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="TimeLimitRunView.Designer.cs">
+      <DependentUpon>TimeLimitRunView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="UserDefinedAlgorithmView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="UserDefinedAlgorithmView.Designer.cs">
+      <DependentUpon>UserDefinedAlgorithmView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="EngineAlgorithmView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="EngineAlgorithmView.Designer.cs">
+      <DependentUpon>EngineAlgorithmView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ResultCollectionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ResultCollectionView.Designer.cs">
+      <DependentUpon>ResultCollectionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ResultView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ResultView.Designer.cs">
+      <DependentUpon>ResultView.cs</DependentUpon>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis.Views\3.3\HeuristicLab.Analysis.Views-3.3.csproj">
+      <Project>{76945D76-CA61-4147-9DC2-0ACDCDDF87F9}</Project>
+      <Name>HeuristicLab.Analysis.Views-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
+      <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project>
+      <Name>HeuristicLab.Optimization-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
+      <Project>{887425B4-4348-49ED-A457-B7D2C26DDBF9}</Project>
+      <Name>HeuristicLab.Analysis-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="CreateNewSingleEncodingDialog.resx">
+      <DependentUpon>CreateNewSingleEncodingDialog.cs</DependentUpon>
+    </EmbeddedResource>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <PropertyGroup>
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd
+</PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/IOptimizerView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/IOptimizerView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/IOptimizerView.Designer.cs	(revision 12764)
@@ -0,0 +1,171 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class IOptimizerView {
+    /// <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() {
+      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(IOptimizerView));
+      this.startButton = new System.Windows.Forms.Button();
+      this.executionTimeTextBox = new System.Windows.Forms.TextBox();
+      this.executionTimeLabel = new System.Windows.Forms.Label();
+      this.pauseButton = new System.Windows.Forms.Button();
+      this.stopButton = new System.Windows.Forms.Button();
+      this.resetButton = new System.Windows.Forms.Button();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      this.nameTextBox.Size = new System.Drawing.Size(349, 20);
+      // 
+      // infoLabel
+      // 
+      this.infoLabel.Location = new System.Drawing.Point(413, 3);
+      // 
+      // startButton
+      // 
+      this.startButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.startButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Play;
+      this.startButton.Location = new System.Drawing.Point(0, 205);
+      this.startButton.Name = "startButton";
+      this.startButton.Size = new System.Drawing.Size(24, 24);
+      this.startButton.TabIndex = 10;
+      this.toolTip.SetToolTip(this.startButton, "Start/Resume Optimizer");
+      this.startButton.UseVisualStyleBackColor = true;
+      this.startButton.Click += new System.EventHandler(this.startButton_Click);
+      // 
+      // executionTimeTextBox
+      // 
+      this.executionTimeTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.executionTimeTextBox.Location = new System.Drawing.Point(295, 209);
+      this.executionTimeTextBox.Name = "executionTimeTextBox";
+      this.executionTimeTextBox.ReadOnly = true;
+      this.executionTimeTextBox.Size = new System.Drawing.Size(137, 20);
+      this.executionTimeTextBox.TabIndex = 15;
+      // 
+      // executionTimeLabel
+      // 
+      this.executionTimeLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.executionTimeLabel.AutoSize = true;
+      this.executionTimeLabel.Location = new System.Drawing.Point(206, 212);
+      this.executionTimeLabel.Name = "executionTimeLabel";
+      this.executionTimeLabel.Size = new System.Drawing.Size(83, 13);
+      this.executionTimeLabel.TabIndex = 14;
+      this.executionTimeLabel.Text = "&Execution Time:";
+      // 
+      // pauseButton
+      // 
+      this.pauseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.pauseButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Pause;
+      this.pauseButton.Location = new System.Drawing.Point(30, 205);
+      this.pauseButton.Name = "pauseButton";
+      this.pauseButton.Size = new System.Drawing.Size(24, 24);
+      this.pauseButton.TabIndex = 11;
+      this.toolTip.SetToolTip(this.pauseButton, "Pause Optimizer");
+      this.pauseButton.UseVisualStyleBackColor = true;
+      this.pauseButton.Click += new System.EventHandler(this.pauseButton_Click);
+      // 
+      // stopButton
+      // 
+      this.stopButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.stopButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Stop;
+      this.stopButton.Location = new System.Drawing.Point(60, 205);
+      this.stopButton.Name = "stopButton";
+      this.stopButton.Size = new System.Drawing.Size(24, 24);
+      this.stopButton.TabIndex = 12;
+      this.toolTip.SetToolTip(this.stopButton, "Stop Optimizer");
+      this.stopButton.UseVisualStyleBackColor = true;
+      this.stopButton.Click += new System.EventHandler(this.stopButton_Click);
+      // 
+      // resetButton
+      // 
+      this.resetButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.resetButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Restart;
+      this.resetButton.Location = new System.Drawing.Point(90, 205);
+      this.resetButton.Name = "resetButton";
+      this.resetButton.Size = new System.Drawing.Size(24, 24);
+      this.resetButton.TabIndex = 13;
+      this.toolTip.SetToolTip(this.resetButton, "Reset Optimizer");
+      this.resetButton.UseVisualStyleBackColor = true;
+      this.resetButton.Click += new System.EventHandler(this.resetButton_Click);
+      // 
+      // IOptimizerView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.startButton);
+      this.Controls.Add(this.executionTimeTextBox);
+      this.Controls.Add(this.executionTimeLabel);
+      this.Controls.Add(this.pauseButton);
+      this.Controls.Add(this.stopButton);
+      this.Controls.Add(this.resetButton);
+      this.Name = "IOptimizerView";
+      this.Size = new System.Drawing.Size(432, 229);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      this.Controls.SetChildIndex(this.resetButton, 0);
+      this.Controls.SetChildIndex(this.stopButton, 0);
+      this.Controls.SetChildIndex(this.pauseButton, 0);
+      this.Controls.SetChildIndex(this.executionTimeLabel, 0);
+      this.Controls.SetChildIndex(this.executionTimeTextBox, 0);
+      this.Controls.SetChildIndex(this.startButton, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    protected System.Windows.Forms.Button startButton;
+    protected System.Windows.Forms.TextBox executionTimeTextBox;
+    protected System.Windows.Forms.Label executionTimeLabel;
+    protected System.Windows.Forms.Button pauseButton;
+    protected System.Windows.Forms.Button stopButton;
+    protected System.Windows.Forms.Button resetButton;
+
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/IOptimizerView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/IOptimizerView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/IOptimizerView.cs	(revision 12764)
@@ -0,0 +1,165 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Windows.Forms;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("IOptimizer View")]
+  [Content(typeof(IOptimizer), false)]
+  public partial class IOptimizerView : NamedItemView {
+    public IOptimizerView() {
+      InitializeComponent();
+    }
+
+    public new IOptimizer Content {
+      get { return (IOptimizer)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.ExceptionOccurred -= new EventHandler<EventArgs<Exception>>(Content_ExceptionOccurred);
+      Content.ExecutionStateChanged -= new EventHandler(Content_ExecutionStateChanged);
+      Content.ExecutionTimeChanged -= new EventHandler(Content_ExecutionTimeChanged);
+      Content.Prepared -= new EventHandler(Content_Prepared);
+      Content.Started -= new EventHandler(Content_Started);
+      Content.Paused -= new EventHandler(Content_Paused);
+      Content.Stopped -= new EventHandler(Content_Stopped);
+      base.DeregisterContentEvents();
+    }
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ExceptionOccurred += new EventHandler<EventArgs<Exception>>(Content_ExceptionOccurred);
+      Content.ExecutionStateChanged += new EventHandler(Content_ExecutionStateChanged);
+      Content.ExecutionTimeChanged += new EventHandler(Content_ExecutionTimeChanged);
+      Content.Prepared += new EventHandler(Content_Prepared);
+      Content.Started += new EventHandler(Content_Started);
+      Content.Paused += new EventHandler(Content_Paused);
+      Content.Stopped += new EventHandler(Content_Stopped);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        executionTimeTextBox.Text = "-";
+      } else {
+        Locked = ReadOnly = Content.ExecutionState == ExecutionState.Started;
+        executionTimeTextBox.Text = Content.ExecutionTime.ToString();
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      executionTimeTextBox.Enabled = Content != null;
+      SetEnabledStateOfExecutableButtons();
+    }
+
+    #region Content Events
+    protected virtual void Content_ExecutionStateChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_ExecutionStateChanged), sender, e);
+      else
+        startButton.Enabled = pauseButton.Enabled = stopButton.Enabled = resetButton.Enabled = false;
+    }
+    protected virtual void Content_Prepared(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_Prepared), sender, e);
+      else {
+        nameTextBox.Enabled = infoLabel.Enabled = true;
+        ReadOnly = Locked = false;
+        SetEnabledStateOfExecutableButtons();
+      }
+    }
+    protected virtual void Content_Started(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_Started), sender, e);
+      else {
+        nameTextBox.Enabled = infoLabel.Enabled = false;
+        ReadOnly = Locked = true;
+        SetEnabledStateOfExecutableButtons();
+      }
+    }
+    protected virtual void Content_Paused(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_Paused), sender, e);
+      else {
+        nameTextBox.Enabled = infoLabel.Enabled = true;
+        ReadOnly = Locked = false;
+        SetEnabledStateOfExecutableButtons();
+      }
+    }
+    protected virtual void Content_Stopped(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_Stopped), sender, e);
+      else {
+        nameTextBox.Enabled = infoLabel.Enabled = true;
+        ReadOnly = Locked = false;
+        SetEnabledStateOfExecutableButtons();
+      }
+    }
+    protected virtual void Content_ExecutionTimeChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_ExecutionTimeChanged), sender, e);
+      else
+        executionTimeTextBox.Text = Content == null ? "-" : Content.ExecutionTime.ToString();
+    }
+    protected virtual void Content_ExceptionOccurred(object sender, EventArgs<Exception> e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler<EventArgs<Exception>>(Content_ExceptionOccurred), sender, e);
+      else
+        ErrorHandling.ShowErrorDialog(this, e.Value);
+    }
+    #endregion
+
+    #region Control events
+    protected virtual void startButton_Click(object sender, EventArgs e) {
+      Content.Start();
+    }
+    protected virtual void pauseButton_Click(object sender, EventArgs e) {
+      Content.Pause();
+    }
+    protected virtual void stopButton_Click(object sender, EventArgs e) {
+      Content.Stop();
+    }
+    protected virtual void resetButton_Click(object sender, EventArgs e) {
+      Content.Prepare(false);
+    }
+    #endregion
+
+    #region Helpers
+    protected virtual void SetEnabledStateOfExecutableButtons() {
+      if (Content == null) {
+        startButton.Enabled = pauseButton.Enabled = stopButton.Enabled = resetButton.Enabled = false;
+      } else {
+        startButton.Enabled = (Content.ExecutionState == ExecutionState.Prepared) || (Content.ExecutionState == ExecutionState.Paused);
+        pauseButton.Enabled = Content.ExecutionState == ExecutionState.Started;
+        stopButton.Enabled = (Content.ExecutionState == ExecutionState.Started) || (Content.ExecutionState == ExecutionState.Paused);
+        resetButton.Enabled = Content.ExecutionState != ExecutionState.Started;
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ISolutionSimilarityCalculatorView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ISolutionSimilarityCalculatorView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ISolutionSimilarityCalculatorView.Designer.cs	(revision 12764)
@@ -0,0 +1,112 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class ISolutionSimilarityCalculatorView {
+    /// <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.label1 = new System.Windows.Forms.Label();
+      this.label2 = new System.Windows.Forms.Label();
+      this.qualityVariableNameTextBox = new System.Windows.Forms.TextBox();
+      this.solutionVariableNameTextBox = new System.Windows.Forms.TextBox();
+      this.SuspendLayout();
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(3, 6);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(135, 13);
+      this.label1.TabIndex = 0;
+      this.label1.Text = "Variable Name of Solution: ";
+      // 
+      // label2
+      // 
+      this.label2.AutoSize = true;
+      this.label2.Location = new System.Drawing.Point(3, 32);
+      this.label2.Name = "label2";
+      this.label2.Size = new System.Drawing.Size(126, 13);
+      this.label2.TabIndex = 1;
+      this.label2.Text = "Variable Name of Quality:";
+      // 
+      // qualityVariableNameTextBox
+      // 
+      this.qualityVariableNameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.qualityVariableNameTextBox.Location = new System.Drawing.Point(144, 29);
+      this.qualityVariableNameTextBox.Name = "qualityVariableNameTextBox";
+      this.qualityVariableNameTextBox.Size = new System.Drawing.Size(287, 20);
+      this.qualityVariableNameTextBox.TabIndex = 2;
+      this.qualityVariableNameTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.qualityVariableNameTextBox_Validating);
+      // 
+      // solutionVariableNameTextBox
+      // 
+      this.solutionVariableNameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.solutionVariableNameTextBox.Location = new System.Drawing.Point(144, 3);
+      this.solutionVariableNameTextBox.Name = "solutionVariableNameTextBox";
+      this.solutionVariableNameTextBox.Size = new System.Drawing.Size(287, 20);
+      this.solutionVariableNameTextBox.TabIndex = 3;
+      this.solutionVariableNameTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.solutionVariableNameTextBox_Validating);
+      // 
+      // ISingleObjectiveSolutionSimilarityCalculatorView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.solutionVariableNameTextBox);
+      this.Controls.Add(this.qualityVariableNameTextBox);
+      this.Controls.Add(this.label2);
+      this.Controls.Add(this.label1);
+      this.Name = "ISingleObjectiveSolutionSimilarityCalculatorView";
+      this.Size = new System.Drawing.Size(434, 53);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.Label label2;
+    private System.Windows.Forms.TextBox qualityVariableNameTextBox;
+    private System.Windows.Forms.TextBox solutionVariableNameTextBox;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ISolutionSimilarityCalculatorView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ISolutionSimilarityCalculatorView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ISolutionSimilarityCalculatorView.cs	(revision 12764)
@@ -0,0 +1,61 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("ISolutionSimilarityCalculator View")]
+  [Content(typeof(ISolutionSimilarityCalculator), true)]
+  public partial class ISolutionSimilarityCalculatorView : AsynchronousContentView {
+    public ISolutionSimilarityCalculatorView() {
+      InitializeComponent();
+    }
+
+    public new ISolutionSimilarityCalculator Content {
+      get { return (ISolutionSimilarityCalculator)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        solutionVariableNameTextBox.Clear();
+        qualityVariableNameTextBox.Clear();
+      } else {
+        solutionVariableNameTextBox.Text = Content.SolutionVariableName;
+        qualityVariableNameTextBox.Text = Content.QualityVariableName;
+      }
+    }
+
+    private void solutionVariableNameTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      if (Content != null && Content.SolutionVariableName != solutionVariableNameTextBox.Text) {
+        Content.SolutionVariableName = solutionVariableNameTextBox.Text;
+      }
+    }
+
+    private void qualityVariableNameTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      if (Content != null && Content.QualityVariableName != qualityVariableNameTextBox.Text) {
+        Content.QualityVariableName = qualityVariableNameTextBox.Text;
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/MultiEncodingView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/MultiEncodingView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/MultiEncodingView.Designer.cs	(revision 12764)
@@ -0,0 +1,272 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class MultiEncodingView {
+    /// <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.encodingsListView = new System.Windows.Forms.ListView();
+      this.encodingNameColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+      this.encodingTypeColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+      this.addEncodingButton = new System.Windows.Forms.Button();
+      this.removeEncodingButton = new System.Windows.Forms.Button();
+      this.splitContainer = new System.Windows.Forms.SplitContainer();
+      this.encodingDetailsGroupBox = new System.Windows.Forms.GroupBox();
+      this.encodingDetailViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.encodingsGroupBox = new System.Windows.Forms.GroupBox();
+      this.tabControl = new System.Windows.Forms.TabControl();
+      this.encodingsTabPage = new System.Windows.Forms.TabPage();
+      this.parametersTabPage = new System.Windows.Forms.TabPage();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.encodingDetailsGroupBox.SuspendLayout();
+      this.encodingsGroupBox.SuspendLayout();
+      this.tabControl.SuspendLayout();
+      this.encodingsTabPage.SuspendLayout();
+      this.parametersTabPage.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // parameterCollectionView
+      // 
+      this.parameterCollectionView.Location = new System.Drawing.Point(6, 6);
+      this.parameterCollectionView.Size = new System.Drawing.Size(643, 433);
+      this.parameterCollectionView.TabIndex = 0;
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      this.nameTextBox.Size = new System.Drawing.Size(583, 20);
+      // 
+      // infoLabel
+      // 
+      this.infoLabel.Location = new System.Drawing.Point(647, 3);
+      // 
+      // encodingsListView
+      // 
+      this.encodingsListView.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.encodingsListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+            this.encodingNameColumnHeader,
+            this.encodingTypeColumnHeader});
+      this.encodingsListView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
+      this.encodingsListView.HideSelection = false;
+      this.encodingsListView.Location = new System.Drawing.Point(3, 33);
+      this.encodingsListView.MultiSelect = false;
+      this.encodingsListView.Name = "encodingsListView";
+      this.encodingsListView.ShowGroups = false;
+      this.encodingsListView.Size = new System.Drawing.Size(241, 378);
+      this.encodingsListView.TabIndex = 2;
+      this.encodingsListView.UseCompatibleStateImageBehavior = false;
+      this.encodingsListView.View = System.Windows.Forms.View.Details;
+      this.encodingsListView.SelectedIndexChanged += new System.EventHandler(this.encodingsListView_SelectedIndexChanged);
+      // 
+      // encodingNameColumnHeader
+      // 
+      this.encodingNameColumnHeader.Text = "Name";
+      this.encodingNameColumnHeader.Width = 100;
+      // 
+      // encodingTypeColumnHeader
+      // 
+      this.encodingTypeColumnHeader.Text = "Type";
+      this.encodingTypeColumnHeader.Width = 136;
+      // 
+      // addEncodingButton
+      // 
+      this.addEncodingButton.Location = new System.Drawing.Point(3, 3);
+      this.addEncodingButton.Name = "addEncodingButton";
+      this.addEncodingButton.Size = new System.Drawing.Size(24, 24);
+      this.addEncodingButton.TabIndex = 0;
+      this.addEncodingButton.Text = "+";
+      this.addEncodingButton.UseVisualStyleBackColor = true;
+      this.addEncodingButton.Click += new System.EventHandler(this.addEncodingButton_Click);
+      // 
+      // removeEncodingButton
+      // 
+      this.removeEncodingButton.Location = new System.Drawing.Point(33, 3);
+      this.removeEncodingButton.Name = "removeEncodingButton";
+      this.removeEncodingButton.Size = new System.Drawing.Size(24, 24);
+      this.removeEncodingButton.TabIndex = 1;
+      this.removeEncodingButton.Text = "x";
+      this.removeEncodingButton.UseVisualStyleBackColor = true;
+      this.removeEncodingButton.Click += new System.EventHandler(this.removeEncodingButton_Click);
+      // 
+      // splitContainer
+      // 
+      this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
+      this.splitContainer.Location = new System.Drawing.Point(3, 16);
+      this.splitContainer.Name = "splitContainer";
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.encodingsListView);
+      this.splitContainer.Panel1.Controls.Add(this.removeEncodingButton);
+      this.splitContainer.Panel1.Controls.Add(this.addEncodingButton);
+      // 
+      // splitContainer.Panel2
+      // 
+      this.splitContainer.Panel2.Controls.Add(this.encodingDetailsGroupBox);
+      this.splitContainer.Size = new System.Drawing.Size(637, 414);
+      this.splitContainer.SplitterDistance = 247;
+      this.splitContainer.TabIndex = 5;
+      // 
+      // encodingDetailsGroupBox
+      // 
+      this.encodingDetailsGroupBox.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.encodingDetailsGroupBox.Controls.Add(this.encodingDetailViewHost);
+      this.encodingDetailsGroupBox.Location = new System.Drawing.Point(3, 27);
+      this.encodingDetailsGroupBox.Name = "encodingDetailsGroupBox";
+      this.encodingDetailsGroupBox.Size = new System.Drawing.Size(380, 384);
+      this.encodingDetailsGroupBox.TabIndex = 0;
+      this.encodingDetailsGroupBox.TabStop = false;
+      this.encodingDetailsGroupBox.Text = "Details";
+      // 
+      // encodingDetailViewHost
+      // 
+      this.encodingDetailViewHost.Caption = "View";
+      this.encodingDetailViewHost.Content = null;
+      this.encodingDetailViewHost.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.encodingDetailViewHost.Enabled = false;
+      this.encodingDetailViewHost.Location = new System.Drawing.Point(3, 16);
+      this.encodingDetailViewHost.Name = "encodingDetailViewHost";
+      this.encodingDetailViewHost.ReadOnly = false;
+      this.encodingDetailViewHost.Size = new System.Drawing.Size(374, 365);
+      this.encodingDetailViewHost.TabIndex = 0;
+      this.encodingDetailViewHost.ViewsLabelVisible = true;
+      this.encodingDetailViewHost.ViewType = null;
+      // 
+      // encodingsGroupBox
+      // 
+      this.encodingsGroupBox.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.encodingsGroupBox.Controls.Add(this.splitContainer);
+      this.encodingsGroupBox.Location = new System.Drawing.Point(6, 6);
+      this.encodingsGroupBox.Name = "encodingsGroupBox";
+      this.encodingsGroupBox.Size = new System.Drawing.Size(643, 433);
+      this.encodingsGroupBox.TabIndex = 0;
+      this.encodingsGroupBox.TabStop = false;
+      this.encodingsGroupBox.Text = "Encodings";
+      // 
+      // tabControl
+      // 
+      this.tabControl.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.tabControl.Controls.Add(this.encodingsTabPage);
+      this.tabControl.Controls.Add(this.parametersTabPage);
+      this.tabControl.Location = new System.Drawing.Point(0, 26);
+      this.tabControl.Name = "tabControl";
+      this.tabControl.SelectedIndex = 0;
+      this.tabControl.Size = new System.Drawing.Size(663, 471);
+      this.tabControl.TabIndex = 3;
+      // 
+      // encodingsTabPage
+      // 
+      this.encodingsTabPage.Controls.Add(this.encodingsGroupBox);
+      this.encodingsTabPage.Location = new System.Drawing.Point(4, 22);
+      this.encodingsTabPage.Name = "encodingsTabPage";
+      this.encodingsTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.encodingsTabPage.Size = new System.Drawing.Size(655, 445);
+      this.encodingsTabPage.TabIndex = 0;
+      this.encodingsTabPage.Text = "Encodings";
+      this.encodingsTabPage.UseVisualStyleBackColor = true;
+      // 
+      // parametersTabPage
+      // 
+      this.parametersTabPage.Controls.Add(this.parameterCollectionView);
+      this.parametersTabPage.Location = new System.Drawing.Point(4, 22);
+      this.parametersTabPage.Name = "parametersTabPage";
+      this.parametersTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.parametersTabPage.Size = new System.Drawing.Size(655, 445);
+      this.parametersTabPage.TabIndex = 1;
+      this.parametersTabPage.Text = "Parameters";
+      this.parametersTabPage.UseVisualStyleBackColor = true;
+      // 
+      // MultiEncodingView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.tabControl);
+      this.Name = "MultiEncodingView";
+      this.Size = new System.Drawing.Size(666, 497);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      this.Controls.SetChildIndex(this.tabControl, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.encodingDetailsGroupBox.ResumeLayout(false);
+      this.encodingsGroupBox.ResumeLayout(false);
+      this.tabControl.ResumeLayout(false);
+      this.encodingsTabPage.ResumeLayout(false);
+      this.parametersTabPage.ResumeLayout(false);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.ListView encodingsListView;
+    private System.Windows.Forms.Button addEncodingButton;
+    private System.Windows.Forms.Button removeEncodingButton;
+    private System.Windows.Forms.SplitContainer splitContainer;
+    private System.Windows.Forms.ColumnHeader encodingNameColumnHeader;
+    private System.Windows.Forms.ColumnHeader encodingTypeColumnHeader;
+    private System.Windows.Forms.GroupBox encodingDetailsGroupBox;
+    private MainForm.WindowsForms.ViewHost encodingDetailViewHost;
+    private System.Windows.Forms.GroupBox encodingsGroupBox;
+    private System.Windows.Forms.TabControl tabControl;
+    private System.Windows.Forms.TabPage encodingsTabPage;
+    private System.Windows.Forms.TabPage parametersTabPage;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/MultiEncodingView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/MultiEncodingView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/MultiEncodingView.cs	(revision 12764)
@@ -0,0 +1,144 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Drawing;
+using System.Linq;
+using System.Reflection;
+using System.Windows.Forms;
+using HeuristicLab.Common.Resources;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("MultiEncoding View")]
+  [Content(typeof(MultiEncoding), IsDefaultView = true)]
+  public sealed partial class MultiEncodingView : ParameterizedNamedItemView {
+
+    public new MultiEncoding Content {
+      get { return (MultiEncoding)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public MultiEncodingView() {
+      InitializeComponent();
+      addEncodingButton.Text = string.Empty;
+      addEncodingButton.Image = VSImageLibrary.Add;
+      removeEncodingButton.Text = string.Empty;
+      removeEncodingButton.Image = VSImageLibrary.Remove;
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.EncodingsChanged -= ContentOnEncodingsChanged;
+    }
+
+    protected override void RegisterContentEvents() {
+      Content.EncodingsChanged += ContentOnEncodingsChanged;
+      base.RegisterContentEvents();
+    }
+
+    private void ContentOnEncodingsChanged(object sender, EventArgs eventArgs) {
+      RecreateEncodingsList();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      encodingDetailViewHost.Content = null;
+      RecreateEncodingsList();
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      addEncodingButton.Enabled = !Locked && !ReadOnly && Content != null;
+      removeEncodingButton.Enabled = !Locked && !ReadOnly && Content != null
+                                     && encodingsListView.SelectedItems.Count > 0;
+    }
+
+    private void addEncodingButton_Click(object sender, EventArgs e) {
+      using (var dialog = new CreateNewSingleEncodingDialog()) {
+        dialog.ForbiddenNames = Content.Encodings.Select(x => x.Name).Concat(new[] { Content.Name });
+        if (dialog.ShowDialog() == DialogResult.OK) {
+          IEncoding encoding;
+          try {
+            encoding = (IEncoding)Activator.CreateInstance(dialog.EncodingType, dialog.EncodingName);
+          } catch (MissingMethodException mmex) {
+            PluginInfrastructure.ErrorHandling.ShowErrorDialog("The encoding must have a constructor that takes the name as a single string argument", mmex);
+            return;
+          } catch (TargetInvocationException tiex) {
+            PluginInfrastructure.ErrorHandling.ShowErrorDialog("The encoding could not be created due to an error in the constructor.", tiex);
+            return;
+          } catch (MethodAccessException maex) {
+            PluginInfrastructure.ErrorHandling.ShowErrorDialog("The encoding's string constructor is not public.", maex);
+            return;
+          }
+          Content.Add(encoding);
+        }
+      }
+    }
+
+    private void removeEncodingButton_Click(object sender, EventArgs e) {
+      var encoding = GetSelectedEncoding();
+      var success = Content.Remove(encoding);
+      encodingDetailViewHost.Content = null;
+      if (!success) MessageBox.Show("Could not remove encoding.", "Error while removing encoding.", MessageBoxButtons.OK, MessageBoxIcon.Error);
+    }
+
+    private void encodingsListView_SelectedIndexChanged(object sender, EventArgs e) {
+      if (encodingsListView.SelectedItems.Count > 0) {
+        var encoding = GetSelectedEncoding();
+        encodingDetailViewHost.Content = encoding;
+      } else encodingDetailViewHost.Content = null;
+      SetEnabledStateOfControls();
+    }
+
+    private IEncoding GetSelectedEncoding() {
+      var selected = encodingsListView.SelectedItems[0];
+      var encodingName = selected.Text;
+      var encoding = Content.Encodings.Single(x => x.Name == encodingName);
+      return encoding;
+    }
+
+    private void RecreateEncodingsList() {
+      encodingsListView.SelectedIndices.Clear();
+      encodingsListView.Items.Clear();
+      if (encodingsListView.SmallImageList != null)
+        foreach (Image img in encodingsListView.SmallImageList.Images) img.Dispose();
+      encodingsListView.SmallImageList = new ImageList();
+      if (Content != null) {
+        foreach (var enc in Content.Encodings)
+          CreateListViewItem(enc);
+      }
+    }
+
+    private void CreateListViewItem(IEncoding enc) {
+      encodingsListView.SmallImageList.Images.Add(enc.ItemImage);
+      var item = new ListViewItem() {
+        ImageIndex = encodingsListView.SmallImageList.Images.Count - 1,
+        Text = enc.Name
+      };
+      item.SubItems.Add(new ListViewItem.ListViewSubItem() {
+        Text = enc.GetType().Name
+      });
+      encodingsListView.Items.Add(item);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/OptimizerListView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/OptimizerListView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/OptimizerListView.Designer.cs	(revision 12764)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class OptimizerListView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+    }
+
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/OptimizerListView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/OptimizerListView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/OptimizerListView.cs	(revision 12764)
@@ -0,0 +1,102 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("OptimizerList View")]
+  [Content(typeof(OptimizerList), true)]
+  [Content(typeof(IItemList<IOptimizer>), false)]
+  public partial class OptimizerListView : ItemListView<IOptimizer> {
+    /// <summary>
+    /// Initializes a new instance of <see cref="VariablesScopeView"/> with caption "Variables Scope View".
+    /// </summary>
+    public OptimizerListView() {
+      InitializeComponent();
+      itemsGroupBox.Text = "Optimizers";
+    }
+
+    protected override IOptimizer CreateItem() {
+      if (typeSelectorDialog == null) {
+        typeSelectorDialog = new TypeSelectorDialog();
+        typeSelectorDialog.Caption = "Select Optimizer";
+        typeSelectorDialog.TypeSelector.Caption = "Available Optimizers";
+        typeSelectorDialog.TypeSelector.Configure(typeof(IOptimizer), false, true);
+      }
+
+      if (typeSelectorDialog.ShowDialog(this) == DialogResult.OK) {
+        try {
+          return (IOptimizer)typeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
+        } catch (Exception ex) {
+          ErrorHandling.ShowErrorDialog(this, ex);
+        }
+      }
+      return null;
+    }
+
+    protected override void DeregisterItemEvents(IOptimizer item) {
+      var batchRun = item as BatchRun;
+      if (batchRun != null) {
+        batchRun.RepetitionsChanged -= BatchRun_UpdateText;
+        batchRun.RepetetionsCounterChanged -= BatchRun_UpdateText;
+      }
+      base.DeregisterItemEvents(item);
+    }
+
+    protected override void RegisterItemEvents(IOptimizer item) {
+      base.RegisterItemEvents(item);
+      var batchRun = item as BatchRun;
+      if (batchRun != null) {
+        batchRun.RepetitionsChanged += BatchRun_UpdateText;
+        batchRun.RepetetionsCounterChanged += BatchRun_UpdateText;
+      }
+    }
+
+    protected override ListViewItem CreateListViewItem(IOptimizer item) {
+      var listViewItem = base.CreateListViewItem(item);
+      var batchRun = item as BatchRun;
+      if (batchRun != null) {
+        listViewItem.Text += string.Format(" {0}/{1}", batchRun.RepetitionsCounter, batchRun.Repetitions);
+      }
+      return listViewItem;
+    }
+
+    protected override void UpdateListViewItemText(ListViewItem listViewItem) {
+      base.UpdateListViewItemText(listViewItem);
+      var batchRun = listViewItem.Tag as BatchRun;
+      if (batchRun != null) {
+        listViewItem.Text = batchRun.ToString() + string.Format(" {0}/{1}", batchRun.RepetitionsCounter, batchRun.Repetitions);
+      }
+    }
+
+    protected virtual void BatchRun_UpdateText(object sender, EventArgs eventArgs) {
+      if (sender is BatchRun) {
+        foreach (var item in GetListViewItemsForItem(sender as BatchRun))
+          UpdateListViewItemText(item);
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/Plugin.cs.frame
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/Plugin.cs.frame	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/Plugin.cs.frame	(revision 12764)
@@ -0,0 +1,46 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Optimization.Views {
+  /// <summary>
+  /// Plugin class for HeuristicLab.Optimization.Views plugin.
+  /// </summary>
+  [Plugin("HeuristicLab.Optimization.Views", "3.3.12.$WCREV$")]
+  [PluginFile("HeuristicLab.Optimization.Views-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Analysis", "3.3")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Core.Views", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Data.Views", "3.3")]
+  [PluginDependency("HeuristicLab.MainForm", "3.3")]
+  [PluginDependency("HeuristicLab.MainForm.WindowsForms", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Problems.Instances", "3.3")]
+  [PluginDependency("HeuristicLab.Problems.Instances.Views", "3.3")]
+  [PluginDependency("HeuristicLab.Visualization.ChartControlsExtensions","3.3")]
+  public class HeuristicLabOptimizationViewsPlugin : PluginBase {
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ProblemInstanceProviderView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ProblemInstanceProviderView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ProblemInstanceProviderView.Designer.cs	(revision 12764)
@@ -0,0 +1,129 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class ProblemInstanceProviderView<T> {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      this.loadButton = new System.Windows.Forms.Button();
+      this.instanceLabel = new System.Windows.Forms.Label();
+      this.instancesComboBox = new System.Windows.Forms.ComboBox();
+      this.importButton = new System.Windows.Forms.Button();
+      this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
+      this.toolTip = new System.Windows.Forms.ToolTip(this.components);
+      this.SuspendLayout();
+      // 
+      // loadButton
+      // 
+      this.loadButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.loadButton.Location = new System.Drawing.Point(549, -1);
+      this.loadButton.Name = "loadButton";
+      this.loadButton.Size = new System.Drawing.Size(26, 23);
+      this.loadButton.TabIndex = 6;
+      this.loadButton.Text = "Load";
+      this.loadButton.UseVisualStyleBackColor = true;
+      this.loadButton.Click += new System.EventHandler(this.loadButton_Click);
+      // 
+      // instanceLabel
+      // 
+      this.instanceLabel.AutoSize = true;
+      this.instanceLabel.Location = new System.Drawing.Point(-3, 3);
+      this.instanceLabel.Name = "instanceLabel";
+      this.instanceLabel.Size = new System.Drawing.Size(51, 13);
+      this.instanceLabel.TabIndex = 4;
+      this.instanceLabel.Text = "Instance:";
+      // 
+      // instancesComboBox
+      // 
+      this.instancesComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.instancesComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.instancesComboBox.FormattingEnabled = true;
+      this.instancesComboBox.Location = new System.Drawing.Point(54, 0);
+      this.instancesComboBox.Name = "instancesComboBox";
+      this.instancesComboBox.Size = new System.Drawing.Size(489, 21);
+      this.instancesComboBox.TabIndex = 7;
+      this.instancesComboBox.DataSourceChanged += new System.EventHandler(this.comboBox_DataSourceChanged);
+      // 
+      // importButton
+      // 
+      this.importButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.importButton.Location = new System.Drawing.Point(581, -1);
+      this.importButton.Name = "importButton";
+      this.importButton.Size = new System.Drawing.Size(26, 23);
+      this.importButton.TabIndex = 6;
+      this.importButton.Text = "Import";
+      this.importButton.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
+      this.importButton.UseVisualStyleBackColor = true;
+      this.importButton.Click += new System.EventHandler(this.importButton_Click);
+      // 
+      // openFileDialog
+      // 
+      this.openFileDialog.Filter = "All files|*.*";
+      // 
+      // ProblemInstanceProviderView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.instancesComboBox);
+      this.Controls.Add(this.importButton);
+      this.Controls.Add(this.loadButton);
+      this.Controls.Add(this.instanceLabel);
+      this.Name = "ProblemInstanceProviderView";
+      this.Size = new System.Drawing.Size(610, 21);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.OpenFileDialog openFileDialog;
+    private System.Windows.Forms.ToolTip toolTip;
+    protected System.Windows.Forms.Button loadButton;
+    protected System.Windows.Forms.Label instanceLabel;
+    protected System.Windows.Forms.ComboBox instancesComboBox;
+    protected System.Windows.Forms.Button importButton;
+
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ProblemInstanceProviderView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ProblemInstanceProviderView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ProblemInstanceProviderView.cs	(revision 12764)
@@ -0,0 +1,108 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.IO;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Common.Resources;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+using HeuristicLab.Problems.Instances;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("ProblemInstanceProviderView")]
+  [Content(typeof(IProblemInstanceProvider<>), IsDefaultView = true)]
+  public partial class ProblemInstanceProviderView<T> : AsynchronousContentView {
+
+    public new IProblemInstanceProvider<T> Content {
+      get { return (IProblemInstanceProvider<T>)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ProblemInstanceProviderView() {
+      InitializeComponent();
+      importButton.Text = String.Empty;
+      importButton.Image = VSImageLibrary.Open;
+      toolTip.SetToolTip(importButton, "Import a " + GetProblemType() + " instance from file.");
+      loadButton.Text = String.Empty;
+      loadButton.Image = VSImageLibrary.RefreshDocument;
+      toolTip.SetToolTip(loadButton, "Load the selected instance.");
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        instancesComboBox.DataSource = null;
+      } else {
+        instancesComboBox.DisplayMember = "Name";
+        instancesComboBox.DataSource = Content.GetDataDescriptors().ToList();
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      instancesComboBox.Enabled = !ReadOnly && !Locked && Content != null && Content.Consumer != null;
+      loadButton.Enabled = !ReadOnly && !Locked && Content != null && Content.Consumer != null;
+    }
+
+    protected virtual void loadButton_Click(object sender, EventArgs e) {
+      var descriptor = (IDataDescriptor)instancesComboBox.SelectedItem;
+      var instance = Content.LoadData(descriptor);
+      try {
+        Content.Consumer.Load(instance);
+      } catch (Exception ex) {
+        MessageBox.Show(String.Format("This problem does not support loading the instance {0}: {1}", descriptor.Name, Environment.NewLine + ex.Message), "Cannot load instance");
+      }
+    }
+
+    protected virtual void importButton_Click(object sender, EventArgs e) {
+      openFileDialog.FileName = GetProblemType() + " instance";
+      if (openFileDialog.ShowDialog() == DialogResult.OK) {
+        T instance = default(T);
+        try {
+          instance = Content.LoadData(openFileDialog.FileName);
+        } catch (Exception ex) {
+          MessageBox.Show(String.Format("There was an error parsing the file: {0}", Environment.NewLine + ex.Message), "Error while parsing", MessageBoxButtons.OK, MessageBoxIcon.Error);
+          return;
+        }
+        try {
+          Content.Consumer.Load(instance);
+        } catch (Exception ex) {
+          MessageBox.Show(String.Format("This problem does not support loading the instance {0}: {1}", Path.GetFileName(openFileDialog.FileName), Environment.NewLine + ex.Message), "Cannot load instance");
+        }
+      }
+    }
+
+    private void comboBox_DataSourceChanged(object sender, EventArgs e) {
+      var comboBox = (ComboBox)sender;
+      if (comboBox.DataSource == null)
+        comboBox.Items.Clear();
+    }
+
+    protected virtual string GetProblemType() {
+      string dataTypeName = typeof(T).Name.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries).Last();
+      if (dataTypeName.EndsWith("Data"))
+        return dataTypeName.Substring(0, dataTypeName.Length - "Data".Length);
+      else return dataTypeName;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ProblemView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ProblemView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ProblemView.Designer.cs	(revision 12764)
@@ -0,0 +1,165 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class ProblemView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.problemInstanceSplitContainer = new System.Windows.Forms.SplitContainer();
+      this.libraryLabel = new System.Windows.Forms.Label();
+      this.problemInstanceProviderComboBox = new System.Windows.Forms.ComboBox();
+      this.problemInstanceProviderViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.problemInstanceSplitContainer)).BeginInit();
+      this.problemInstanceSplitContainer.Panel1.SuspendLayout();
+      this.problemInstanceSplitContainer.Panel2.SuspendLayout();
+      this.problemInstanceSplitContainer.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // parameterCollectionView
+      // 
+      this.parameterCollectionView.Location = new System.Drawing.Point(6, 27);
+      this.parameterCollectionView.Size = new System.Drawing.Size(501, 303);
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      this.nameTextBox.Location = new System.Drawing.Point(47, 1);
+      this.nameTextBox.Size = new System.Drawing.Size(438, 20);
+      // 
+      // nameLabel
+      // 
+      this.nameLabel.Location = new System.Drawing.Point(3, 6);
+      // 
+      // infoLabel
+      // 
+      this.infoLabel.Location = new System.Drawing.Point(491, 4);
+      // 
+      // problemInstanceSplitContainer
+      // 
+      this.problemInstanceSplitContainer.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.problemInstanceSplitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
+      this.problemInstanceSplitContainer.IsSplitterFixed = true;
+      this.problemInstanceSplitContainer.Location = new System.Drawing.Point(0, 0);
+      this.problemInstanceSplitContainer.Name = "problemInstanceSplitContainer";
+      this.problemInstanceSplitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
+      // 
+      // problemInstanceSplitContainer.Panel1
+      // 
+      this.problemInstanceSplitContainer.Panel1.Controls.Add(this.libraryLabel);
+      this.problemInstanceSplitContainer.Panel1.Controls.Add(this.problemInstanceProviderComboBox);
+      this.problemInstanceSplitContainer.Panel1.Controls.Add(this.problemInstanceProviderViewHost);
+      this.problemInstanceSplitContainer.Panel1MinSize = 10;
+      // 
+      // problemInstanceSplitContainer.Panel2
+      // 
+      this.problemInstanceSplitContainer.Panel2.Controls.Add(this.nameLabel);
+      this.problemInstanceSplitContainer.Panel2.Controls.Add(this.nameTextBox);
+      this.problemInstanceSplitContainer.Panel2.Controls.Add(this.parameterCollectionView);
+      this.problemInstanceSplitContainer.Panel2.Controls.Add(this.infoLabel);
+      this.problemInstanceSplitContainer.Size = new System.Drawing.Size(511, 363);
+      this.problemInstanceSplitContainer.SplitterDistance = 26;
+      this.problemInstanceSplitContainer.TabIndex = 13;
+      // 
+      // libraryLabel
+      // 
+      this.libraryLabel.AutoSize = true;
+      this.libraryLabel.Location = new System.Drawing.Point(3, 6);
+      this.libraryLabel.Name = "libraryLabel";
+      this.libraryLabel.Size = new System.Drawing.Size(41, 13);
+      this.libraryLabel.TabIndex = 17;
+      this.libraryLabel.Text = "Library:";
+      // 
+      // problemInstanceProviderComboBox
+      // 
+      this.problemInstanceProviderComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.problemInstanceProviderComboBox.FormattingEnabled = true;
+      this.problemInstanceProviderComboBox.Location = new System.Drawing.Point(50, 2);
+      this.problemInstanceProviderComboBox.Name = "problemInstanceProviderComboBox";
+      this.problemInstanceProviderComboBox.Size = new System.Drawing.Size(208, 21);
+      this.problemInstanceProviderComboBox.TabIndex = 18;
+      this.problemInstanceProviderComboBox.SelectedIndexChanged += new System.EventHandler(this.problemInstanceProviderComboBox_SelectedIndexChanged);
+      // 
+      // problemInstanceProviderViewHost
+      // 
+      this.problemInstanceProviderViewHost.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.problemInstanceProviderViewHost.Caption = "ProblemInstanceConsumerView";
+      this.problemInstanceProviderViewHost.Content = null;
+      this.problemInstanceProviderViewHost.Enabled = false;
+      this.problemInstanceProviderViewHost.Location = new System.Drawing.Point(264, 1);
+      this.problemInstanceProviderViewHost.Name = "problemInstanceProviderViewHost";
+      this.problemInstanceProviderViewHost.ReadOnly = false;
+      this.problemInstanceProviderViewHost.Size = new System.Drawing.Size(247, 23);
+      this.problemInstanceProviderViewHost.TabIndex = 0;
+      this.problemInstanceProviderViewHost.ViewsLabelVisible = false;
+      this.problemInstanceProviderViewHost.ViewType = null;
+      // 
+      // ProblemView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.problemInstanceSplitContainer);
+      this.Name = "ProblemView";
+      this.Size = new System.Drawing.Size(511, 363);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.problemInstanceSplitContainer.Panel1.ResumeLayout(false);
+      this.problemInstanceSplitContainer.Panel1.PerformLayout();
+      this.problemInstanceSplitContainer.Panel2.ResumeLayout(false);
+      this.problemInstanceSplitContainer.Panel2.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.problemInstanceSplitContainer)).EndInit();
+      this.problemInstanceSplitContainer.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    protected System.Windows.Forms.SplitContainer problemInstanceSplitContainer;
+    protected HeuristicLab.MainForm.WindowsForms.ViewHost problemInstanceProviderViewHost;
+    protected System.Windows.Forms.Label libraryLabel;
+    protected System.Windows.Forms.ComboBox problemInstanceProviderComboBox;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ProblemView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ProblemView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ProblemView.cs	(revision 12764)
@@ -0,0 +1,125 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.Problems.Instances;
+using HeuristicLab.Problems.Instances.Views;
+
+namespace HeuristicLab.Optimization.Views {
+  /// <summary>
+  /// The base class for visual representations of items.
+  /// </summary>
+  [View("Problem View")]
+  [Content(typeof(IProblem), true)]
+  public partial class ProblemView : ParameterizedNamedItemView {
+
+    public new IProblem Content {
+      get { return (IProblem)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected IEnumerable<IProblemInstanceProvider> problemInstanceProviders;
+    public IEnumerable<IProblemInstanceProvider> ProblemInstanceProviders {
+      get { return new List<IProblemInstanceProvider>(problemInstanceProviders); }
+    }
+
+    public IProblemInstanceProvider SelectedProvider { get; protected set; }
+
+    /// <summary>
+    /// Initializes a new instance of <see cref="ItemBaseView"/>.
+    /// </summary>
+    public ProblemView() {
+      InitializeComponent();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        problemInstanceProviders = null;
+        problemInstanceProviderComboBox.DataSource = null;
+        problemInstanceSplitContainer.Panel1Collapsed = true;
+      } else {
+        var consumer = Content as IProblemInstanceConsumer;
+        if (consumer != null) {
+          problemInstanceProviders = ProblemInstanceManager.GetProviders(Content);
+          bool expand = problemInstanceProviders.Any();
+          if (expand) {
+            problemInstanceProviderComboBox.DisplayMember = "Name";
+            problemInstanceProviderComboBox.DataSource = ProblemInstanceProviders.OrderBy(x => x.Name).ToList();
+          }
+          problemInstanceSplitContainer.Panel1Collapsed = !expand;
+        } else
+          problemInstanceSplitContainer.Panel1Collapsed = true;
+      }
+      SetEnabledStateOfControls();
+    }
+
+    protected virtual void problemInstanceProviderComboBox_SelectedIndexChanged(object sender, System.EventArgs e) {
+      if (problemInstanceProviderComboBox.SelectedIndex >= 0) {
+        SelectedProvider = (IProblemInstanceProvider)problemInstanceProviderComboBox.SelectedItem;
+        problemInstanceProviderViewHost.Content = SelectedProvider;
+        var view = (ProblemInstanceProviderView)problemInstanceProviderViewHost.ActiveView;
+        var consumer = (IProblemInstanceConsumer)Content;
+        view.Consumer = consumer;
+        if (CheckForIProblemInstanceExporter(consumer))
+          view.Exporter = (IProblemInstanceExporter)Content;
+        else view.Exporter = null;
+        SetTooltip();
+      } else {
+        SelectedProvider = null;
+      }
+      SetEnabledStateOfControls();
+    }
+
+    protected bool CheckForIProblemInstanceExporter(IProblemInstanceConsumer content) {
+      return Content.GetType().GetInterfaces()
+                    .Any(x => x == typeof(IProblemInstanceExporter));
+    }
+
+    #region ToolTip
+    protected void SetTooltip() {
+      toolTip.SetToolTip(problemInstanceProviderComboBox, GetProviderToolTip());
+    }
+
+    private string GetProviderToolTip() {
+      var provider = SelectedProvider;
+      string toolTip = provider.Name;
+
+      if (!String.IsNullOrEmpty(provider.ReferencePublication)) {
+        toolTip = toolTip
+            + Environment.NewLine + Environment.NewLine
+            + provider.ReferencePublication;
+      }
+      if (provider.WebLink != null) {
+        toolTip = toolTip
+            + Environment.NewLine
+            + provider.WebLink.ToString();
+      }
+
+      return toolTip;
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/Properties/AssemblyInfo.cs.frame	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/Properties/AssemblyInfo.cs.frame	(revision 12764)
@@ -0,0 +1,56 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.Optimization.Views")]
+[assembly: AssemblyDescription("Views of the HeuristicLab optimization classes")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2015 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("53eb21a9-b086-4341-ae53-2ee34cefae3e")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.12.$WCREV$")]
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultCollectionView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultCollectionView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultCollectionView.Designer.cs	(revision 12764)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class ResultCollectionView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+    }
+
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultCollectionView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultCollectionView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultCollectionView.cs	(revision 12764)
@@ -0,0 +1,61 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("ResultCollection View")]
+  [Content(typeof(ResultCollection), true)]
+  [Content(typeof(IKeyedItemCollection<string, IResult>), false)]
+  public partial class ResultCollectionView : NamedItemCollectionView<IResult> {
+
+    public override bool ReadOnly {
+      get { return true; }
+      set { /*not needed because results are always readonly */}
+    }
+
+    public ResultCollectionView() {
+      InitializeComponent();
+      itemsGroupBox.Text = "Results";
+      viewHost.ViewsLabelVisible = false;
+    }
+
+    protected override IResult CreateItem() {
+      return null;
+    }
+
+    protected override void itemsListView_DoubleClick(object sender, EventArgs e) {
+      if (itemsListView.SelectedItems.Count == 1) {
+        IResult result = itemsListView.SelectedItems[0].Tag as IResult;
+        if (result != null) {
+          IContentView view = MainFormManager.MainForm.ShowContent(result, typeof(ResultView));
+          if (view != null) {
+            view.ReadOnly = ReadOnly;
+            view.Locked = Locked;
+          }
+        }
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultParameterView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultParameterView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultParameterView.Designer.cs	(revision 12764)
@@ -0,0 +1,140 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class ResultParameterView<T> {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.resultNameTextBox = new System.Windows.Forms.TextBox();
+      this.resultNameLabel = new System.Windows.Forms.Label();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // dataTypeLabel
+      // 
+      this.dataTypeLabel.Location = new System.Drawing.Point(3, 55);
+      this.dataTypeLabel.TabIndex = 5;
+      // 
+      // dataTypeTextBox
+      // 
+      this.dataTypeTextBox.Location = new System.Drawing.Point(80, 52);
+      this.dataTypeTextBox.Size = new System.Drawing.Size(306, 20);
+      this.dataTypeTextBox.TabIndex = 6;
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      this.nameTextBox.Location = new System.Drawing.Point(80, 0);
+      this.nameTextBox.Size = new System.Drawing.Size(281, 20);
+      // 
+      // infoLabel
+      // 
+      this.infoLabel.Location = new System.Drawing.Point(367, 3);
+      // 
+      // actualNameTextBox
+      // 
+      this.actualNameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.actualNameTextBox.Location = new System.Drawing.Point(80, 26);
+      this.actualNameTextBox.Name = "actualNameTextBox";
+      this.actualNameTextBox.Size = new System.Drawing.Size(306, 20);
+      this.actualNameTextBox.TabIndex = 4;
+      this.actualNameTextBox.Validated += new System.EventHandler(this.actualNameTextBox_Validated);
+      // 
+      // actualNameLabel
+      // 
+      this.actualNameLabel.AutoSize = true;
+      this.actualNameLabel.Location = new System.Drawing.Point(3, 29);
+      this.actualNameLabel.Name = "actualNameLabel";
+      this.actualNameLabel.Size = new System.Drawing.Size(71, 13);
+      this.actualNameLabel.TabIndex = 3;
+      this.actualNameLabel.Text = "&Actual Name:";
+      // 
+      // resultNameTextBox
+      // 
+      this.resultNameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.resultNameTextBox.Location = new System.Drawing.Point(80, 78);
+      this.resultNameTextBox.Name = "resultNameTextBox";
+      this.resultNameTextBox.Size = new System.Drawing.Size(306, 20);
+      this.resultNameTextBox.TabIndex = 6;
+      this.resultNameTextBox.Validated += new System.EventHandler(this.resultNameTextBox_Validated);
+      // 
+      // resultNameLabel
+      // 
+      this.resultNameLabel.AutoSize = true;
+      this.resultNameLabel.Location = new System.Drawing.Point(3, 81);
+      this.resultNameLabel.Name = "resultNameLabel";
+      this.resultNameLabel.Size = new System.Drawing.Size(71, 13);
+      this.resultNameLabel.TabIndex = 5;
+      this.resultNameLabel.Text = "&Result Name:";
+      // 
+      // LookupParameterView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.resultNameTextBox);
+      this.Controls.Add(this.resultNameLabel);
+      this.Name = "ResultParameterView";
+      this.Size = new System.Drawing.Size(386, 76);
+      this.Controls.SetChildIndex(this.dataTypeLabel, 0);
+      this.Controls.SetChildIndex(this.dataTypeTextBox, 0);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      this.Controls.SetChildIndex(this.actualNameLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      this.Controls.SetChildIndex(this.actualNameTextBox, 0);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.resultNameLabel, 0);
+      this.Controls.SetChildIndex(this.resultNameTextBox, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    protected System.Windows.Forms.TextBox resultNameTextBox;
+    protected System.Windows.Forms.Label resultNameLabel;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultParameterView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultParameterView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultParameterView.cs	(revision 12764)
@@ -0,0 +1,77 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+using HeuristicLab.MainForm;
+using HeuristicLab.Parameters.Views;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("ResultParameter View")]
+  [Content(typeof(ResultParameter<>), true)]
+  [Content(typeof(IResultParameter<>), false)]
+  public partial class ResultParameterView<T> : LookupParameterView<ResultCollection> where T : class, IItem, new() {
+
+    public new IResultParameter<T> Content {
+      get { return (IResultParameter<T>)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ResultParameterView() {
+      InitializeComponent();
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.ResultNameChanged -= new EventHandler(Content_ResultNameChanged);
+      base.DeregisterContentEvents();
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ResultNameChanged += new EventHandler(Content_ResultNameChanged);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null)
+        resultNameTextBox.Text = "-";
+      else
+        resultNameTextBox.Text = Content.ResultName;
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      resultNameTextBox.Enabled = Content != null;
+      resultNameTextBox.ReadOnly = ReadOnly;
+    }
+
+    private void Content_ResultNameChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_ResultNameChanged), sender, e);
+      else
+        resultNameTextBox.Text = Content.ResultName;
+    }
+
+    private void resultNameTextBox_Validated(object sender, EventArgs e) {
+      Content.ResultName = resultNameTextBox.Text;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultValueView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultValueView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultValueView.Designer.cs	(revision 12764)
@@ -0,0 +1,98 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class ResultValueView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      this.viewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.infoLabel = new System.Windows.Forms.Label();
+      this.toolTip = new System.Windows.Forms.ToolTip(this.components);
+      this.SuspendLayout();
+      // 
+      // viewHost
+      // 
+      this.viewHost.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.viewHost.Caption = "View";
+      this.viewHost.Content = null;
+      this.viewHost.Enabled = false;
+      this.viewHost.Location = new System.Drawing.Point(0, 0);
+      this.viewHost.Name = "viewHost";
+      this.viewHost.ReadOnly = false;
+      this.viewHost.Size = new System.Drawing.Size(334, 274);
+      this.viewHost.TabIndex = 0;
+      this.viewHost.ViewsLabelVisible = true;
+      this.viewHost.ViewType = null;
+      // 
+      // infoLabel
+      // 
+      this.infoLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.infoLabel.Image = HeuristicLab.Common.Resources.VSImageLibrary.Information;
+      this.infoLabel.Location = new System.Drawing.Point(340, 3);
+      this.infoLabel.Name = "infoLabel";
+      this.infoLabel.Size = new System.Drawing.Size(16, 16);
+      this.infoLabel.TabIndex = 1;
+      this.toolTip.SetToolTip(this.infoLabel, "Double-click to open description editor.");
+      this.infoLabel.DoubleClick += new System.EventHandler(this.infoLabel_DoubleClick);
+      // 
+      // ResultValueView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.infoLabel);
+      this.Controls.Add(this.viewHost);
+      this.Name = "ResultValueView";
+      this.Size = new System.Drawing.Size(359, 274);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private HeuristicLab.MainForm.WindowsForms.ViewHost viewHost;
+    private System.Windows.Forms.Label infoLabel;
+    private System.Windows.Forms.ToolTip toolTip;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultValueView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultValueView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultValueView.cs	(revision 12764)
@@ -0,0 +1,112 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Windows.Forms;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("Result Value View")]
+  [Content(typeof(Result), true)]
+  [Content(typeof(IResult), false)]
+  public sealed partial class ResultValueView : ItemView {
+    private const string infoLabelToolTipSuffix = "Double-click to open description editor.";
+
+    public new IResult Content {
+      get { return (IResult)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public override bool ReadOnly {
+      get { return true; }
+      set { /*not needed because results are always readonly */}
+    }
+
+    public ResultValueView() {
+      InitializeComponent();
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.NameChanged -= new EventHandler(Content_NameChanged);
+      Content.DescriptionChanged -= new EventHandler(Content_DescriptionChanged);
+      Content.ValueChanged -= new EventHandler(Content_ValueChanged);
+      base.DeregisterContentEvents();
+    }
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.NameChanged += new EventHandler(Content_NameChanged);
+      Content.DescriptionChanged += new EventHandler(Content_DescriptionChanged);
+      Content.ValueChanged += new EventHandler(Content_ValueChanged);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        viewHost.Content = null;
+        toolTip.SetToolTip(infoLabel, string.Empty);
+        if (ViewAttribute.HasViewAttribute(this.GetType()))
+          this.Caption = ViewAttribute.GetViewName(this.GetType());
+        else
+          this.Caption = "ResultValue View";
+      } else {
+        viewHost.ViewType = null;
+        viewHost.Content = Content.Value;
+        toolTip.SetToolTip(infoLabel, string.IsNullOrEmpty(Content.Description) ? infoLabelToolTipSuffix : Content.Description + Environment.NewLine + Environment.NewLine + infoLabelToolTipSuffix);
+        Caption = Content.Name;
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      viewHost.Enabled = Content != null;
+      viewHost.ReadOnly = this.ReadOnly;
+      infoLabel.Enabled = Content != null;
+    }
+
+    private void Content_NameChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_NameChanged), sender, e);
+      else
+        Caption = Content.Name;
+    }
+    private void Content_DescriptionChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_DescriptionChanged), sender, e);
+      else
+        toolTip.SetToolTip(infoLabel, string.IsNullOrEmpty(Content.Description) ? infoLabelToolTipSuffix : Content.Description + Environment.NewLine + Environment.NewLine + infoLabelToolTipSuffix);
+    }
+    private void Content_ValueChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_ValueChanged), sender, e);
+      else {
+        viewHost.Content = Content.Value;
+      }
+    }
+
+    private void infoLabel_DoubleClick(object sender, System.EventArgs e) {
+      using (TextDialog dialog = new TextDialog("Description of " + Content.Name, Content.Description, ReadOnly || !Content.CanChangeDescription)) {
+        if (dialog.ShowDialog(this) == DialogResult.OK)
+          Content.Description = dialog.Content;
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultView.Designer.cs	(revision 12764)
@@ -0,0 +1,157 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class ResultView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.dataTypeLabel = new System.Windows.Forms.Label();
+      this.dataTypeTextBox = new System.Windows.Forms.TextBox();
+      this.valueGroupBox = new System.Windows.Forms.GroupBox();
+      this.valuePanel = new System.Windows.Forms.Panel();
+      this.viewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.valueGroupBox.SuspendLayout();
+      this.valuePanel.SuspendLayout();
+      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(69, 0);
+      this.nameTextBox.Size = new System.Drawing.Size(265, 20);
+      // 
+      // infoLabel
+      // 
+      this.infoLabel.Location = new System.Drawing.Point(340, 3);
+      // 
+      // dataTypeLabel
+      // 
+      this.dataTypeLabel.AutoSize = true;
+      this.dataTypeLabel.Location = new System.Drawing.Point(3, 29);
+      this.dataTypeLabel.Name = "dataTypeLabel";
+      this.dataTypeLabel.Size = new System.Drawing.Size(60, 13);
+      this.dataTypeLabel.TabIndex = 3;
+      this.dataTypeLabel.Text = "Data &Type:";
+      // 
+      // dataTypeTextBox
+      // 
+      this.dataTypeTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.dataTypeTextBox.Location = new System.Drawing.Point(69, 26);
+      this.dataTypeTextBox.Name = "dataTypeTextBox";
+      this.dataTypeTextBox.ReadOnly = true;
+      this.dataTypeTextBox.Size = new System.Drawing.Size(290, 20);
+      this.dataTypeTextBox.TabIndex = 4;
+      // 
+      // valueGroupBox
+      // 
+      this.valueGroupBox.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.valueGroupBox.Controls.Add(this.valuePanel);
+      this.valueGroupBox.Location = new System.Drawing.Point(0, 52);
+      this.valueGroupBox.Name = "valueGroupBox";
+      this.valueGroupBox.Size = new System.Drawing.Size(359, 222);
+      this.valueGroupBox.TabIndex = 5;
+      this.valueGroupBox.TabStop = false;
+      this.valueGroupBox.Text = "Value";
+      // 
+      // valuePanel
+      // 
+      this.valuePanel.AllowDrop = true;
+      this.valuePanel.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.valuePanel.Controls.Add(this.viewHost);
+      this.valuePanel.Location = new System.Drawing.Point(6, 19);
+      this.valuePanel.Name = "valuePanel";
+      this.valuePanel.Size = new System.Drawing.Size(347, 197);
+      this.valuePanel.TabIndex = 2;
+      // 
+      // viewHost
+      // 
+      this.viewHost.Caption = "View";
+      this.viewHost.Content = null;
+      this.viewHost.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.viewHost.Enabled = false;
+      this.viewHost.Location = new System.Drawing.Point(0, 0);
+      this.viewHost.Name = "viewHost";
+      this.viewHost.ReadOnly = false;
+      this.viewHost.Size = new System.Drawing.Size(347, 197);
+      this.viewHost.TabIndex = 0;
+      this.viewHost.ViewsLabelVisible = true;
+      this.viewHost.ViewType = null;
+      // 
+      // ResultView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.valueGroupBox);
+      this.Controls.Add(this.dataTypeLabel);
+      this.Controls.Add(this.dataTypeTextBox);
+      this.Name = "ResultView";
+      this.Size = new System.Drawing.Size(359, 274);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      this.Controls.SetChildIndex(this.dataTypeTextBox, 0);
+      this.Controls.SetChildIndex(this.dataTypeLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.valueGroupBox, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.valueGroupBox.ResumeLayout(false);
+      this.valuePanel.ResumeLayout(false);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Label dataTypeLabel;
+    private System.Windows.Forms.TextBox dataTypeTextBox;
+    private System.Windows.Forms.GroupBox valueGroupBox;
+    private HeuristicLab.MainForm.WindowsForms.ViewHost viewHost;
+    private System.Windows.Forms.Panel valuePanel;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/ResultView.cs	(revision 12764)
@@ -0,0 +1,83 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Windows.Forms;
+using HeuristicLab.Common;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("Result View")]
+  [Content(typeof(Result), false)]
+  [Content(typeof(IResult), false)]
+  public sealed partial class ResultView : NamedItemView {
+    public new IResult Content {
+      get { return (IResult)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public override bool ReadOnly {
+      get { return true; }
+      set { /*not needed because results are always readonly */}
+    }
+
+    public ResultView() {
+      InitializeComponent();
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.ValueChanged -= new EventHandler(Content_ValueChanged);
+      base.DeregisterContentEvents();
+    }
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ValueChanged += new EventHandler(Content_ValueChanged);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        dataTypeTextBox.Text = "-";
+        viewHost.Content = null;
+      } else {
+        dataTypeTextBox.Text = Content.DataType.GetPrettyName();
+        viewHost.ViewType = null;
+        viewHost.Content = Content.Value;
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      dataTypeTextBox.Enabled = Content != null;
+      viewHost.Enabled = Content != null;
+      viewHost.ReadOnly = this.ReadOnly;
+    }
+
+    private void Content_ValueChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_ValueChanged), sender, e);
+      else {
+        viewHost.Content = Content.Value;
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionColumnConstraintView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionColumnConstraintView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionColumnConstraintView.Designer.cs	(revision 12764)
@@ -0,0 +1,143 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class RunCollectionColumnConstraintView {
+    /// <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.lblConstrainedMember = new System.Windows.Forms.Label();
+      this.lblComparisonOperation = new System.Windows.Forms.Label();
+      this.lblCompareValue = new System.Windows.Forms.Label();
+      this.cmbConstraintOperation = new System.Windows.Forms.ComboBox();
+      this.chbActive = new System.Windows.Forms.CheckBox();
+      this.cmbConstraintColumn = new System.Windows.Forms.ComboBox();
+      this.SuspendLayout();
+      // 
+      // lblConstrainedMember
+      // 
+      this.lblConstrainedMember.AutoSize = true;
+      this.lblConstrainedMember.Location = new System.Drawing.Point(3, 6);
+      this.lblConstrainedMember.Name = "lblConstrainedMember";
+      this.lblConstrainedMember.Size = new System.Drawing.Size(107, 13);
+      this.lblConstrainedMember.TabIndex = 0;
+      this.lblConstrainedMember.Text = "Constrained Member:";
+      // 
+      // lblComparisonOperation
+      // 
+      this.lblComparisonOperation.AutoSize = true;
+      this.lblComparisonOperation.Location = new System.Drawing.Point(3, 32);
+      this.lblComparisonOperation.Name = "lblComparisonOperation";
+      this.lblComparisonOperation.Size = new System.Drawing.Size(106, 13);
+      this.lblComparisonOperation.TabIndex = 1;
+      this.lblComparisonOperation.Text = "Constraint Operation:";
+      // 
+      // lblCompareValue
+      // 
+      this.lblCompareValue.AutoSize = true;
+      this.lblCompareValue.Location = new System.Drawing.Point(3, 59);
+      this.lblCompareValue.Name = "lblCompareValue";
+      this.lblCompareValue.Size = new System.Drawing.Size(83, 13);
+      this.lblCompareValue.TabIndex = 2;
+      this.lblCompareValue.Text = "Constraint Data:";
+      // 
+      // cmbConstraintOperation
+      // 
+      this.cmbConstraintOperation.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.cmbConstraintOperation.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.cmbConstraintOperation.FormattingEnabled = true;
+      this.cmbConstraintOperation.Location = new System.Drawing.Point(127, 29);
+      this.cmbConstraintOperation.Name = "cmbConstraintOperation";
+      this.cmbConstraintOperation.Size = new System.Drawing.Size(246, 21);
+      this.cmbConstraintOperation.TabIndex = 4;
+      this.cmbConstraintOperation.SelectedIndexChanged += new System.EventHandler(this.cmbComparisonOperation_SelectedIndexChanged);
+      // 
+      // chbActive
+      // 
+      this.chbActive.AutoSize = true;
+      this.chbActive.Location = new System.Drawing.Point(127, 82);
+      this.chbActive.Name = "chbActive";
+      this.chbActive.Size = new System.Drawing.Size(56, 17);
+      this.chbActive.TabIndex = 7;
+      this.chbActive.Text = "Active";
+      this.chbActive.UseVisualStyleBackColor = true;
+      this.chbActive.CheckedChanged += new System.EventHandler(this.chbActive_CheckedChanged);
+      // 
+      // cmbConstraintColumn
+      // 
+      this.cmbConstraintColumn.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.cmbConstraintColumn.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.cmbConstraintColumn.FormattingEnabled = true;
+      this.cmbConstraintColumn.Location = new System.Drawing.Point(127, 3);
+      this.cmbConstraintColumn.Name = "cmbConstraintColumn";
+      this.cmbConstraintColumn.Size = new System.Drawing.Size(246, 21);
+      this.cmbConstraintColumn.TabIndex = 8;
+      this.cmbConstraintColumn.SelectedIndexChanged += new System.EventHandler(this.cmbConstraintColumn_SelectedIndexChanged);
+      // 
+      // RunCollectionConstraintView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.cmbConstraintColumn);
+      this.Controls.Add(this.chbActive);
+      this.Controls.Add(this.cmbConstraintOperation);
+      this.Controls.Add(this.lblCompareValue);
+      this.Controls.Add(this.lblComparisonOperation);
+      this.Controls.Add(this.lblConstrainedMember);
+      this.Name = "RunCollectionConstraintView";
+      this.Size = new System.Drawing.Size(376, 102);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Label lblConstrainedMember;
+    private System.Windows.Forms.Label lblComparisonOperation;
+    private System.Windows.Forms.Label lblCompareValue;
+    private System.Windows.Forms.CheckBox chbActive;
+    protected System.Windows.Forms.ComboBox cmbConstraintColumn;
+    protected System.Windows.Forms.ComboBox cmbConstraintOperation;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionColumnConstraintView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionColumnConstraintView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionColumnConstraintView.cs	(revision 12764)
@@ -0,0 +1,125 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Optimization.Views {
+  [Content(typeof(IRunCollectionColumnConstraint))]
+  public partial class RunCollectionColumnConstraintView : ItemView {
+    public RunCollectionColumnConstraintView() {
+      InitializeComponent();
+    }
+
+    public new IRunCollectionColumnConstraint Content {
+      get { return (IRunCollectionColumnConstraint)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      cmbConstraintColumn.Items.Clear();
+      cmbConstraintOperation.Items.Clear();
+
+      if (Content != null) {
+        cmbConstraintOperation.Items.AddRange(Content.AllowedConstraintOperations.ToArray());
+        if (Content.ConstraintOperation != null)
+          cmbConstraintOperation.SelectedItem = Content.ConstraintOperation;
+        else if (cmbConstraintOperation.Items.Count != 0)
+          cmbConstraintOperation.SelectedIndex = 0;
+        UpdateColumnComboBox();
+        chbActive.Checked = Content.Active;
+        ReadOnly = Content.Active;
+      } else
+        chbActive.Checked = false;
+    }
+
+    protected virtual void UpdateColumnComboBox() {
+      this.cmbConstraintColumn.Items.Clear();
+      if (Content.ConstrainedValue != null) {
+        this.cmbConstraintColumn.Items.AddRange(((IStringConvertibleMatrix)Content.ConstrainedValue).ColumnNames.ToArray());
+        if (!string.IsNullOrEmpty(Content.ConstraintColumn))
+          this.cmbConstraintColumn.SelectedItem = Content.ConstraintColumn;
+      }
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      this.Content.ActiveChanged += new EventHandler(Content_ActiveChanged);
+      this.Content.ConstraintOperationChanged += new EventHandler(Content_ComparisonOperationChanged);
+      this.Content.ConstraintColumnChanged += new EventHandler(Content_ConstraintColumnChanged);
+      this.Content.ConstrainedValueChanged += new EventHandler(Content_ConstrainedValueChanged);
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      this.Content.ActiveChanged -= new EventHandler(Content_ActiveChanged);
+      this.Content.ConstraintOperationChanged -= new EventHandler(Content_ComparisonOperationChanged);
+      this.Content.ConstraintColumnChanged -= new EventHandler(Content_ConstraintColumnChanged);
+      this.Content.ConstrainedValueChanged += new EventHandler(Content_ConstrainedValueChanged);
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      cmbConstraintColumn.Enabled = !this.ReadOnly && Content != null;
+      cmbConstraintOperation.Enabled = !this.ReadOnly && Content != null;
+      chbActive.Enabled = !this.Locked && Content != null;
+    }
+
+    protected virtual void Content_ConstrainedValueChanged(object sender, EventArgs e) {
+      this.UpdateColumnComboBox();
+    }
+
+    protected virtual void Content_ConstraintColumnChanged(object sender, EventArgs e) {
+      if (Content.ConstrainedValue != null) {
+        if (cmbConstraintColumn.SelectedItem.ToString() != Content.ConstraintColumn)
+          cmbConstraintColumn.SelectedItem = Content.ConstraintColumn;
+      }
+    }
+    private void cmbConstraintColumn_SelectedIndexChanged(object sender, EventArgs e) {
+      if (Content.ConstrainedValue != null) {
+        Content.ConstraintColumn = (string)cmbConstraintColumn.SelectedItem;
+      }
+    }
+
+    protected virtual void Content_ComparisonOperationChanged(object sender, EventArgs e) {
+      if (Content.ConstraintOperation != (ConstraintOperation)this.cmbConstraintOperation.SelectedItem)
+        this.cmbConstraintOperation.SelectedItem = Content.ConstraintOperation;
+    }
+    protected virtual void cmbComparisonOperation_SelectedIndexChanged(object sender, EventArgs e) {
+      Content.ConstraintOperation = (ConstraintOperation)this.cmbConstraintOperation.SelectedItem;
+    }
+
+    protected virtual void Content_ActiveChanged(object sender, EventArgs e) {
+      if (this.chbActive.Checked != Content.Active)
+        this.chbActive.Checked = Content.Active;
+      this.ReadOnly = Content.Active;
+    }
+    protected virtual void chbActive_CheckedChanged(object sender, EventArgs e) {
+      if (Content != null)
+        Content.Active = chbActive.Checked;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionComparisonConstraintView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionComparisonConstraintView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionComparisonConstraintView.Designer.cs	(revision 12764)
@@ -0,0 +1,91 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class RunCollectionComparisonConstraintView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      this.txtConstraintData = new System.Windows.Forms.TextBox();
+      this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // txtConstraintData
+      // 
+      this.txtConstraintData.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.errorProvider.SetIconAlignment(this.txtConstraintData, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.txtConstraintData, 2);
+      this.txtConstraintData.Location = new System.Drawing.Point(127, 56);
+      this.txtConstraintData.Name = "txtConstraintData";
+      this.txtConstraintData.Size = new System.Drawing.Size(246, 20);
+      this.txtConstraintData.TabIndex = 9;
+      this.txtConstraintData.Validated += new System.EventHandler(this.txtConstraintData_Validated);
+      this.txtConstraintData.Validating += new System.ComponentModel.CancelEventHandler(this.txtConstraintData_Validating);
+      // 
+      // errorProvider
+      // 
+      this.errorProvider.ContainerControl = this;
+      // 
+      // RunCollectionComparisonConstraintView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.txtConstraintData);
+      this.errorProvider.SetIconAlignment(this, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.Name = "RunCollectionComparisonConstraintView";
+      this.Controls.SetChildIndex(this.txtConstraintData, 0);
+      this.Controls.SetChildIndex(this.cmbConstraintOperation, 0);
+      this.Controls.SetChildIndex(this.cmbConstraintColumn, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.TextBox txtConstraintData;
+    private System.Windows.Forms.ErrorProvider errorProvider;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionComparisonConstraintView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionComparisonConstraintView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionComparisonConstraintView.cs	(revision 12764)
@@ -0,0 +1,114 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Optimization.Views {
+  [Content(typeof(RunCollectionComparisonConstraint), true)]
+  public partial class RunCollectionComparisonConstraintView : RunCollectionColumnConstraintView {
+    public RunCollectionComparisonConstraintView() {
+      InitializeComponent();
+    }
+
+    public new RunCollectionComparisonConstraint Content {
+      get { return (RunCollectionComparisonConstraint)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null || Content.ConstraintData == null)
+        this.txtConstraintData.Text = string.Empty;
+      else
+        this.txtConstraintData.Text = Content.ConstraintData.GetValue();
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ConstraintDataChanged += new EventHandler(Content_ConstraintDataChanged);
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.ConstraintDataChanged -= new EventHandler(Content_ConstraintDataChanged);
+    }
+
+    protected override void UpdateColumnComboBox() {
+      this.cmbConstraintColumn.Items.Clear();
+      if (Content.ConstrainedValue != null) {
+        IStringConvertibleMatrix matrix = (IStringConvertibleMatrix)Content.ConstrainedValue;
+        foreach (string columnName in matrix.ColumnNames) {
+          IEnumerable<Type> dataTypes = Content.ConstrainedValue.GetDataType(columnName);
+          if (dataTypes.Count() == 1) {
+            Type dataType = dataTypes.First();
+            if (typeof(IStringConvertibleValue).IsAssignableFrom(dataType) && typeof(IComparable).IsAssignableFrom(dataType))
+              this.cmbConstraintColumn.Items.Add(columnName);
+          }
+        }
+        if (!string.IsNullOrEmpty(Content.ConstraintColumn)) {
+          this.cmbConstraintColumn.SelectedItem = Content.ConstraintColumn;
+          if (Content.ConstraintData != null)
+            txtConstraintData.Text = Content.ConstraintData.GetValue();
+          else
+            this.Content_ConstraintColumnChanged(cmbConstraintColumn, EventArgs.Empty);
+        }
+      }
+    }
+
+    protected override void Content_ConstraintColumnChanged(object sender, EventArgs e) {
+      base.Content_ConstraintColumnChanged(sender, e);
+      this.Content.ConstraintData = (IStringConvertibleValue)Activator.CreateInstance(Content.ConstrainedValue.GetDataType(cmbConstraintColumn.SelectedItem.ToString()).First());
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      txtConstraintData.Enabled = Content != null;
+      txtConstraintData.ReadOnly = ReadOnly;
+    }
+
+    protected virtual void Content_ConstraintDataChanged(object sender, EventArgs e) {
+      if (Content.ConstraintData != null)
+        txtConstraintData.Text = Content.ConstraintData.GetValue();
+      else
+        txtConstraintData.Text = string.Empty;
+    }
+
+    private void txtConstraintData_Validated(object sender, EventArgs e) {
+      IStringConvertibleValue value = (IStringConvertibleValue)Activator.CreateInstance(Content.ConstrainedValue.GetDataType(cmbConstraintColumn.SelectedItem.ToString()).First());
+      value.SetValue(txtConstraintData.Text);
+      Content.ConstraintData = value;
+    }
+
+    private void txtConstraintData_Validating(object sender, CancelEventArgs e) {
+      string errorMessage = string.Empty;
+      if (!Content.ConstraintData.Validate(txtConstraintData.Text, out errorMessage)) {
+        errorProvider.SetError(txtConstraintData, errorMessage);
+        e.Cancel = true;
+      } else
+        errorProvider.Clear();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionConstraintCollectionView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionConstraintCollectionView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionConstraintCollectionView.Designer.cs	(revision 12764)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class RunCollectionConstraintCollectionView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+    }
+
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionConstraintCollectionView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionConstraintCollectionView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionConstraintCollectionView.cs	(revision 12764)
@@ -0,0 +1,87 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("ConstraintCollection View")]
+  [Content(typeof(RunCollectionConstraintCollection), true)]
+  [Content(typeof(IItemCollection<IRunCollectionConstraint>), false)]
+  public partial class RunCollectionConstraintCollectionView : ItemCollectionView<IRunCollectionConstraint> {
+    public RunCollectionConstraintCollectionView() {
+      InitializeComponent();
+      itemsGroupBox.Text = "RunCollection Constraints";
+    }
+
+    protected override IRunCollectionConstraint CreateItem() {
+      if (typeSelectorDialog == null) {
+        typeSelectorDialog = new TypeSelectorDialog();
+        typeSelectorDialog.Caption = "Select RunCollection Constraint";
+        typeSelectorDialog.TypeSelector.Caption = "Available Constraints";
+        typeSelectorDialog.TypeSelector.Configure(typeof(IRunCollectionConstraint), false, true);
+      }
+
+      if (typeSelectorDialog.ShowDialog(this) == DialogResult.OK) {
+        try {
+          return (IRunCollectionConstraint)typeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
+        }
+        catch (Exception ex) {
+          ErrorHandling.ShowErrorDialog(this, ex);
+        }
+      }
+      return null;
+    }
+
+    protected override ListViewItem CreateListViewItem(IRunCollectionConstraint item) {
+      ListViewItem listViewItem = base.CreateListViewItem(item);
+      if (item != null) {
+        listViewItem.Font = item.Active ? new Font(listViewItem.Font, FontStyle.Bold) : new Font(listViewItem.Font, FontStyle.Regular);
+      }
+      return listViewItem;
+    }
+
+    protected override void DeregisterItemEvents(IRunCollectionConstraint item) {
+      item.ActiveChanged -= new EventHandler(Item_ActiveChanged);
+      base.DeregisterItemEvents(item);
+    }
+    protected override void RegisterItemEvents(IRunCollectionConstraint item) {
+      base.RegisterItemEvents(item);
+      item.ActiveChanged += new EventHandler(Item_ActiveChanged);
+    }
+
+    protected virtual void Item_ActiveChanged(object sender, EventArgs e) {
+      IRunCollectionConstraint constraint = (IRunCollectionConstraint)sender;
+      foreach (ListViewItem listViewItem in GetListViewItemsForItem(constraint)) {
+        if (constraint.Active)
+          listViewItem.Font = new Font(listViewItem.Font, FontStyle.Bold);
+        else
+          listViewItem.Font = new Font(listViewItem.Font, FontStyle.Regular);
+      }
+      this.AdjustListViewColumnSizes();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionContentConstraintView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionContentConstraintView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionContentConstraintView.Designer.cs	(revision 12764)
@@ -0,0 +1,93 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Windows.Forms;
+
+namespace HeuristicLab.Optimization.Views {
+  partial class RunCollectionContentConstraintView {
+    /// <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.chbActive = new System.Windows.Forms.CheckBox();
+      this.runsView = new HeuristicLab.Optimization.Views.RunCollectionContentConstraintView.RunSetView();
+      this.SuspendLayout();
+      // 
+      // chbActive
+      // 
+      this.chbActive.AutoSize = true;
+      this.chbActive.Location = new System.Drawing.Point(3, 3);
+      this.chbActive.Name = "chbActive";
+      this.chbActive.Size = new System.Drawing.Size(56, 17);
+      this.chbActive.TabIndex = 7;
+      this.chbActive.Text = "Active";
+      this.chbActive.UseVisualStyleBackColor = true;
+      this.chbActive.CheckedChanged += new System.EventHandler(this.chbActive_CheckedChanged);
+      // 
+      // operatorSetView1
+      // 
+      this.runsView.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom;
+      this.runsView.Caption = "Runs View";
+      this.runsView.Content = null;
+      this.runsView.Location = new System.Drawing.Point(3, 26);
+      this.runsView.Name = "runsView";
+      this.runsView.ReadOnly = false;
+      this.runsView.Size = new System.Drawing.Size(309, 323);
+      this.runsView.TabIndex = 8;
+      // 
+      // RunCollectionContentConstraintView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.runsView);
+      this.Controls.Add(this.chbActive);
+      this.Name = "RunCollectionContentConstraintView";
+      this.Size = new System.Drawing.Size(315, 352);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.CheckBox chbActive;
+    private RunSetView runsView;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionContentConstraintView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionContentConstraintView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionContentConstraintView.cs	(revision 12764)
@@ -0,0 +1,111 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Common;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Optimization.Views {
+  [Content(typeof(RunCollectionContentConstraint), true)]
+  public partial class RunCollectionContentConstraintView : ItemView {
+    public RunCollectionContentConstraintView() {
+      InitializeComponent();
+      runsView.ShowDetails = false;
+    }
+
+    public new RunCollectionContentConstraint Content {
+      get { return (RunCollectionContentConstraint)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content != null) {
+        chbActive.Checked = Content.Active;
+        ReadOnly = Content.Active;
+        runsView.RunCollection = Content.ConstrainedValue;
+        runsView.Content = Content.ConstraintData;
+      } else {
+        chbActive.Checked = false;
+        runsView.RunCollection = null;
+        runsView.Content = null;
+      }
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ActiveChanged += new EventHandler(Content_ActiveChanged);
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.ActiveChanged -= new EventHandler(Content_ActiveChanged);
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      chbActive.Enabled = !Locked && Content != null;
+      runsView.Enabled = !Locked && Content != null;
+    }
+
+    protected virtual void Content_ActiveChanged(object sender, EventArgs e) {
+      chbActive.Checked = Content.Active;
+      ReadOnly = Content.Active;
+    }
+    protected virtual void chbActive_CheckedChanged(object sender, EventArgs e) {
+      if (Content != null)
+        Content.Active = chbActive.Checked;
+    }
+
+    private class RunSetView : ItemSetView<IRun> {
+      public RunCollection RunCollection { get; set; }
+
+      public RunSetView()
+        : base() {
+        addButton.Enabled = false;
+      }
+
+      protected override void SetEnabledStateOfControls() {
+        base.SetEnabledStateOfControls();
+        addButton.Enabled = false;
+      }
+
+      protected override void itemsListView_DragEnter(object sender, DragEventArgs e) {
+        base.itemsListView_DragEnter(sender, e);
+        if (RunCollection != null) {
+          var dropData = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+          foreach (var run in dropData.GetObjectGraphObjects().OfType<IRun>())
+            validDragOperation = validDragOperation && RunCollection.Contains(run);
+        }
+      }
+
+      protected override void itemsListView_DragOver(object sender, DragEventArgs e) {
+        e.Effect = DragDropEffects.None;
+        if (validDragOperation && !draggedItemsAlreadyContained) {
+          e.Effect = DragDropEffects.Link;
+        }
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionEqualityConstraintView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionEqualityConstraintView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionEqualityConstraintView.Designer.cs	(revision 12764)
@@ -0,0 +1,78 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class RunCollectionEqualityConstraintView {
+    /// <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.txtConstraintData = new System.Windows.Forms.TextBox();
+      this.SuspendLayout();
+      // 
+      // txtConstraintData
+      // 
+      this.txtConstraintData.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.txtConstraintData.Location = new System.Drawing.Point(127, 56);
+      this.txtConstraintData.Name = "txtConstraintData";
+      this.txtConstraintData.Size = new System.Drawing.Size(246, 20);
+      this.txtConstraintData.TabIndex = 9;
+      this.txtConstraintData.TextChanged += new System.EventHandler(this.txtConstraintData_TextChanged);
+      // 
+      // RunCollectionEqualityConstraintView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.txtConstraintData);
+      this.Name = "RunCollectionEqualityConstraintView";
+      this.Controls.SetChildIndex(this.txtConstraintData, 0);
+      this.Controls.SetChildIndex(this.cmbConstraintOperation, 0);
+      this.Controls.SetChildIndex(this.cmbConstraintColumn, 0);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.TextBox txtConstraintData;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionEqualityConstraintView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionEqualityConstraintView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionEqualityConstraintView.cs	(revision 12764)
@@ -0,0 +1,56 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Optimization.Views {
+  [Content(typeof(RunCollectionEqualityConstraint), true)]
+  public partial class RunCollectionEqualityConstraintView : RunCollectionColumnConstraintView {
+    public RunCollectionEqualityConstraintView() {
+      InitializeComponent();
+    }
+
+    public new RunCollectionEqualityConstraint Content {
+      get { return (RunCollectionEqualityConstraint)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null || Content.ConstraintData == null)
+        this.txtConstraintData.Text = string.Empty;
+      else
+        this.txtConstraintData.Text = Content.ConstraintData.ToString();
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      txtConstraintData.Enabled = Content != null;
+      txtConstraintData.ReadOnly = ReadOnly;
+    }
+
+    private void txtConstraintData_TextChanged(object sender, EventArgs e) {
+      if (Content != null)
+        Content.ConstraintData = txtConstraintData.Text;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionTypeCompatibilityConstraintView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionTypeCompatibilityConstraintView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionTypeCompatibilityConstraintView.Designer.cs	(revision 12764)
@@ -0,0 +1,81 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class RunCollectionTypeCompatibilityConstraintView {
+    /// <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.cmbType = new System.Windows.Forms.ComboBox();
+      this.SuspendLayout();
+      // 
+      // cmbType
+      // 
+      this.cmbType.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.cmbType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.cmbType.FormattingEnabled = true;
+      this.cmbType.Location = new System.Drawing.Point(127, 55);
+      this.cmbType.Name = "cmbType";
+      this.cmbType.Size = new System.Drawing.Size(246, 21);
+      this.cmbType.TabIndex = 9;
+      this.cmbType.SelectedIndexChanged += new System.EventHandler(this.cmbType_SelectedIndexChanged);
+      // 
+      // RunCollectionTypeCompatibilityConstraintView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.cmbType);
+      this.Name = "RunCollectionTypeCompatibilityConstraintView";
+      this.Controls.SetChildIndex(this.cmbType, 0);
+      this.Controls.SetChildIndex(this.cmbConstraintOperation, 0);
+      this.Controls.SetChildIndex(this.cmbConstraintColumn, 0);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.ComboBox cmbType;
+
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionTypeCompatibilityConstraintView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionTypeCompatibilityConstraintView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionTypeCompatibilityConstraintView.cs	(revision 12764)
@@ -0,0 +1,79 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Optimization.Views {
+  [Content(typeof(RunCollectionTypeCompatibilityConstraint), true)]
+  public partial class RunCollectionTypeCompatibilityConstraintView : RunCollectionColumnConstraintView {
+    public RunCollectionTypeCompatibilityConstraintView() {
+      InitializeComponent();
+      cmbType.DisplayMember = "Name";
+    }
+
+    public new RunCollectionTypeCompatibilityConstraint Content {
+      get { return (RunCollectionTypeCompatibilityConstraint)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void Content_ConstraintColumnChanged(object sender, EventArgs e) {
+      base.Content_ConstraintColumnChanged(sender, e);
+      UpdateTypeColumn();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      UpdateTypeColumn();
+    }
+
+    protected virtual void UpdateTypeColumn() {
+      cmbType.Items.Clear();
+      if (Content != null && Content.ConstrainedValue != null) {
+        foreach (Type t in Content.ConstrainedValue.GetDataType(cmbConstraintColumn.SelectedItem.ToString()))
+          cmbType.Items.Add(t);
+        if (Content.ConstraintData != null)
+          cmbType.SelectedItem = Content.ConstraintData;
+        else if (cmbType.Items.Count > 0)
+          cmbType.SelectedIndex = 0;
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      cmbType.Enabled = Content != null && !this.ReadOnly;
+    }
+
+    private void cmbType_SelectedIndexChanged(object sender, EventArgs e) {
+      if (Content != null)
+        Content.ConstraintData = (Type)cmbType.SelectedItem;
+    }
+
+    private struct ComboBoxItem {
+      public ComboBoxItem(string name, Type type) {
+        this.Name = name;
+        this.Type = type;
+      }
+      public string Name;
+      public Type Type;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionModifierListView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionModifierListView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionModifierListView.Designer.cs	(revision 12764)
@@ -0,0 +1,84 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+
+namespace HeuristicLab.Optimization.Views {
+  partial class RunCollectionModifiersListView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.evaluateButton = new System.Windows.Forms.Button();
+      this.SuspendLayout();
+      //
+      // splitContainer.Panel1
+      //
+      this.splitContainer.Panel1.Controls.Add(this.evaluateButton);
+      //
+      // showDetailsCheckBox 
+      //
+      this.showDetailsCheckBox.Location = new System.Drawing.Point(153, 3);
+      this.showDetailsCheckBox.TabIndex = 5;
+      //
+      // evaluateButton
+      //
+      this.evaluateButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Play;
+      this.evaluateButton.Location = new System.Drawing.Point(123, 3);
+      this.evaluateButton.Name = "evaluateButton";
+      this.evaluateButton.Size = new System.Drawing.Size(24, 24);
+      this.evaluateButton.TabIndex = 4;
+      this.toolTip.SetToolTip(this.evaluateButton, "Evaluate");
+      this.evaluateButton.UseVisualStyleBackColor = true;
+      this.evaluateButton.Click += new System.EventHandler(this.evaluateButton_Click);
+      //
+      // itemListView
+      //
+      this.itemsListView.TabIndex = 6;
+      this.ResumeLayout(false);
+    }
+
+    protected System.Windows.Forms.Button evaluateButton;
+
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionModifierListView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionModifierListView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionModifierListView.cs	(revision 12764)
@@ -0,0 +1,75 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Optimization.Views {
+
+  [View("Modifier View")]
+  [Content(typeof(ICheckedItemList<IRunCollectionModifier>), false)]
+  public partial class RunCollectionModifiersListView : CheckedItemListView<IRunCollectionModifier> {
+
+    public Action Evaluator { get; set; }
+
+    public RunCollectionModifiersListView() {
+      InitializeComponent();
+      itemsGroupBox.Text = "RunCollection Modifiers";
+    }
+
+    protected override IRunCollectionModifier CreateItem() {
+      if (typeSelectorDialog == null) {
+        typeSelectorDialog = new TypeSelectorDialog();
+        typeSelectorDialog.Caption = "Select RunCollection Modifiers";
+        typeSelectorDialog.TypeSelector.Caption = "Available Modifiers";
+        typeSelectorDialog.TypeSelector.Configure(typeof(IRunCollectionModifier), false, true);
+      }
+
+      if (typeSelectorDialog.ShowDialog(this) == DialogResult.OK) {
+        try {
+          return (IRunCollectionModifier)typeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
+        } catch (Exception ex) {
+          ErrorHandling.ShowErrorDialog(this, ex);
+        }
+      }
+      return null;
+    }
+
+    private void evaluateButton_Click(object sender, EventArgs e) {
+      var evaluator = Evaluator;
+      evaluateButton.Enabled = false;
+      var worker = new BackgroundWorker();
+      worker.DoWork += (s, a) => evaluator();
+      worker.RunWorkerCompleted += (s, a) => {
+        evaluateButton.Enabled = Content != null;
+        if (a.Error != null)
+          new ErrorDialog("Evaluation Failed", a.Error).ShowDialog(ParentForm);
+      };
+      worker.RunWorkerAsync();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBoxPlotView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBoxPlotView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBoxPlotView.Designer.cs	(revision 12764)
@@ -0,0 +1,242 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class RunCollectionBoxPlotView {
+    /// <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.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
+      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RunCollectionBoxPlotView));
+      this.xAxisLabel = new System.Windows.Forms.Label();
+      this.xAxisComboBox = new System.Windows.Forms.ComboBox();
+      this.yAxisLabel = new System.Windows.Forms.Label();
+      this.yAxisComboBox = new System.Windows.Forms.ComboBox();
+      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      this.noRunsLabel = new System.Windows.Forms.Label();
+      this.splitContainer = new System.Windows.Forms.SplitContainer();
+      this.showStatisticsCheckBox = new System.Windows.Forms.CheckBox();
+      this.statisticsGroupBox = new System.Windows.Forms.GroupBox();
+      this.statisticsMatrixView = new HeuristicLab.Data.Views.StringConvertibleMatrixView();
+      this.tooltip = new System.Windows.Forms.ToolTip(this.components);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.statisticsGroupBox.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // xAxisLabel
+      // 
+      this.xAxisLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.xAxisLabel.AutoSize = true;
+      this.xAxisLabel.Location = new System.Drawing.Point(363, 345);
+      this.xAxisLabel.Name = "xAxisLabel";
+      this.xAxisLabel.Size = new System.Drawing.Size(15, 13);
+      this.xAxisLabel.TabIndex = 12;
+      this.xAxisLabel.Text = "x:";
+      // 
+      // xAxisComboBox
+      // 
+      this.xAxisComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.xAxisComboBox.BackColor = System.Drawing.SystemColors.ControlLightLight;
+      this.xAxisComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.xAxisComboBox.FormattingEnabled = true;
+      this.xAxisComboBox.Location = new System.Drawing.Point(384, 342);
+      this.xAxisComboBox.Name = "xAxisComboBox";
+      this.xAxisComboBox.Size = new System.Drawing.Size(600, 21);
+      this.xAxisComboBox.TabIndex = 11;
+      this.xAxisComboBox.SelectedIndexChanged += new System.EventHandler(this.AxisComboBox_SelectedIndexChanged);
+      // 
+      // yAxisLabel
+      // 
+      this.yAxisLabel.AutoSize = true;
+      this.yAxisLabel.Location = new System.Drawing.Point(3, 6);
+      this.yAxisLabel.Name = "yAxisLabel";
+      this.yAxisLabel.Size = new System.Drawing.Size(15, 13);
+      this.yAxisLabel.TabIndex = 10;
+      this.yAxisLabel.Text = "y:";
+      // 
+      // yAxisComboBox
+      // 
+      this.yAxisComboBox.BackColor = System.Drawing.SystemColors.ControlLightLight;
+      this.yAxisComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.yAxisComboBox.FormattingEnabled = true;
+      this.yAxisComboBox.Location = new System.Drawing.Point(24, 3);
+      this.yAxisComboBox.Name = "yAxisComboBox";
+      this.yAxisComboBox.Size = new System.Drawing.Size(600, 21);
+      this.yAxisComboBox.TabIndex = 9;
+      this.yAxisComboBox.SelectedIndexChanged += new System.EventHandler(this.AxisComboBox_SelectedIndexChanged);
+      // 
+      // chart
+      // 
+      this.chart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      chartArea1.Name = "ChartArea1";
+      this.chart.ChartAreas.Add(chartArea1);
+      this.chart.Location = new System.Drawing.Point(-1, 30);
+      this.chart.Name = "chart";
+      series1.ChartArea = "ChartArea1";
+      series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.BoxPlot;
+      series1.IsVisibleInLegend = false;
+      series1.MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.Circle;
+      series1.Name = "DataSeries";
+      series1.YValuesPerPoint = 6;
+      this.chart.Series.Add(series1);
+      this.chart.Size = new System.Drawing.Size(989, 306);
+      this.chart.TabIndex = 17;
+      this.chart.Text = "chart";
+      this.chart.AxisViewChanged += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.ViewEventArgs>(this.chart_AxisViewChanged);
+      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
+      // 
+      // noRunsLabel
+      // 
+      this.noRunsLabel.Anchor = System.Windows.Forms.AnchorStyles.None;
+      this.noRunsLabel.AutoSize = true;
+      this.noRunsLabel.Location = new System.Drawing.Point(434, 167);
+      this.noRunsLabel.Name = "noRunsLabel";
+      this.noRunsLabel.Size = new System.Drawing.Size(138, 13);
+      this.noRunsLabel.TabIndex = 22;
+      this.noRunsLabel.Text = "No runs could be displayed.";
+      // 
+      // splitContainer
+      // 
+      this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.splitContainer.Location = new System.Drawing.Point(0, 0);
+      this.splitContainer.Name = "splitContainer";
+      this.splitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.showStatisticsCheckBox);
+      this.splitContainer.Panel1.Controls.Add(this.xAxisLabel);
+      this.splitContainer.Panel1.Controls.Add(this.noRunsLabel);
+      this.splitContainer.Panel1.Controls.Add(this.yAxisLabel);
+      this.splitContainer.Panel1.Controls.Add(this.xAxisComboBox);
+      this.splitContainer.Panel1.Controls.Add(this.yAxisComboBox);
+      this.splitContainer.Panel1.Controls.Add(this.chart);
+      // 
+      // splitContainer.Panel2
+      // 
+      this.splitContainer.Panel2.Controls.Add(this.statisticsGroupBox);
+      this.splitContainer.Size = new System.Drawing.Size(987, 550);
+      this.splitContainer.SplitterDistance = 366;
+      this.splitContainer.TabIndex = 23;
+      // 
+      // showStatisticsCheckBox
+      // 
+      this.showStatisticsCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.showStatisticsCheckBox.Appearance = System.Windows.Forms.Appearance.Button;
+      this.showStatisticsCheckBox.Checked = true;
+      this.showStatisticsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.showStatisticsCheckBox.Image = HeuristicLab.Common.Resources.VSImageLibrary.Properties;
+      this.showStatisticsCheckBox.Location = new System.Drawing.Point(3, 339);
+      this.showStatisticsCheckBox.Name = "showStatisticsCheckBox";
+      this.showStatisticsCheckBox.Size = new System.Drawing.Size(24, 24);
+      this.showStatisticsCheckBox.TabIndex = 23;
+      this.tooltip.SetToolTip(this.showStatisticsCheckBox, "Show/Hide Statistics");
+      this.showStatisticsCheckBox.UseVisualStyleBackColor = true;
+      this.showStatisticsCheckBox.CheckedChanged += new System.EventHandler(this.showStatisticsCheckBox_CheckedChanged);
+      // 
+      // statisticsGroupBox
+      // 
+      this.statisticsGroupBox.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.statisticsGroupBox.Controls.Add(this.statisticsMatrixView);
+      this.statisticsGroupBox.Location = new System.Drawing.Point(3, 3);
+      this.statisticsGroupBox.Name = "statisticsGroupBox";
+      this.statisticsGroupBox.Size = new System.Drawing.Size(981, 174);
+      this.statisticsGroupBox.TabIndex = 1;
+      this.statisticsGroupBox.TabStop = false;
+      this.statisticsGroupBox.Text = "Statistics";
+      // 
+      // statisticsMatrixView
+      // 
+      this.statisticsMatrixView.Caption = "StringConvertibleMatrix View";
+      this.statisticsMatrixView.Content = null;
+      this.statisticsMatrixView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.statisticsMatrixView.Location = new System.Drawing.Point(3, 16);
+      this.statisticsMatrixView.Name = "statisticsMatrixView";
+      this.statisticsMatrixView.ReadOnly = true;
+      this.statisticsMatrixView.ShowRowsAndColumnsTextBox = false;
+      this.statisticsMatrixView.ShowStatisticalInformation = false;
+      this.statisticsMatrixView.Size = new System.Drawing.Size(975, 155);
+      this.statisticsMatrixView.TabIndex = 0;
+      // 
+      // RunCollectionBoxPlotView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.BackColor = System.Drawing.SystemColors.Window;
+      this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+      this.Controls.Add(this.splitContainer);
+      this.Name = "RunCollectionBoxPlotView";
+      this.Size = new System.Drawing.Size(987, 550);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel1.PerformLayout();
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.statisticsGroupBox.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Label xAxisLabel;
+    internal System.Windows.Forms.ComboBox xAxisComboBox;
+    private System.Windows.Forms.Label yAxisLabel;
+    internal System.Windows.Forms.ComboBox yAxisComboBox;
+    private HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
+    private System.Windows.Forms.Label noRunsLabel;
+    private System.Windows.Forms.SplitContainer splitContainer;
+    private Data.Views.StringConvertibleMatrixView statisticsMatrixView;
+    private System.Windows.Forms.GroupBox statisticsGroupBox;
+    private System.Windows.Forms.ToolTip tooltip;
+    protected System.Windows.Forms.CheckBox showStatisticsCheckBox;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBoxPlotView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBoxPlotView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBoxPlotView.cs	(revision 12764)
@@ -0,0 +1,463 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("Box Plot")]
+  [Content(typeof(RunCollection), false)]
+  public partial class RunCollectionBoxPlotView : AsynchronousContentView {
+    private enum AxisDimension { Color = 0 }
+    private const string BoxPlotSeriesName = "BoxPlotSeries";
+    private const string BoxPlotChartAreaName = "BoxPlotChartArea";
+
+    private bool suppressUpdates = false;
+    private string xAxisValue;
+    private string yAxisValue;
+    private Dictionary<int, Dictionary<object, double>> categoricalMapping;
+    private SortedDictionary<double, Series> seriesCache;
+
+    public RunCollectionBoxPlotView() {
+      InitializeComponent();
+      categoricalMapping = new Dictionary<int, Dictionary<object, double>>();
+      seriesCache = new SortedDictionary<double, Series>();
+      chart.ChartAreas[0].Visible = false;
+      chart.Series.Clear();
+      chart.ChartAreas.Add(BoxPlotChartAreaName);
+      chart.CustomizeAllChartAreas();
+      chart.ChartAreas[BoxPlotChartAreaName].Axes.ToList().ForEach(x => { x.ScaleView.Zoomable = true; x.ScaleView.MinSize = 0; });
+      chart.ChartAreas[BoxPlotChartAreaName].CursorX.Interval = 0.5;
+      chart.ChartAreas[BoxPlotChartAreaName].CursorY.Interval = 1e-5;
+    }
+
+    public new RunCollection Content {
+      get { return (RunCollection)base.Content; }
+      set { base.Content = value; }
+    }
+    public IStringConvertibleMatrix Matrix {
+      get { return this.Content; }
+    }
+
+    #region RunCollection and Run events
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.Reset += new EventHandler(Content_Reset);
+      Content.ColumnNamesChanged += new EventHandler(Content_ColumnNamesChanged);
+      Content.ItemsAdded += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded);
+      Content.ItemsRemoved += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
+      Content.CollectionReset += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
+      Content.UpdateOfRunsInProgressChanged += new EventHandler(Content_UpdateOfRunsInProgressChanged);
+      Content.OptimizerNameChanged += new EventHandler(Content_AlgorithmNameChanged);
+      RegisterRunEvents(Content);
+    }
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.Reset -= new EventHandler(Content_Reset);
+      Content.ColumnNamesChanged -= new EventHandler(Content_ColumnNamesChanged);
+      Content.ItemsAdded -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded);
+      Content.ItemsRemoved -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
+      Content.CollectionReset -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
+      Content.UpdateOfRunsInProgressChanged -= new EventHandler(Content_UpdateOfRunsInProgressChanged);
+      Content.OptimizerNameChanged -= new EventHandler(Content_AlgorithmNameChanged);
+      DeregisterRunEvents(Content);
+    }
+
+    protected virtual void RegisterRunEvents(IEnumerable<IRun> runs) {
+      foreach (IRun run in runs)
+        run.PropertyChanged += run_PropertyChanged;
+    }
+    protected virtual void DeregisterRunEvents(IEnumerable<IRun> runs) {
+      foreach (IRun run in runs)
+        run.PropertyChanged -= run_PropertyChanged;
+    }
+
+    private void Content_CollectionReset(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IRun> e) {
+      DeregisterRunEvents(e.OldItems);
+      RegisterRunEvents(e.Items);
+    }
+    private void Content_ItemsRemoved(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IRun> e) {
+      DeregisterRunEvents(e.Items);
+    }
+    private void Content_ItemsAdded(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IRun> e) {
+      RegisterRunEvents(e.Items);
+    }
+    private void Content_UpdateOfRunsInProgressChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_UpdateOfRunsInProgressChanged), sender, e);
+      else {
+        suppressUpdates = Content.UpdateOfRunsInProgress;
+        if (!suppressUpdates) UpdateDataPoints();
+      }
+    }
+
+    private void Content_Reset(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_Reset), sender, e);
+      else if (!suppressUpdates) {
+        UpdateDataPoints();
+        UpdateAxisLabels();
+      }
+    }
+    private void Content_ColumnNamesChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_ColumnNamesChanged), sender, e);
+      else {
+        UpdateComboBoxes();
+      }
+    }
+    private void run_PropertyChanged(object sender, PropertyChangedEventArgs e) {
+      if (InvokeRequired)
+        this.Invoke((Action<object, PropertyChangedEventArgs>)run_PropertyChanged, sender, e);
+      else if (!suppressUpdates) {
+        if (e.PropertyName == "Visible")
+          UpdateDataPoints();
+      }
+    }
+
+    private void Content_AlgorithmNameChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_AlgorithmNameChanged), sender, e);
+      else UpdateCaption();
+    }
+    #endregion
+
+    #region update comboboxes, datapoints, runs
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      this.categoricalMapping.Clear();
+      UpdateComboBoxes();
+      UpdateDataPoints();
+      UpdateCaption();
+    }
+
+    private void UpdateCaption() {
+      Caption = Content != null ? Content.OptimizerName + " Box Plot" : ViewAttribute.GetViewName(GetType());
+    }
+
+    private void UpdateComboBoxes() {
+      string selectedXAxis = (string)this.xAxisComboBox.SelectedItem;
+      string selectedYAxis = (string)this.yAxisComboBox.SelectedItem;
+      this.xAxisComboBox.Items.Clear();
+      this.yAxisComboBox.Items.Clear();
+      if (Content != null) {
+        string[] additionalAxisDimension = Enum.GetNames(typeof(AxisDimension));
+        this.xAxisComboBox.Items.AddRange(additionalAxisDimension);
+        this.xAxisComboBox.Items.AddRange(Matrix.ColumnNames.ToArray());
+        this.yAxisComboBox.Items.AddRange(additionalAxisDimension);
+        this.yAxisComboBox.Items.AddRange(Matrix.ColumnNames.ToArray());
+
+        bool changed = false;
+        if (selectedXAxis != null && xAxisComboBox.Items.Contains(selectedXAxis)) {
+          xAxisComboBox.SelectedItem = selectedXAxis;
+          changed = true;
+        }
+        if (selectedYAxis != null && yAxisComboBox.Items.Contains(selectedYAxis)) {
+          yAxisComboBox.SelectedItem = selectedYAxis;
+          changed = true;
+        }
+        if (changed)
+          UpdateDataPoints();
+      }
+    }
+
+    private void UpdateDataPoints() {
+      this.categoricalMapping.Clear();
+      this.chart.Series.Clear();
+      this.seriesCache.Clear();
+      if (Content != null) {
+        foreach (IRun run in this.Content.Where(r => r.Visible))
+          this.AddDataPoint(run);
+        foreach (Series s in this.seriesCache.Values)
+          this.chart.Series.Add(s);
+
+        UpdateStatistics();
+        if (seriesCache.Count > 0) {
+          Series boxPlotSeries = CreateBoxPlotSeries();
+          this.chart.Series.Add(boxPlotSeries);
+        }
+
+        UpdateAxisLabels();
+      }
+      UpdateNoRunsVisibleLabel();
+    }
+
+    private void UpdateStatistics() {
+      DoubleMatrix matrix = new DoubleMatrix(9, seriesCache.Count);
+      matrix.SortableView = false;
+      List<string> columnNames = new List<string>();
+      foreach (Series series in seriesCache.Values) {
+        DataPoint datapoint = series.Points.FirstOrDefault();
+        if (datapoint != null) {
+          IRun run = (IRun)datapoint.Tag;
+          string selectedAxis = xAxisValue;
+          IItem value = null;
+
+          if (Enum.IsDefined(typeof(AxisDimension), selectedAxis)) {
+            AxisDimension axisDimension = (AxisDimension)Enum.Parse(typeof(AxisDimension), selectedAxis);
+            switch (axisDimension) {
+              case AxisDimension.Color: value = new StringValue(run.Color.ToString());
+                break;
+            }
+          } else value = Content.GetValue(run, selectedAxis);
+          string columnName = string.Empty;
+          if (value is DoubleValue || value is IntValue)
+            columnName = selectedAxis + ": ";
+          columnName += value.ToString();
+          columnNames.Add(columnName);
+        }
+      }
+      matrix.ColumnNames = columnNames;
+      matrix.RowNames = new string[] { "Count", "Minimum", "Maximum", "Median", "Average", "Standard Deviation", "Variance", "25th Percentile", "75th Percentile" };
+
+      for (int i = 0; i < seriesCache.Count; i++) {
+        Series series = seriesCache.ElementAt(i).Value;
+        double[] seriesValues = series.Points.Select(p => p.YValues[0]).OrderBy(d => d).ToArray();
+        matrix[0, i] = seriesValues.Length;
+        matrix[1, i] = seriesValues.Min();
+        matrix[2, i] = seriesValues.Max();
+        matrix[3, i] = seriesValues.Median();
+        matrix[4, i] = seriesValues.Average();
+        matrix[5, i] = seriesValues.StandardDeviation();
+        matrix[6, i] = seriesValues.Variance();
+        matrix[7, i] = seriesValues.Percentile(0.25);
+        matrix[8, i] = seriesValues.Percentile(0.75);
+      }
+      statisticsMatrixView.Content = matrix;
+    }
+
+    private Series CreateBoxPlotSeries() {
+      Series boxPlotSeries = new Series(BoxPlotSeriesName);
+      string seriesNames = string.Concat(seriesCache.Keys.Select(x => x.ToString() + ";").ToArray());
+      seriesNames = seriesNames.Remove(seriesNames.Length - 1); //delete last ; from string
+
+      boxPlotSeries.ChartArea = BoxPlotChartAreaName;
+      boxPlotSeries.ChartType = SeriesChartType.BoxPlot;
+      boxPlotSeries["BoxPlotSeries"] = seriesNames;
+      boxPlotSeries["BoxPlotShowUnusualValues"] = "true";
+      boxPlotSeries["PointWidth"] = "0.4";
+      boxPlotSeries.BackGradientStyle = System.Windows.Forms.DataVisualization.Charting.GradientStyle.VerticalCenter;
+      boxPlotSeries.BackSecondaryColor = System.Drawing.Color.FromArgb(130, 224, 64, 10);
+      boxPlotSeries.BorderColor = System.Drawing.Color.FromArgb(64, 64, 64);
+      boxPlotSeries.Color = System.Drawing.Color.FromArgb(224, 64, 10);
+
+      return boxPlotSeries;
+    }
+
+    private void AddDataPoint(IRun run) {
+      double? xValue;
+      double? yValue;
+
+      if (!xAxisComboBox.DroppedDown)
+        this.xAxisValue = (string)xAxisComboBox.SelectedItem;
+      if (!yAxisComboBox.DroppedDown)
+        this.yAxisValue = (string)yAxisComboBox.SelectedItem;
+
+      xValue = GetValue(run, this.xAxisValue);
+      yValue = GetValue(run, this.yAxisValue);
+
+      if (xValue.HasValue && yValue.HasValue) {
+        if (!this.seriesCache.ContainsKey(xValue.Value))
+          seriesCache[xValue.Value] = new Series(xValue.Value.ToString());
+
+        Series series = seriesCache[xValue.Value];
+        DataPoint point = new DataPoint(xValue.Value, yValue.Value);
+        point.Tag = run;
+        series.Points.Add(point);
+      }
+    }
+    #endregion
+
+    #region get values from run
+    private double? GetValue(IRun run, string columnName) {
+      if (run == null || string.IsNullOrEmpty(columnName))
+        return null;
+
+      if (Enum.IsDefined(typeof(AxisDimension), columnName)) {
+        AxisDimension axisDimension = (AxisDimension)Enum.Parse(typeof(AxisDimension), columnName);
+        return GetValue(run, axisDimension);
+      } else {
+        int columnIndex = Matrix.ColumnNames.ToList().IndexOf(columnName);
+        IItem value = Content.GetValue(run, columnIndex);
+        if (value == null)
+          return null;
+
+        DoubleValue doubleValue = value as DoubleValue;
+        IntValue intValue = value as IntValue;
+        TimeSpanValue timeSpanValue = value as TimeSpanValue;
+        double? ret = null;
+        if (doubleValue != null) {
+          if (!double.IsNaN(doubleValue.Value) && !double.IsInfinity(doubleValue.Value))
+            ret = doubleValue.Value;
+        } else if (intValue != null)
+          ret = intValue.Value;
+        else if (timeSpanValue != null) {
+          ret = timeSpanValue.Value.TotalSeconds;
+        } else
+          ret = GetCategoricalValue(columnIndex, value.ToString());
+
+        return ret;
+      }
+    }
+    private double? GetCategoricalValue(int dimension, string value) {
+      if (!this.categoricalMapping.ContainsKey(dimension)) {
+        this.categoricalMapping[dimension] = new Dictionary<object, double>();
+        var orderedCategories = Content.Where(r => r.Visible && Content.GetValue(r, dimension) != null).Select(r => Content.GetValue(r, dimension).ToString())
+                                       .Distinct().OrderBy(x => x, new NaturalStringComparer());
+        int count = 1;
+        foreach (var category in orderedCategories) {
+          this.categoricalMapping[dimension].Add(category, count);
+          count++;
+        }
+      }
+      if (!this.categoricalMapping[dimension].ContainsKey(value)) return null;
+      return this.categoricalMapping[dimension][value];
+    }
+    private double? GetValue(IRun run, AxisDimension axisDimension) {
+      double? value = double.NaN;
+      switch (axisDimension) {
+        case AxisDimension.Color: {
+            value = GetCategoricalValue(-1, run.Color.ToString());
+            break;
+          }
+        default: {
+            throw new ArgumentException("No handling strategy for " + axisDimension.ToString() + " is defined.");
+          }
+      }
+      return value;
+    }
+    #endregion
+
+    #region GUI events
+    private void UpdateNoRunsVisibleLabel() {
+      if (this.chart.Series.Count > 0) {
+        noRunsLabel.Visible = false;
+        showStatisticsCheckBox.Enabled = true;
+        splitContainer.Panel2Collapsed = !showStatisticsCheckBox.Checked;
+      } else {
+        noRunsLabel.Visible = true;
+        showStatisticsCheckBox.Enabled = false;
+        splitContainer.Panel2Collapsed = true;
+      }
+    }
+
+    private void AxisComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      UpdateDataPoints();
+    }
+    private void UpdateAxisLabels() {
+      Axis xAxis = this.chart.ChartAreas[BoxPlotChartAreaName].AxisX;
+      Axis yAxis = this.chart.ChartAreas[BoxPlotChartAreaName].AxisY;
+      int axisDimensionCount = Enum.GetNames(typeof(AxisDimension)).Count();
+      //mkommend: combobox.SelectedIndex could not be used as this changes during hovering over possible values
+      var xSAxisSelectedIndex = xAxisValue == null ? 0 : xAxisComboBox.Items.IndexOf(xAxisValue);
+      var ySAxisSelectedIndex = yAxisValue == null ? 0 : xAxisComboBox.Items.IndexOf(yAxisValue);
+      SetCustomAxisLabels(xAxis, xSAxisSelectedIndex - axisDimensionCount);
+      SetCustomAxisLabels(yAxis, ySAxisSelectedIndex - axisDimensionCount);
+      if (xAxisValue != null)
+        xAxis.Title = xAxisValue;
+      if (yAxisValue != null)
+        yAxis.Title = yAxisValue;
+    }
+
+    private void chart_AxisViewChanged(object sender, System.Windows.Forms.DataVisualization.Charting.ViewEventArgs e) {
+      this.UpdateAxisLabels();
+    }
+
+    private void SetCustomAxisLabels(Axis axis, int dimension) {
+      axis.CustomLabels.Clear();
+      if (categoricalMapping.ContainsKey(dimension)) {
+        int position = 1;
+        foreach (var pair in categoricalMapping[dimension].Where(x => seriesCache.ContainsKey(x.Value))) {
+          string labelText = pair.Key.ToString();
+          CustomLabel label = new CustomLabel();
+          label.ToolTip = labelText;
+          if (labelText.Length > 25)
+            labelText = labelText.Substring(0, 25) + " ... ";
+          label.Text = labelText;
+          label.GridTicks = GridTickTypes.TickMark;
+          label.FromPosition = position - 0.5;
+          label.ToPosition = position + 0.5;
+          axis.CustomLabels.Add(label);
+          position++;
+        }
+      } else if (dimension > 0 && Content.GetValue(0, dimension) is TimeSpanValue) {
+        this.chart.ChartAreas[0].RecalculateAxesScale();
+        Axis correspondingAxis = this.chart.ChartAreas[0].Axes.Where(x => x.Name == axis.Name).SingleOrDefault();
+        if (correspondingAxis == null)
+          correspondingAxis = axis;
+        for (double i = correspondingAxis.Minimum; i <= correspondingAxis.Maximum; i += correspondingAxis.LabelStyle.Interval) {
+          TimeSpan time = TimeSpan.FromSeconds(i);
+          string x = string.Format("{0:00}:{1:00}:{2:00}", (int)time.Hours, time.Minutes, time.Seconds);
+          axis.CustomLabels.Add(i - correspondingAxis.LabelStyle.Interval / 2, i + correspondingAxis.LabelStyle.Interval / 2, x);
+        }
+      } else if (chart.ChartAreas[BoxPlotChartAreaName].AxisX == axis) {
+        double position = 1.0;
+        foreach (Series series in chart.Series) {
+          if (series.Name != BoxPlotSeriesName) {
+            string labelText = series.Points[0].XValue.ToString();
+            CustomLabel label = new CustomLabel();
+            label.FromPosition = position - 0.5;
+            label.ToPosition = position + 0.5;
+            label.GridTicks = GridTickTypes.TickMark;
+            label.Text = labelText;
+            axis.CustomLabels.Add(label);
+            position++;
+          }
+        }
+      }
+    }
+
+    private void chart_MouseMove(object sender, MouseEventArgs e) {
+      string newTooltipText = string.Empty;
+      string oldTooltipText;
+      HitTestResult h = this.chart.HitTest(e.X, e.Y);
+      if (h.ChartElementType == ChartElementType.AxisLabels) {
+        newTooltipText = ((CustomLabel)h.Object).ToolTip;
+      }
+
+      oldTooltipText = this.tooltip.GetToolTip(chart);
+      if (newTooltipText != oldTooltipText)
+        this.tooltip.SetToolTip(chart, newTooltipText);
+    }
+    #endregion
+
+    private void showStatisticsCheckBox_CheckedChanged(object sender, EventArgs e) {
+      splitContainer.Panel2Collapsed = !showStatisticsCheckBox.Checked;
+    }
+
+    public void SetXAxis(string axisName) {
+      xAxisComboBox.SelectedItem = axisName;
+    }
+
+    public void SetYAxis(string axisName) {
+      yAxisComboBox.SelectedItem = axisName;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBubbleChartView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBubbleChartView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBubbleChartView.Designer.cs	(revision 12764)
@@ -0,0 +1,484 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class RunCollectionBubbleChartView {
+    /// <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.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
+      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RunCollectionBubbleChartView));
+      this.yJitterLabel = new System.Windows.Forms.Label();
+      this.xJitterlabel = new System.Windows.Forms.Label();
+      this.xTrackBar = new System.Windows.Forms.TrackBar();
+      this.xAxisLabel = new System.Windows.Forms.Label();
+      this.xAxisComboBox = new System.Windows.Forms.ComboBox();
+      this.yAxisLabel = new System.Windows.Forms.Label();
+      this.yAxisComboBox = new System.Windows.Forms.ComboBox();
+      this.yTrackBar = new System.Windows.Forms.TrackBar();
+      this.sizeComboBox = new System.Windows.Forms.ComboBox();
+      this.sizeLabel = new System.Windows.Forms.Label();
+      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      this.openBoxPlotViewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.hideRunsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.zoomButton = new System.Windows.Forms.RadioButton();
+      this.selectButton = new System.Windows.Forms.RadioButton();
+      this.radioButtonGroup = new System.Windows.Forms.GroupBox();
+      this.colorRunsButton = new System.Windows.Forms.Button();
+      this.colorDialog = new System.Windows.Forms.ColorDialog();
+      this.tooltip = new System.Windows.Forms.ToolTip(this.components);
+      this.colorXAxisButton = new System.Windows.Forms.Button();
+      this.colorYAxisButton = new System.Windows.Forms.Button();
+      this.transparencyTrackBar = new System.Windows.Forms.TrackBar();
+      this.hideRunsButton = new System.Windows.Forms.Button();
+      this.colorDialogButton = new System.Windows.Forms.Button();
+      this.noRunsLabel = new System.Windows.Forms.Label();
+      this.sizeTrackBar = new System.Windows.Forms.TrackBar();
+      this.getDataAsMatrixToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.transparencyLabel = new System.Windows.Forms.Label();
+      this.unhideAllRunToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.colorResetToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      ((System.ComponentModel.ISupportInitialize)(this.xTrackBar)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.yTrackBar)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      this.radioButtonGroup.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.transparencyTrackBar)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.sizeTrackBar)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // yJitterLabel
+      // 
+      this.yJitterLabel.AutoSize = true;
+      this.yJitterLabel.Location = new System.Drawing.Point(457, 6);
+      this.yJitterLabel.Name = "yJitterLabel";
+      this.yJitterLabel.Size = new System.Drawing.Size(32, 13);
+      this.yJitterLabel.TabIndex = 13;
+      this.yJitterLabel.Text = "Jitter:";
+      // 
+      // xJitterlabel
+      // 
+      this.xJitterlabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.xJitterlabel.AutoSize = true;
+      this.xJitterlabel.Location = new System.Drawing.Point(893, 719);
+      this.xJitterlabel.Name = "xJitterlabel";
+      this.xJitterlabel.Size = new System.Drawing.Size(32, 13);
+      this.xJitterlabel.TabIndex = 12;
+      this.xJitterlabel.Text = "Jitter:";
+      // 
+      // xTrackBar
+      // 
+      this.xTrackBar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.xTrackBar.Enabled = false;
+      this.xTrackBar.Location = new System.Drawing.Point(919, 715);
+      this.xTrackBar.Maximum = 100;
+      this.xTrackBar.Name = "xTrackBar";
+      this.xTrackBar.Size = new System.Drawing.Size(64, 45);
+      this.xTrackBar.TabIndex = 11;
+      this.xTrackBar.TickStyle = System.Windows.Forms.TickStyle.None;
+      this.xTrackBar.ValueChanged += new System.EventHandler(this.jitterTrackBar_ValueChanged);
+      // 
+      // xAxisLabel
+      // 
+      this.xAxisLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.xAxisLabel.AutoSize = true;
+      this.xAxisLabel.Location = new System.Drawing.Point(439, 719);
+      this.xAxisLabel.Name = "xAxisLabel";
+      this.xAxisLabel.Size = new System.Drawing.Size(15, 13);
+      this.xAxisLabel.TabIndex = 8;
+      this.xAxisLabel.Text = "x:";
+      // 
+      // xAxisComboBox
+      // 
+      this.xAxisComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.xAxisComboBox.BackColor = System.Drawing.SystemColors.ControlLightLight;
+      this.xAxisComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.xAxisComboBox.DropDownWidth = 500;
+      this.xAxisComboBox.FormattingEnabled = true;
+      this.xAxisComboBox.Location = new System.Drawing.Point(460, 715);
+      this.xAxisComboBox.Name = "xAxisComboBox";
+      this.xAxisComboBox.Size = new System.Drawing.Size(400, 21);
+      this.xAxisComboBox.TabIndex = 7;
+      this.xAxisComboBox.SelectedValueChanged += new System.EventHandler(this.AxisComboBox_SelectedValueChanged);
+      // 
+      // yAxisLabel
+      // 
+      this.yAxisLabel.AutoSize = true;
+      this.yAxisLabel.Location = new System.Drawing.Point(3, 6);
+      this.yAxisLabel.Name = "yAxisLabel";
+      this.yAxisLabel.Size = new System.Drawing.Size(15, 13);
+      this.yAxisLabel.TabIndex = 6;
+      this.yAxisLabel.Text = "y:";
+      // 
+      // yAxisComboBox
+      // 
+      this.yAxisComboBox.BackColor = System.Drawing.SystemColors.ControlLightLight;
+      this.yAxisComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.yAxisComboBox.DropDownWidth = 800;
+      this.yAxisComboBox.FormattingEnabled = true;
+      this.yAxisComboBox.Location = new System.Drawing.Point(24, 3);
+      this.yAxisComboBox.Name = "yAxisComboBox";
+      this.yAxisComboBox.Size = new System.Drawing.Size(400, 21);
+      this.yAxisComboBox.TabIndex = 5;
+      this.yAxisComboBox.SelectedValueChanged += new System.EventHandler(this.AxisComboBox_SelectedValueChanged);
+      // 
+      // yTrackBar
+      // 
+      this.yTrackBar.Enabled = false;
+      this.yTrackBar.Location = new System.Drawing.Point(483, 3);
+      this.yTrackBar.Maximum = 100;
+      this.yTrackBar.Name = "yTrackBar";
+      this.yTrackBar.Size = new System.Drawing.Size(59, 45);
+      this.yTrackBar.TabIndex = 10;
+      this.yTrackBar.TickStyle = System.Windows.Forms.TickStyle.None;
+      this.yTrackBar.ValueChanged += new System.EventHandler(this.jitterTrackBar_ValueChanged);
+      // 
+      // sizeComboBox
+      // 
+      this.sizeComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.sizeComboBox.BackColor = System.Drawing.SystemColors.ControlLightLight;
+      this.sizeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.sizeComboBox.DropDownWidth = 400;
+      this.sizeComboBox.FormattingEnabled = true;
+      this.sizeComboBox.Location = new System.Drawing.Point(613, 3);
+      this.sizeComboBox.Name = "sizeComboBox";
+      this.sizeComboBox.Size = new System.Drawing.Size(300, 21);
+      this.sizeComboBox.TabIndex = 14;
+      this.sizeComboBox.SelectedValueChanged += new System.EventHandler(this.AxisComboBox_SelectedValueChanged);
+      // 
+      // sizeLabel
+      // 
+      this.sizeLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.sizeLabel.AutoSize = true;
+      this.sizeLabel.Location = new System.Drawing.Point(541, 6);
+      this.sizeLabel.Name = "sizeLabel";
+      this.sizeLabel.Size = new System.Drawing.Size(66, 13);
+      this.sizeLabel.TabIndex = 15;
+      this.sizeLabel.Text = "Bubble Size:";
+      // 
+      // chart
+      // 
+      this.chart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      chartArea1.Name = "ChartArea1";
+      this.chart.ChartAreas.Add(chartArea1);
+      this.chart.Location = new System.Drawing.Point(-1, 30);
+      this.chart.Name = "chart";
+      series1.ChartArea = "ChartArea1";
+      series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Point;
+      series1.IsVisibleInLegend = false;
+      series1.MarkerStyle = System.Windows.Forms.DataVisualization.Charting.MarkerStyle.Circle;
+      series1.Name = "Bubbles";
+      series1.YValuesPerPoint = 2;
+      this.chart.Series.Add(series1);
+      this.chart.Size = new System.Drawing.Size(988, 681);
+      this.chart.TabIndex = 16;
+      this.chart.Text = "chart";
+      this.chart.AxisViewChanged += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.ViewEventArgs>(this.chart_AxisViewChanged);
+      this.chart.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDoubleClick);
+      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
+      this.chart.MouseUp += new System.Windows.Forms.MouseEventHandler(this.chart_MouseUp);
+      // 
+      // openBoxPlotViewToolStripMenuItem
+      // 
+      this.openBoxPlotViewToolStripMenuItem.Name = "openBoxPlotViewToolStripMenuItem";
+      this.openBoxPlotViewToolStripMenuItem.Size = new System.Drawing.Size(256, 22);
+      this.openBoxPlotViewToolStripMenuItem.Text = "Open BoxPlot View";
+      this.openBoxPlotViewToolStripMenuItem.Click += new System.EventHandler(this.openBoxPlotViewToolStripMenuItem_Click);
+      // 
+      // hideRunsToolStripMenuItem
+      // 
+      this.hideRunsToolStripMenuItem.Name = "hideRunsToolStripMenuItem";
+      this.hideRunsToolStripMenuItem.Size = new System.Drawing.Size(256, 22);
+      this.hideRunsToolStripMenuItem.Text = "Hide selected Runs";
+      this.hideRunsToolStripMenuItem.Click += new System.EventHandler(this.hideRunsToolStripMenuItem_Click);
+      // 
+      // zoomButton
+      // 
+      this.zoomButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.zoomButton.AutoSize = true;
+      this.zoomButton.Checked = true;
+      this.zoomButton.Location = new System.Drawing.Point(6, 11);
+      this.zoomButton.Name = "zoomButton";
+      this.zoomButton.Size = new System.Drawing.Size(52, 17);
+      this.zoomButton.TabIndex = 17;
+      this.zoomButton.TabStop = true;
+      this.zoomButton.Text = "Zoom";
+      this.zoomButton.UseVisualStyleBackColor = true;
+      this.zoomButton.CheckedChanged += new System.EventHandler(this.zoomButton_CheckedChanged);
+      // 
+      // selectButton
+      // 
+      this.selectButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.selectButton.AutoSize = true;
+      this.selectButton.Location = new System.Drawing.Point(61, 11);
+      this.selectButton.Name = "selectButton";
+      this.selectButton.Size = new System.Drawing.Size(55, 17);
+      this.selectButton.TabIndex = 18;
+      this.selectButton.Text = "Select";
+      this.selectButton.UseVisualStyleBackColor = true;
+      // 
+      // radioButtonGroup
+      // 
+      this.radioButtonGroup.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.radioButtonGroup.Controls.Add(this.zoomButton);
+      this.radioButtonGroup.Controls.Add(this.selectButton);
+      this.radioButtonGroup.Location = new System.Drawing.Point(3, 704);
+      this.radioButtonGroup.Name = "radioButtonGroup";
+      this.radioButtonGroup.Size = new System.Drawing.Size(122, 32);
+      this.radioButtonGroup.TabIndex = 19;
+      this.radioButtonGroup.TabStop = false;
+      // 
+      // colorRunsButton
+      // 
+      this.colorRunsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.colorRunsButton.Enabled = false;
+      this.colorRunsButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+      this.colorRunsButton.Location = new System.Drawing.Point(131, 713);
+      this.colorRunsButton.Name = "colorRunsButton";
+      this.colorRunsButton.Size = new System.Drawing.Size(21, 21);
+      this.colorRunsButton.TabIndex = 20;
+      this.tooltip.SetToolTip(this.colorRunsButton, "Color all selected runs");
+      this.colorRunsButton.UseVisualStyleBackColor = true;
+      this.colorRunsButton.Click += new System.EventHandler(this.colorRunsButton_Click);
+      // 
+      // colorDialog
+      // 
+      this.colorDialog.AllowFullOpen = false;
+      this.colorDialog.FullOpen = true;
+      // 
+      // colorXAxisButton
+      // 
+      this.colorXAxisButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.colorXAxisButton.Enabled = false;
+      this.colorXAxisButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.DisplayInColorVertical;
+      this.colorXAxisButton.Location = new System.Drawing.Point(866, 715);
+      this.colorXAxisButton.Name = "colorXAxisButton";
+      this.colorXAxisButton.Size = new System.Drawing.Size(21, 21);
+      this.colorXAxisButton.TabIndex = 22;
+      this.tooltip.SetToolTip(this.colorXAxisButton, "Color all runs according to their x-values");
+      this.colorXAxisButton.UseVisualStyleBackColor = true;
+      this.colorXAxisButton.Click += new System.EventHandler(this.colorXAxisButton_Click);
+      // 
+      // colorYAxisButton
+      // 
+      this.colorYAxisButton.Enabled = false;
+      this.colorYAxisButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.DisplayInColor;
+      this.colorYAxisButton.Location = new System.Drawing.Point(430, 3);
+      this.colorYAxisButton.Name = "colorYAxisButton";
+      this.colorYAxisButton.Size = new System.Drawing.Size(21, 21);
+      this.colorYAxisButton.TabIndex = 23;
+      this.tooltip.SetToolTip(this.colorYAxisButton, "Color all runs according to their y-values");
+      this.colorYAxisButton.UseVisualStyleBackColor = true;
+      this.colorYAxisButton.Click += new System.EventHandler(this.colorYAxisButton_Click);
+      // 
+      // transparencyTrackBar
+      // 
+      this.transparencyTrackBar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.transparencyTrackBar.LargeChange = 16;
+      this.transparencyTrackBar.Location = new System.Drawing.Point(302, 715);
+      this.transparencyTrackBar.Maximum = 254;
+      this.transparencyTrackBar.Name = "transparencyTrackBar";
+      this.transparencyTrackBar.Size = new System.Drawing.Size(64, 45);
+      this.transparencyTrackBar.TabIndex = 24;
+      this.transparencyTrackBar.TickStyle = System.Windows.Forms.TickStyle.None;
+      this.tooltip.SetToolTip(this.transparencyTrackBar, "Sets the transparency of the colors");
+      this.transparencyTrackBar.ValueChanged += new System.EventHandler(this.transparencyTrackBar_ValueChanged);
+      // 
+      // hideRunsButton
+      // 
+      this.hideRunsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.hideRunsButton.Enabled = false;
+      this.hideRunsButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+      this.hideRunsButton.Location = new System.Drawing.Point(172, 713);
+      this.hideRunsButton.Name = "hideRunsButton";
+      this.hideRunsButton.Size = new System.Drawing.Size(43, 21);
+      this.hideRunsButton.TabIndex = 26;
+      this.hideRunsButton.Text = "Hide";
+      this.tooltip.SetToolTip(this.hideRunsButton, "Hides all selected runs");
+      this.hideRunsButton.UseVisualStyleBackColor = true;
+      this.hideRunsButton.Click += new System.EventHandler(this.hideRunsButton_Click);
+      // 
+      // colorDialogButton
+      // 
+      this.colorDialogButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.colorDialogButton.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
+      this.colorDialogButton.Enabled = false;
+      this.colorDialogButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+      this.colorDialogButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+      this.colorDialogButton.Location = new System.Drawing.Point(152, 713);
+      this.colorDialogButton.Name = "colorDialogButton";
+      this.colorDialogButton.Size = new System.Drawing.Size(14, 21);
+      this.colorDialogButton.TabIndex = 25;
+      this.colorDialogButton.Text = "v";
+      this.tooltip.SetToolTip(this.colorDialogButton, "Choose color");
+      this.colorDialogButton.UseVisualStyleBackColor = true;
+      this.colorDialogButton.Click += new System.EventHandler(this.colorDialogButton_Click);
+      // 
+      // noRunsLabel
+      // 
+      this.noRunsLabel.Anchor = System.Windows.Forms.AnchorStyles.None;
+      this.noRunsLabel.AutoSize = true;
+      this.noRunsLabel.Location = new System.Drawing.Point(432, 350);
+      this.noRunsLabel.Name = "noRunsLabel";
+      this.noRunsLabel.Size = new System.Drawing.Size(138, 13);
+      this.noRunsLabel.TabIndex = 21;
+      this.noRunsLabel.Text = "No runs could be displayed.";
+      // 
+      // sizeTrackBar
+      // 
+      this.sizeTrackBar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.sizeTrackBar.Location = new System.Drawing.Point(919, 3);
+      this.sizeTrackBar.Maximum = 20;
+      this.sizeTrackBar.Minimum = -20;
+      this.sizeTrackBar.Name = "sizeTrackBar";
+      this.sizeTrackBar.Size = new System.Drawing.Size(64, 45);
+      this.sizeTrackBar.TabIndex = 24;
+      this.sizeTrackBar.TickFrequency = 20;
+      this.sizeTrackBar.TickStyle = System.Windows.Forms.TickStyle.TopLeft;
+      this.sizeTrackBar.ValueChanged += new System.EventHandler(this.sizeTrackBar_ValueChanged);
+      // 
+      // getDataAsMatrixToolStripMenuItem
+      // 
+      this.getDataAsMatrixToolStripMenuItem.Name = "getDataAsMatrixToolStripMenuItem";
+      this.getDataAsMatrixToolStripMenuItem.Size = new System.Drawing.Size(256, 22);
+      this.getDataAsMatrixToolStripMenuItem.Text = "Get Data as Matrix";
+      this.getDataAsMatrixToolStripMenuItem.Click += new System.EventHandler(this.getDataAsMatrixToolStripMenuItem_Click);
+      // 
+      // transparencyLabel
+      // 
+      this.transparencyLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.transparencyLabel.AutoSize = true;
+      this.transparencyLabel.Location = new System.Drawing.Point(233, 717);
+      this.transparencyLabel.Name = "transparencyLabel";
+      this.transparencyLabel.Size = new System.Drawing.Size(75, 13);
+      this.transparencyLabel.TabIndex = 12;
+      this.transparencyLabel.Text = "Transparency:";
+      // 
+      // unhideAllRunToolStripMenuItem
+      // 
+      this.unhideAllRunToolStripMenuItem.Name = "unhideAllRunToolStripMenuItem";
+      this.unhideAllRunToolStripMenuItem.Size = new System.Drawing.Size(256, 22);
+      this.unhideAllRunToolStripMenuItem.Text = "Unhide all";
+      this.unhideAllRunToolStripMenuItem.Click += new System.EventHandler(this.unhideAllRunToolStripMenuItem_Click);
+      // 
+      // colorResetToolStripMenuItem
+      // 
+      this.colorResetToolStripMenuItem.Name = "colorResetToolStripMenuItem";
+      this.colorResetToolStripMenuItem.Size = new System.Drawing.Size(256, 22);
+      this.colorResetToolStripMenuItem.Text = "Color reset";
+      this.colorResetToolStripMenuItem.Click += new System.EventHandler(this.colorResetToolStripMenuItem_Click);
+      // 
+      // RunCollectionBubbleChartView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.BackColor = System.Drawing.SystemColors.Window;
+      this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+      this.Controls.Add(this.hideRunsButton);
+      this.Controls.Add(this.sizeTrackBar);
+      this.Controls.Add(this.colorYAxisButton);
+      this.Controls.Add(this.colorXAxisButton);
+      this.Controls.Add(this.noRunsLabel);
+      this.Controls.Add(this.colorRunsButton);
+      this.Controls.Add(this.radioButtonGroup);
+      this.Controls.Add(this.yJitterLabel);
+      this.Controls.Add(this.transparencyLabel);
+      this.Controls.Add(this.xJitterlabel);
+      this.Controls.Add(this.xTrackBar);
+      this.Controls.Add(this.xAxisLabel);
+      this.Controls.Add(this.xAxisComboBox);
+      this.Controls.Add(this.yAxisLabel);
+      this.Controls.Add(this.yAxisComboBox);
+      this.Controls.Add(this.yTrackBar);
+      this.Controls.Add(this.colorDialogButton);
+      this.Controls.Add(this.chart);
+      this.Controls.Add(this.transparencyTrackBar);
+      this.Controls.Add(this.sizeLabel);
+      this.Controls.Add(this.sizeComboBox);
+      this.Name = "RunCollectionBubbleChartView";
+      this.Size = new System.Drawing.Size(986, 741);
+      ((System.ComponentModel.ISupportInitialize)(this.xTrackBar)).EndInit();
+      ((System.ComponentModel.ISupportInitialize)(this.yTrackBar)).EndInit();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.radioButtonGroup.ResumeLayout(false);
+      this.radioButtonGroup.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.transparencyTrackBar)).EndInit();
+      ((System.ComponentModel.ISupportInitialize)(this.sizeTrackBar)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+    #endregion
+
+    private System.Windows.Forms.Label xAxisLabel;
+    private System.Windows.Forms.ComboBox xAxisComboBox;
+    private System.Windows.Forms.Label yAxisLabel;
+    private System.Windows.Forms.ComboBox yAxisComboBox;
+    private System.Windows.Forms.TrackBar yTrackBar;
+    private System.Windows.Forms.TrackBar xTrackBar;
+    private System.Windows.Forms.Label xJitterlabel;
+    private System.Windows.Forms.Label yJitterLabel;
+    private System.Windows.Forms.ComboBox sizeComboBox;
+    private System.Windows.Forms.Label sizeLabel;
+    private HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
+    private System.Windows.Forms.RadioButton zoomButton;
+    private System.Windows.Forms.RadioButton selectButton;
+    private System.Windows.Forms.GroupBox radioButtonGroup;
+    private System.Windows.Forms.Button colorRunsButton;
+    private System.Windows.Forms.ColorDialog colorDialog;
+    private System.Windows.Forms.ToolTip tooltip;
+    private System.Windows.Forms.Label noRunsLabel;
+    private System.Windows.Forms.ToolStripMenuItem openBoxPlotViewToolStripMenuItem;
+    private System.Windows.Forms.ToolStripMenuItem hideRunsToolStripMenuItem;
+    private System.Windows.Forms.Button colorXAxisButton;
+    private System.Windows.Forms.Button colorYAxisButton;
+    private System.Windows.Forms.TrackBar sizeTrackBar;
+    private System.Windows.Forms.ToolStripMenuItem getDataAsMatrixToolStripMenuItem;
+    private System.Windows.Forms.TrackBar transparencyTrackBar;
+    private System.Windows.Forms.Label transparencyLabel;
+    private System.Windows.Forms.Button hideRunsButton;
+    private System.Windows.Forms.ToolStripMenuItem unhideAllRunToolStripMenuItem;
+    private System.Windows.Forms.ToolStripMenuItem colorResetToolStripMenuItem;
+    private System.Windows.Forms.Button colorDialogButton;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBubbleChartView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBubbleChartView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBubbleChartView.cs	(revision 12764)
@@ -0,0 +1,886 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("Bubble Chart")]
+  [Content(typeof(RunCollection), false)]
+  public partial class RunCollectionBubbleChartView : AsynchronousContentView {
+    private enum SizeDimension { Constant = 0 }
+    private enum AxisDimension { Index = 0 }
+
+    private string xAxisValue;
+    private string yAxisValue;
+    private string sizeAxisValue;
+
+    private readonly Dictionary<IRun, List<DataPoint>> runToDataPointMapping = new Dictionary<IRun, List<DataPoint>>();
+    private readonly Dictionary<IRun, int> runToIndexMapping = new Dictionary<IRun, int>();
+    private readonly Dictionary<int, Dictionary<object, double>> categoricalMapping = new Dictionary<int, Dictionary<object, double>>();
+    private readonly Dictionary<IRun, double> xJitter = new Dictionary<IRun, double>();
+    private readonly Dictionary<IRun, double> yJitter = new Dictionary<IRun, double>();
+
+    private readonly HashSet<IRun> selectedRuns = new HashSet<IRun>();
+    private readonly Random random = new Random();
+    private double xJitterFactor = 0.0;
+    private double yJitterFactor = 0.0;
+    private bool isSelecting = false;
+    private bool suppressUpdates = false;
+
+    private readonly RunCollectionContentConstraint visibilityConstraint = new RunCollectionContentConstraint() { Active = true };
+
+    public RunCollectionBubbleChartView() {
+      InitializeComponent();
+
+      chart.ContextMenuStrip.Items.Insert(0, openBoxPlotViewToolStripMenuItem);
+      chart.ContextMenuStrip.Items.Insert(1, getDataAsMatrixToolStripMenuItem);
+      chart.ContextMenuStrip.Items.Insert(2, new ToolStripSeparator());
+      chart.ContextMenuStrip.Items.Insert(3, hideRunsToolStripMenuItem);
+      chart.ContextMenuStrip.Items.Insert(4, unhideAllRunToolStripMenuItem);
+      chart.ContextMenuStrip.Items.Insert(5, colorResetToolStripMenuItem);
+      chart.ContextMenuStrip.Items.Insert(6, new ToolStripSeparator());
+      chart.ContextMenuStrip.Opening += new System.ComponentModel.CancelEventHandler(ContextMenuStrip_Opening);
+
+      colorDialog.Color = Color.Orange;
+      colorRunsButton.Image = this.GenerateImage(16, 16, this.colorDialog.Color);
+      isSelecting = false;
+
+      chart.CustomizeAllChartAreas();
+      chart.ChartAreas[0].CursorX.Interval = 1;
+      chart.ChartAreas[0].CursorY.Interval = 1;
+      chart.ChartAreas[0].AxisX.ScaleView.Zoomable = !this.isSelecting;
+      chart.ChartAreas[0].AxisY.ScaleView.Zoomable = !this.isSelecting;
+    }
+
+    public new RunCollection Content {
+      get { return (RunCollection)base.Content; }
+      set { base.Content = value; }
+    }
+    public IStringConvertibleMatrix Matrix {
+      get { return this.Content; }
+    }
+    public IEnumerable<IRun> SelectedRuns {
+      get { return selectedRuns; }
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.Reset += new EventHandler(Content_Reset);
+      Content.ColumnNamesChanged += new EventHandler(Content_ColumnNamesChanged);
+      Content.ItemsAdded += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded);
+      Content.ItemsRemoved += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
+      Content.CollectionReset += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
+      Content.OptimizerNameChanged += new EventHandler(Content_AlgorithmNameChanged);
+      Content.UpdateOfRunsInProgressChanged += new EventHandler(Content_UpdateOfRunsInProgressChanged);
+      RegisterRunEvents(Content);
+    }
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.Reset -= new EventHandler(Content_Reset);
+      Content.ColumnNamesChanged -= new EventHandler(Content_ColumnNamesChanged);
+      Content.ItemsAdded -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded);
+      Content.ItemsRemoved -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
+      Content.CollectionReset -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
+      Content.OptimizerNameChanged -= new EventHandler(Content_AlgorithmNameChanged);
+      Content.UpdateOfRunsInProgressChanged -= new EventHandler(Content_UpdateOfRunsInProgressChanged);
+      DeregisterRunEvents(Content);
+    }
+    protected virtual void RegisterRunEvents(IEnumerable<IRun> runs) {
+      foreach (IRun run in runs)
+        run.PropertyChanged += run_PropertyChanged;
+    }
+    protected virtual void DeregisterRunEvents(IEnumerable<IRun> runs) {
+      foreach (IRun run in runs)
+        run.PropertyChanged -= run_PropertyChanged;
+    }
+
+    private void Content_CollectionReset(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IRun> e) {
+      DeregisterRunEvents(e.OldItems);
+      RegisterRunEvents(e.Items);
+    }
+    private void Content_ItemsRemoved(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IRun> e) {
+      DeregisterRunEvents(e.Items);
+    }
+    private void Content_ItemsAdded(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IRun> e) {
+      RegisterRunEvents(e.Items);
+    }
+    private void run_PropertyChanged(object sender, PropertyChangedEventArgs e) {
+      if (suppressUpdates) return;
+      if (InvokeRequired)
+        this.Invoke((Action<object, PropertyChangedEventArgs>)run_PropertyChanged, sender, e);
+      else {
+        if (e.PropertyName == "Color" || e.PropertyName == "Visible") {
+          IRun run = (IRun)sender;
+          UpdateRun(run);
+          UpdateCursorInterval();
+          chart.ChartAreas[0].RecalculateAxesScale();
+          UpdateAxisLabels();
+        }
+      }
+    }
+
+    private void Content_UpdateOfRunsInProgressChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        this.Invoke(new EventHandler(Content_UpdateOfRunsInProgressChanged), sender, e);
+      else {
+        suppressUpdates = Content.UpdateOfRunsInProgress;
+        if (suppressUpdates) return;
+
+        UpdateDataPoints();
+        UpdateAxisLabels();
+      }
+    }
+
+    private void UpdateRun(IRun run) {
+      if (runToDataPointMapping.ContainsKey(run)) {
+        foreach (DataPoint point in runToDataPointMapping[run]) {
+          if (!run.Visible) {
+            this.chart.Series[0].Points.Remove(point);
+            continue;
+          }
+          if (selectedRuns.Contains(run)) {
+            point.Color = Color.Red;
+            point.MarkerStyle = MarkerStyle.Cross;
+          } else {
+            point.Color = Color.FromArgb(255 - LogTransform(transparencyTrackBar.Value), ((IRun)point.Tag).Color);
+            point.MarkerStyle = MarkerStyle.Circle;
+          }
+
+        }
+        if (!run.Visible) runToDataPointMapping.Remove(run);
+      } else {
+        AddDataPoint(run);
+      }
+
+      if (this.chart.Series[0].Points.Count == 0)
+        noRunsLabel.Visible = true;
+      else
+        noRunsLabel.Visible = false;
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      UpdateComboBoxes();
+      UpdateDataPoints();
+      UpdateCaption();
+    }
+
+    private void RebuildInverseIndex() {
+      if (Content != null) {
+        runToIndexMapping.Clear();
+        int i = 0;
+        foreach (var run in Content) {
+          runToIndexMapping.Add(run, i);
+          i++;
+        }
+      }
+    }
+
+    private void Content_ColumnNamesChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_ColumnNamesChanged), sender, e);
+      else
+        UpdateComboBoxes();
+    }
+
+    private void UpdateCaption() {
+      Caption = Content != null ? Content.OptimizerName + " Bubble Chart" : ViewAttribute.GetViewName(GetType());
+    }
+
+    private void UpdateComboBoxes() {
+      string selectedXAxis = (string)this.xAxisComboBox.SelectedItem;
+      string selectedYAxis = (string)this.yAxisComboBox.SelectedItem;
+      string selectedSizeAxis = (string)this.sizeComboBox.SelectedItem;
+      this.xAxisComboBox.Items.Clear();
+      this.yAxisComboBox.Items.Clear();
+      this.sizeComboBox.Items.Clear();
+      if (Content != null) {
+        string[] additionalAxisDimension = Enum.GetNames(typeof(AxisDimension));
+        this.xAxisComboBox.Items.AddRange(additionalAxisDimension);
+        this.xAxisComboBox.Items.AddRange(Matrix.ColumnNames.ToArray());
+        this.yAxisComboBox.Items.AddRange(additionalAxisDimension);
+        this.yAxisComboBox.Items.AddRange(Matrix.ColumnNames.ToArray());
+        string[] additionalSizeDimension = Enum.GetNames(typeof(SizeDimension));
+        this.sizeComboBox.Items.AddRange(additionalSizeDimension);
+        this.sizeComboBox.Items.AddRange(Matrix.ColumnNames.ToArray());
+        this.sizeComboBox.SelectedItem = SizeDimension.Constant.ToString();
+
+        bool changed = false;
+        if (selectedXAxis != null && xAxisComboBox.Items.Contains(selectedXAxis)) {
+          xAxisComboBox.SelectedItem = selectedXAxis;
+          changed = true;
+        }
+        if (selectedYAxis != null && yAxisComboBox.Items.Contains(selectedYAxis)) {
+          yAxisComboBox.SelectedItem = selectedYAxis;
+          changed = true;
+        }
+        if (selectedSizeAxis != null && sizeComboBox.Items.Contains(selectedSizeAxis)) {
+          sizeComboBox.SelectedItem = selectedSizeAxis;
+          changed = true;
+        }
+        if (changed) {
+          UpdateDataPoints();
+          UpdateAxisLabels();
+        }
+      }
+    }
+
+    private void Content_AlgorithmNameChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_AlgorithmNameChanged), sender, e);
+      else UpdateCaption();
+    }
+
+    private void Content_Reset(object sender, EventArgs e) {
+      if (suppressUpdates) return;
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_Reset), sender, e);
+      else {
+        UpdateDataPoints();
+        UpdateAxisLabels();
+      }
+    }
+
+    private void UpdateDataPoints() {
+      Series series = this.chart.Series[0];
+      series.Points.Clear();
+      runToDataPointMapping.Clear();
+      categoricalMapping.Clear();
+      selectedRuns.Clear();
+      RebuildInverseIndex();
+
+      chart.ChartAreas[0].AxisX.IsMarginVisible = xAxisValue != AxisDimension.Index.ToString();
+      chart.ChartAreas[0].AxisY.IsMarginVisible = yAxisValue != AxisDimension.Index.ToString();
+
+      if (Content != null) {
+        foreach (IRun run in this.Content)
+          this.AddDataPoint(run);
+
+        if (this.chart.Series[0].Points.Count == 0)
+          noRunsLabel.Visible = true;
+        else {
+          noRunsLabel.Visible = false;
+          UpdateMarkerSizes();
+          UpdateCursorInterval();
+        }
+      }
+      xTrackBar.Value = 0;
+      yTrackBar.Value = 0;
+
+      //needed to set axis back to automatic and refresh them, otherwise their values may remain NaN
+      var xAxis = chart.ChartAreas[0].AxisX;
+      var yAxis = chart.ChartAreas[0].AxisY;
+      SetAutomaticUpdateOfAxis(xAxis, true);
+      SetAutomaticUpdateOfAxis(yAxis, true);
+      chart.Refresh();
+    }
+
+    private void UpdateMarkerSizes() {
+      var series = chart.Series[0];
+      if (series.Points.Count <= 0) return;
+
+      var sizeValues = series.Points.Select(p => p.YValues[1]);
+      double minSizeValue = sizeValues.Min();
+      double maxSizeValue = sizeValues.Max();
+      double sizeRange = maxSizeValue - minSizeValue;
+
+      const int smallestBubbleSize = 7;
+
+      foreach (DataPoint point in series.Points) {
+        //calculates the relative size of the data point  0 <= relativeSize <= 1
+        double relativeSize = (point.YValues[1] - minSizeValue);
+        if (sizeRange > double.Epsilon) {
+          relativeSize /= sizeRange;
+
+          //invert bubble sizes if the value of the trackbar is negative
+          if (sizeTrackBar.Value < 0) relativeSize = Math.Abs(relativeSize - 1);
+        } else relativeSize = 1;
+
+        double sizeChange = Math.Abs(sizeTrackBar.Value) * relativeSize;
+        point.MarkerSize = (int)Math.Round(sizeChange + smallestBubbleSize);
+      }
+    }
+
+    private void UpdateDataPointJitter() {
+      var xAxis = this.chart.ChartAreas[0].AxisX;
+      var yAxis = this.chart.ChartAreas[0].AxisY;
+
+      double xAxisRange = xAxis.Maximum - xAxis.Minimum;
+      double yAxisRange = yAxis.Maximum - yAxis.Minimum;
+
+      foreach (DataPoint point in chart.Series[0].Points) {
+        IRun run = (IRun)point.Tag;
+        double xValue = GetValue(run, xAxisValue).Value;
+        double yValue = GetValue(run, yAxisValue).Value;
+
+        if (!xJitterFactor.IsAlmost(0.0))
+          xValue += 0.1 * GetXJitter(run) * xJitterFactor * (xAxisRange);
+        if (!yJitterFactor.IsAlmost(0.0))
+          yValue += 0.1 * GetYJitter(run) * yJitterFactor * (yAxisRange);
+
+        point.XValue = xValue;
+        point.YValues[0] = yValue;
+      }
+
+      if (xJitterFactor.IsAlmost(0.0) && yJitterFactor.IsAlmost(0.0)) {
+        SetAutomaticUpdateOfAxis(xAxis, true);
+        SetAutomaticUpdateOfAxis(yAxis, true);
+        chart.ChartAreas[0].RecalculateAxesScale();
+      } else {
+        SetAutomaticUpdateOfAxis(xAxis, false);
+        SetAutomaticUpdateOfAxis(yAxis, false);
+      }
+    }
+
+    // sets an axis to automatic or restrains it to its current values
+    // this is used that none of the set values is changed when jitter is applied, so that the chart stays the same
+    private void SetAutomaticUpdateOfAxis(Axis axis, bool enabled) {
+      if (enabled) {
+        axis.Maximum = double.NaN;
+        axis.Minimum = double.NaN;
+        axis.MajorGrid.Interval = double.NaN;
+        axis.MajorTickMark.Interval = double.NaN;
+        axis.LabelStyle.Interval = double.NaN;
+      } else {
+        axis.Minimum = axis.Minimum;
+        axis.Maximum = axis.Maximum;
+        axis.MajorGrid.Interval = axis.MajorGrid.Interval;
+        axis.MajorTickMark.Interval = axis.MajorTickMark.Interval;
+        axis.LabelStyle.Interval = axis.LabelStyle.Interval;
+      }
+    }
+
+    private void AddDataPoint(IRun run) {
+      double? xValue;
+      double? yValue;
+      double? sizeValue;
+      Series series = this.chart.Series[0];
+
+      xValue = GetValue(run, xAxisValue);
+      yValue = GetValue(run, yAxisValue);
+      sizeValue = GetValue(run, sizeAxisValue);
+
+      if (xValue.HasValue && yValue.HasValue && sizeValue.HasValue) {
+        xValue = xValue.Value;
+        yValue = yValue.Value;
+
+        if (run.Visible) {
+          DataPoint point = new DataPoint(xValue.Value, new double[] { yValue.Value, sizeValue.Value });
+          point.Tag = run;
+          series.Points.Add(point);
+          if (!runToDataPointMapping.ContainsKey(run)) runToDataPointMapping.Add(run, new List<DataPoint>());
+          runToDataPointMapping[run].Add(point);
+          UpdateRun(run);
+        }
+      }
+    }
+    private double? GetValue(IRun run, string columnName) {
+      if (run == null || string.IsNullOrEmpty(columnName))
+        return null;
+
+      if (Enum.IsDefined(typeof(AxisDimension), columnName)) {
+        AxisDimension axisDimension = (AxisDimension)Enum.Parse(typeof(AxisDimension), columnName);
+        return GetValue(run, axisDimension);
+      } else if (Enum.IsDefined(typeof(SizeDimension), columnName)) {
+        SizeDimension sizeDimension = (SizeDimension)Enum.Parse(typeof(SizeDimension), columnName);
+        return GetValue(run, sizeDimension);
+      } else {
+        int columnIndex = Matrix.ColumnNames.ToList().IndexOf(columnName);
+        IItem value = Content.GetValue(run, columnIndex);
+        if (value == null)
+          return null;
+
+        DoubleValue doubleValue = value as DoubleValue;
+        IntValue intValue = value as IntValue;
+        TimeSpanValue timeSpanValue = value as TimeSpanValue;
+        double? ret = null;
+        if (doubleValue != null) {
+          if (!double.IsNaN(doubleValue.Value) && !double.IsInfinity(doubleValue.Value))
+            ret = doubleValue.Value;
+        } else if (intValue != null)
+          ret = intValue.Value;
+        else if (timeSpanValue != null) {
+          ret = timeSpanValue.Value.TotalSeconds;
+        } else
+          ret = GetCategoricalValue(columnIndex, value.ToString());
+
+        return ret;
+      }
+    }
+    private double? GetCategoricalValue(int dimension, string value) {
+      if (!this.categoricalMapping.ContainsKey(dimension)) {
+        this.categoricalMapping[dimension] = new Dictionary<object, double>();
+        var orderedCategories = Content.Where(r => r.Visible && Content.GetValue(r, dimension) != null).Select(r => Content.GetValue(r, dimension).ToString())
+                                    .Distinct().OrderBy(x => x, new NaturalStringComparer());
+        int count = 1;
+        foreach (var category in orderedCategories) {
+          this.categoricalMapping[dimension].Add(category, count);
+          count++;
+        }
+      }
+      if (!this.categoricalMapping[dimension].ContainsKey(value)) return null;
+      return this.categoricalMapping[dimension][value];
+    }
+
+    private double GetValue(IRun run, AxisDimension axisDimension) {
+      double value = double.NaN;
+      switch (axisDimension) {
+        case AxisDimension.Index: {
+            value = runToIndexMapping[run];
+            break;
+          }
+        default: {
+            throw new ArgumentException("No handling strategy for " + axisDimension.ToString() + " is defined.");
+          }
+      }
+      return value;
+    }
+    private double GetValue(IRun run, SizeDimension sizeDimension) {
+      double value = double.NaN;
+      switch (sizeDimension) {
+        case SizeDimension.Constant: {
+            value = 2;
+            break;
+          }
+        default: {
+            throw new ArgumentException("No handling strategy for " + sizeDimension.ToString() + " is defined.");
+          }
+      }
+      return value;
+    }
+    private void UpdateCursorInterval() {
+      double xMin = double.MaxValue;
+      double xMax = double.MinValue;
+      double yMin = double.MaxValue;
+      double yMax = double.MinValue;
+
+      foreach (var point in chart.Series[0].Points) {
+        if (point.IsEmpty) continue;
+        if (point.XValue < xMin) xMin = point.XValue;
+        if (point.XValue > xMax) xMax = point.XValue;
+        if (point.YValues[0] < yMin) yMin = point.YValues[0];
+        if (point.YValues[0] > yMax) yMax = point.YValues[0];
+      }
+
+      double xRange = 0.0;
+      double yRange = 0.0;
+      if (xMin != double.MaxValue && xMax != double.MinValue) xRange = xMax - xMin;
+      if (yMin != double.MaxValue && yMax != double.MinValue) yRange = yMax - yMin;
+
+      if (xRange.IsAlmost(0.0)) xRange = 1.0;
+      if (yRange.IsAlmost(0.0)) yRange = 1.0;
+      double xDigits = (int)Math.Log10(xRange) - 3;
+      double yDigits = (int)Math.Log10(yRange) - 3;
+      double xZoomInterval = Math.Pow(10, xDigits);
+      double yZoomInterval = Math.Pow(10, yDigits);
+      this.chart.ChartAreas[0].CursorX.Interval = xZoomInterval;
+      this.chart.ChartAreas[0].CursorY.Interval = yZoomInterval;
+
+      //code to handle TimeSpanValues correct
+      int axisDimensionCount = Enum.GetNames(typeof(AxisDimension)).Count();
+      int columnIndex = xAxisComboBox.SelectedIndex - axisDimensionCount;
+      if (columnIndex >= 0 && Content.GetValue(0, columnIndex) is TimeSpanValue)
+        this.chart.ChartAreas[0].CursorX.Interval = 1;
+      columnIndex = yAxisComboBox.SelectedIndex - axisDimensionCount;
+      if (columnIndex >= 0 && Content.GetValue(0, columnIndex) is TimeSpanValue)
+        this.chart.ChartAreas[0].CursorY.Interval = 1;
+    }
+
+    #region Drag & drop and tooltip
+    private void chart_MouseDoubleClick(object sender, MouseEventArgs e) {
+      HitTestResult h = this.chart.HitTest(e.X, e.Y, ChartElementType.DataPoint);
+      if (h.ChartElementType == ChartElementType.DataPoint) {
+        IRun run = (IRun)((DataPoint)h.Object).Tag;
+        IContentView view = MainFormManager.MainForm.ShowContent(run);
+        if (view != null) {
+          view.ReadOnly = this.ReadOnly;
+          view.Locked = this.Locked;
+        }
+
+        this.chart.ChartAreas[0].CursorX.SelectionStart = this.chart.ChartAreas[0].CursorX.SelectionEnd;
+        this.chart.ChartAreas[0].CursorY.SelectionStart = this.chart.ChartAreas[0].CursorY.SelectionEnd;
+      }
+      UpdateAxisLabels();
+    }
+
+    private void chart_MouseUp(object sender, MouseEventArgs e) {
+      if (!isSelecting) return;
+
+      System.Windows.Forms.DataVisualization.Charting.Cursor xCursor = chart.ChartAreas[0].CursorX;
+      System.Windows.Forms.DataVisualization.Charting.Cursor yCursor = chart.ChartAreas[0].CursorY;
+
+      double minX = Math.Min(xCursor.SelectionStart, xCursor.SelectionEnd);
+      double maxX = Math.Max(xCursor.SelectionStart, xCursor.SelectionEnd);
+      double minY = Math.Min(yCursor.SelectionStart, yCursor.SelectionEnd);
+      double maxY = Math.Max(yCursor.SelectionStart, yCursor.SelectionEnd);
+
+      if (Control.ModifierKeys != Keys.Control) {
+        ClearSelectedRuns();
+      }
+
+      //check for click to select a single model
+      if (minX == maxX && minY == maxY) {
+        HitTestResult hitTest = chart.HitTest(e.X, e.Y, ChartElementType.DataPoint);
+        if (hitTest.ChartElementType == ChartElementType.DataPoint) {
+          int pointIndex = hitTest.PointIndex;
+          var point = chart.Series[0].Points[pointIndex];
+          IRun run = (IRun)point.Tag;
+          if (selectedRuns.Contains(run)) {
+            point.MarkerStyle = MarkerStyle.Circle;
+            point.Color = Color.FromArgb(255 - LogTransform(transparencyTrackBar.Value), run.Color);
+            selectedRuns.Remove(run);
+          } else {
+            point.Color = Color.Red;
+            point.MarkerStyle = MarkerStyle.Cross;
+            selectedRuns.Add(run);
+          }
+        }
+      } else {
+        foreach (DataPoint point in this.chart.Series[0].Points) {
+          if (point.XValue < minX || point.XValue > maxX) continue;
+          if (point.YValues[0] < minY || point.YValues[0] > maxY) continue;
+          point.MarkerStyle = MarkerStyle.Cross;
+          point.Color = Color.Red;
+          IRun run = (IRun)point.Tag;
+          selectedRuns.Add(run);
+        }
+      }
+
+      this.chart.ChartAreas[0].CursorX.SelectionStart = this.chart.ChartAreas[0].CursorX.SelectionEnd;
+      this.chart.ChartAreas[0].CursorY.SelectionStart = this.chart.ChartAreas[0].CursorY.SelectionEnd;
+      this.OnChanged();
+    }
+
+    private void chart_MouseMove(object sender, MouseEventArgs e) {
+      if (Control.MouseButtons != MouseButtons.None) return;
+      HitTestResult h = this.chart.HitTest(e.X, e.Y);
+      string newTooltipText = string.Empty;
+      string oldTooltipText;
+      if (h.ChartElementType == ChartElementType.DataPoint) {
+        IRun run = (IRun)((DataPoint)h.Object).Tag;
+        newTooltipText = BuildTooltip(run);
+      } else if (h.ChartElementType == ChartElementType.AxisLabels) {
+        newTooltipText = ((CustomLabel)h.Object).ToolTip;
+      }
+
+      oldTooltipText = this.tooltip.GetToolTip(chart);
+      if (newTooltipText != oldTooltipText)
+        this.tooltip.SetToolTip(chart, newTooltipText);
+    }
+
+    private string BuildTooltip(IRun run) {
+      string tooltip;
+      tooltip = run.Name + System.Environment.NewLine;
+
+      double? xValue = this.GetValue(run, (string)xAxisComboBox.SelectedItem);
+      double? yValue = this.GetValue(run, (string)yAxisComboBox.SelectedItem);
+      double? sizeValue = this.GetValue(run, (string)sizeComboBox.SelectedItem);
+
+      string xString = xValue == null ? string.Empty : xValue.Value.ToString();
+      string yString = yValue == null ? string.Empty : yValue.Value.ToString();
+      string sizeString = sizeValue == null ? string.Empty : sizeValue.Value.ToString();
+
+      //code to handle TimeSpanValues correct
+      int axisDimensionCount = Enum.GetNames(typeof(AxisDimension)).Count();
+      int columnIndex = xAxisComboBox.SelectedIndex - axisDimensionCount;
+      if (xValue.HasValue && columnIndex > 0 && Content.GetValue(0, columnIndex) is TimeSpanValue) {
+        TimeSpan time = TimeSpan.FromSeconds(xValue.Value);
+        xString = string.Format("{0:00}:{1:00}:{2:00.00}", (int)time.TotalHours, time.Minutes, time.Seconds);
+      }
+      columnIndex = yAxisComboBox.SelectedIndex - axisDimensionCount;
+      if (yValue.HasValue && columnIndex > 0 && Content.GetValue(0, columnIndex) is TimeSpanValue) {
+        TimeSpan time = TimeSpan.FromSeconds(yValue.Value);
+        yString = string.Format("{0:00}:{1:00}:{2:00.00}", (int)time.TotalHours, time.Minutes, time.Seconds);
+      }
+
+      tooltip += xAxisComboBox.SelectedItem + " : " + xString + Environment.NewLine;
+      tooltip += yAxisComboBox.SelectedItem + " : " + yString + Environment.NewLine;
+      tooltip += sizeComboBox.SelectedItem + " : " + sizeString + Environment.NewLine;
+
+      return tooltip;
+    }
+    #endregion
+
+    #region GUI events and updating
+    private double GetXJitter(IRun run) {
+      if (!this.xJitter.ContainsKey(run))
+        this.xJitter[run] = random.NextDouble() * 2.0 - 1.0;
+      return this.xJitter[run];
+    }
+    private double GetYJitter(IRun run) {
+      if (!this.yJitter.ContainsKey(run))
+        this.yJitter[run] = random.NextDouble() * 2.0 - 1.0;
+      return this.yJitter[run];
+    }
+    private void jitterTrackBar_ValueChanged(object sender, EventArgs e) {
+      this.xJitterFactor = xTrackBar.Value / 100.0;
+      this.yJitterFactor = yTrackBar.Value / 100.0;
+      UpdateDataPointJitter();
+    }
+    private void sizeTrackBar_ValueChanged(object sender, EventArgs e) {
+      UpdateMarkerSizes();
+    }
+
+    private void AxisComboBox_SelectedValueChanged(object sender, EventArgs e) {
+      bool axisSelected = xAxisComboBox.SelectedIndex != -1 && yAxisComboBox.SelectedIndex != -1;
+      xTrackBar.Enabled = yTrackBar.Enabled = axisSelected;
+      colorXAxisButton.Enabled = colorYAxisButton.Enabled = axisSelected;
+
+      xAxisValue = (string)xAxisComboBox.SelectedItem;
+      yAxisValue = (string)yAxisComboBox.SelectedItem;
+      sizeAxisValue = (string)sizeComboBox.SelectedItem;
+
+      UpdateDataPoints();
+      UpdateAxisLabels();
+    }
+    private void UpdateAxisLabels() {
+      Axis xAxis = this.chart.ChartAreas[0].AxisX;
+      Axis yAxis = this.chart.ChartAreas[0].AxisY;
+      int axisDimensionCount = Enum.GetNames(typeof(AxisDimension)).Count();
+      //mkommend: combobox.SelectedIndex could not be used as this changes during hovering over possible values
+      var xSAxisSelectedIndex = xAxisValue == null ? 0 : xAxisComboBox.Items.IndexOf(xAxisValue);
+      var ySAxisSelectedIndex = yAxisValue == null ? 0 : xAxisComboBox.Items.IndexOf(yAxisValue);
+      SetCustomAxisLabels(xAxis, xSAxisSelectedIndex - axisDimensionCount);
+      SetCustomAxisLabels(yAxis, ySAxisSelectedIndex - axisDimensionCount);
+      if (xAxisValue != null)
+        xAxis.Title = xAxisValue;
+      if (yAxisValue != null)
+        yAxis.Title = yAxisValue;
+    }
+
+    private void chart_AxisViewChanged(object sender, System.Windows.Forms.DataVisualization.Charting.ViewEventArgs e) {
+      this.UpdateAxisLabels();
+    }
+
+    private void SetCustomAxisLabels(Axis axis, int dimension) {
+      axis.CustomLabels.Clear();
+      if (categoricalMapping.ContainsKey(dimension)) {
+        foreach (var pair in categoricalMapping[dimension]) {
+          string labelText = pair.Key.ToString();
+          CustomLabel label = new CustomLabel();
+          label.ToolTip = labelText;
+          if (labelText.Length > 25)
+            labelText = labelText.Substring(0, 25) + " ... ";
+          label.Text = labelText;
+          label.GridTicks = GridTickTypes.TickMark;
+          label.FromPosition = pair.Value - 0.5;
+          label.ToPosition = pair.Value + 0.5;
+          axis.CustomLabels.Add(label);
+        }
+      } else if (dimension > 0 && Content.GetValue(0, dimension) is TimeSpanValue) {
+        this.chart.ChartAreas[0].RecalculateAxesScale();
+        for (double i = axis.Minimum; i <= axis.Maximum; i += axis.LabelStyle.Interval) {
+          TimeSpan time = TimeSpan.FromSeconds(i);
+          string x = string.Format("{0:00}:{1:00}:{2:00}", time.Hours, time.Minutes, time.Seconds);
+          axis.CustomLabels.Add(i - axis.LabelStyle.Interval / 2, i + axis.LabelStyle.Interval / 2, x);
+        }
+      }
+    }
+
+    private void zoomButton_CheckedChanged(object sender, EventArgs e) {
+      this.isSelecting = selectButton.Checked;
+      this.colorRunsButton.Enabled = this.isSelecting;
+      this.colorDialogButton.Enabled = this.isSelecting;
+      this.hideRunsButton.Enabled = this.isSelecting;
+      this.chart.ChartAreas[0].AxisX.ScaleView.Zoomable = !isSelecting;
+      this.chart.ChartAreas[0].AxisY.ScaleView.Zoomable = !isSelecting;
+      ClearSelectedRuns();
+    }
+
+    private void ContextMenuStrip_Opening(object sender, System.ComponentModel.CancelEventArgs e) {
+      hideRunsToolStripMenuItem.Visible = selectedRuns.Any();
+    }
+
+    private void unhideAllRunToolStripMenuItem_Click(object sender, EventArgs e) {
+      visibilityConstraint.ConstraintData.Clear();
+      if (Content.Constraints.Contains(visibilityConstraint)) Content.Constraints.Remove(visibilityConstraint);
+    }
+    private void hideRunsToolStripMenuItem_Click(object sender, EventArgs e) {
+      //ToList is necessary to prevent lazy evaluation
+      HideRuns(selectedRuns.ToList());
+      //could not use ClearSelectedRuns as the runs are not visible anymore
+      selectedRuns.Clear();
+    }
+    private void hideRunsButton_Click(object sender, EventArgs e) {
+      //ToList is necessary to prevent lazy evaluation
+      HideRuns(selectedRuns.ToList());
+      //could not use ClearSelectedRuns as the runs are not visible anymore
+      selectedRuns.Clear();
+    }
+
+    private void HideRuns(IEnumerable<IRun> runs) {
+      visibilityConstraint.Active = false;
+      if (!Content.Constraints.Contains(visibilityConstraint)) Content.Constraints.Add(visibilityConstraint);
+      foreach (var run in runs) {
+        visibilityConstraint.ConstraintData.Add(run);
+      }
+      visibilityConstraint.Active = true;
+    }
+
+    private void ClearSelectedRuns() {
+      foreach (var run in selectedRuns) {
+        foreach (var point in runToDataPointMapping[run]) {
+          point.MarkerStyle = MarkerStyle.Circle;
+          point.Color = Color.FromArgb(255 - LogTransform(transparencyTrackBar.Value), run.Color);
+        }
+      }
+      selectedRuns.Clear();
+    }
+
+    // returns a value in [0..255]
+    private int LogTransform(int x) {
+      double min = transparencyTrackBar.Minimum;
+      double max = transparencyTrackBar.Maximum;
+      double r = (x - min) / (max - min);  // r \in [0..1]
+      double l = Math.Max(Math.Min((1.0 - Math.Pow(0.05, r)) / 0.95, 1), 0); // l \in [0..1]
+      return (int)Math.Round(255.0 * l);
+    }
+
+    private void openBoxPlotViewToolStripMenuItem_Click(object sender, EventArgs e) {
+      RunCollectionBoxPlotView boxplotView = new RunCollectionBoxPlotView();
+      boxplotView.Content = this.Content;
+      boxplotView.xAxisComboBox.SelectedItem = xAxisComboBox.SelectedItem;
+      boxplotView.yAxisComboBox.SelectedItem = yAxisComboBox.SelectedItem;
+      boxplotView.Show();
+    }
+
+    private void getDataAsMatrixToolStripMenuItem_Click(object sender, EventArgs e) {
+      int xCol = Matrix.ColumnNames.ToList().IndexOf(xAxisValue);
+      int yCol = Matrix.ColumnNames.ToList().IndexOf(yAxisValue);
+
+      var grouped = new Dictionary<string, List<string>>();
+      Dictionary<double, string> reverseMapping = null;
+      if (categoricalMapping.ContainsKey(xCol))
+        reverseMapping = categoricalMapping[xCol].ToDictionary(x => x.Value, y => y.Key.ToString());
+      foreach (var run in Content.Where(r => r.Visible)) {
+        var x = GetValue(run, xAxisValue);
+        object y;
+        if (categoricalMapping.ContainsKey(yCol))
+          y = Content.GetValue(run, yAxisValue);
+        else y = GetValue(run, yAxisValue);
+        if (!(x.HasValue && y != null)) continue;
+
+        var category = reverseMapping == null ? x.Value.ToString() : reverseMapping[x.Value];
+        if (!grouped.ContainsKey(category)) grouped[category] = new List<string>();
+        grouped[category].Add(y.ToString());
+      }
+
+      if (!grouped.Any()) return;
+      var matrix = new StringMatrix(grouped.Values.Max(x => x.Count), grouped.Count) {
+        ColumnNames = grouped.Keys.ToArray()
+      };
+      int i = 0;
+      foreach (var col in matrix.ColumnNames) {
+        int j = 0;
+        foreach (var y in grouped[col])
+          matrix[j++, i] = y;
+        i++;
+      }
+      matrix.SortableView = false;
+      var view = MainFormManager.MainForm.ShowContent(matrix);
+      view.ReadOnly = true;
+    }
+
+    private void transparencyTrackBar_ValueChanged(object sender, EventArgs e) {
+      foreach (var run in Content)
+        UpdateRun(run);
+    }
+    #endregion
+
+    #region coloring
+    private void colorResetToolStripMenuItem_Click(object sender, EventArgs e) {
+      Content.UpdateOfRunsInProgress = true;
+
+      IEnumerable<IRun> runs;
+      if (selectedRuns.Any()) runs = selectedRuns;
+      else runs = Content;
+
+      foreach (var run in runs)
+        run.Color = Color.Black;
+      ClearSelectedRuns();
+
+      Content.UpdateOfRunsInProgress = false;
+    }
+    private void colorDialogButton_Click(object sender, EventArgs e) {
+      if (colorDialog.ShowDialog(this) == DialogResult.OK) {
+        this.colorRunsButton.Image = this.GenerateImage(16, 16, this.colorDialog.Color);
+        colorRunsButton_Click(sender, e);
+      }
+    }
+    private Image GenerateImage(int width, int height, Color fillColor) {
+      Image colorImage = new Bitmap(width, height);
+      using (Graphics gfx = Graphics.FromImage(colorImage)) {
+        using (SolidBrush brush = new SolidBrush(fillColor)) {
+          gfx.FillRectangle(brush, 0, 0, width, height);
+        }
+      }
+      return colorImage;
+    }
+
+    private void colorRunsButton_Click(object sender, EventArgs e) {
+      if (!selectedRuns.Any()) return;
+      Content.UpdateOfRunsInProgress = true;
+      foreach (var run in selectedRuns)
+        run.Color = colorDialog.Color;
+
+      ClearSelectedRuns();
+      Content.UpdateOfRunsInProgress = false;
+    }
+
+    private void colorXAxisButton_Click(object sender, EventArgs e) {
+      ColorRuns(xAxisValue);
+    }
+    private void colorYAxisButton_Click(object sender, EventArgs e) {
+      ColorRuns(yAxisValue);
+    }
+    private void ColorRuns(string axisValue) {
+      var runs = Content.Where(r => r.Visible).Select(r => new { Run = r, Value = GetValue(r, axisValue) }).Where(r => r.Value.HasValue).ToList();
+      double minValue = runs.Min(r => r.Value.Value);
+      double maxValue = runs.Max(r => r.Value.Value);
+      double range = maxValue - minValue;
+      // UpdateOfRunsInProgress has to be set to true, otherwise run_Changed is called all the time (also in other views)
+      Content.UpdateOfRunsInProgress = true;
+      if (range.IsAlmost(0)) {
+        Color c = ColorGradient.Colors[0];
+        runs.ForEach(r => r.Run.Color = c);
+      } else {
+        int maxColorIndex = ColorGradient.Colors.Count - 1;
+        foreach (var r in runs) {
+          int colorIndex = (int)(maxColorIndex * (r.Value - minValue) / (range));
+          r.Run.Color = ColorGradient.Colors[colorIndex];
+        }
+      }
+      Content.UpdateOfRunsInProgress = false;
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionChartAggregationView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionChartAggregationView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionChartAggregationView.Designer.cs	(revision 12764)
@@ -0,0 +1,135 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+namespace HeuristicLab.Optimization.Views {
+  partial class RunCollectionChartAggregationView {
+    /// <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.dataTableComboBox = new System.Windows.Forms.ComboBox();
+      this.label1 = new System.Windows.Forms.Label();
+      this.viewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.label2 = new System.Windows.Forms.Label();
+      this.dataRowComboBox = new System.Windows.Forms.ComboBox();
+      this.SuspendLayout();
+      // 
+      // dataTableComboBox
+      // 
+      this.dataTableComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.dataTableComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.dataTableComboBox.FormattingEnabled = true;
+      this.dataTableComboBox.Location = new System.Drawing.Point(69, 3);
+      this.dataTableComboBox.Name = "dataTableComboBox";
+      this.dataTableComboBox.Size = new System.Drawing.Size(455, 21);
+      this.dataTableComboBox.TabIndex = 0;
+      this.dataTableComboBox.SelectedIndexChanged += new System.EventHandler(this.dataTableComboBox_SelectedIndexChanged);
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(3, 6);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(60, 13);
+      this.label1.TabIndex = 1;
+      this.label1.Text = "DataTable:";
+      // 
+      // viewHost
+      // 
+      this.viewHost.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.viewHost.Caption = "View";
+      this.viewHost.Content = null;
+      this.viewHost.Enabled = false;
+      this.viewHost.Location = new System.Drawing.Point(4, 57);
+      this.viewHost.Name = "viewHost";
+      this.viewHost.ReadOnly = false;
+      this.viewHost.Size = new System.Drawing.Size(520, 314);
+      this.viewHost.TabIndex = 2;
+      this.viewHost.ViewsLabelVisible = true;
+      this.viewHost.ViewType = null;
+      // 
+      // label2
+      // 
+      this.label2.AutoSize = true;
+      this.label2.Location = new System.Drawing.Point(3, 33);
+      this.label2.Name = "label2";
+      this.label2.Size = new System.Drawing.Size(55, 13);
+      this.label2.TabIndex = 3;
+      this.label2.Text = "DataRow:";
+      // 
+      // dataRowComboBox
+      // 
+      this.dataRowComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.dataRowComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.dataRowComboBox.FormattingEnabled = true;
+      this.dataRowComboBox.Location = new System.Drawing.Point(69, 30);
+      this.dataRowComboBox.Name = "dataRowComboBox";
+      this.dataRowComboBox.Size = new System.Drawing.Size(455, 21);
+      this.dataRowComboBox.TabIndex = 4;
+      this.dataRowComboBox.SelectedIndexChanged += new System.EventHandler(this.dataRowComboBox_SelectedIndexChanged);
+      // 
+      // RunCollectionChartAggregationView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.dataRowComboBox);
+      this.Controls.Add(this.label2);
+      this.Controls.Add(this.viewHost);
+      this.Controls.Add(this.label1);
+      this.Controls.Add(this.dataTableComboBox);
+      this.Name = "RunCollectionChartAggregationView";
+      this.Size = new System.Drawing.Size(527, 374);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.ComboBox dataTableComboBox;
+    private System.Windows.Forms.Label label1;
+    private MainForm.WindowsForms.ViewHost viewHost;
+    private System.Windows.Forms.Label label2;
+    private System.Windows.Forms.ComboBox dataRowComboBox;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionChartAggregationView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionChartAggregationView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionChartAggregationView.cs	(revision 12764)
@@ -0,0 +1,270 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using HeuristicLab.Analysis;
+using HeuristicLab.Collections;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("Chart Aggregation")]
+  [Content(typeof(RunCollection), false)]
+  public partial class RunCollectionChartAggregationView : ItemView {
+    private const string AllDataRows = "All DataRows";
+
+    public new RunCollection Content {
+      get { return (RunCollection)base.Content; }
+      set { base.Content = value; }
+    }
+
+    private int rowNumber;
+    private bool suppressUpdates;
+    private readonly Dictionary<IRun, IEnumerable<DataRow>> runMapping;
+    private readonly DataTable combinedDataTable;
+    public DataTable CombinedDataTable {
+      get { return combinedDataTable; }
+    }
+
+    public RunCollectionChartAggregationView() {
+      InitializeComponent();
+      runMapping = new Dictionary<IRun, IEnumerable<DataRow>>();
+      combinedDataTable = new DataTable("Combined DataTable", "A data table containing data rows from multiple runs.");
+      viewHost.Content = combinedDataTable;
+      suppressUpdates = false;
+    }
+
+    #region Content events
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ItemsAdded += Content_ItemsAdded;
+      Content.ItemsRemoved += Content_ItemsRemoved;
+      Content.CollectionReset += Content_CollectionReset;
+      Content.UpdateOfRunsInProgressChanged += Content_UpdateOfRunsInProgressChanged;
+      Content.OptimizerNameChanged += Content_AlgorithmNameChanged;
+    }
+    protected override void DeregisterContentEvents() {
+      Content.ItemsAdded -= Content_ItemsAdded;
+      Content.ItemsRemoved -= Content_ItemsRemoved;
+      Content.CollectionReset -= Content_CollectionReset;
+      Content.UpdateOfRunsInProgressChanged -= Content_UpdateOfRunsInProgressChanged;
+      Content.OptimizerNameChanged -= Content_AlgorithmNameChanged;
+      base.DeregisterContentEvents();
+    }
+
+    private void Content_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      if (suppressUpdates) return;
+      if (InvokeRequired) {
+        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded), sender, e);
+        return;
+      }
+      UpdateDataTableComboBox();
+      UpdateDataRowComboBox();
+      AddRuns(e.Items);
+    }
+    private void Content_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      if (suppressUpdates) return;
+      if (InvokeRequired) {
+        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved), sender, e);
+        return;
+      }
+      UpdateDataTableComboBox();
+      UpdateDataRowComboBox();
+      RemoveRuns(e.Items);
+    }
+    private void Content_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      if (suppressUpdates) return;
+      if (InvokeRequired) {
+        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset), sender, e);
+        return;
+      }
+      UpdateDataTableComboBox();
+      UpdateDataRowComboBox();
+      RemoveRuns(e.OldItems);
+      AddRuns(e.Items);
+    }
+    private void Content_AlgorithmNameChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_AlgorithmNameChanged), sender, e);
+      else UpdateCaption();
+    }
+    private void Content_UpdateOfRunsInProgressChanged(object sender, EventArgs e) {
+      if (InvokeRequired) {
+        Invoke(new EventHandler(Content_UpdateOfRunsInProgressChanged), sender, e);
+        return;
+      }
+      suppressUpdates = Content.UpdateOfRunsInProgress;
+      if (!suppressUpdates) {
+        UpdateDataTableComboBox();
+        UpdateDataRowComboBox();
+        UpdateRuns(Content);
+      }
+    }
+
+    private void RegisterRunEvents(IRun run) {
+      run.PropertyChanged += run_PropertyChanged;
+    }
+    private void DeregisterRunEvents(IRun run) {
+      run.PropertyChanged -= run_PropertyChanged;
+    }
+    private void run_PropertyChanged(object sender, PropertyChangedEventArgs e) {
+      if (suppressUpdates) return;
+      if (InvokeRequired) {
+        Invoke((Action<object, PropertyChangedEventArgs>)run_PropertyChanged, sender, e);
+      } else {
+        var run = (IRun)sender;
+        if (e.PropertyName == "Color" || e.PropertyName == "Visible")
+          UpdateRuns(new[] { run });
+      }
+    }
+    #endregion
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      dataTableComboBox.Items.Clear();
+      dataRowComboBox.Items.Clear();
+      combinedDataTable.Rows.Clear();
+      runMapping.Clear();
+
+      UpdateCaption();
+      if (Content != null) {
+        UpdateDataTableComboBox();
+      }
+    }
+
+    private void RebuildCombinedDataTable() {
+      RemoveRuns(Content);
+      rowNumber = 0;
+      AddRuns(Content);
+    }
+
+    private void AddRuns(IEnumerable<IRun> runs) {
+      foreach (var run in runs) {
+        runMapping[run] = ExtractDataRowsFromRun(run).ToList();
+        RegisterRunEvents(run);
+      }
+      var dataRows = runs.Where(r => r.Visible && runMapping.ContainsKey(r)).SelectMany(r => runMapping[r]);
+      combinedDataTable.Rows.AddRange(dataRows);
+    }
+
+    private void RemoveRuns(IEnumerable<IRun> runs) {
+      var dataRows = runs.Where(r => runMapping.ContainsKey(r)).SelectMany(r => runMapping[r]).ToList();
+      foreach (var run in runs) {
+        if (!runMapping.ContainsKey(run)) continue;
+        runMapping.Remove(run);
+        DeregisterRunEvents(run);
+      }
+      combinedDataTable.Rows.RemoveRange(dataRows);
+    }
+
+    private void UpdateRuns(IEnumerable<IRun> runs) {
+      foreach (var run in runs) {
+        //update color
+        if (!runMapping.ContainsKey(run)) {
+          runMapping[run] = ExtractDataRowsFromRun(run).ToList();
+          RegisterRunEvents(run);
+        } else {
+          foreach (var dataRow in runMapping[run]) {
+            dataRow.VisualProperties.Color = run.Color;
+          }
+        }
+      }
+      //update visibility - remove and add all rows to keep the same order as before
+      combinedDataTable.Rows.Clear();
+      combinedDataTable.Rows.AddRange(runMapping.Where(mapping => mapping.Key.Visible).SelectMany(mapping => mapping.Value));
+    }
+
+    private IEnumerable<DataRow> ExtractDataRowsFromRun(IRun run) {
+      var resultName = (string)dataTableComboBox.SelectedItem;
+      if (string.IsNullOrEmpty(resultName)) yield break;
+
+      var rowName = (string)dataRowComboBox.SelectedItem;
+      if (!run.Results.ContainsKey(resultName)) yield break;
+
+      var dataTable = (DataTable)run.Results[resultName];
+      foreach (var dataRow in dataTable.Rows) {
+        if (dataRow.Name != rowName && rowName != AllDataRows) continue;
+        rowNumber++;
+        var clonedRow = (DataRow)dataRow.Clone();
+        //row names must be unique -> add incremented number to the row name
+        clonedRow.Name = run.Name + "." + dataRow.Name + rowNumber;
+        clonedRow.VisualProperties.DisplayName = run.Name + "." + dataRow.Name;
+        clonedRow.VisualProperties.Color = run.Color;
+        yield return clonedRow;
+      }
+    }
+
+    private void UpdateDataTableComboBox() {
+      string selectedItem = (string)dataTableComboBox.SelectedItem;
+
+      dataTableComboBox.Items.Clear();
+      var dataTables = (from run in Content
+                        from result in run.Results
+                        where result.Value is DataTable
+                        select result.Key).Distinct().ToArray();
+
+      dataTableComboBox.Items.AddRange(dataTables);
+      if (selectedItem != null && dataTableComboBox.Items.Contains(selectedItem)) {
+        dataTableComboBox.SelectedItem = selectedItem;
+      } else if (dataTableComboBox.Items.Count > 0) {
+        dataTableComboBox.SelectedItem = dataTableComboBox.Items[0];
+      }
+    }
+
+    private void UpdateCaption() {
+      Caption = Content != null ? Content.OptimizerName + " Chart Aggregation" : ViewAttribute.GetViewName(GetType());
+    }
+
+    private void UpdateDataRowComboBox() {
+      string selectedItem = (string)dataRowComboBox.SelectedItem;
+
+      dataRowComboBox.Items.Clear();
+      var resultName = (string)dataTableComboBox.SelectedItem;
+      if (resultName == null) return;
+
+      var dataTables = from run in Content
+                       where run.Results.ContainsKey(resultName)
+                       select run.Results[resultName] as DataTable;
+      var rowNames = (from dataTable in dataTables
+                      from row in dataTable.Rows
+                      select row.Name).Distinct().ToArray();
+
+      dataRowComboBox.Items.AddRange(rowNames);
+      dataRowComboBox.Items.Add(AllDataRows);
+      if (selectedItem != null && dataRowComboBox.Items.Contains(selectedItem)) {
+        dataRowComboBox.SelectedItem = selectedItem;
+      } else if (dataRowComboBox.Items.Count > 0) {
+        dataRowComboBox.SelectedItem = dataRowComboBox.Items[0];
+      }
+    }
+
+    private void dataTableComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      UpdateDataRowComboBox();
+    }
+    private void dataRowComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      if (suppressUpdates) return;
+      RebuildCombinedDataTable();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionTableView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionTableView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionTableView.Designer.cs	(revision 12764)
@@ -0,0 +1,72 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class RunCollectionTableView {
+    /// <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() {
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // rowsTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.rowsTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.rowsTextBox, 2);
+      // 
+      // RunCollectionTableView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.Name = "RunCollectionTableView";
+      this.ShowStatisticalInformation = true;
+      this.Controls.SetChildIndex(this.rowsLabel, 0);
+      this.Controls.SetChildIndex(this.columnsLabel, 0);
+      this.Controls.SetChildIndex(this.rowsTextBox, 0);
+      this.Controls.SetChildIndex(this.columnsTextBox, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionTableView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionTableView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionTableView.cs	(revision 12764)
@@ -0,0 +1,261 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.Data.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("Table")]
+  [Content(typeof(RunCollection), false)]
+  public sealed partial class RunCollectionTableView : StringConvertibleMatrixView {
+    private int[] runToRowMapping;
+    private bool suppressUpdates = false;
+    public RunCollectionTableView() {
+      InitializeComponent();
+      dataGridView.RowHeaderMouseDoubleClick += new DataGridViewCellMouseEventHandler(dataGridView_RowHeaderMouseDoubleClick);
+    }
+
+    public override bool ReadOnly {
+      get { return true; }
+      set { /*not needed because results are always readonly */}
+    }
+
+    public new RunCollection Content {
+      get { return (RunCollection)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content != null) {
+        UpdateRowAttributes();
+      }
+      UpdateCaption();
+    }
+
+    #region events
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ItemsAdded += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded);
+      Content.ItemsRemoved += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
+      Content.CollectionReset += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
+      Content.UpdateOfRunsInProgressChanged += new EventHandler(Content_UpdateOfRunsInProgressChanged);
+      Content.OptimizerNameChanged += new EventHandler(Content_AlgorithmNameChanged);
+      RegisterRunEvents(Content);
+    }
+    private void RegisterRunEvents(IEnumerable<IRun> runs) {
+      foreach (IRun run in runs)
+        run.PropertyChanged += run_PropertyChanged;
+    }
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.ItemsAdded -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded);
+      Content.ItemsRemoved -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
+      Content.CollectionReset -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
+      Content.UpdateOfRunsInProgressChanged -= new EventHandler(Content_UpdateOfRunsInProgressChanged);
+      Content.OptimizerNameChanged -= new EventHandler(Content_AlgorithmNameChanged);
+      DeregisterRunEvents(Content);
+    }
+    private void DeregisterRunEvents(IEnumerable<IRun> runs) {
+      foreach (IRun run in runs)
+        run.PropertyChanged -= run_PropertyChanged;
+    }
+    private void Content_CollectionReset(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IRun> e) {
+      DeregisterRunEvents(e.OldItems);
+      RegisterRunEvents(e.Items);
+    }
+    private void Content_ItemsRemoved(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IRun> e) {
+      DeregisterRunEvents(e.Items);
+    }
+    private void Content_ItemsAdded(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IRun> e) {
+      RegisterRunEvents(e.Items);
+    }
+    private void Content_AlgorithmNameChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_AlgorithmNameChanged), sender, e);
+      else UpdateCaption();
+    }
+    private void run_PropertyChanged(object sender, PropertyChangedEventArgs e) {
+      if (suppressUpdates) return;
+      if (InvokeRequired)
+        this.Invoke((Action<object, PropertyChangedEventArgs>)run_PropertyChanged, sender, e);
+      else {
+        IRun run = (IRun)sender;
+        if (e.PropertyName == "Color" || e.PropertyName == "Visible")
+          UpdateRun(run);
+      }
+    }
+    #endregion
+
+    private void UpdateCaption() {
+      Caption = Content != null ? Content.OptimizerName + " Table" : ViewAttribute.GetViewName(GetType());
+    }
+
+    protected override void UpdateData() {
+      if (suppressUpdates) return;
+      base.UpdateData();
+    }
+
+    protected override void UpdateColumnHeaders() {
+      HashSet<string> visibleColumnNames = new HashSet<string>(dataGridView.Columns.OfType<DataGridViewColumn>()
+       .Where(c => c.Visible && !string.IsNullOrEmpty(c.HeaderText)).Select(c => c.HeaderText));
+
+      for (int i = 0; i < dataGridView.ColumnCount; i++) {
+        if (i < base.Content.ColumnNames.Count())
+          dataGridView.Columns[i].HeaderText = base.Content.ColumnNames.ElementAt(i);
+        else
+          dataGridView.Columns[i].HeaderText = "Column " + (i + 1);
+        dataGridView.Columns[i].Visible = visibleColumnNames.Count == 0 || visibleColumnNames.Contains(dataGridView.Columns[i].HeaderText);
+      }
+    }
+
+    private void UpdateRun(IRun run) {
+      foreach (int runIndex in GetIndexOfRun(run)) {
+        int rowIndex = runToRowMapping[runIndex];
+        this.dataGridView.Rows[rowIndex].Visible = run.Visible;
+        this.dataGridView.Rows[rowIndex].DefaultCellStyle.ForeColor = run.Color;
+      }
+      this.UpdateRowHeaders();
+    }
+
+
+    private void Content_UpdateOfRunsInProgressChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_UpdateOfRunsInProgressChanged), sender, e);
+      else {
+        suppressUpdates = Content.UpdateOfRunsInProgress;
+        if (!suppressUpdates) {
+          UpdateData();
+          UpdateRowAttributes();
+        }
+      }
+    }
+
+    private IEnumerable<int> GetIndexOfRun(IRun run) {
+      int i = 0;
+      foreach (IRun actualRun in Content) {
+        if (actualRun == run)
+          yield return i;
+        i++;
+      }
+    }
+
+    private void dataGridView_RowHeaderMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e) {
+      if (e.RowIndex >= 0) {
+        IRun run = Content.ElementAt(runToRowMapping.ToList().IndexOf(e.RowIndex));
+        IContentView view = MainFormManager.MainForm.ShowContent(run);
+        if (view != null) {
+          view.ReadOnly = this.ReadOnly;
+          view.Locked = this.Locked;
+        }
+      }
+    }
+
+    protected override void ClearSorting() {
+      base.ClearSorting();
+      UpdateRowAttributes();
+    }
+
+    protected override int[] Sort(IEnumerable<KeyValuePair<int, SortOrder>> sortedColumns) {
+      int[] newSortedIndex = Enumerable.Range(0, Content.Count).ToArray();
+      RunCollectionRowComparer rowComparer = new RunCollectionRowComparer();
+      if (sortedColumns.Count() != 0) {
+        rowComparer.SortedIndices = sortedColumns;
+        rowComparer.Matrix = Content;
+        Array.Sort(newSortedIndex, rowComparer);
+      }
+
+      runToRowMapping = new int[newSortedIndex.Length];
+      int i = 0;
+      foreach (int runIndex in newSortedIndex) {
+        runToRowMapping[runIndex] = i;
+        i++;
+      }
+      UpdateRowAttributes(rebuild: false);
+      return newSortedIndex;
+    }
+
+    private void UpdateRowAttributes(bool rebuild = true) {
+      if (rebuild) runToRowMapping = Enumerable.Range(0, Content.Count).ToArray();
+      int runIndex = 0;
+      foreach (IRun run in Content) {
+        int rowIndex = this.runToRowMapping[runIndex];
+        this.dataGridView.Rows[rowIndex].Visible = run.Visible;
+        this.dataGridView.Rows[rowIndex].DefaultCellStyle.ForeColor = run.Color;
+        runIndex++;
+      }
+      rowsTextBox.Text = dataGridView.Rows.GetRowCount(DataGridViewElementStates.Visible).ToString();
+      UpdateRowHeaders();
+    }
+
+    public class RunCollectionRowComparer : IComparer<int> {
+      public RunCollectionRowComparer() {
+      }
+
+      private List<KeyValuePair<int, SortOrder>> sortedIndices;
+      public IEnumerable<KeyValuePair<int, SortOrder>> SortedIndices {
+        get { return this.sortedIndices; }
+        set { sortedIndices = new List<KeyValuePair<int, SortOrder>>(value); }
+      }
+      private RunCollection matrix;
+      public RunCollection Matrix {
+        get { return this.matrix; }
+        set { this.matrix = value; }
+      }
+
+      public int Compare(int x, int y) {
+        int result = 0;
+        IItem value1, value2;
+        IComparable comparable1, comparable2;
+
+        if (matrix == null)
+          throw new InvalidOperationException("Could not sort IStringConvertibleMatrix if the matrix member is null.");
+        if (sortedIndices == null)
+          return 0;
+
+        foreach (KeyValuePair<int, SortOrder> pair in sortedIndices.Where(p => p.Value != SortOrder.None)) {
+          value1 = matrix.GetValue(x, pair.Key);
+          value2 = matrix.GetValue(y, pair.Key);
+          comparable1 = value1 as IComparable;
+          comparable2 = value2 as IComparable;
+          if (comparable1 != null)
+            result = comparable1.CompareTo(comparable2);
+          else {
+            string string1 = value1 != null ? value1.ToString() : string.Empty;
+            string string2 = value2 != null ? value2.ToString() : string.Empty;
+            result = string1.CompareTo(string2);
+          }
+          if (pair.Value == SortOrder.Descending)
+            result *= -1;
+          if (result != 0)
+            return result;
+        }
+        return result;
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionView.Designer.cs	(revision 12764)
@@ -0,0 +1,349 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Windows.Forms;
+
+namespace HeuristicLab.Optimization.Views {
+  partial class RunCollectionView {
+    /// <summary>
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary>
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region 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.splitContainer = new System.Windows.Forms.SplitContainer();
+      this.showDetailsCheckBox = new System.Windows.Forms.CheckBox();
+      this.clearButton = new System.Windows.Forms.Button();
+      this.toolStrip = new System.Windows.Forms.ToolStrip();
+      this.analyzeRunsToolStripDropDownButton = new System.Windows.Forms.ToolStripDropDownButton();
+      this.itemsListView = new System.Windows.Forms.ListView();
+      this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+      this.imageList = new System.Windows.Forms.ImageList(this.components);
+      this.removeButton = new System.Windows.Forms.Button();
+      this.detailsGroupBox = new System.Windows.Forms.GroupBox();
+      this.viewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.itemsGroupBox = new System.Windows.Forms.GroupBox();
+      this.toolTip = new System.Windows.Forms.ToolTip(this.components);
+      this.tabControl = new HeuristicLab.MainForm.WindowsForms.DragOverTabControl();
+      this.runPage = new System.Windows.Forms.TabPage();
+      this.constraintPage = new System.Windows.Forms.TabPage();
+      this.runCollectionConstraintCollectionView = new HeuristicLab.Optimization.Views.RunCollectionConstraintCollectionView();
+      this.modifiersPage = new System.Windows.Forms.TabPage();
+      this.runCollectionModifiersListView = new HeuristicLab.Optimization.Views.RunCollectionModifiersListView();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.toolStrip.SuspendLayout();
+      this.detailsGroupBox.SuspendLayout();
+      this.itemsGroupBox.SuspendLayout();
+      this.tabControl.SuspendLayout();
+      this.runPage.SuspendLayout();
+      this.constraintPage.SuspendLayout();
+      this.modifiersPage.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // splitContainer
+      // 
+      this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
+      this.splitContainer.Location = new System.Drawing.Point(3, 16);
+      this.splitContainer.Name = "splitContainer";
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.showDetailsCheckBox);
+      this.splitContainer.Panel1.Controls.Add(this.clearButton);
+      this.splitContainer.Panel1.Controls.Add(this.toolStrip);
+      this.splitContainer.Panel1.Controls.Add(this.itemsListView);
+      this.splitContainer.Panel1.Controls.Add(this.removeButton);
+      this.splitContainer.Panel1MinSize = 100;
+      // 
+      // splitContainer.Panel2
+      // 
+      this.splitContainer.Panel2.Controls.Add(this.detailsGroupBox);
+      this.splitContainer.Size = new System.Drawing.Size(512, 332);
+      this.splitContainer.SplitterDistance = 250;
+      this.splitContainer.TabIndex = 0;
+      // 
+      // showDetailsCheckBox
+      // 
+      this.showDetailsCheckBox.Appearance = System.Windows.Forms.Appearance.Button;
+      this.showDetailsCheckBox.Checked = true;
+      this.showDetailsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.showDetailsCheckBox.Image = HeuristicLab.Common.Resources.VSImageLibrary.Properties;
+      this.showDetailsCheckBox.Location = new System.Drawing.Point(87, 3);
+      this.showDetailsCheckBox.Name = "showDetailsCheckBox";
+      this.showDetailsCheckBox.Size = new System.Drawing.Size(24, 24);
+      this.showDetailsCheckBox.TabIndex = 2;
+      this.toolTip.SetToolTip(this.showDetailsCheckBox, "Show/Hide Details");
+      this.showDetailsCheckBox.UseVisualStyleBackColor = true;
+      this.showDetailsCheckBox.CheckedChanged += new System.EventHandler(this.showDetailsCheckBox_CheckedChanged);
+      // 
+      // clearButton
+      // 
+      this.clearButton.Enabled = false;
+      this.clearButton.Location = new System.Drawing.Point(33, 3);
+      this.clearButton.Name = "clearButton";
+      this.clearButton.Size = new System.Drawing.Size(48, 24);
+      this.clearButton.TabIndex = 1;
+      this.clearButton.Text = "&Clear";
+      this.toolTip.SetToolTip(this.clearButton, "Remove All Runs");
+      this.clearButton.UseVisualStyleBackColor = true;
+      this.clearButton.Click += new System.EventHandler(this.clearButton_Click);
+      // 
+      // toolStrip
+      // 
+      this.toolStrip.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.toolStrip.AutoSize = false;
+      this.toolStrip.Dock = System.Windows.Forms.DockStyle.None;
+      this.toolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
+      this.toolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.analyzeRunsToolStripDropDownButton});
+      this.toolStrip.Location = new System.Drawing.Point(114, 3);
+      this.toolStrip.Name = "toolStrip";
+      this.toolStrip.Size = new System.Drawing.Size(133, 24);
+      this.toolStrip.TabIndex = 3;
+      this.toolStrip.Text = "toolStrip1";
+      // 
+      // analyzeRunsToolStripDropDownButton
+      // 
+      this.analyzeRunsToolStripDropDownButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
+      this.analyzeRunsToolStripDropDownButton.ImageTransparentColor = System.Drawing.Color.Magenta;
+      this.analyzeRunsToolStripDropDownButton.Name = "analyzeRunsToolStripDropDownButton";
+      this.analyzeRunsToolStripDropDownButton.Size = new System.Drawing.Size(99, 21);
+      this.analyzeRunsToolStripDropDownButton.Text = "&Analyze Runs...";
+      this.analyzeRunsToolStripDropDownButton.ToolTipText = "Show Run Analysis Views";
+      // 
+      // itemsListView
+      // 
+      this.itemsListView.AllowDrop = true;
+      this.itemsListView.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.itemsListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+            this.columnHeader1});
+      this.itemsListView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None;
+      this.itemsListView.HideSelection = false;
+      this.itemsListView.Location = new System.Drawing.Point(3, 33);
+      this.itemsListView.Name = "itemsListView";
+      this.itemsListView.ShowItemToolTips = true;
+      this.itemsListView.Size = new System.Drawing.Size(244, 295);
+      this.itemsListView.SmallImageList = this.imageList;
+      this.itemsListView.TabIndex = 4;
+      this.itemsListView.UseCompatibleStateImageBehavior = false;
+      this.itemsListView.View = System.Windows.Forms.View.Details;
+      this.itemsListView.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.itemsListView_ItemDrag);
+      this.itemsListView.SelectedIndexChanged += new System.EventHandler(this.itemsListView_SelectedIndexChanged);
+      this.itemsListView.DragDrop += new System.Windows.Forms.DragEventHandler(this.itemsListView_DragDrop);
+      this.itemsListView.DragEnter += new System.Windows.Forms.DragEventHandler(this.itemsListView_DragEnter);
+      this.itemsListView.DragOver += new System.Windows.Forms.DragEventHandler(this.itemsListView_DragOver);
+      this.itemsListView.DoubleClick += new System.EventHandler(this.itemsListView_DoubleClick);
+      this.itemsListView.KeyDown += new System.Windows.Forms.KeyEventHandler(this.itemsListView_KeyDown);
+      // 
+      // imageList
+      // 
+      this.imageList.ColorDepth = System.Windows.Forms.ColorDepth.Depth8Bit;
+      this.imageList.ImageSize = new System.Drawing.Size(16, 16);
+      this.imageList.TransparentColor = System.Drawing.Color.Transparent;
+      // 
+      // removeButton
+      // 
+      this.removeButton.Enabled = false;
+      this.removeButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Remove;
+      this.removeButton.Location = new System.Drawing.Point(3, 3);
+      this.removeButton.Name = "removeButton";
+      this.removeButton.Size = new System.Drawing.Size(24, 24);
+      this.removeButton.TabIndex = 0;
+      this.toolTip.SetToolTip(this.removeButton, "Remove");
+      this.removeButton.UseVisualStyleBackColor = true;
+      this.removeButton.Click += new System.EventHandler(this.removeButton_Click);
+      // 
+      // detailsGroupBox
+      // 
+      this.detailsGroupBox.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.detailsGroupBox.Controls.Add(this.viewHost);
+      this.detailsGroupBox.Location = new System.Drawing.Point(3, 27);
+      this.detailsGroupBox.Name = "detailsGroupBox";
+      this.detailsGroupBox.Size = new System.Drawing.Size(252, 303);
+      this.detailsGroupBox.TabIndex = 0;
+      this.detailsGroupBox.TabStop = false;
+      this.detailsGroupBox.Text = "Details";
+      // 
+      // viewHost
+      // 
+      this.viewHost.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.viewHost.Caption = "View";
+      this.viewHost.Content = null;
+      this.viewHost.Location = new System.Drawing.Point(6, 19);
+      this.viewHost.Name = "viewHost";
+      this.viewHost.ReadOnly = false;
+      this.viewHost.Size = new System.Drawing.Size(240, 278);
+      this.viewHost.TabIndex = 0;
+      this.viewHost.ViewType = null;
+      // 
+      // itemsGroupBox
+      // 
+      this.itemsGroupBox.Controls.Add(this.splitContainer);
+      this.itemsGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.itemsGroupBox.Location = new System.Drawing.Point(3, 3);
+      this.itemsGroupBox.Name = "itemsGroupBox";
+      this.itemsGroupBox.Size = new System.Drawing.Size(518, 351);
+      this.itemsGroupBox.TabIndex = 0;
+      this.itemsGroupBox.TabStop = false;
+      this.itemsGroupBox.Text = "Items";
+      // 
+      // tabControl
+      // 
+      this.tabControl.Controls.Add(this.runPage);
+      this.tabControl.Controls.Add(this.constraintPage);
+      this.tabControl.Controls.Add(this.modifiersPage);
+      this.tabControl.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.tabControl.Location = new System.Drawing.Point(0, 0);
+      this.tabControl.Name = "tabControl";
+      this.tabControl.SelectedIndex = 0;
+      this.tabControl.Size = new System.Drawing.Size(532, 383);
+      this.tabControl.TabIndex = 0;
+      // 
+      // runPage
+      // 
+      this.runPage.Controls.Add(this.itemsGroupBox);
+      this.runPage.Location = new System.Drawing.Point(4, 22);
+      this.runPage.Name = "runPage";
+      this.runPage.Padding = new System.Windows.Forms.Padding(3);
+      this.runPage.Size = new System.Drawing.Size(524, 357);
+      this.runPage.TabIndex = 0;
+      this.runPage.Text = "Runs";
+      this.runPage.UseVisualStyleBackColor = true;
+      // 
+      // constraintPage
+      // 
+      this.constraintPage.Controls.Add(this.runCollectionConstraintCollectionView);
+      this.constraintPage.Location = new System.Drawing.Point(4, 22);
+      this.constraintPage.Name = "constraintPage";
+      this.constraintPage.Padding = new System.Windows.Forms.Padding(3);
+      this.constraintPage.Size = new System.Drawing.Size(524, 357);
+      this.constraintPage.TabIndex = 1;
+      this.constraintPage.Text = "Filtering";
+      this.constraintPage.UseVisualStyleBackColor = true;
+      // 
+      // runCollectionConstraintCollectionView
+      // 
+      this.runCollectionConstraintCollectionView.Caption = "ConstraintCollection View";
+      this.runCollectionConstraintCollectionView.Content = null;
+      this.runCollectionConstraintCollectionView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.runCollectionConstraintCollectionView.Location = new System.Drawing.Point(3, 3);
+      this.runCollectionConstraintCollectionView.Name = "runCollectionConstraintCollectionView";
+      this.runCollectionConstraintCollectionView.ReadOnly = false;
+      this.runCollectionConstraintCollectionView.Size = new System.Drawing.Size(518, 351);
+      this.runCollectionConstraintCollectionView.TabIndex = 0;
+      // 
+      // modifiersPage
+      // 
+      this.modifiersPage.Controls.Add(this.runCollectionModifiersListView);
+      this.modifiersPage.Location = new System.Drawing.Point(4, 22);
+      this.modifiersPage.Name = "modifiersPage";
+      this.modifiersPage.Padding = new System.Windows.Forms.Padding(3);
+      this.modifiersPage.Size = new System.Drawing.Size(524, 357);
+      this.modifiersPage.TabIndex = 2;
+      this.modifiersPage.Text = "Modification";
+      this.modifiersPage.UseVisualStyleBackColor = true;
+      // 
+      // runCollectionModifiersListView
+      // 
+      this.runCollectionModifiersListView.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.runCollectionModifiersListView.Caption = "Modifier View";
+      this.runCollectionModifiersListView.Content = null;
+      this.runCollectionModifiersListView.Evaluator = null;
+      this.runCollectionModifiersListView.Location = new System.Drawing.Point(3, 3);
+      this.runCollectionModifiersListView.Name = "runCollectionModifiersListView";
+      this.runCollectionModifiersListView.ReadOnly = false;
+      this.runCollectionModifiersListView.Size = new System.Drawing.Size(518, 351);
+      this.runCollectionModifiersListView.TabIndex = 0;
+      // 
+      // RunCollectionView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.Controls.Add(this.tabControl);
+      this.Name = "RunCollectionView";
+      this.Size = new System.Drawing.Size(532, 383);
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel2.ResumeLayout(false);
+      this.splitContainer.ResumeLayout(false);
+      this.toolStrip.ResumeLayout(false);
+      this.toolStrip.PerformLayout();
+      this.detailsGroupBox.ResumeLayout(false);
+      this.itemsGroupBox.ResumeLayout(false);
+      this.tabControl.ResumeLayout(false);
+      this.runPage.ResumeLayout(false);
+      this.constraintPage.ResumeLayout(false);
+      this.modifiersPage.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.SplitContainer splitContainer;
+    private System.Windows.Forms.ColumnHeader columnHeader1;
+    private GroupBox itemsGroupBox;
+    private ListView itemsListView;
+    private GroupBox detailsGroupBox;
+    private Button removeButton;
+    private ToolTip toolTip;
+    private ImageList imageList;
+    private HeuristicLab.MainForm.WindowsForms.ViewHost viewHost;
+    private ToolStrip toolStrip;
+    private ToolStripDropDownButton analyzeRunsToolStripDropDownButton;
+    private HeuristicLab.MainForm.WindowsForms.DragOverTabControl tabControl;
+    private TabPage runPage;
+    private TabPage constraintPage;
+    private RunCollectionConstraintCollectionView runCollectionConstraintCollectionView;
+    private Button clearButton;
+    private CheckBox showDetailsCheckBox;
+    private TabPage modifiersPage;
+    private RunCollectionModifiersListView runCollectionModifiersListView;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionView.cs	(revision 12764)
@@ -0,0 +1,537 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("RunCollection View")]
+  [Content(typeof(RunCollection), true)]
+  [Content(typeof(IItemCollection<IRun>), false)]
+  public sealed partial class RunCollectionView : ItemView {
+    private Dictionary<IRun, List<ListViewItem>> itemListViewItemMapping;
+    private bool validDragOperation;
+    private bool suppressUpdates;
+
+    public new IItemCollection<IRun> Content {
+      get { return (IItemCollection<IRun>)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public RunCollection RunCollection {
+      get { return Content as RunCollection; }
+    }
+
+    public ListView ItemsListView {
+      get { return itemsListView; }
+    }
+
+    public RunCollectionView() {
+      InitializeComponent();
+      itemsGroupBox.Text = "Runs";
+      itemListViewItemMapping = new Dictionary<IRun, List<ListViewItem>>();
+      runCollectionModifiersListView.Evaluator = EvaluateModifications;
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded);
+      Content.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
+      Content.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
+      if (RunCollection != null)
+        RunCollection.UpdateOfRunsInProgressChanged -= new EventHandler(RunCollection_UpdateOfRunsInProgressChanged);
+      foreach (IRun run in itemListViewItemMapping.Keys) {
+        DeregisterItemEvents(run);
+      }
+      base.DeregisterContentEvents();
+    }
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded);
+      Content.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved);
+      Content.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset);
+      if (RunCollection != null)
+        RunCollection.UpdateOfRunsInProgressChanged += new EventHandler(RunCollection_UpdateOfRunsInProgressChanged);
+    }
+    private void DeregisterItemEvents(IRun item) {
+      item.ItemImageChanged -= new EventHandler(Item_ItemImageChanged);
+      item.ToStringChanged -= new EventHandler(Item_ToStringChanged);
+      item.PropertyChanged -= Item_PropertyChanged;
+    }
+    private void RegisterItemEvents(IRun item) {
+      item.ItemImageChanged += new EventHandler(Item_ItemImageChanged);
+      item.ToStringChanged += new EventHandler(Item_ToStringChanged);
+      item.PropertyChanged += Item_PropertyChanged;
+    }
+
+    protected override void OnInitialized(EventArgs e) {
+      base.OnInitialized(e);
+      var viewTypes = MainFormManager.GetViewTypes(typeof(RunCollection), true);
+      foreach (Type viewType in viewTypes.OrderBy(x => ViewAttribute.GetViewName(x))) {
+        if ((viewType != typeof(ItemCollectionView<IRun>)) && (viewType != typeof(ViewHost))) {
+          ToolStripMenuItem menuItem = new ToolStripMenuItem();
+          menuItem.Text = ViewAttribute.GetViewName(viewType);
+          menuItem.Tag = viewType;
+          menuItem.Click += new EventHandler(menuItem_Click);
+          analyzeRunsToolStripDropDownButton.DropDownItems.Add(menuItem);
+        }
+      }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+
+      string selectedName = null;
+      if ((itemsListView.SelectedItems.Count == 1) && (itemsListView.SelectedItems[0].Tag != null))
+        selectedName = ((IRun)itemsListView.SelectedItems[0].Tag).Name;
+
+      itemsListView.Items.Clear();
+      itemListViewItemMapping.Clear();
+      RebuildImageList();
+      viewHost.Content = null;
+
+      if (Content != null) {
+        if (RunCollection != null) {
+          if (!tabControl.TabPages.Contains(constraintPage))
+            tabControl.TabPages.Add(constraintPage);
+          runCollectionConstraintCollectionView.Content = RunCollection.Constraints;
+          runCollectionConstraintCollectionView.ReadOnly = itemsListView.Items.Count == 0;
+          if (!tabControl.TabPages.Contains(modifiersPage))
+            tabControl.TabPages.Add(modifiersPage);
+          runCollectionModifiersListView.Content = RunCollection.Modifiers;
+        }
+        foreach (IRun item in Content) {
+          ListViewItem listViewItem = CreateListViewItem(item);
+          AddListViewItem(listViewItem);
+          if ((selectedName != null) && item.Name.Equals(selectedName))
+            listViewItem.Selected = true;
+        }
+        AdjustListViewColumnSizes();
+      } else {
+        runCollectionConstraintCollectionView.Content = null;
+        if (tabControl.TabPages.Contains(constraintPage))
+          tabControl.TabPages.Remove(constraintPage);
+        if (tabControl.TabPages.Contains(modifiersPage))
+          tabControl.TabPages.Remove(modifiersPage);
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      if (Content == null) {
+        analyzeRunsToolStripDropDownButton.Enabled = false;
+        runCollectionConstraintCollectionView.ReadOnly = true;
+        itemsListView.Enabled = false;
+        detailsGroupBox.Enabled = false;
+        viewHost.Enabled = false;
+        removeButton.Enabled = false;
+        clearButton.Enabled = false;
+      } else {
+        analyzeRunsToolStripDropDownButton.Enabled = itemsListView.Items.Count > 0;
+        runCollectionConstraintCollectionView.ReadOnly = itemsListView.Items.Count == 0;
+        itemsListView.Enabled = true;
+        detailsGroupBox.Enabled = itemsListView.SelectedItems.Count == 1;
+        removeButton.Enabled = itemsListView.SelectedItems.Count > 0 && !Content.IsReadOnly && !ReadOnly;
+        clearButton.Enabled = itemsListView.Items.Count > 0 && !Content.IsReadOnly && !ReadOnly;
+        viewHost.Enabled = true;
+      }
+    }
+
+    private ListViewItem CreateListViewItem(IRun item) {
+      ListViewItem listViewItem = new ListViewItem();
+      if (item == null) {
+        listViewItem.Text = "null";
+        itemsListView.SmallImageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Nothing);
+        listViewItem.ImageIndex = itemsListView.SmallImageList.Images.Count - 1;
+      } else {
+        listViewItem.Text = item.ToString();
+        listViewItem.ToolTipText = item.ItemName + ": " + item.ItemDescription;
+        itemsListView.SmallImageList.Images.Add(item.ItemImage);
+        listViewItem.ImageIndex = itemsListView.SmallImageList.Images.Count - 1;
+        listViewItem.Tag = item;
+
+        if (item.Visible) {
+          listViewItem.Font = new Font(listViewItem.Font, FontStyle.Regular);
+          listViewItem.ForeColor = item.Color;
+        } else {
+          listViewItem.Font = new Font(listViewItem.Font, FontStyle.Italic);
+          listViewItem.ForeColor = Color.LightGray;
+        }
+      }
+      return listViewItem;
+    }
+    private void AddListViewItem(ListViewItem listViewItem) {
+      if (listViewItem == null) throw new ArgumentNullException();
+      itemsListView.Items.Add(listViewItem);
+      IRun run = listViewItem.Tag as IRun;
+      if (run != null) {
+        if (!itemListViewItemMapping.ContainsKey(run)) {
+          itemListViewItemMapping.Add(run, new List<ListViewItem>());
+          RegisterItemEvents(run);
+        }
+        itemListViewItemMapping[run].Add(listViewItem);
+      }
+    }
+    private void RemoveListViewItem(ListViewItem listViewItem) {
+      if (listViewItem == null) throw new ArgumentNullException();
+      IRun run = listViewItem.Tag as IRun;
+      if (run != null) {
+        itemListViewItemMapping[run].Remove(listViewItem);
+        if (itemListViewItemMapping[run].Count == 0) {
+          DeregisterItemEvents(run);
+          itemListViewItemMapping.Remove(run);
+        }
+      }
+      listViewItem.Remove();
+    }
+    private void UpdateListViewItemImage(ListViewItem listViewItem) {
+      if (listViewItem == null) throw new ArgumentNullException();
+      IRun item = listViewItem.Tag as IRun;
+      int i = listViewItem.ImageIndex;
+      itemsListView.SmallImageList.Images[i] = item == null ? HeuristicLab.Common.Resources.VSImageLibrary.Nothing : item.ItemImage;
+      listViewItem.ImageIndex = -1;
+      listViewItem.ImageIndex = i;
+    }
+    private void UpdateListViewItemText(ListViewItem listViewItem) {
+      if (listViewItem == null) throw new ArgumentNullException();
+      IRun item = listViewItem.Tag as IRun;
+      listViewItem.Text = item == null ? "null" : item.ToString();
+      listViewItem.ToolTipText = item == null ? string.Empty : item.ItemName + ": " + item.ItemDescription;
+    }
+    private IEnumerable<ListViewItem> GetListViewItemsForItem(IRun item) {
+      if (item == null) {
+        List<ListViewItem> listViewItems = new List<ListViewItem>();
+        foreach (ListViewItem listViewItem in itemsListView.Items) {
+          if (listViewItem.Tag == null) listViewItems.Add(listViewItem);
+        }
+        return listViewItems;
+      } else {
+        List<ListViewItem> listViewItems = null;
+        itemListViewItemMapping.TryGetValue(item, out listViewItems);
+        return listViewItems == null ? Enumerable.Empty<ListViewItem>() : listViewItems;
+      }
+    }
+
+    #region ListView Events
+    private void itemsListView_SelectedIndexChanged(object sender, EventArgs e) {
+      removeButton.Enabled = itemsListView.SelectedItems.Count > 0 && (Content != null) && !Content.IsReadOnly && !ReadOnly;
+      // for performance reason (multiple selection fires this handler for every selected item)
+      if (itemsListView.SelectedIndices.Count <= 1)
+        AdjustListViewColumnSizes();
+      if (showDetailsCheckBox.Checked) {
+        if (itemsListView.SelectedItems.Count == 1) {
+          IRun item = (IRun)itemsListView.SelectedItems[0].Tag;
+          detailsGroupBox.Enabled = true;
+          viewHost.Content = item;
+        } else {
+          viewHost.Content = null;
+          detailsGroupBox.Enabled = false;
+        }
+      }
+    }
+    private void itemsListView_KeyDown(object sender, KeyEventArgs e) {
+      if (e.KeyCode == Keys.Delete) {
+        if ((itemsListView.SelectedItems.Count > 0) && !Content.IsReadOnly && !ReadOnly) {
+          if (RunCollection != null) {
+            RunCollection.RemoveRange(itemsListView.SelectedItems.Cast<ListViewItem>().Select(i => (IRun)i.Tag));
+          } else {
+            foreach (ListViewItem item in itemsListView.SelectedItems)
+              Content.Remove((IRun)item.Tag);
+          }
+        }
+      }
+    }
+    private void itemsListView_DoubleClick(object sender, EventArgs e) {
+      if (itemsListView.SelectedItems.Count == 1) {
+        IRun item = itemsListView.SelectedItems[0].Tag as IRun;
+        if (item != null) {
+          IContentView view = MainFormManager.MainForm.ShowContent(item);
+          if (view != null) {
+            view.ReadOnly = ReadOnly;
+            view.Locked = Locked;
+          }
+        }
+      }
+    }
+    private void itemsListView_ItemDrag(object sender, ItemDragEventArgs e) {
+      if (!Locked) {
+        List<IRun> items = new List<IRun>();
+        foreach (ListViewItem listViewItem in itemsListView.SelectedItems) {
+          IRun item = listViewItem.Tag as IRun;
+          if (item != null) items.Add(item);
+        }
+
+        if (items.Count > 0) {
+          DataObject data = new DataObject();
+          if (items.Count == 1) data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, items[0]);
+          else data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, items);
+          if (Content.IsReadOnly || ReadOnly) {
+            DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link);
+          } else {
+            DragDropEffects result = DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link | DragDropEffects.Move);
+            if (result.HasFlag(DragDropEffects.Move)) {
+              foreach (IRun item in items) Content.Remove(item);
+            }
+          }
+        }
+      }
+    }
+    private void itemsListView_DragEnter(object sender, DragEventArgs e) {
+      validDragOperation = false;
+      if (!Content.IsReadOnly && !ReadOnly && (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IRun)) {
+        validDragOperation = true;
+      } else if (!Content.IsReadOnly && !ReadOnly && (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IEnumerable)) {
+        validDragOperation = true;
+        IEnumerable items = (IEnumerable)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+        foreach (object item in items)
+          validDragOperation = validDragOperation && (item is IRun);
+      }
+    }
+    private void itemsListView_DragOver(object sender, DragEventArgs e) {
+      e.Effect = DragDropEffects.None;
+      if (validDragOperation) {
+        if ((e.KeyState & 32) == 32) e.Effect = DragDropEffects.Link;  // ALT key
+        else if ((e.KeyState & 4) == 4) e.Effect = DragDropEffects.Move;  // SHIFT key
+        else if (e.AllowedEffect.HasFlag(DragDropEffects.Copy)) e.Effect = DragDropEffects.Copy;
+        else if (e.AllowedEffect.HasFlag(DragDropEffects.Move)) e.Effect = DragDropEffects.Move;
+        else if (e.AllowedEffect.HasFlag(DragDropEffects.Link)) e.Effect = DragDropEffects.Link;
+      }
+    }
+    private void itemsListView_DragDrop(object sender, DragEventArgs e) {
+      if (e.Effect != DragDropEffects.None) {
+        if (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IRun) {
+          IRun item = (IRun)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+          Content.Add(e.Effect.HasFlag(DragDropEffects.Copy) ? (IRun)item.Clone() : item);
+        } else if (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IEnumerable) {
+          IEnumerable<IRun> items = ((IEnumerable)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat)).Cast<IRun>();
+          if (e.Effect.HasFlag(DragDropEffects.Copy)) {
+            Cloner cloner = new Cloner();
+            items = items.Select(x => cloner.Clone(x));
+          }
+          if (RunCollection != null) {
+            RunCollection.AddRange(items);
+          } else { // the content is an IItemCollection<IRun>
+            foreach (IRun item in items)
+              Content.Add(item);
+          }
+        }
+      }
+    }
+    #endregion
+
+    #region Button Events
+    private void menuItem_Click(object sender, EventArgs e) {
+      ToolStripMenuItem menuItem = (ToolStripMenuItem)sender;
+      Type viewType = (Type)menuItem.Tag;
+      IContentView view = MainFormManager.MainForm.ShowContent(Content, viewType);
+      if (view != null) {
+        view.Locked = Locked;
+        view.ReadOnly = ReadOnly;
+      }
+    }
+    private void removeButton_Click(object sender, EventArgs e) {
+      if (itemsListView.SelectedItems.Count > 0) {
+        if (RunCollection != null) {
+          RunCollection.RemoveRange(itemsListView.SelectedItems.Cast<ListViewItem>().Select(i => (IRun)i.Tag));
+        } else {
+          foreach (ListViewItem item in itemsListView.SelectedItems)
+            Content.Remove((IRun)item.Tag);
+        }
+        itemsListView.SelectedItems.Clear();
+      }
+    }
+    private void clearButton_Click(object sender, EventArgs e) {
+      Content.Clear();
+    }
+    #endregion
+
+    #region Control Events
+    private void showDetailsCheckBox_CheckedChanged(object sender, EventArgs e) {
+      if (showDetailsCheckBox.Checked) {
+        splitContainer.Panel2Collapsed = false;
+        detailsGroupBox.Enabled = itemsListView.SelectedItems.Count == 1;
+        viewHost.Content = itemsListView.SelectedItems.Count == 1 ? (IRun)itemsListView.SelectedItems[0].Tag : null;
+      } else {
+        splitContainer.Panel2Collapsed = true;
+        viewHost.Content = null;
+      }
+    }
+    private void EvaluateModifications() {
+      if (RunCollection == null)
+        return;
+      ReadOnly = true;
+      try {
+        RunCollection.Modify();
+      } finally {
+        ReadOnly = false;
+      }
+    }
+    #endregion
+
+    #region Content Events
+    private void Content_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      if (suppressUpdates) return;
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded), sender, e);
+      else {
+        foreach (IRun item in e.Items)
+          AddListViewItem(CreateListViewItem(item));
+
+        AdjustListViewColumnSizes();
+        analyzeRunsToolStripDropDownButton.Enabled = itemsListView.Items.Count > 0;
+        clearButton.Enabled = itemsListView.Items.Count > 0 && !Content.IsReadOnly && !ReadOnly;
+        runCollectionConstraintCollectionView.ReadOnly = itemsListView.Items.Count == 0;
+      }
+    }
+    private void Content_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      if (suppressUpdates) return;
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved), sender, e);
+      else {
+        foreach (IRun item in e.Items) {
+          //remove only the first matching ListViewItem, because the IRun could be contained multiple times in the ItemCollection
+          ListViewItem listViewItem = GetListViewItemsForItem(item).FirstOrDefault();
+          if (listViewItem != null) RemoveListViewItem(listViewItem);
+        }
+        RebuildImageList();
+        analyzeRunsToolStripDropDownButton.Enabled = itemsListView.Items.Count > 0;
+        clearButton.Enabled = itemsListView.Items.Count > 0 && !Content.IsReadOnly && !ReadOnly;
+        runCollectionConstraintCollectionView.ReadOnly = itemsListView.Items.Count == 0;
+      }
+    }
+    private void Content_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      if (suppressUpdates) return;
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset), sender, e);
+      else {
+        foreach (IRun item in e.OldItems) {
+          //remove only the first matching ListViewItem, because the IRun could be contained multiple times in the ItemCollection
+          ListViewItem listViewItem = GetListViewItemsForItem(item).FirstOrDefault();
+          if (listViewItem != null) RemoveListViewItem(listViewItem);
+        }
+        RebuildImageList();
+        foreach (IRun item in e.Items)
+          AddListViewItem(CreateListViewItem(item));
+
+        AdjustListViewColumnSizes();
+        analyzeRunsToolStripDropDownButton.Enabled = itemsListView.Items.Count > 0;
+        clearButton.Enabled = itemsListView.Items.Count > 0 && !Content.IsReadOnly && !ReadOnly;
+        runCollectionConstraintCollectionView.ReadOnly = itemsListView.Items.Count == 0;
+      }
+    }
+    private void RunCollection_UpdateOfRunsInProgressChanged(object sender, EventArgs e) {
+      if (InvokeRequired) Invoke((Action<object, EventArgs>)RunCollection_UpdateOfRunsInProgressChanged, sender, e);
+      else {
+        suppressUpdates = RunCollection.UpdateOfRunsInProgress;
+        if (!suppressUpdates) {
+          foreach (IRun item in Content) {
+            //remove only the first matching ListViewItem, because the IRun could be contained multiple times in the ItemCollection
+            ListViewItem listViewItem = GetListViewItemsForItem(item).FirstOrDefault();
+            if (listViewItem != null) RemoveListViewItem(listViewItem);
+          }
+          RebuildImageList();
+          foreach (IRun item in Content)
+            AddListViewItem(CreateListViewItem(item));
+
+          AdjustListViewColumnSizes();
+          analyzeRunsToolStripDropDownButton.Enabled = itemsListView.Items.Count > 0;
+          clearButton.Enabled = itemsListView.Items.Count > 0 && !Content.IsReadOnly && !ReadOnly;
+          runCollectionConstraintCollectionView.ReadOnly = itemsListView.Items.Count == 0;
+        }
+      }
+    }
+    #endregion
+
+    #region Item Events
+    private void Item_ItemImageChanged(object sender, EventArgs e) {
+      if (suppressUpdates) return;
+      if (InvokeRequired)
+        Invoke(new EventHandler(Item_ItemImageChanged), sender, e);
+      else {
+        IRun item = (IRun)sender;
+        foreach (ListViewItem listViewItem in GetListViewItemsForItem(item))
+          UpdateListViewItemImage(listViewItem);
+      }
+    }
+    private void Item_ToStringChanged(object sender, EventArgs e) {
+      if (suppressUpdates) return;
+      if (InvokeRequired)
+        Invoke(new EventHandler(Item_ToStringChanged), sender, e);
+      else {
+        IRun item = (IRun)sender;
+        foreach (ListViewItem listViewItem in GetListViewItemsForItem(item))
+          UpdateListViewItemText(listViewItem);
+        AdjustListViewColumnSizes();
+      }
+    }
+    private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e) {
+      if (suppressUpdates) return;
+      if (InvokeRequired)
+        Invoke((Action<object, PropertyChangedEventArgs>)Item_PropertyChanged, sender, e);
+      else {
+        IRun run = (IRun)sender;
+        if (e.PropertyName == "Color" || e.PropertyName == "Visible")
+          UpdateRun(run);
+      }
+    }
+
+    private void UpdateRun(IRun run) {
+      foreach (ListViewItem listViewItem in GetListViewItemsForItem(run)) {
+        if (run.Visible) {
+          listViewItem.Font = new Font(listViewItem.Font, FontStyle.Regular);
+          listViewItem.ForeColor = run.Color;
+        } else {
+          listViewItem.Font = new Font(listViewItem.Font, FontStyle.Italic);
+          listViewItem.ForeColor = Color.LightGray;
+        }
+      }
+    }
+    #endregion
+
+    #region Helpers
+    private void AdjustListViewColumnSizes() {
+      if (itemsListView.Items.Count > 0) {
+        for (int i = 0; i < itemsListView.Columns.Count; i++) {
+          itemsListView.Columns[i].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
+        }
+      }
+    }
+    private void RebuildImageList() {
+      itemsListView.SmallImageList.Images.Clear();
+      foreach (ListViewItem listViewItem in itemsListView.Items) {
+        IRun item = listViewItem.Tag as IRun;
+        itemsListView.SmallImageList.Images.Add(item == null ? HeuristicLab.Common.Resources.VSImageLibrary.Nothing : item.ItemImage);
+        listViewItem.ImageIndex = itemsListView.SmallImageList.Images.Count - 1;
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunView.Designer.cs	(revision 12764)
@@ -0,0 +1,297 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class RunView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      System.Windows.Forms.ListViewGroup listViewGroup1 = new System.Windows.Forms.ListViewGroup("Results", System.Windows.Forms.HorizontalAlignment.Left);
+      System.Windows.Forms.ListViewGroup listViewGroup2 = new System.Windows.Forms.ListViewGroup("Parameters", System.Windows.Forms.HorizontalAlignment.Left);
+      this.parametersResultsGroupBox = new System.Windows.Forms.GroupBox();
+      this.splitContainer = new System.Windows.Forms.SplitContainer();
+      this.listView = new System.Windows.Forms.ListView();
+      this.nameColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+      this.valueColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+      this.imageList = new System.Windows.Forms.ImageList(this.components);
+      this.detailsGroupBox = new System.Windows.Forms.GroupBox();
+      this.viewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.showAlgorithmButton = new System.Windows.Forms.Button();
+      this.changeColorButton = new System.Windows.Forms.Button();
+      this.colorLabel = new System.Windows.Forms.Label();
+      this.colorDialog = new System.Windows.Forms.ColorDialog();
+      this.showDetailsCheckBox = new System.Windows.Forms.CheckBox();
+      this.colorArea = new System.Windows.Forms.Label();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.parametersResultsGroupBox.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.detailsGroupBox.SuspendLayout();
+      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(56, 0);
+      this.nameTextBox.Size = new System.Drawing.Size(414, 20);
+      // 
+      // infoLabel
+      // 
+      this.infoLabel.Location = new System.Drawing.Point(476, 3);
+      // 
+      // parametersResultsGroupBox
+      // 
+      this.parametersResultsGroupBox.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.parametersResultsGroupBox.Controls.Add(this.splitContainer);
+      this.parametersResultsGroupBox.Location = new System.Drawing.Point(0, 56);
+      this.parametersResultsGroupBox.Name = "parametersResultsGroupBox";
+      this.parametersResultsGroupBox.Size = new System.Drawing.Size(495, 268);
+      this.parametersResultsGroupBox.TabIndex = 6;
+      this.parametersResultsGroupBox.TabStop = false;
+      this.parametersResultsGroupBox.Text = "Parameters && Results";
+      // 
+      // splitContainer
+      // 
+      this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.splitContainer.Location = new System.Drawing.Point(3, 16);
+      this.splitContainer.Name = "splitContainer";
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.listView);
+      // 
+      // splitContainer.Panel2
+      // 
+      this.splitContainer.Panel2.Controls.Add(this.detailsGroupBox);
+      this.splitContainer.Size = new System.Drawing.Size(489, 249);
+      this.splitContainer.SplitterDistance = 177;
+      this.splitContainer.TabIndex = 0;
+      // 
+      // listView
+      // 
+      this.listView.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.listView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+            this.nameColumnHeader,
+            this.valueColumnHeader});
+      this.listView.FullRowSelect = true;
+      listViewGroup1.Header = "Results";
+      listViewGroup1.Name = "resultsGroup";
+      listViewGroup2.Header = "Parameters";
+      listViewGroup2.Name = "parametersGroup";
+      this.listView.Groups.AddRange(new System.Windows.Forms.ListViewGroup[] {
+            listViewGroup1,
+            listViewGroup2});
+      this.listView.HideSelection = false;
+      this.listView.Location = new System.Drawing.Point(3, 3);
+      this.listView.MultiSelect = false;
+      this.listView.Name = "listView";
+      this.listView.ShowItemToolTips = true;
+      this.listView.Size = new System.Drawing.Size(171, 243);
+      this.listView.SmallImageList = this.imageList;
+      this.listView.Sorting = System.Windows.Forms.SortOrder.Ascending;
+      this.listView.TabIndex = 0;
+      this.listView.UseCompatibleStateImageBehavior = false;
+      this.listView.View = System.Windows.Forms.View.Details;
+      this.listView.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.listView_ItemDrag);
+      this.listView.SelectedIndexChanged += new System.EventHandler(this.listView_SelectedIndexChanged);
+      this.listView.DoubleClick += new System.EventHandler(this.listView_DoubleClick);
+      // 
+      // nameColumnHeader
+      // 
+      this.nameColumnHeader.Text = "Name";
+      // 
+      // valueColumnHeader
+      // 
+      this.valueColumnHeader.Text = "Value";
+      // 
+      // imageList
+      // 
+      this.imageList.ColorDepth = System.Windows.Forms.ColorDepth.Depth8Bit;
+      this.imageList.ImageSize = new System.Drawing.Size(16, 16);
+      this.imageList.TransparentColor = System.Drawing.Color.Transparent;
+      // 
+      // detailsGroupBox
+      // 
+      this.detailsGroupBox.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.detailsGroupBox.Controls.Add(this.viewHost);
+      this.detailsGroupBox.Location = new System.Drawing.Point(3, 3);
+      this.detailsGroupBox.Name = "detailsGroupBox";
+      this.detailsGroupBox.Size = new System.Drawing.Size(302, 243);
+      this.detailsGroupBox.TabIndex = 0;
+      this.detailsGroupBox.TabStop = false;
+      this.detailsGroupBox.Text = "Details";
+      // 
+      // viewHost
+      // 
+      this.viewHost.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.viewHost.Caption = "View";
+      this.viewHost.Content = null;
+      this.viewHost.Enabled = false;
+      this.viewHost.Location = new System.Drawing.Point(6, 19);
+      this.viewHost.Name = "viewHost";
+      this.viewHost.ReadOnly = true;
+      this.viewHost.Size = new System.Drawing.Size(290, 218);
+      this.viewHost.TabIndex = 0;
+      this.viewHost.ViewsLabelVisible = true;
+      this.viewHost.ViewType = null;
+      // 
+      // showAlgorithmButton
+      // 
+      this.showAlgorithmButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.showAlgorithmButton.Location = new System.Drawing.Point(0, 330);
+      this.showAlgorithmButton.Name = "showAlgorithmButton";
+      this.showAlgorithmButton.Size = new System.Drawing.Size(495, 23);
+      this.showAlgorithmButton.TabIndex = 8;
+      this.showAlgorithmButton.Text = "&Show Algorithm";
+      this.toolTip.SetToolTip(this.showAlgorithmButton, "Show the algorithm which produced these results");
+      this.showAlgorithmButton.UseVisualStyleBackColor = true;
+      this.showAlgorithmButton.Click += new System.EventHandler(this.showAlgorithmButton_Click);
+      // 
+      // changeColorButton
+      // 
+      this.changeColorButton.Enabled = false;
+      this.changeColorButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+      this.changeColorButton.Location = new System.Drawing.Point(78, 26);
+      this.changeColorButton.Name = "changeColorButton";
+      this.changeColorButton.Size = new System.Drawing.Size(64, 24);
+      this.changeColorButton.TabIndex = 5;
+      this.changeColorButton.Text = "&Change...";
+      this.changeColorButton.UseVisualStyleBackColor = true;
+      this.changeColorButton.Click += new System.EventHandler(this.changeColorButton_Click);
+      // 
+      // colorLabel
+      // 
+      this.colorLabel.AutoSize = true;
+      this.colorLabel.Location = new System.Drawing.Point(3, 32);
+      this.colorLabel.Name = "colorLabel";
+      this.colorLabel.Size = new System.Drawing.Size(34, 13);
+      this.colorLabel.TabIndex = 3;
+      this.colorLabel.Text = "C&olor:";
+      // 
+      // showDetailsCheckBox
+      // 
+      this.showDetailsCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.showDetailsCheckBox.Appearance = System.Windows.Forms.Appearance.Button;
+      this.showDetailsCheckBox.Checked = true;
+      this.showDetailsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.showDetailsCheckBox.Image = HeuristicLab.Common.Resources.VSImageLibrary.Properties;
+      this.showDetailsCheckBox.Location = new System.Drawing.Point(471, 26);
+      this.showDetailsCheckBox.Name = "showDetailsCheckBox";
+      this.showDetailsCheckBox.Size = new System.Drawing.Size(24, 24);
+      this.showDetailsCheckBox.TabIndex = 7;
+      this.toolTip.SetToolTip(this.showDetailsCheckBox, "Show/Hide Details");
+      this.showDetailsCheckBox.UseVisualStyleBackColor = true;
+      this.showDetailsCheckBox.CheckedChanged += new System.EventHandler(this.showDetailsCheckBox_CheckedChanged);
+      // 
+      // colorArea
+      // 
+      this.colorArea.BackColor = System.Drawing.Color.White;
+      this.colorArea.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+      this.colorArea.Location = new System.Drawing.Point(56, 31);
+      this.colorArea.Name = "colorArea";
+      this.colorArea.Size = new System.Drawing.Size(16, 16);
+      this.colorArea.TabIndex = 4;
+      // 
+      // RunView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.colorArea);
+      this.Controls.Add(this.showDetailsCheckBox);
+      this.Controls.Add(this.colorLabel);
+      this.Controls.Add(this.changeColorButton);
+      this.Controls.Add(this.parametersResultsGroupBox);
+      this.Controls.Add(this.showAlgorithmButton);
+      this.Name = "RunView";
+      this.Size = new System.Drawing.Size(495, 353);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      this.Controls.SetChildIndex(this.showAlgorithmButton, 0);
+      this.Controls.SetChildIndex(this.parametersResultsGroupBox, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.changeColorButton, 0);
+      this.Controls.SetChildIndex(this.colorLabel, 0);
+      this.Controls.SetChildIndex(this.showDetailsCheckBox, 0);
+      this.Controls.SetChildIndex(this.colorArea, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.parametersResultsGroupBox.ResumeLayout(false);
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.detailsGroupBox.ResumeLayout(false);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.GroupBox parametersResultsGroupBox;
+    private System.Windows.Forms.SplitContainer splitContainer;
+    private System.Windows.Forms.GroupBox detailsGroupBox;
+    private System.Windows.Forms.ListView listView;
+    private System.Windows.Forms.ColumnHeader nameColumnHeader;
+    private System.Windows.Forms.ColumnHeader valueColumnHeader;
+    private HeuristicLab.MainForm.WindowsForms.ViewHost viewHost;
+    private System.Windows.Forms.ImageList imageList;
+    private System.Windows.Forms.Button showAlgorithmButton;
+    private System.Windows.Forms.Label colorLabel;
+    private System.Windows.Forms.Button changeColorButton;
+    private System.Windows.Forms.ColorDialog colorDialog;
+    private System.Windows.Forms.CheckBox showDetailsCheckBox;
+    private System.Windows.Forms.Label colorArea;
+
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/RunView.cs	(revision 12764)
@@ -0,0 +1,306 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Optimization.Views {
+  /// <summary>
+  /// The visual representation of a <see cref="Variable"/>.
+  /// </summary>
+  [View("Run View")]
+  [Content(typeof(IRun), true)]
+  public sealed partial class RunView : NamedItemView {
+    private readonly Dictionary<string, ListViewItem> parametersItemToListViewItem;
+    private readonly Dictionary<string, ListViewItem> resultsItemToListViewItem;
+    /// <summary>
+    /// Gets or sets the variable to represent visually.
+    /// </summary>
+    /// <remarks>Uses property <see cref="ViewBase.Item"/> of base class <see cref="ViewBase"/>.
+    /// No own data storage present.</remarks>
+    public new IRun Content {
+      get { return (IRun)base.Content; }
+      set { base.Content = value; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of <see cref="VariableView"/> with caption "Variable".
+    /// </summary>
+    public RunView() {
+      InitializeComponent();
+      parametersItemToListViewItem = new Dictionary<string, ListViewItem>();
+      resultsItemToListViewItem = new Dictionary<string, ListViewItem>();
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.PropertyChanged += Content_PropertyChanged;
+      RegisterContentParametersEvents();
+      RegisterContentResultsEents();
+    }
+    private void RegisterContentParametersEvents() {
+      Content.Parameters.ItemsAdded += ParametersOnItemsChanged;
+      Content.Parameters.ItemsRemoved += ParametersOnItemsRemoved;
+      Content.Parameters.ItemsReplaced += ParametersOnItemsChanged;
+      Content.Parameters.CollectionReset += ParametersOnItemsChanged;
+    }
+    private void RegisterContentResultsEents() {
+      Content.Results.ItemsAdded += ResultsOnItemsChanged;
+      Content.Results.ItemsRemoved += ResultsOnItemsRemoved;
+      Content.Results.ItemsReplaced += ResultsOnItemsChanged;
+      Content.Results.CollectionReset += ResultsOnItemsChanged;
+    }
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.PropertyChanged -= Content_PropertyChanged;
+      DeregisterContentParametersEvents();
+      DeregisterContentResultsEvents();
+    }
+    private void DeregisterContentParametersEvents() {
+      Content.Parameters.ItemsAdded -= ParametersOnItemsChanged;
+      Content.Parameters.ItemsRemoved -= ParametersOnItemsRemoved;
+      Content.Parameters.ItemsReplaced -= ParametersOnItemsChanged;
+      Content.Parameters.CollectionReset -= ParametersOnItemsChanged;
+    }
+    private void DeregisterContentResultsEvents() {
+      Content.Results.ItemsAdded -= ResultsOnItemsChanged;
+      Content.Results.ItemsRemoved -= ResultsOnItemsRemoved;
+      Content.Results.ItemsReplaced -= ResultsOnItemsChanged;
+      Content.Results.CollectionReset -= ResultsOnItemsChanged;
+    }
+
+    private void Content_PropertyChanged(object sender, PropertyChangedEventArgs e) {
+      if (e.PropertyName == "Color") {
+        if (InvokeRequired) this.Invoke((Action)UpdateColor, null);
+        else UpdateColor();
+      } else if (e.PropertyName == "Parameters") {
+        if (InvokeRequired) this.Invoke((Action<bool>)FillParametersListView, true);
+        else FillParametersListView();
+        RegisterContentParametersEvents();
+      } else if (e.PropertyName == "Results") {
+        if (InvokeRequired) this.Invoke((Action<bool>)FillResultsListView, true);
+        else FillResultsListView();
+        RegisterContentResultsEents();
+      }
+    }
+
+    private void ParametersOnItemsChanged(object sender, CollectionItemsChangedEventArgs<KeyValuePair<string, IItem>> e) {
+      foreach (var item in e.OldItems) {
+        listView.Items.Remove(parametersItemToListViewItem[item.Key]);
+        parametersItemToListViewItem.Remove(item.Key);
+      }
+      foreach (var item in e.Items) {
+        var listViewItem = CreateListViewItem(item.Key, Content.Parameters[item.Key], listView.Groups["parametersGroup"]);
+        listView.Items.Add(listViewItem);
+        parametersItemToListViewItem[item.Key] = listViewItem;
+      }
+    }
+
+    private void ParametersOnItemsRemoved(object sender, CollectionItemsChangedEventArgs<KeyValuePair<string, IItem>> e) {
+      foreach (var item in e.Items) {
+        listView.Items.Remove(parametersItemToListViewItem[item.Key]);
+        parametersItemToListViewItem.Remove(item.Key);
+      }
+    }
+
+    private void ResultsOnItemsChanged(object sender, CollectionItemsChangedEventArgs<KeyValuePair<string, IItem>> e) {
+      foreach (var item in e.OldItems) {
+        listView.Items.Remove(resultsItemToListViewItem[item.Key]);
+        resultsItemToListViewItem.Remove(item.Key);
+      }
+      foreach (var item in e.Items) {
+        var listViewItem = CreateListViewItem(item.Key, Content.Results[item.Key], listView.Groups["resultsGroup"]);
+        listView.Items.Add(listViewItem);
+        resultsItemToListViewItem[item.Key] = listViewItem;
+      }
+    }
+
+    private void ResultsOnItemsRemoved(object sender, CollectionItemsChangedEventArgs<KeyValuePair<string, IItem>> e) {
+      foreach (var item in e.Items) {
+        listView.Items.Remove(resultsItemToListViewItem[item.Key]);
+        resultsItemToListViewItem.Remove(item.Key);
+      }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      viewHost.Content = null;
+      if (Content != null)
+        UpdateColor();
+      FillListView();
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      listView.Enabled = Content != null;
+      detailsGroupBox.Enabled = (Content != null) && (listView.SelectedItems.Count == 1);
+      changeColorButton.Enabled = Content != null;
+      showAlgorithmButton.Enabled = Content != null && Content.Algorithm != null && !Locked;
+    }
+
+    protected override void PropagateStateChanges(Control control, Type type, System.Reflection.PropertyInfo propertyInfo) {
+      if (propertyInfo.Name == "ReadOnly") return;
+      base.PropagateStateChanges(control, type, propertyInfo);
+    }
+
+    private void changeColorButton_Click(object sender, EventArgs e) {
+      if (colorDialog.ShowDialog(this) == DialogResult.OK) {
+        this.Content.Color = this.colorDialog.Color;
+      }
+    }
+    private void UpdateColor() {
+      this.colorDialog.Color = this.Content.Color;
+      this.colorArea.BackColor = this.Content.Color;
+    }
+
+    private string selectedName;
+    private void FillListView() {
+      if (listView.SelectedItems.Count == 1) selectedName = listView.SelectedItems[0].SubItems[0].Text;
+
+      FillParametersListView(false);
+      FillResultsListView(false);
+      if (listView.Items.Count > 0) {
+        for (int i = 0; i < listView.Columns.Count; i++)
+          listView.Columns[i].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
+        selectedName = null;
+      }
+    }
+
+    private void FillParametersListView(bool resize = true) {
+      listView.BeginUpdate();
+      foreach (var item in listView.Groups["parametersGroup"].Items.OfType<ListViewItem>().OrderByDescending(x => x.ImageIndex).ToList()) {
+        listView.SmallImageList.Images.RemoveAt(item.ImageIndex);
+        listView.Items.Remove(item);
+      }
+      parametersItemToListViewItem.Clear();
+
+      var counter = 0;
+      foreach (var item in listView.Items.OfType<ListViewItem>().OrderBy(x => x.ImageIndex).ToList())
+        item.ImageIndex = counter++;
+      listView.EndUpdate();
+
+      if (Content != null) {
+        foreach (string key in Content.Parameters.Keys) {
+          var listViewItem = CreateListViewItem(key, Content.Parameters[key], listView.Groups["parametersGroup"]);
+          listView.Items.Add(listViewItem);
+          if ((selectedName != null) && key.Equals(selectedName)) listViewItem.Selected = true;
+          parametersItemToListViewItem[key] = listViewItem;
+        }
+        if (resize && listView.Items.Count > 0) {
+          for (int i = 0; i < listView.Columns.Count; i++)
+            listView.Columns[i].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
+        }
+      }
+    }
+
+    private void FillResultsListView(bool resize = true) {
+      listView.BeginUpdate();
+      foreach (var item in listView.Groups["resultsGroup"].Items.OfType<ListViewItem>().OrderByDescending(x => x.ImageIndex).ToList()) {
+        listView.SmallImageList.Images.RemoveAt(item.ImageIndex);
+        listView.Items.Remove(item);
+      }
+      resultsItemToListViewItem.Clear();
+
+      var counter = 0;
+      foreach (var item in listView.Items.OfType<ListViewItem>().OrderBy(x => x.ImageIndex).ToList())
+        item.ImageIndex = counter++;
+      listView.EndUpdate();
+
+      if (Content != null) {
+        foreach (string key in Content.Results.Keys) {
+          var listViewItem = CreateListViewItem(key, Content.Results[key], listView.Groups["resultsGroup"]);
+          listView.Items.Add(listViewItem);
+          if ((selectedName != null) && key.Equals(selectedName)) listViewItem.Selected = true;
+          resultsItemToListViewItem[key] = listViewItem;
+        }
+        if (resize && listView.Items.Count > 0) {
+          for (int i = 0; i < listView.Columns.Count; i++)
+            listView.Columns[i].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
+        }
+      }
+    }
+
+    private ListViewItem CreateListViewItem(string name, IItem value, ListViewGroup group) {
+      var item = new ListViewItem(new string[] { name, value != null ? value.ToString() : "-" });
+      item.Tag = value;
+      item.Group = group;
+      listView.SmallImageList.Images.Add(value == null ? HeuristicLab.Common.Resources.VSImageLibrary.Nothing : value.ItemImage);
+      item.ImageIndex = listView.SmallImageList.Images.Count - 1;
+      return item;
+    }
+
+    private void listView_SelectedIndexChanged(object sender, EventArgs e) {
+      if (showDetailsCheckBox.Checked) {
+        if (listView.SelectedItems.Count == 1) {
+          detailsGroupBox.Enabled = true;
+          viewHost.Content = listView.SelectedItems[0].Tag as IContent;
+        } else {
+          viewHost.Content = null;
+          detailsGroupBox.Enabled = false;
+        }
+      }
+    }
+    private void listView_DoubleClick(object sender, EventArgs e) {
+      if (listView.SelectedItems.Count == 1) {
+        IItem item = (IItem)listView.SelectedItems[0].Tag;
+        IContentView view = MainFormManager.MainForm.ShowContent(item);
+        if (view != null) {
+          view.ReadOnly = true;
+          view.Locked = Locked;
+        }
+      }
+    }
+    private void listView_ItemDrag(object sender, ItemDragEventArgs e) {
+      if (!Locked) {
+        ListViewItem listViewItem = (ListViewItem)e.Item;
+        IItem item = (IItem)listViewItem.Tag;
+        if (item != null) {
+          DataObject data = new DataObject();
+          data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, item);
+          DragDropEffects result = DoDragDrop(data, DragDropEffects.Copy);
+        }
+      }
+    }
+    private void showDetailsCheckBox_CheckedChanged(object sender, EventArgs e) {
+      if (showDetailsCheckBox.Checked) {
+        splitContainer.Panel2Collapsed = false;
+        detailsGroupBox.Enabled = listView.SelectedItems.Count == 1;
+        viewHost.Content = listView.SelectedItems.Count == 1 ? (IContent)listView.SelectedItems[0].Tag : null;
+      } else {
+        splitContainer.Panel2Collapsed = true;
+        viewHost.Content = null;
+      }
+    }
+    private void showAlgorithmButton_Click(object sender, EventArgs e) {
+      if (!Locked) {
+        MainFormManager.MainForm.ShowContent((IContent)Content.Algorithm.Clone());
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/TimeLimitRunView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/TimeLimitRunView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/TimeLimitRunView.Designer.cs	(revision 12764)
@@ -0,0 +1,361 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Optimization.Views {
+  partial class TimeLimitRunView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    #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() {
+      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TimeLimitRunView));
+      this.timeLimitLabel = new System.Windows.Forms.Label();
+      this.timeLimitTextBox = new System.Windows.Forms.TextBox();
+      this.label1 = new System.Windows.Forms.Label();
+      this.snapshotsTextBox = new System.Windows.Forms.TextBox();
+      this.storeAlgorithmInEachSnapshotCheckBox = new System.Windows.Forms.CheckBox();
+      this.tabControl = new HeuristicLab.MainForm.WindowsForms.DragOverTabControl();
+      this.algorithmTabPage = new System.Windows.Forms.TabPage();
+      this.algorithmViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.openAlgorithmButton = new System.Windows.Forms.Button();
+      this.newAlgorithmButton = new System.Windows.Forms.Button();
+      this.snapshotsTabPage = new System.Windows.Forms.TabPage();
+      this.snapshotsView = new HeuristicLab.Optimization.Views.RunCollectionView();
+      this.runsTabPage = new System.Windows.Forms.TabPage();
+      this.runsView = new HeuristicLab.Optimization.Views.RunCollectionView();
+      this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
+      this.snapshotButton = new System.Windows.Forms.Button();
+      this.sequenceButton = new System.Windows.Forms.Button();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.tabControl.SuspendLayout();
+      this.algorithmTabPage.SuspendLayout();
+      this.snapshotsTabPage.SuspendLayout();
+      this.runsTabPage.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // startButton
+      // 
+      this.startButton.Location = new System.Drawing.Point(0, 440);
+      this.startButton.TabIndex = 9;
+      this.toolTip.SetToolTip(this.startButton, "Start/Resume Optimizer");
+      // 
+      // executionTimeTextBox
+      // 
+      this.executionTimeTextBox.Location = new System.Drawing.Point(412, 444);
+      // 
+      // executionTimeLabel
+      // 
+      this.executionTimeLabel.Location = new System.Drawing.Point(323, 447);
+      // 
+      // pauseButton
+      // 
+      this.pauseButton.Location = new System.Drawing.Point(30, 440);
+      this.pauseButton.TabIndex = 10;
+      this.toolTip.SetToolTip(this.pauseButton, "Pause Optimizer");
+      // 
+      // stopButton
+      // 
+      this.stopButton.Location = new System.Drawing.Point(60, 440);
+      this.stopButton.TabIndex = 11;
+      this.toolTip.SetToolTip(this.stopButton, "Stop Optimizer");
+      // 
+      // resetButton
+      // 
+      this.resetButton.Location = new System.Drawing.Point(90, 440);
+      this.resetButton.TabIndex = 12;
+      this.toolTip.SetToolTip(this.resetButton, "Reset Optimizer");
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      this.nameTextBox.Location = new System.Drawing.Point(69, 0);
+      this.nameTextBox.Size = new System.Drawing.Size(455, 20);
+      // 
+      // infoLabel
+      // 
+      this.infoLabel.Location = new System.Drawing.Point(530, 3);
+      // 
+      // timeLimitLabel
+      // 
+      this.timeLimitLabel.AutoSize = true;
+      this.timeLimitLabel.Location = new System.Drawing.Point(3, 29);
+      this.timeLimitLabel.Name = "timeLimitLabel";
+      this.timeLimitLabel.Size = new System.Drawing.Size(53, 13);
+      this.timeLimitLabel.TabIndex = 3;
+      this.timeLimitLabel.Text = "Time limit:";
+      // 
+      // timeLimitTextBox
+      // 
+      this.timeLimitTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.timeLimitTextBox.Location = new System.Drawing.Point(69, 26);
+      this.timeLimitTextBox.Name = "timeLimitTextBox";
+      this.timeLimitTextBox.Size = new System.Drawing.Size(455, 20);
+      this.timeLimitTextBox.TabIndex = 4;
+      this.timeLimitTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.timeLimitTextBox_Validating);
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(3, 55);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(60, 13);
+      this.label1.TabIndex = 5;
+      this.label1.Text = "Snapshots:";
+      // 
+      // snapshotsTextBox
+      // 
+      this.snapshotsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.snapshotsTextBox.Location = new System.Drawing.Point(69, 52);
+      this.snapshotsTextBox.Name = "snapshotsTextBox";
+      this.snapshotsTextBox.Size = new System.Drawing.Size(175, 20);
+      this.snapshotsTextBox.TabIndex = 6;
+      this.snapshotsTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.snapshotsTextBox_Validating);
+      // 
+      // storeAlgorithmInEachSnapshotCheckBox
+      // 
+      this.storeAlgorithmInEachSnapshotCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.storeAlgorithmInEachSnapshotCheckBox.AutoSize = true;
+      this.storeAlgorithmInEachSnapshotCheckBox.Location = new System.Drawing.Point(340, 54);
+      this.storeAlgorithmInEachSnapshotCheckBox.Name = "storeAlgorithmInEachSnapshotCheckBox";
+      this.storeAlgorithmInEachSnapshotCheckBox.Size = new System.Drawing.Size(184, 17);
+      this.storeAlgorithmInEachSnapshotCheckBox.TabIndex = 7;
+      this.storeAlgorithmInEachSnapshotCheckBox.Text = "Store Algorithm in Each Snapshot";
+      this.storeAlgorithmInEachSnapshotCheckBox.UseVisualStyleBackColor = true;
+      this.storeAlgorithmInEachSnapshotCheckBox.CheckedChanged += new System.EventHandler(this.storeAlgorithmInEachSnapshotCheckBox_CheckedChanged);
+      // 
+      // tabControl
+      // 
+      this.tabControl.AllowDrop = true;
+      this.tabControl.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.tabControl.Controls.Add(this.algorithmTabPage);
+      this.tabControl.Controls.Add(this.snapshotsTabPage);
+      this.tabControl.Controls.Add(this.runsTabPage);
+      this.tabControl.Location = new System.Drawing.Point(0, 78);
+      this.tabControl.Name = "tabControl";
+      this.tabControl.SelectedIndex = 0;
+      this.tabControl.Size = new System.Drawing.Size(546, 356);
+      this.tabControl.TabIndex = 8;
+      // 
+      // algorithmTabPage
+      // 
+      this.algorithmTabPage.AllowDrop = true;
+      this.algorithmTabPage.Controls.Add(this.algorithmViewHost);
+      this.algorithmTabPage.Controls.Add(this.openAlgorithmButton);
+      this.algorithmTabPage.Controls.Add(this.newAlgorithmButton);
+      this.algorithmTabPage.Location = new System.Drawing.Point(4, 22);
+      this.algorithmTabPage.Name = "algorithmTabPage";
+      this.algorithmTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.algorithmTabPage.Size = new System.Drawing.Size(538, 330);
+      this.algorithmTabPage.TabIndex = 1;
+      this.algorithmTabPage.Text = "Algorithm";
+      this.algorithmTabPage.UseVisualStyleBackColor = true;
+      this.algorithmTabPage.DragDrop += new System.Windows.Forms.DragEventHandler(this.algorithmTabPage_DragDrop);
+      this.algorithmTabPage.DragEnter += new System.Windows.Forms.DragEventHandler(this.algorithmTabPage_DragEnterOver);
+      this.algorithmTabPage.DragOver += new System.Windows.Forms.DragEventHandler(this.algorithmTabPage_DragEnterOver);
+      // 
+      // algorithmViewHost
+      // 
+      this.algorithmViewHost.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.algorithmViewHost.Caption = "View";
+      this.algorithmViewHost.Content = null;
+      this.algorithmViewHost.Enabled = false;
+      this.algorithmViewHost.Location = new System.Drawing.Point(6, 36);
+      this.algorithmViewHost.Name = "algorithmViewHost";
+      this.algorithmViewHost.ReadOnly = false;
+      this.algorithmViewHost.Size = new System.Drawing.Size(526, 288);
+      this.algorithmViewHost.TabIndex = 2;
+      this.algorithmViewHost.ViewsLabelVisible = true;
+      this.algorithmViewHost.ViewType = null;
+      // 
+      // openAlgorithmButton
+      // 
+      this.openAlgorithmButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Open;
+      this.openAlgorithmButton.Location = new System.Drawing.Point(36, 6);
+      this.openAlgorithmButton.Name = "openAlgorithmButton";
+      this.openAlgorithmButton.Size = new System.Drawing.Size(24, 24);
+      this.openAlgorithmButton.TabIndex = 1;
+      this.toolTip.SetToolTip(this.openAlgorithmButton, "Open Optimizer");
+      this.openAlgorithmButton.UseVisualStyleBackColor = true;
+      this.openAlgorithmButton.Click += new System.EventHandler(this.openAlgorithmButton_Click);
+      // 
+      // newAlgorithmButton
+      // 
+      this.newAlgorithmButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.NewDocument;
+      this.newAlgorithmButton.Location = new System.Drawing.Point(6, 6);
+      this.newAlgorithmButton.Name = "newAlgorithmButton";
+      this.newAlgorithmButton.Size = new System.Drawing.Size(24, 24);
+      this.newAlgorithmButton.TabIndex = 0;
+      this.toolTip.SetToolTip(this.newAlgorithmButton, "New Optimizer");
+      this.newAlgorithmButton.UseVisualStyleBackColor = true;
+      this.newAlgorithmButton.Click += new System.EventHandler(this.newAlgorithmButton_Click);
+      // 
+      // snapshotsTabPage
+      // 
+      this.snapshotsTabPage.Controls.Add(this.snapshotsView);
+      this.snapshotsTabPage.Location = new System.Drawing.Point(4, 22);
+      this.snapshotsTabPage.Name = "snapshotsTabPage";
+      this.snapshotsTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.snapshotsTabPage.Size = new System.Drawing.Size(538, 330);
+      this.snapshotsTabPage.TabIndex = 2;
+      this.snapshotsTabPage.Text = "Snapshots";
+      this.snapshotsTabPage.UseVisualStyleBackColor = true;
+      // 
+      // snapshotsView
+      // 
+      this.snapshotsView.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.snapshotsView.Caption = "RunCollection View";
+      this.snapshotsView.Content = null;
+      this.snapshotsView.Location = new System.Drawing.Point(6, 6);
+      this.snapshotsView.Name = "snapshotsView";
+      this.snapshotsView.ReadOnly = false;
+      this.snapshotsView.Size = new System.Drawing.Size(526, 317);
+      this.snapshotsView.TabIndex = 0;
+      // 
+      // runsTabPage
+      // 
+      this.runsTabPage.Controls.Add(this.runsView);
+      this.runsTabPage.Location = new System.Drawing.Point(4, 22);
+      this.runsTabPage.Name = "runsTabPage";
+      this.runsTabPage.Size = new System.Drawing.Size(538, 330);
+      this.runsTabPage.TabIndex = 3;
+      this.runsTabPage.Text = "Runs";
+      this.runsTabPage.UseVisualStyleBackColor = true;
+      // 
+      // runsView
+      // 
+      this.runsView.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.runsView.Caption = "RunCollection View";
+      this.runsView.Content = null;
+      this.runsView.Location = new System.Drawing.Point(6, 6);
+      this.runsView.Name = "runsView";
+      this.runsView.ReadOnly = false;
+      this.runsView.Size = new System.Drawing.Size(526, 317);
+      this.runsView.TabIndex = 1;
+      // 
+      // openFileDialog
+      // 
+      this.openFileDialog.DefaultExt = "hl";
+      this.openFileDialog.FileName = "Optimizer";
+      this.openFileDialog.Filter = "HeuristicLab Files|*.hl|All Files|*.*";
+      this.openFileDialog.Title = "Open Optimizer";
+      // 
+      // snapshotButton
+      // 
+      this.snapshotButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.snapshotButton.Location = new System.Drawing.Point(120, 440);
+      this.snapshotButton.Name = "snapshotButton";
+      this.snapshotButton.Size = new System.Drawing.Size(24, 24);
+      this.snapshotButton.TabIndex = 13;
+      this.snapshotButton.Text = "Snapshot";
+      this.toolTip.SetToolTip(this.snapshotButton, "Create Snapshot");
+      this.snapshotButton.UseVisualStyleBackColor = true;
+      this.snapshotButton.Click += new System.EventHandler(this.snapshotButton_Click);
+      // 
+      // sequenceButton
+      // 
+      this.sequenceButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.sequenceButton.Location = new System.Drawing.Point(250, 50);
+      this.sequenceButton.Name = "sequenceButton";
+      this.sequenceButton.Size = new System.Drawing.Size(75, 23);
+      this.sequenceButton.TabIndex = 16;
+      this.sequenceButton.Text = "Sequence...";
+      this.sequenceButton.UseVisualStyleBackColor = true;
+      this.sequenceButton.Click += new System.EventHandler(this.sequenceButton_Click);
+      // 
+      // TimeLimitRunView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.sequenceButton);
+      this.Controls.Add(this.snapshotButton);
+      this.Controls.Add(this.tabControl);
+      this.Controls.Add(this.timeLimitTextBox);
+      this.Controls.Add(this.timeLimitLabel);
+      this.Controls.Add(this.label1);
+      this.Controls.Add(this.snapshotsTextBox);
+      this.Controls.Add(this.storeAlgorithmInEachSnapshotCheckBox);
+      this.Name = "TimeLimitRunView";
+      this.Size = new System.Drawing.Size(549, 464);
+      this.Controls.SetChildIndex(this.storeAlgorithmInEachSnapshotCheckBox, 0);
+      this.Controls.SetChildIndex(this.snapshotsTextBox, 0);
+      this.Controls.SetChildIndex(this.label1, 0);
+      this.Controls.SetChildIndex(this.timeLimitLabel, 0);
+      this.Controls.SetChildIndex(this.timeLimitTextBox, 0);
+      this.Controls.SetChildIndex(this.tabControl, 0);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      this.Controls.SetChildIndex(this.resetButton, 0);
+      this.Controls.SetChildIndex(this.stopButton, 0);
+      this.Controls.SetChildIndex(this.pauseButton, 0);
+      this.Controls.SetChildIndex(this.executionTimeLabel, 0);
+      this.Controls.SetChildIndex(this.executionTimeTextBox, 0);
+      this.Controls.SetChildIndex(this.startButton, 0);
+      this.Controls.SetChildIndex(this.snapshotButton, 0);
+      this.Controls.SetChildIndex(this.sequenceButton, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.tabControl.ResumeLayout(false);
+      this.algorithmTabPage.ResumeLayout(false);
+      this.snapshotsTabPage.ResumeLayout(false);
+      this.runsTabPage.ResumeLayout(false);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Label timeLimitLabel;
+    private System.Windows.Forms.TextBox timeLimitTextBox;
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.TextBox snapshotsTextBox;
+    private System.Windows.Forms.CheckBox storeAlgorithmInEachSnapshotCheckBox;
+    private MainForm.WindowsForms.DragOverTabControl tabControl;
+    private System.Windows.Forms.TabPage algorithmTabPage;
+    private MainForm.WindowsForms.ViewHost algorithmViewHost;
+    private System.Windows.Forms.Button openAlgorithmButton;
+    private System.Windows.Forms.Button newAlgorithmButton;
+    private System.Windows.Forms.TabPage snapshotsTabPage;
+    private RunCollectionView snapshotsView;
+    private System.Windows.Forms.TabPage runsTabPage;
+    private RunCollectionView runsView;
+    private System.Windows.Forms.OpenFileDialog openFileDialog;
+    private System.Windows.Forms.Button snapshotButton;
+    private System.Windows.Forms.Button sequenceButton;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/TimeLimitRunView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/TimeLimitRunView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/TimeLimitRunView.cs	(revision 12764)
@@ -0,0 +1,310 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.ComponentModel;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Windows.Forms;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Common.Resources;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("TimeLimit Run View")]
+  [Content(typeof(TimeLimitRun), IsDefaultView = true)]
+  public partial class TimeLimitRunView : IOptimizerView {
+    protected TypeSelectorDialog algorithmTypeSelectorDialog;
+    protected virtual bool SuppressEvents { get; set; }
+
+    public new TimeLimitRun Content {
+      get { return (TimeLimitRun)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public TimeLimitRunView() {
+      InitializeComponent();
+      snapshotButton.Text = String.Empty;
+      snapshotButton.Image = VSImageLibrary.Camera;
+    }
+
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (algorithmTypeSelectorDialog != null) algorithmTypeSelectorDialog.Dispose();
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.PropertyChanged -= Content_PropertyChanged;
+      Content.SnapshotTimes.ItemsAdded -= Content_SnapshotTimes_Changed;
+      Content.SnapshotTimes.ItemsMoved -= Content_SnapshotTimes_Changed;
+      Content.SnapshotTimes.ItemsRemoved -= Content_SnapshotTimes_Changed;
+      Content.SnapshotTimes.ItemsReplaced -= Content_SnapshotTimes_Changed;
+      Content.SnapshotTimes.CollectionReset -= Content_SnapshotTimes_Changed;
+      base.DeregisterContentEvents();
+    }
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.PropertyChanged += Content_PropertyChanged;
+      Content.SnapshotTimes.ItemsAdded += Content_SnapshotTimes_Changed;
+      Content.SnapshotTimes.ItemsMoved += Content_SnapshotTimes_Changed;
+      Content.SnapshotTimes.ItemsRemoved += Content_SnapshotTimes_Changed;
+      Content.SnapshotTimes.ItemsReplaced += Content_SnapshotTimes_Changed;
+      Content.SnapshotTimes.CollectionReset += Content_SnapshotTimes_Changed;
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      SuppressEvents = true;
+      try {
+        if (Content == null) {
+          timeLimitTextBox.Text = TimeSpanHelper.FormatNatural(TimeSpan.FromSeconds(60));
+          snapshotsTextBox.Text = String.Empty;
+          storeAlgorithmInEachSnapshotCheckBox.Checked = false;
+          algorithmViewHost.Content = null;
+          snapshotsView.Content = null;
+          runsView.Content = null;
+        } else {
+          timeLimitTextBox.Text = TimeSpanHelper.FormatNatural(Content.MaximumExecutionTime);
+          snapshotsTextBox.Text = String.Join(" ; ", Content.SnapshotTimes.Select(x => TimeSpanHelper.FormatNatural(x, true)));
+          storeAlgorithmInEachSnapshotCheckBox.Checked = Content.StoreAlgorithmInEachSnapshot;
+          algorithmViewHost.Content = Content.Algorithm;
+          snapshotsView.Content = Content.Snapshots;
+          runsView.Content = Content.Runs;
+        }
+      } finally { SuppressEvents = false; }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      timeLimitTextBox.Enabled = Content != null && !ReadOnly;
+      snapshotsTextBox.Enabled = Content != null && !ReadOnly;
+      storeAlgorithmInEachSnapshotCheckBox.Enabled = Content != null && !ReadOnly;
+      newAlgorithmButton.Enabled = Content != null && !ReadOnly;
+      openAlgorithmButton.Enabled = Content != null && !ReadOnly;
+      algorithmViewHost.Enabled = Content != null;
+      snapshotsView.Enabled = Content != null;
+      runsView.Enabled = Content != null;
+    }
+
+    protected override void SetEnabledStateOfExecutableButtons() {
+      base.SetEnabledStateOfExecutableButtons();
+      snapshotButton.Enabled = Content != null && Content.Algorithm != null && Content.ExecutionState == ExecutionState.Paused;
+    }
+
+    protected override void OnClosed(FormClosedEventArgs e) {
+      if ((Content != null) && (Content.ExecutionState == ExecutionState.Started)) {
+        //The content must be stopped if no other view showing the content is available
+        var optimizers = MainFormManager.MainForm.Views.OfType<IContentView>().Where(v => v != this).Select(v => v.Content).OfType<IAlgorithm>();
+        if (!optimizers.Contains(Content.Algorithm)) {
+          var nestedOptimizers = optimizers.SelectMany(opt => opt.NestedOptimizers);
+          if (!nestedOptimizers.Contains(Content)) Content.Stop();
+        }
+      }
+      base.OnClosed(e);
+    }
+
+    #region Event Handlers
+    #region Content events
+    private void Content_PropertyChanged(object sender, PropertyChangedEventArgs e) {
+      switch (e.PropertyName) {
+        case "MaximumExecutionTime":
+          SuppressEvents = true;
+          try {
+            timeLimitTextBox.Text = TimeSpanHelper.FormatNatural(Content.MaximumExecutionTime);
+          } finally { SuppressEvents = false; }
+          break;
+        case "SnapshotTimes":
+          SuppressEvents = true;
+          try {
+            if (Content.SnapshotTimes.Any())
+              snapshotsTextBox.Text = String.Join(" ; ", Content.SnapshotTimes.Select(x => TimeSpanHelper.FormatNatural(x, true)));
+            else snapshotsTextBox.Text = String.Empty;
+            Content.SnapshotTimes.ItemsAdded += Content_SnapshotTimes_Changed;
+            Content.SnapshotTimes.ItemsMoved += Content_SnapshotTimes_Changed;
+            Content.SnapshotTimes.ItemsRemoved += Content_SnapshotTimes_Changed;
+            Content.SnapshotTimes.ItemsReplaced += Content_SnapshotTimes_Changed;
+            Content.SnapshotTimes.CollectionReset += Content_SnapshotTimes_Changed;
+          } finally { SuppressEvents = false; }
+          break;
+        case "StoreAlgorithmInEachSnapshot":
+          SuppressEvents = true;
+          try {
+            storeAlgorithmInEachSnapshotCheckBox.Checked = Content.StoreAlgorithmInEachSnapshot;
+          } finally { SuppressEvents = false; }
+          break;
+        case "Algorithm":
+          SuppressEvents = true;
+          try {
+            algorithmViewHost.Content = Content.Algorithm;
+          } finally { SuppressEvents = false; }
+          break;
+        case "Snapshots":
+          SuppressEvents = true;
+          try {
+            snapshotsView.Content = Content.Snapshots;
+          } finally { SuppressEvents = false; }
+          break;
+        case "Runs":
+          SuppressEvents = true;
+          try {
+            runsView.Content = Content.Runs;
+          } finally { SuppressEvents = false; }
+          break;
+      }
+    }
+
+    private void Content_SnapshotTimes_Changed(object sender, EventArgs e) {
+      SuppressEvents = true;
+      try {
+        if (Content.SnapshotTimes.Any())
+          snapshotsTextBox.Text = string.Join(" ; ", Content.SnapshotTimes.Select(x => TimeSpanHelper.FormatNatural(x, true)));
+        else snapshotsTextBox.Text = String.Empty;
+      } finally { SuppressEvents = false; }
+    }
+    #endregion
+
+    #region Control events
+    private void timeLimitTextBox_Validating(object sender, CancelEventArgs e) {
+      if (SuppressEvents) return;
+      TimeSpan ts;
+      if (!TimeSpanHelper.TryGetFromNaturalFormat(timeLimitTextBox.Text, out ts)) {
+        e.Cancel = !timeLimitTextBox.ReadOnly && timeLimitTextBox.Enabled;
+        errorProvider.SetError(timeLimitTextBox, "Please enter a valid time span, e.g. 20 seconds ; 45s ; 4min ; 1h ; 3 hours ; 2 days ; 4d");
+      } else {
+        Content.MaximumExecutionTime = ts;
+        e.Cancel = false;
+        errorProvider.SetError(timeLimitTextBox, null);
+      }
+    }
+
+    private void snapshotsTextBox_Validating(object sender, CancelEventArgs e) {
+      if (SuppressEvents) return;
+      e.Cancel = false;
+      errorProvider.SetError(snapshotsTextBox, null);
+
+      var snapshotTimes = new ObservableList<TimeSpan>();
+      var matches = Regex.Matches(snapshotsTextBox.Text, @"(\d+[ ;,\t]*\w+)");
+      foreach (Match m in matches) {
+        TimeSpan value;
+        if (!TimeSpanHelper.TryGetFromNaturalFormat(m.Value, out value)) {
+          e.Cancel = !snapshotsTextBox.ReadOnly && snapshotsTextBox.Enabled; // don't cancel an operation that cannot be edited
+          errorProvider.SetError(snapshotsTextBox, "Error parsing " + m.Value + ", please provide a valid time span, e.g. 20 seconds ; 45s ; 4min ; 1h ; 3 hours ; 2 days ; 4d");
+          return;
+        } else {
+          snapshotTimes.Add(value);
+        }
+      }
+      Content.SnapshotTimes = snapshotTimes;
+    }
+
+    private void storeAlgorithmInEachSnapshotCheckBox_CheckedChanged(object sender, EventArgs e) {
+      if (SuppressEvents) return;
+      SuppressEvents = true;
+      try {
+        Content.StoreAlgorithmInEachSnapshot = storeAlgorithmInEachSnapshotCheckBox.Checked;
+      } finally { SuppressEvents = false; }
+    }
+
+    private void newAlgorithmButton_Click(object sender, EventArgs e) {
+      if (algorithmTypeSelectorDialog == null) {
+        algorithmTypeSelectorDialog = new TypeSelectorDialog { Caption = "Select Algorithm" };
+        algorithmTypeSelectorDialog.TypeSelector.Caption = "Available Algorithms";
+        algorithmTypeSelectorDialog.TypeSelector.Configure(typeof(IAlgorithm), false, true);
+      }
+      if (algorithmTypeSelectorDialog.ShowDialog(this) == DialogResult.OK) {
+        try {
+          Content.Algorithm = (IAlgorithm)algorithmTypeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
+        } catch (Exception ex) {
+          ErrorHandling.ShowErrorDialog(this, ex);
+        }
+      }
+    }
+
+    private void openAlgorithmButton_Click(object sender, EventArgs e) {
+      openFileDialog.Title = "Open Algorithm";
+      if (openFileDialog.ShowDialog(this) == DialogResult.OK) {
+        newAlgorithmButton.Enabled = openAlgorithmButton.Enabled = false;
+        algorithmViewHost.Enabled = false;
+
+        ContentManager.LoadAsync(openFileDialog.FileName, delegate(IStorableContent content, Exception error) {
+          try {
+            if (error != null) throw error;
+            var algorithm = content as IAlgorithm;
+            if (algorithm == null)
+              MessageBox.Show(this, "The selected file does not contain an algorithm.", "Invalid File", MessageBoxButtons.OK, MessageBoxIcon.Error);
+            else
+              Content.Algorithm = algorithm;
+          } catch (Exception ex) {
+            ErrorHandling.ShowErrorDialog(this, ex);
+          } finally {
+            Invoke(new Action(delegate() {
+              algorithmViewHost.Enabled = true;
+              newAlgorithmButton.Enabled = openAlgorithmButton.Enabled = true;
+            }));
+          }
+        });
+      }
+    }
+
+    private void algorithmTabPage_DragEnterOver(object sender, DragEventArgs e) {
+      e.Effect = DragDropEffects.None;
+      if (!ReadOnly && (e.Data.GetData(Constants.DragDropDataFormat) is IAlgorithm)) {
+        if ((e.KeyState & 32) == 32) e.Effect = DragDropEffects.Link;  // ALT key
+        else if ((e.KeyState & 4) == 4) e.Effect = DragDropEffects.Move;  // SHIFT key
+        else if (e.AllowedEffect.HasFlag(DragDropEffects.Copy)) e.Effect = DragDropEffects.Copy;
+        else if (e.AllowedEffect.HasFlag(DragDropEffects.Move)) e.Effect = DragDropEffects.Move;
+        else if (e.AllowedEffect.HasFlag(DragDropEffects.Link)) e.Effect = DragDropEffects.Link;
+      }
+    }
+
+    private void algorithmTabPage_DragDrop(object sender, DragEventArgs e) {
+      if (e.Effect != DragDropEffects.None) {
+        var algorithm = e.Data.GetData(Constants.DragDropDataFormat) as IAlgorithm;
+        if (e.Effect.HasFlag(DragDropEffects.Copy)) algorithm = (IAlgorithm)algorithm.Clone();
+        Content.Algorithm = algorithm;
+      }
+    }
+
+    private void snapshotButton_Click(object sender, EventArgs e) {
+      Content.Snapshot();
+    }
+
+    private void sequenceButton_Click(object sender, EventArgs e) {
+      using (var dialog = new DefineArithmeticTimeSpanProgressionDialog(TimeSpan.FromSeconds(1), Content.MaximumExecutionTime, TimeSpan.FromSeconds(1))) {
+        if (dialog.ShowDialog() == DialogResult.OK) {
+          if (dialog.Values.Any())
+            Content.SnapshotTimes = new ObservableList<TimeSpan>(dialog.Values);
+          else Content.SnapshotTimes = new ObservableList<TimeSpan>();
+        }
+      }
+    }
+    #endregion
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/UserDefinedAlgorithmView.Designer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/UserDefinedAlgorithmView.Designer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/UserDefinedAlgorithmView.Designer.cs	(revision 12764)
@@ -0,0 +1,166 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class UserDefinedAlgorithmView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.globalScopeTabPage = new System.Windows.Forms.TabPage();
+      this.globalScopeView = new HeuristicLab.Core.Views.ScopeView();
+      this.engineTabPage.SuspendLayout();
+      this.operatorGraphTabPage.SuspendLayout();
+      this.tabControl.SuspendLayout();
+      this.parametersTabPage.SuspendLayout();
+      this.problemTabPage.SuspendLayout();
+      this.resultsTabPage.SuspendLayout();
+      this.runsTabPage.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.globalScopeTabPage.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // engineComboBox
+      // 
+      this.engineComboBox.Size = new System.Drawing.Size(644, 21);
+      // 
+      // engineViewHost
+      // 
+      this.engineViewHost.Size = new System.Drawing.Size(693, 402);
+      // 
+      // openOperatorGraphButton
+      // 
+      this.toolTip.SetToolTip(this.openOperatorGraphButton, "Open Operator Graph");
+      this.openOperatorGraphButton.Click += new System.EventHandler(openOperatorGraphButton_Click);
+      // 
+      // newOperatorGraphButton
+      // 
+      this.toolTip.SetToolTip(this.newOperatorGraphButton, "New Operator Graph");
+      this.newOperatorGraphButton.Click += new System.EventHandler(newOperatorGraphButton_Click);
+      // 
+      // tabControl
+      // 
+      this.tabControl.Controls.Add(this.globalScopeTabPage);
+      this.tabControl.Controls.SetChildIndex(this.engineTabPage, 0);
+      this.tabControl.Controls.SetChildIndex(this.globalScopeTabPage, 0);
+      this.tabControl.Controls.SetChildIndex(this.operatorGraphTabPage, 0);
+      this.tabControl.Controls.SetChildIndex(this.runsTabPage, 0);
+      this.tabControl.Controls.SetChildIndex(this.resultsTabPage, 0);
+      this.tabControl.Controls.SetChildIndex(this.parametersTabPage, 0);
+      this.tabControl.Controls.SetChildIndex(this.problemTabPage, 0);
+      // 
+      // newProblemButton
+      // 
+      this.toolTip.SetToolTip(this.newProblemButton, "New Problem");
+      // 
+      // openProblemButton
+      // 
+      this.toolTip.SetToolTip(this.openProblemButton, "Open Problem");
+      // 
+      // startButton
+      // 
+      this.toolTip.SetToolTip(this.startButton, "Start/Resume Algorithm");
+      // 
+      // pauseButton
+      // 
+      this.toolTip.SetToolTip(this.pauseButton, "Pause Algorithm");
+      // 
+      // resetButton
+      // 
+      this.toolTip.SetToolTip(this.resetButton, "Reset Algorithm");
+      // 
+      // stopButton
+      // 
+      this.toolTip.SetToolTip(this.stopButton, "Stop Algorithm");
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      // 
+      // globalScopeTabPage
+      // 
+      this.globalScopeTabPage.Controls.Add(this.globalScopeView);
+      this.globalScopeTabPage.Location = new System.Drawing.Point(4, 22);
+      this.globalScopeTabPage.Name = "globalScopeTabPage";
+      this.globalScopeTabPage.Size = new System.Drawing.Size(705, 441);
+      this.globalScopeTabPage.TabIndex = 6;
+      this.globalScopeTabPage.Text = "Global Scope";
+      this.globalScopeTabPage.UseVisualStyleBackColor = true;
+      // 
+      // globalScopeView
+      // 
+      this.globalScopeView.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.globalScopeView.Content = null;
+      this.globalScopeView.Location = new System.Drawing.Point(3, 3);
+      this.globalScopeView.Name = "globalScopeView";
+      this.globalScopeView.ReadOnly = false;
+      this.globalScopeView.Size = new System.Drawing.Size(699, 435);
+      this.globalScopeView.TabIndex = 0;
+      // 
+      // UserDefinedAlgorithmView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Name = "UserDefinedAlgorithmView";
+      this.engineTabPage.ResumeLayout(false);
+      this.engineTabPage.PerformLayout();
+      this.operatorGraphTabPage.ResumeLayout(false);
+      this.tabControl.ResumeLayout(false);
+      this.parametersTabPage.ResumeLayout(false);
+      this.problemTabPage.ResumeLayout(false);
+      this.resultsTabPage.ResumeLayout(false);
+      this.runsTabPage.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.globalScopeTabPage.ResumeLayout(false);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.TabPage globalScopeTabPage;
+    private HeuristicLab.Core.Views.ScopeView globalScopeView;
+
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/UserDefinedAlgorithmView.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/UserDefinedAlgorithmView.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization.Views/3.3/UserDefinedAlgorithmView.cs	(revision 12764)
@@ -0,0 +1,95 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Windows.Forms;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.MainForm;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Optimization.Views {
+  /// <summary>
+  /// The base class for visual representations of items.
+  /// </summary>
+  [View("UserDefinedAlgorithm View")]
+  [Content(typeof(UserDefinedAlgorithm), true)]
+  public sealed partial class UserDefinedAlgorithmView : EngineAlgorithmView {
+    public new UserDefinedAlgorithm Content {
+      get { return (UserDefinedAlgorithm)base.Content; }
+      set { base.Content = value; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of <see cref="ItemBaseView"/>.
+    /// </summary>
+    public UserDefinedAlgorithmView() {
+      InitializeComponent();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null)
+        globalScopeView.Content = null;
+      else
+        globalScopeView.Content = Content.GlobalScope;
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      globalScopeView.Enabled = Content != null;
+      newOperatorGraphButton.Enabled = Content != null && !ReadOnly;
+      openOperatorGraphButton.Enabled = Content != null && !ReadOnly;
+      operatorGraphViewHost.ReadOnly = Content == null || ReadOnly;
+    }
+
+    private void newOperatorGraphButton_Click(object sender, EventArgs e) {
+      Content.OperatorGraph = new OperatorGraph();
+    }
+    private void openOperatorGraphButton_Click(object sender, EventArgs e) {
+      openFileDialog.Title = "Open Operator Graph";
+      if (openFileDialog.ShowDialog(this) == DialogResult.OK) {
+        newOperatorGraphButton.Enabled = openOperatorGraphButton.Enabled = false;
+        operatorGraphViewHost.Enabled = false;
+
+        ContentManager.LoadAsync(openFileDialog.FileName, delegate(IStorableContent content, Exception error) {
+          try {
+            if (error != null) throw error;
+            OperatorGraph operatorGraph = content as OperatorGraph;
+            if (operatorGraph == null)
+              MessageBox.Show(this, "The selected file does not contain an operator graph.", "Invalid File", MessageBoxButtons.OK, MessageBoxIcon.Error);
+            else
+              Content.OperatorGraph = operatorGraph;
+          }
+          catch (Exception ex) {
+            ErrorHandling.ShowErrorDialog(this, ex);
+          }
+          finally {
+            Invoke(new Action(delegate() {
+              operatorGraphViewHost.Enabled = true;
+              newOperatorGraphButton.Enabled = openOperatorGraphButton.Enabled = true;
+            }));
+          }
+        });
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Algorithms/Algorithm.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Algorithms/Algorithm.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Algorithms/Algorithm.cs	(revision 12764)
@@ -0,0 +1,330 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// A base class for algorithms.
+  /// </summary>
+  [Item("Algorithm", "A base class for algorithms.")]
+  [StorableClass]
+  public abstract class Algorithm : ParameterizedNamedItem, IAlgorithm {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Event; }
+    }
+    public override Image ItemImage {
+      get {
+        if (ExecutionState == ExecutionState.Prepared) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutablePrepared;
+        else if (ExecutionState == ExecutionState.Started) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStarted;
+        else if (ExecutionState == ExecutionState.Paused) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutablePaused;
+        else if (ExecutionState == ExecutionState.Stopped) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStopped;
+        else return base.ItemImage;
+      }
+    }
+
+    [Storable]
+    private ExecutionState executionState;
+    public ExecutionState ExecutionState {
+      get { return executionState; }
+      private set {
+        if (executionState != value) {
+          executionState = value;
+          OnExecutionStateChanged();
+          OnItemImageChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private TimeSpan executionTime;
+    public TimeSpan ExecutionTime {
+      get { return executionTime; }
+      protected set {
+        executionTime = value;
+        OnExecutionTimeChanged();
+      }
+    }
+
+    public virtual Type ProblemType {
+      get { return typeof(IProblem); }
+    }
+
+    [Storable]
+    private IProblem problem;
+    public IProblem Problem {
+      get { return problem; }
+      set {
+        if (problem != value) {
+          if ((value != null) && !ProblemType.IsInstanceOfType(value)) throw new ArgumentException("Invalid problem type.");
+          if (problem != null) DeregisterProblemEvents();
+          problem = value;
+          if (problem != null) RegisterProblemEvents();
+          OnProblemChanged();
+          Prepare();
+        }
+      }
+    }
+
+    public abstract ResultCollection Results { get; }
+
+    [Storable]
+    private bool storeAlgorithmInEachRun;
+    public bool StoreAlgorithmInEachRun {
+      get { return storeAlgorithmInEachRun; }
+      set {
+        if (storeAlgorithmInEachRun != value) {
+          storeAlgorithmInEachRun = value;
+          OnStoreAlgorithmInEachRunChanged();
+        }
+      }
+    }
+
+    [Storable]
+    protected int runsCounter;
+
+    [Storable]
+    private RunCollection runs;
+    public RunCollection Runs {
+      get { return runs; }
+      protected set {
+        if (value == null) throw new ArgumentNullException();
+        if (runs != value) {
+          if (runs != null) DeregisterRunsEvents();
+          runs = value;
+          if (runs != null) RegisterRunsEvents();
+        }
+      }
+    }
+
+    public virtual IEnumerable<IOptimizer> NestedOptimizers {
+      get { return Enumerable.Empty<IOptimizer>(); }
+    }
+
+    protected Algorithm()
+      : base() {
+      executionState = ExecutionState.Stopped;
+      executionTime = TimeSpan.Zero;
+      storeAlgorithmInEachRun = false;
+      runsCounter = 0;
+      Runs = new RunCollection { OptimizerName = Name };
+    }
+    protected Algorithm(string name)
+      : base(name) {
+      executionState = ExecutionState.Stopped;
+      executionTime = TimeSpan.Zero;
+      storeAlgorithmInEachRun = false;
+      runsCounter = 0;
+      Runs = new RunCollection { OptimizerName = Name };
+    }
+    protected Algorithm(string name, ParameterCollection parameters)
+      : base(name, parameters) {
+      executionState = ExecutionState.Stopped;
+      executionTime = TimeSpan.Zero;
+      storeAlgorithmInEachRun = false;
+      runsCounter = 0;
+      Runs = new RunCollection { OptimizerName = Name };
+    }
+    protected Algorithm(string name, string description)
+      : base(name, description) {
+      executionState = ExecutionState.Stopped;
+      executionTime = TimeSpan.Zero;
+      storeAlgorithmInEachRun = false;
+      runsCounter = 0;
+      Runs = new RunCollection { OptimizerName = Name };
+    }
+    protected Algorithm(string name, string description, ParameterCollection parameters)
+      : base(name, description, parameters) {
+      executionState = ExecutionState.Stopped;
+      executionTime = TimeSpan.Zero;
+      storeAlgorithmInEachRun = false;
+      runsCounter = 0;
+      Runs = new RunCollection { OptimizerName = Name };
+    }
+    [StorableConstructor]
+    protected Algorithm(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      Initialize();
+    }
+
+    protected Algorithm(Algorithm original, Cloner cloner)
+      : base(original, cloner) {
+      if (ExecutionState == ExecutionState.Started) throw new InvalidOperationException(string.Format("Clone not allowed in execution state \"{0}\".", ExecutionState));
+      executionState = original.executionState;
+      executionTime = original.executionTime;
+      problem = cloner.Clone(original.problem);
+      storeAlgorithmInEachRun = original.storeAlgorithmInEachRun;
+      runsCounter = original.runsCounter;
+      runs = cloner.Clone(original.runs);
+      Initialize();
+    }
+
+    private void Initialize() {
+      if (problem != null) RegisterProblemEvents();
+      if (runs != null) RegisterRunsEvents();
+    }
+
+    public virtual void Prepare() {
+      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped))
+        throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState));
+    }
+    public void Prepare(bool clearRuns) {
+      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped))
+        throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState));
+      if (clearRuns) runs.Clear();
+      Prepare();
+    }
+    public virtual void Start() {
+      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
+        throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
+    }
+    public virtual void Pause() {
+      if (ExecutionState != ExecutionState.Started)
+        throw new InvalidOperationException(string.Format("Pause not allowed in execution state \"{0}\".", ExecutionState));
+    }
+    public virtual void Stop() {
+      if ((ExecutionState != ExecutionState.Started) && (ExecutionState != ExecutionState.Paused))
+        throw new InvalidOperationException(string.Format("Stop not allowed in execution state \"{0}\".", ExecutionState));
+    }
+
+    public override void CollectParameterValues(IDictionary<string, IItem> values) {
+      base.CollectParameterValues(values);
+      values.Add("Algorithm Name", new StringValue(Name));
+      values.Add("Algorithm Type", new StringValue(this.GetType().GetPrettyName()));
+      if (Problem != null) {
+        Problem.CollectParameterValues(values);
+        values.Add("Problem Name", new StringValue(Problem.Name));
+        values.Add("Problem Type", new StringValue(Problem.GetType().GetPrettyName()));
+      }
+    }
+    public virtual void CollectResultValues(IDictionary<string, IItem> values) {
+      values.Add("Execution Time", new TimeSpanValue(ExecutionTime));
+      Results.CollectResultValues(values);
+    }
+
+    protected override IEnumerable<KeyValuePair<string, IItem>> GetCollectedValues(IValueParameter param) {
+      var children = base.GetCollectedValues(param);
+      foreach (var child in children) {
+        if (child.Value is IOperator)
+          yield return new KeyValuePair<string, IItem>(child.Key, new StringValue(((IOperator)child.Value).Name));
+        else yield return child;
+      }
+    }
+
+    #region Events
+    protected override void OnNameChanged() {
+      base.OnNameChanged();
+      Runs.OptimizerName = Name;
+    }
+
+    public event EventHandler ExecutionStateChanged;
+    protected virtual void OnExecutionStateChanged() {
+      EventHandler handler = ExecutionStateChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ExecutionTimeChanged;
+    protected virtual void OnExecutionTimeChanged() {
+      EventHandler handler = ExecutionTimeChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ProblemChanged;
+    protected virtual void OnProblemChanged() {
+      EventHandler handler = ProblemChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler StoreAlgorithmInEachRunChanged;
+    protected virtual void OnStoreAlgorithmInEachRunChanged() {
+      EventHandler handler = StoreAlgorithmInEachRunChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Prepared;
+    protected virtual void OnPrepared() {
+      ExecutionTime = TimeSpan.Zero;
+      foreach (IStatefulItem statefulObject in this.GetObjectGraphObjects(new HashSet<object>() { Runs }).OfType<IStatefulItem>()) {
+        statefulObject.InitializeState();
+      }
+      ExecutionState = ExecutionState.Prepared;
+      EventHandler handler = Prepared;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Started;
+    protected virtual void OnStarted() {
+      ExecutionState = ExecutionState.Started;
+      EventHandler handler = Started;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Paused;
+    protected virtual void OnPaused() {
+      ExecutionState = ExecutionState.Paused;
+      EventHandler handler = Paused;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Stopped;
+    protected virtual void OnStopped() {
+      foreach (IStatefulItem statefulObject in this.GetObjectGraphObjects(new HashSet<object>() { Runs }).OfType<IStatefulItem>()) {
+        statefulObject.ClearState();
+      }
+      runsCounter++;
+      runs.Add(new Run(string.Format("{0} Run {1}", Name, runsCounter), this));
+      ExecutionState = ExecutionState.Stopped;
+      EventHandler handler = Stopped;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
+    protected virtual void OnExceptionOccurred(Exception exception) {
+      EventHandler<EventArgs<Exception>> handler = ExceptionOccurred;
+      if (handler != null) handler(this, new EventArgs<Exception>(exception));
+    }
+
+    protected virtual void DeregisterProblemEvents() {
+      problem.OperatorsChanged -= new EventHandler(Problem_OperatorsChanged);
+      problem.Reset -= new EventHandler(Problem_Reset);
+    }
+    protected virtual void RegisterProblemEvents() {
+      problem.OperatorsChanged += new EventHandler(Problem_OperatorsChanged);
+      problem.Reset += new EventHandler(Problem_Reset);
+    }
+    protected virtual void Problem_OperatorsChanged(object sender, EventArgs e) { }
+    protected virtual void Problem_Reset(object sender, EventArgs e) {
+      Prepare();
+    }
+
+    protected virtual void DeregisterRunsEvents() {
+      runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
+    }
+    protected virtual void RegisterRunsEvents() {
+      runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
+    }
+    protected virtual void Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      runsCounter = runs.Count;
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Algorithms/BasicAlgorithm.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Algorithms/BasicAlgorithm.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Algorithms/BasicAlgorithm.cs	(revision 12764)
@@ -0,0 +1,129 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [StorableClass]
+  public abstract class BasicAlgorithm : Algorithm, IStorableContent {
+    public string Filename { get; set; }
+
+    [Storable]
+    private ResultCollection results;
+    public override ResultCollection Results {
+      get { return results; }
+    }
+
+    private CancellationTokenSource cancellationTokenSource;
+    protected CancellationTokenSource CancellationTokenSource {
+      get { return cancellationTokenSource; }
+      private set { cancellationTokenSource = value; }
+    }
+
+    [StorableConstructor]
+    protected BasicAlgorithm(bool deserializing) : base(deserializing) { }
+    protected BasicAlgorithm(BasicAlgorithm original, Cloner cloner)
+      : base(original, cloner) {
+      results = cloner.Clone(original.Results);
+    }
+    protected BasicAlgorithm()
+      : base() {
+      results = new ResultCollection();
+    }
+
+    public override void Prepare() {
+      if (Problem == null) return;
+      base.Prepare();
+      results.Clear();
+      OnPrepared();
+    }
+
+    public override void Start() {
+      base.Start();
+      CancellationTokenSource = new CancellationTokenSource();
+
+      OnStarted();
+      Task task = Task.Factory.StartNew(Run, cancellationTokenSource.Token, cancellationTokenSource.Token);
+      task.ContinueWith(t => {
+        try {
+          t.Wait();
+        } catch (AggregateException ex) {
+          try {
+            ex.Flatten().Handle(x => x is OperationCanceledException);
+          } catch (AggregateException remaining) {
+            if (remaining.InnerExceptions.Count == 1) OnExceptionOccurred(remaining.InnerExceptions[0]);
+            else OnExceptionOccurred(remaining);
+          }
+        }
+        CancellationTokenSource.Dispose();
+        CancellationTokenSource = null;
+        OnStopped();
+      });
+    }
+
+    public override void Pause() {
+      throw new NotSupportedException("Pause is not supported in basic algorithms.");
+    }
+
+    public override void Stop() {
+      // CancellationToken.ThrowIfCancellationRequested() must be called from within the Run method, otherwise stop does nothing
+      // alternatively check the IsCancellationRequested property of the cancellation token
+      base.Stop();
+      CancellationTokenSource.Cancel();
+    }
+
+
+    private DateTime lastUpdateTime;
+    private void Run(object state) {
+      CancellationToken cancellationToken = (CancellationToken)state;
+      lastUpdateTime = DateTime.UtcNow;
+      System.Timers.Timer timer = new System.Timers.Timer(250);
+      timer.AutoReset = true;
+      timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
+      timer.Start();
+      try {
+        Run(cancellationToken);
+      } finally {
+        timer.Elapsed -= new System.Timers.ElapsedEventHandler(timer_Elapsed);
+        timer.Stop();
+        ExecutionTime += DateTime.UtcNow - lastUpdateTime;
+      }
+    }
+
+    protected abstract void Run(CancellationToken cancellationToken);
+
+    #region Events
+    private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
+      System.Timers.Timer timer = (System.Timers.Timer)sender;
+      timer.Enabled = false;
+      DateTime now = DateTime.UtcNow;
+      ExecutionTime += now - lastUpdateTime;
+      lastUpdateTime = now;
+      timer.Enabled = true;
+    }
+    #endregion
+
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Algorithms/EngineAlgorithm.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Algorithms/EngineAlgorithm.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Algorithms/EngineAlgorithm.cs	(revision 12764)
@@ -0,0 +1,238 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// A base class for algorithms which use an engine for execution.
+  /// </summary>
+  [Item("EngineAlgorithm", "A base class for algorithms which use an engine for execution.")]
+  [StorableClass]
+  public abstract class EngineAlgorithm : Algorithm {
+    [Storable]
+    private OperatorGraph operatorGraph;
+    public OperatorGraph OperatorGraph {
+      get { return operatorGraph; }
+      protected set {
+        if (value == null) throw new ArgumentNullException();
+        if (value != operatorGraph) {
+          operatorGraph.InitialOperatorChanged -= new EventHandler(OperatorGraph_InitialOperatorChanged);
+          operatorGraph = value;
+          operatorGraph.InitialOperatorChanged += new EventHandler(OperatorGraph_InitialOperatorChanged);
+          OnOperatorGraphChanged();
+          Prepare();
+        }
+      }
+    }
+
+    [Storable]
+    private IScope globalScope;
+    protected IScope GlobalScope {
+      get { return globalScope; }
+    }
+
+    [Storable]
+    private IEngine engine;
+    public IEngine Engine {
+      get { return engine; }
+      set {
+        if (engine != value) {
+          if (engine != null) DeregisterEngineEvents();
+          engine = value;
+          if (engine != null) RegisterEngineEvents();
+          OnEngineChanged();
+          Prepare();
+        }
+      }
+    }
+
+    public override ResultCollection Results {
+      get {
+        return (ResultCollection)globalScope.Variables["Results"].Value;
+      }
+    }
+
+    protected EngineAlgorithm()
+      : base() {
+      globalScope = new Scope("Global Scope");
+      globalScope.Variables.Add(new Variable("Results", new ResultCollection()));
+      operatorGraph = new OperatorGraph();
+      Initialize();
+    }
+    protected EngineAlgorithm(string name)
+      : base(name) {
+      globalScope = new Scope("Global Scope");
+      globalScope.Variables.Add(new Variable("Results", new ResultCollection()));
+      operatorGraph = new OperatorGraph();
+      Initialize();
+    }
+    protected EngineAlgorithm(string name, ParameterCollection parameters)
+      : base(name, parameters) {
+      globalScope = new Scope("Global Scope");
+      globalScope.Variables.Add(new Variable("Results", new ResultCollection()));
+      operatorGraph = new OperatorGraph();
+      Initialize();
+    }
+    protected EngineAlgorithm(string name, string description)
+      : base(name, description) {
+      globalScope = new Scope("Global Scope");
+      globalScope.Variables.Add(new Variable("Results", new ResultCollection()));
+      operatorGraph = new OperatorGraph();
+      Initialize();
+    }
+    protected EngineAlgorithm(string name, string description, ParameterCollection parameters)
+      : base(name, description, parameters) {
+      globalScope = new Scope("Global Scope");
+      globalScope.Variables.Add(new Variable("Results", new ResultCollection()));
+      operatorGraph = new OperatorGraph();
+      Initialize();
+    }
+    [StorableConstructor]
+    protected EngineAlgorithm(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      Initialize();
+
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code (remove with 3.4)
+      // clear global scope if it contains any sub-scopes or additional variables
+      if ((ExecutionState == Core.ExecutionState.Stopped) && ((globalScope.SubScopes.Count > 0) || (globalScope.Variables.Count > 1))) {
+        ResultCollection results = Results;
+        globalScope.Clear();
+        globalScope.Variables.Add(new Variable("Results", results));
+      }
+      #endregion
+    }
+
+    protected EngineAlgorithm(EngineAlgorithm original, Cloner cloner)
+      : base(original, cloner) {
+      globalScope = cloner.Clone(original.globalScope);
+      engine = cloner.Clone(original.engine);
+      operatorGraph = cloner.Clone(original.operatorGraph);
+      Initialize();
+    }
+
+    private void Initialize() {
+      operatorGraph.InitialOperatorChanged += new EventHandler(OperatorGraph_InitialOperatorChanged);
+      if (engine == null) {
+        var types = ApplicationManager.Manager.GetTypes(typeof(IEngine));
+        Type t = types.FirstOrDefault(x => x.Name.Equals("SequentialEngine"));
+        if (t == null) t = types.FirstOrDefault();
+        if (t != null) engine = (IEngine)Activator.CreateInstance(t);
+      }
+      if (engine != null) RegisterEngineEvents();
+    }
+
+    public virtual IAlgorithm CreateUserDefinedAlgorithm() {
+      return new UserDefinedAlgorithm(this, new Cloner());
+    }
+
+    public override void Prepare() {
+      base.Prepare();
+      globalScope.Clear();
+      globalScope.Variables.Add(new Variable("Results", new ResultCollection()));
+
+      if ((engine != null) && (operatorGraph.InitialOperator != null)) {
+        ExecutionContext context = null;
+        if (Problem != null) {
+          foreach (var item in Problem.ExecutionContextItems)
+            context = new ExecutionContext(context, item, globalScope);
+        }
+        context = new ExecutionContext(context, this, globalScope);
+        context = new ExecutionContext(context, operatorGraph.InitialOperator, globalScope);
+        engine.Prepare(context);
+      }
+    }
+    public override void Start() {
+      base.Start();
+      if (engine != null) engine.Start();
+    }
+    public override void Pause() {
+      base.Pause();
+      if (engine != null) engine.Pause();
+    }
+    public override void Stop() {
+      base.Stop();
+      if (engine != null) engine.Stop();
+    }
+
+    #region Events
+    public event EventHandler EngineChanged;
+    protected virtual void OnEngineChanged() {
+      EventHandler handler = EngineChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler OperatorGraphChanged;
+    protected virtual void OnOperatorGraphChanged() {
+      EventHandler handler = OperatorGraphChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    private void RegisterEngineEvents() {
+      Engine.ExceptionOccurred += new EventHandler<EventArgs<Exception>>(Engine_ExceptionOccurred);
+      Engine.ExecutionTimeChanged += new EventHandler(Engine_ExecutionTimeChanged);
+      Engine.Paused += new EventHandler(Engine_Paused);
+      Engine.Prepared += new EventHandler(Engine_Prepared);
+      Engine.Started += new EventHandler(Engine_Started);
+      Engine.Stopped += new EventHandler(Engine_Stopped);
+    }
+    private void DeregisterEngineEvents() {
+      Engine.ExceptionOccurred -= new EventHandler<EventArgs<Exception>>(Engine_ExceptionOccurred);
+      Engine.ExecutionTimeChanged -= new EventHandler(Engine_ExecutionTimeChanged);
+      Engine.Paused -= new EventHandler(Engine_Paused);
+      Engine.Prepared -= new EventHandler(Engine_Prepared);
+      Engine.Started -= new EventHandler(Engine_Started);
+      Engine.Stopped -= new EventHandler(Engine_Stopped);
+    }
+    private void Engine_ExceptionOccurred(object sender, EventArgs<Exception> e) {
+      OnExceptionOccurred(e.Value);
+    }
+    private void Engine_ExecutionTimeChanged(object sender, EventArgs e) {
+      ExecutionTime = Engine.ExecutionTime;
+    }
+    private void Engine_Paused(object sender, EventArgs e) {
+      OnPaused();
+    }
+    private void Engine_Prepared(object sender, EventArgs e) {
+      OnPrepared();
+    }
+    private void Engine_Started(object sender, EventArgs e) {
+      OnStarted();
+    }
+    private void Engine_Stopped(object sender, EventArgs e) {
+      ResultCollection results = Results;
+      globalScope.Clear();
+      globalScope.Variables.Add(new Variable("Results", results));
+      OnStopped();
+    }
+
+    private void OperatorGraph_InitialOperatorChanged(object sender, EventArgs e) {
+      Prepare();
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Algorithms/HeuristicOptimizationAlgorithm.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Algorithms/HeuristicOptimizationAlgorithm.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Algorithms/HeuristicOptimizationAlgorithm.cs	(revision 12764)
@@ -0,0 +1,65 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// A base class for heuristic optimization algorithms.
+  /// </summary>
+  [Item("Heuristic Optimization Algorithm", "A base class for heuristic optimization algorithms.")]
+  [StorableClass]
+  public abstract class HeuristicOptimizationAlgorithm : Algorithm {
+    public new IHeuristicOptimizationProblem Problem {
+      get { return (IHeuristicOptimizationProblem)base.Problem; }
+      set { base.Problem = value; }
+    }
+
+    protected HeuristicOptimizationAlgorithm() : base() { }
+    protected HeuristicOptimizationAlgorithm(string name) : base(name) { }
+    protected HeuristicOptimizationAlgorithm(string name, ParameterCollection parameters) : base(name, parameters) { }
+    protected HeuristicOptimizationAlgorithm(string name, string description) : base(name, description) { }
+    protected HeuristicOptimizationAlgorithm(string name, string description, ParameterCollection parameters) : base(name, description, parameters) { }
+
+    [StorableConstructor]
+    protected HeuristicOptimizationAlgorithm(bool deserializing) : base(deserializing) { }
+    protected HeuristicOptimizationAlgorithm(HeuristicOptimizationAlgorithm original, Cloner cloner) : base(original, cloner) { }
+
+    #region Events
+    protected override void DeregisterProblemEvents() {
+      Problem.SolutionCreatorChanged -= new EventHandler(Problem_SolutionCreatorChanged);
+      Problem.EvaluatorChanged -= new EventHandler(Problem_EvaluatorChanged);
+      base.DeregisterProblemEvents();
+    }
+    protected override void RegisterProblemEvents() {
+      base.RegisterProblemEvents();
+      Problem.SolutionCreatorChanged += new EventHandler(Problem_SolutionCreatorChanged);
+      Problem.EvaluatorChanged += new EventHandler(Problem_EvaluatorChanged);
+    }
+
+    protected virtual void Problem_SolutionCreatorChanged(object sender, EventArgs e) { }
+    protected virtual void Problem_EvaluatorChanged(object sender, EventArgs e) { }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Algorithms/HeuristicOptimizationEngineAlgorithm.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Algorithms/HeuristicOptimizationEngineAlgorithm.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Algorithms/HeuristicOptimizationEngineAlgorithm.cs	(revision 12764)
@@ -0,0 +1,65 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// A base class for heuristic optimization algorithms using an execution engine.
+  /// </summary>
+  [Item("Heuristic Optimization Enigne Algorithm", "A base class for heuristic optimization algorithms using an execution engine.")]
+  [StorableClass]
+  public abstract class HeuristicOptimizationEngineAlgorithm : EngineAlgorithm {
+    public new IHeuristicOptimizationProblem Problem {
+      get { return (IHeuristicOptimizationProblem)base.Problem; }
+      set { base.Problem = value; }
+    }
+
+    protected HeuristicOptimizationEngineAlgorithm() : base() { }
+    protected HeuristicOptimizationEngineAlgorithm(string name) : base(name) { }
+    protected HeuristicOptimizationEngineAlgorithm(string name, ParameterCollection parameters) : base(name, parameters) { }
+    protected HeuristicOptimizationEngineAlgorithm(string name, string description) : base(name, description) { }
+    protected HeuristicOptimizationEngineAlgorithm(string name, string description, ParameterCollection parameters) : base(name, description, parameters) { }
+
+    [StorableConstructor]
+    protected HeuristicOptimizationEngineAlgorithm(bool deserializing) : base(deserializing) { }
+    protected HeuristicOptimizationEngineAlgorithm(HeuristicOptimizationEngineAlgorithm original, Cloner cloner) : base(original, cloner) { }
+
+    #region Events
+    protected override void DeregisterProblemEvents() {
+      Problem.SolutionCreatorChanged -= new EventHandler(Problem_SolutionCreatorChanged);
+      Problem.EvaluatorChanged -= new EventHandler(Problem_EvaluatorChanged);
+      base.DeregisterProblemEvents();
+    }
+    protected override void RegisterProblemEvents() {
+      base.RegisterProblemEvents();
+      Problem.SolutionCreatorChanged += new EventHandler(Problem_SolutionCreatorChanged);
+      Problem.EvaluatorChanged += new EventHandler(Problem_EvaluatorChanged);
+    }
+
+    protected virtual void Problem_SolutionCreatorChanged(object sender, EventArgs e) { }
+    protected virtual void Problem_EvaluatorChanged(object sender, EventArgs e) { }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Algorithms/UserDefinedAlgorithm.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Algorithms/UserDefinedAlgorithm.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Algorithms/UserDefinedAlgorithm.cs	(revision 12764)
@@ -0,0 +1,115 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An algorithm which can be defined by the user.
+  /// </summary>
+  [Item("User-Defined Algorithm", "An algorithm which can be defined by the user.")]
+  [Creatable(CreatableAttribute.Categories.Algorithms, Priority = 100)]
+  [StorableClass]
+  public sealed class UserDefinedAlgorithm : EngineAlgorithm, IParameterizedItem, IStorableContent {
+    public string Filename { get; set; }
+
+    public new ParameterCollection Parameters {
+      get { return base.Parameters; }
+    }
+    IKeyedItemCollection<string, IParameter> IParameterizedItem.Parameters {
+      get { return Parameters; }
+    }
+
+    public new OperatorGraph OperatorGraph {
+      get { return base.OperatorGraph; }
+      set { base.OperatorGraph = value; }
+    }
+
+    public new IScope GlobalScope {
+      get { return base.GlobalScope; }
+    }
+
+    private IValueParameter AnalyzerParameter {
+      get {
+        IParameter param;
+        if (Parameters.TryGetValue("Analyzer", out param))
+          return param as IValueParameter;
+        return null;
+      }
+    }
+    private IMultiAnalyzer Analyzer {
+      get {
+        if (AnalyzerParameter != null)
+          return AnalyzerParameter.Value as IMultiAnalyzer;
+        return null;
+      }
+    }
+
+    public UserDefinedAlgorithm() : base() { }
+    public UserDefinedAlgorithm(string name) : base(name) { }
+    public UserDefinedAlgorithm(string name, string description) : base(name, description) { }
+    [StorableConstructor]
+    private UserDefinedAlgorithm(bool deserializing) : base(deserializing) { }
+    private UserDefinedAlgorithm(UserDefinedAlgorithm original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    internal UserDefinedAlgorithm(EngineAlgorithm original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new UserDefinedAlgorithm(this, cloner);
+    }
+
+    #region update of problem specific analyzers
+    protected override void OnProblemChanged() {
+      AddProblemAnalyzer();
+      base.OnProblemChanged();
+    }
+    protected override void Problem_OperatorsChanged(object sender, System.EventArgs e) {
+      RemoveProblemAnalyzers();
+      AddProblemAnalyzer();
+      base.Problem_OperatorsChanged(sender, e);
+    }
+
+    protected override void DeregisterProblemEvents() {
+      RemoveProblemAnalyzers();
+      base.DeregisterProblemEvents();
+    }
+
+    private void RemoveProblemAnalyzers() {
+      if (Analyzer != null) {
+        foreach (var analyzer in Problem.Operators.OfType<IAnalyzer>())
+          Analyzer.Operators.Remove(analyzer);
+      }
+    }
+    private void AddProblemAnalyzer() {
+      if (Analyzer != null && Problem != null) {
+        foreach (IAnalyzer analyzer in Problem.Operators.OfType<IAnalyzer>()) {
+          Analyzer.Operators.Add(analyzer, analyzer.EnabledByDefault);
+        }
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/BasicProblem.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/BasicProblem.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/BasicProblem.cs	(revision 12764)
@@ -0,0 +1,160 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [StorableClass]
+  public abstract class BasicProblem<TEncoding, TEvaluator> : HeuristicOptimizationProblem<TEvaluator, ISolutionCreator>, IProblemDefinition, IStorableContent
+    where TEncoding : class, IEncoding
+    where TEvaluator : class, IEvaluator {
+
+    public string Filename { get; set; }
+
+    protected IValueParameter<TEncoding> EncodingParameter {
+      get { return (IValueParameter<TEncoding>)Parameters["Encoding"]; }
+    }
+
+    //mkommend necessary for reuse of operators if the encoding changes
+    private TEncoding oldEncoding;
+
+    IEncoding IProblemDefinition.Encoding { get { return Encoding; } }
+    public TEncoding Encoding {
+      get { return EncodingParameter.Value; }
+      protected set {
+        if (value == null) throw new ArgumentNullException("Encoding must not be null.");
+        EncodingParameter.Value = value;
+      }
+    }
+
+    protected override IEnumerable<IItem> GetOperators() {
+      if (Encoding == null) return base.GetOperators();
+      return base.GetOperators().Concat(Encoding.Operators);
+    }
+    public override IEnumerable<IParameterizedItem> ExecutionContextItems {
+      get {
+        if (Encoding == null) return base.ExecutionContextItems;
+        return base.ExecutionContextItems.Concat(new[] { Encoding });
+      }
+    }
+
+    protected BasicProblem()
+      : base() {
+      Parameters.Add(new ValueParameter<TEncoding>("Encoding", "Describes the configuration of the encoding, what the variables are called, what type they are and their bounds if any."));
+      oldEncoding = Encoding;
+      if(Encoding != null) Parameterize();
+      RegisterEvents();
+    }
+
+    protected BasicProblem(BasicProblem<TEncoding, TEvaluator> original, Cloner cloner)
+      : base(original, cloner) {
+      oldEncoding = cloner.Clone(original.oldEncoding);
+      RegisterEvents();
+    }
+
+    [StorableConstructor]
+    protected BasicProblem(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      oldEncoding = Encoding;
+      RegisterEvents();
+    }
+
+    private void RegisterEvents() {
+      EncodingParameter.ValueChanged += (o, e) => OnEncodingChanged();
+      var multiEncoding = Encoding as MultiEncoding;
+      if (multiEncoding != null) multiEncoding.EncodingsChanged += MultiEncodingOnEncodingsChanged;
+    }
+
+    protected virtual void OnEncodingChanged() {
+      Parameterize();
+
+      OnOperatorsChanged();
+      OnReset();
+    }
+
+    private void Parameterize() {
+      if (oldEncoding != null) {
+        AdaptEncodingOperators(oldEncoding, Encoding);
+        var oldMultiEncoding = oldEncoding as MultiEncoding;
+        if (oldMultiEncoding != null)
+          oldMultiEncoding.EncodingsChanged -= MultiEncodingOnEncodingsChanged;
+      }
+      oldEncoding = Encoding;
+
+      foreach (var op in Operators.OfType<IEncodingOperator>())
+        op.EncodingParameter.ActualName = EncodingParameter.Name;
+
+      var solutionCreatorType = Encoding.GetType().BaseType.GetGenericArguments();
+      var paramType = typeof(ValueParameter<>).MakeGenericType(solutionCreatorType);
+      var solutionCreatorParam = (IParameter)Activator.CreateInstance(paramType, SolutionCreatorParameter.Name, SolutionCreatorParameter.Description,
+        Encoding.SolutionCreator);
+      Parameters.Remove(SolutionCreatorParameter);
+      Parameters.Add(solutionCreatorParam);
+      ((IValueParameter)solutionCreatorParam).ValueChanged += SolutionCreatorParameter_ValueChanged;
+
+      var multiEncoding = Encoding as MultiEncoding;
+      if (multiEncoding != null) multiEncoding.EncodingsChanged += MultiEncodingOnEncodingsChanged;
+    }
+
+    protected override void OnSolutionCreatorChanged() {
+      base.OnSolutionCreatorChanged();
+      Encoding.SolutionCreator = SolutionCreator;
+    }
+
+    private static void AdaptEncodingOperators(IEncoding oldEncoding, IEncoding newEncoding) {
+      if (oldEncoding.GetType() != newEncoding.GetType()) return;
+
+      if (oldEncoding.GetType() == typeof(MultiEncoding)) {
+        var oldMultiEncoding = (MultiEncoding)oldEncoding;
+        var newMultiEncoding = (MultiEncoding)newEncoding;
+        if (!oldMultiEncoding.Encodings.SequenceEqual(newMultiEncoding.Encodings, new TypeEqualityComparer<IEncoding>())) return;
+
+        var nestedEncodings = oldMultiEncoding.Encodings.Zip(newMultiEncoding.Encodings, (o, n) => new { oldEnc = o, newEnc = n });
+        foreach (var multi in nestedEncodings)
+          AdaptEncodingOperators(multi.oldEnc, multi.newEnc);
+      }
+
+      var comparer = new TypeEqualityComparer<IOperator>();
+      var cloner = new Cloner();
+      var oldOperators = oldEncoding.Operators;
+      var newOperators = newEncoding.Operators;
+
+      cloner.RegisterClonedObject(oldEncoding, newEncoding);
+      var operators = oldOperators.Intersect(newOperators, comparer)
+                                  .Select(cloner.Clone)
+                                  .Union(newOperators, comparer).ToList();
+
+      newEncoding.ConfigureOperators(operators);
+      newEncoding.Operators = operators;
+    }
+
+    protected virtual void MultiEncodingOnEncodingsChanged(object sender, EventArgs e) {
+      OnOperatorsChanged();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Encoding.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Encoding.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Encoding.cs	(revision 12764)
@@ -0,0 +1,125 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("Encoding", "Base class for describing different encodings.")]
+  [StorableClass]
+  public abstract class Encoding<T> : ParameterizedNamedItem, IEncoding
+    where T : class,ISolutionCreator {
+    public override sealed bool CanChangeName {
+      get { return false; }
+    }
+
+    private ItemSet<IOperator> encodingOperators = new ItemSet<IOperator>(new TypeEqualityComparer<IOperator>());
+
+    [Storable(Name = "Operators")]
+    private IEnumerable<IOperator> StorableOperators {
+      get { return encodingOperators; }
+      set { encodingOperators = new ItemSet<IOperator>(value, new TypeEqualityComparer<IOperator>()); ; }
+    }
+
+    public IEnumerable<IOperator> Operators {
+      get { return encodingOperators; }
+      set {
+        if (!value.OfType<T>().Any())
+          throw new ArgumentException("The provided operators contain no suitable solution creator");
+        encodingOperators.Clear();
+        foreach (var op in value) encodingOperators.Add(op);
+
+        T newSolutionCreator = (T)encodingOperators.FirstOrDefault(o => o.GetType() == solutionCreator.GetType()) ??
+                               encodingOperators.OfType<T>().First();
+        SolutionCreator = newSolutionCreator;
+        OnOperatorsChanged();
+      }
+    }
+
+    ISolutionCreator IEncoding.SolutionCreator {
+      get { return SolutionCreator; }
+      set {
+        if (!(value is T)) throw new ArgumentException(string.Format("Cannot assign the solution creator {0} to the encoding {1}.", value.GetType().GetPrettyName(), GetType().GetPrettyName()));
+        SolutionCreator = (T)value;
+      }
+    }
+    private T solutionCreator;
+    public T SolutionCreator {
+      get {
+        return solutionCreator;
+      }
+      set {
+        if (value == null) throw new ArgumentNullException("SolutionCreator must not be null.");
+        if (solutionCreator == value) return;
+        encodingOperators.Remove(solutionCreator);
+        encodingOperators.Add(value);
+        solutionCreator = value;
+        OnSolutionCreatorChanged();
+      }
+    }
+
+    [StorableConstructor]
+    protected Encoding(bool deserializing) : base(deserializing) { }
+    protected Encoding(Encoding<T> original, Cloner cloner)
+      : base(original, cloner) {
+      encodingOperators = cloner.Clone(original.encodingOperators);
+      solutionCreator = cloner.Clone(original.solutionCreator);
+    }
+    protected Encoding(string name)
+      : base(name) {
+      Parameters.Add(new FixedValueParameter<ReadOnlyItemSet<IOperator>>(name + ".Operators", "The operators that the encoding specifies.", encodingOperators.AsReadOnly()));
+    }
+
+    public virtual Individual GetIndividual(IScope scope) {
+      return new SingleEncodingIndividual(this, scope);
+    }
+
+    protected bool AddOperator(IOperator @operator) {
+      return encodingOperators.Add(@operator);
+    }
+
+    protected bool RemoveOperator(IOperator @operator) {
+      return encodingOperators.Remove(@operator);
+    }
+
+    public void ConfigureOperator(IOperator @operator) { ConfigureOperators(new[] { @operator }); }
+    public abstract void ConfigureOperators(IEnumerable<IOperator> operators);
+
+    public event EventHandler SolutionCreatorChanged;
+    protected virtual void OnSolutionCreatorChanged() {
+      ConfigureOperator(SolutionCreator);
+      var handler = SolutionCreatorChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler OperatorsChanged;
+    protected virtual void OnOperatorsChanged() {
+      ConfigureOperators(Operators);
+      var handler = OperatorsChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Individuals/Individual.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Individuals/Individual.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Individuals/Individual.cs	(revision 12764)
@@ -0,0 +1,59 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  public abstract class Individual {
+    protected IEncoding Encoding { get; private set; }
+    protected IScope Scope { get; private set; }
+
+    public string Name { get { return Encoding.Name; } }
+
+    protected Individual(IEncoding encoding, IScope scope) {
+      Encoding = encoding;
+      Scope = scope;
+    }
+
+    public abstract IItem this[string name] { get; set; }
+    public abstract TEncoding GetEncoding<TEncoding>() where TEncoding : class, IEncoding;
+
+    public Individual Copy() {
+      return CopyToScope(new Scope());
+    }
+
+    public abstract Individual CopyToScope(IScope scope);
+
+    protected static IItem ExtractScopeValue(string name, IScope scope) {
+      if (!scope.Variables.ContainsKey(name)) throw new ArgumentException(string.Format(" {0} cannot be found in the provided scope.", name));
+      var value = scope.Variables[name].Value;
+      if (value == null) throw new InvalidOperationException(string.Format("Value of {0} is null.", name));
+      return value;
+    }
+
+    protected static void SetScopeValue(string name, IScope scope, IItem value) {
+      if (value == null) throw new ArgumentNullException("value");
+      if (!scope.Variables.ContainsKey(name)) scope.Variables.Add(new Variable(name, value));
+      else scope.Variables[name].Value = value;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Individuals/MultiEncodingIndividual.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Individuals/MultiEncodingIndividual.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Individuals/MultiEncodingIndividual.cs	(revision 12764)
@@ -0,0 +1,76 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  public sealed class MultiEncodingIndividual : Individual {
+    private new MultiEncoding Encoding {
+      get { return (MultiEncoding)base.Encoding; }
+    }
+
+    private readonly IEnumerable<Individual> individuals;
+
+    public MultiEncodingIndividual(MultiEncoding encoding, IScope scope)
+      : base(encoding, scope) {
+      individuals = encoding.Encodings.Select(e => e.GetIndividual(scope)).ToArray();
+    }
+
+    private MultiEncodingIndividual(MultiEncoding encoding, IScope scope, IEnumerable<Individual> individuals)
+      : base(encoding, scope) {
+      this.individuals = individuals;
+    }
+
+
+    public override IItem this[string name] {
+      get {
+        var individual = individuals.SingleOrDefault(i => i.Name == name);
+        if (individual == null) throw new ArgumentException(string.Format("{0} is not part of the specified encoding.", name));
+        return individual[name];
+      }
+      set {
+        var individual = individuals.SingleOrDefault(i => i.Name == name);
+        if (individual == null) throw new ArgumentException(string.Format("{0} is not part of the specified encoding.", name));
+        individual[name] = value;
+      }
+    }
+
+    public override TEncoding GetEncoding<TEncoding>() {
+      TEncoding encoding;
+      try {
+        encoding = (TEncoding)Encoding.Encodings.SingleOrDefault(e => e is TEncoding);
+      } catch (InvalidOperationException) {
+        throw new InvalidOperationException(string.Format("The individual uses multiple {0} .", typeof(TEncoding).GetPrettyName()));
+      }
+      if (encoding == null) throw new InvalidOperationException(string.Format("The individual does not use a {0}.", typeof(TEncoding).GetPrettyName()));
+      return encoding;
+    }
+
+    public override Individual CopyToScope(IScope scope) {
+      var copies = individuals.Select(i => i.CopyToScope(scope)).ToArray();
+      return new MultiEncodingIndividual(Encoding, scope, copies);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Individuals/SingleEncodingIndividual.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Individuals/SingleEncodingIndividual.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Individuals/SingleEncodingIndividual.cs	(revision 12764)
@@ -0,0 +1,57 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  public sealed class SingleEncodingIndividual : Individual {
+    public SingleEncodingIndividual(IEncoding encoding, IScope scope)
+      : base(encoding, scope) {
+      if (encoding is MultiEncoding) throw new ArgumentException("A MultiEncoding must not be used for the creation of a SingleEncodingIndividual");
+      if (!scope.Variables.ContainsKey(encoding.Name)) throw new ArgumentException("The provided scope does not contain an individual.");
+    }
+
+    public override IItem this[string name] {
+      get {
+        if (Name != name) throw new ArgumentException(string.Format("{0} is not part of the individual.", name));
+        return ExtractScopeValue(Name, Scope);
+      }
+      set {
+        if (Name != name) throw new ArgumentException(string.Format("{0} is not part of the individual.", name));
+        SetScopeValue(Name, Scope, value);
+      }
+    }
+
+    public override TEncoding GetEncoding<TEncoding>() {
+      TEncoding encoding = Encoding as TEncoding;
+      if (encoding == null) throw new InvalidOperationException(string.Format("The individual does not use a {0}.", typeof(TEncoding).GetPrettyName()));
+      return encoding;
+    }
+
+    public override Individual CopyToScope(IScope scope) {
+      SetScopeValue(Name, scope, (IItem)this[Name].Clone());
+      return new SingleEncodingIndividual(Encoding, scope);
+    }
+  }
+
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IEncoding.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IEncoding.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IEncoding.cs	(revision 12764)
@@ -0,0 +1,38 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  public interface IEncoding : IParameterizedNamedItem {
+    ISolutionCreator SolutionCreator { get; set; }
+    IEnumerable<IOperator> Operators { get; set; }
+
+    Individual GetIndividual(IScope scope);
+    void ConfigureOperator(IOperator @operator);
+    void ConfigureOperators(IEnumerable<IOperator> operators);
+
+    event EventHandler SolutionCreatorChanged;
+    event EventHandler OperatorsChanged;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IEncodingOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IEncodingOperator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IEncodingOperator.cs	(revision 12764)
@@ -0,0 +1,28 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  public interface IEncodingOperator : IOperator {
+    ILookupParameter<IEncoding> EncodingParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IMultiEncodingOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IMultiEncodingOperator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IMultiEncodingOperator.cs	(revision 12764)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  public interface IMultiEncodingOperator : IOperator {
+    void AddEncoding(IEncoding encoding);
+    bool RemoveEncoding(IEncoding encoding);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IMultiObjectiveProblemDefinition.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IMultiObjectiveProblemDefinition.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IMultiObjectiveProblemDefinition.cs	(revision 12764)
@@ -0,0 +1,30 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  public interface IMultiObjectiveProblemDefinition : IProblemDefinition {
+    bool[] Maximization { get; }
+    double[] Evaluate(Individual individual, IRandom random);
+    void Analyze(Individual[] individuals, double[][] qualities, ResultCollection results, IRandom random);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IProblemDefinition.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IProblemDefinition.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IProblemDefinition.cs	(revision 12764)
@@ -0,0 +1,26 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization {
+  public interface IProblemDefinition {
+    IEncoding Encoding { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/ISingleObjectiveMoveOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/ISingleObjectiveMoveOperator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/ISingleObjectiveMoveOperator.cs	(revision 12764)
@@ -0,0 +1,25 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization {
+  public interface ISingleObjectiveMoveOperator : IMoveOperator, ISingleObjectiveOperator {
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/ISingleObjectiveProblemDefinition.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/ISingleObjectiveProblemDefinition.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/ISingleObjectiveProblemDefinition.cs	(revision 12764)
@@ -0,0 +1,32 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  public interface ISingleObjectiveProblemDefinition : IProblemDefinition {
+    bool Maximization { get; }
+    double Evaluate(Individual individual, IRandom random);
+    void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random);
+    IEnumerable<Individual> GetNeighbors(Individual individual, IRandom random);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/internal/IMultiObjectiveAnalysisOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/internal/IMultiObjectiveAnalysisOperator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/internal/IMultiObjectiveAnalysisOperator.cs	(revision 12764)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  internal interface IMultiObjectiveAnalysisOperator : IEncodingOperator, IAnalyzer, IMultiObjectiveOperator {
+    Action<Individual[], double[][], ResultCollection, IRandom> AnalyzeAction { get; set; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/internal/IMultiObjectiveEvaluationOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/internal/IMultiObjectiveEvaluationOperator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/internal/IMultiObjectiveEvaluationOperator.cs	(revision 12764)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  internal interface IMultiObjectiveEvaluationOperator : IMultiObjectiveEvaluator, IEncodingOperator {
+    Func<Individual, IRandom, double[]> EvaluateFunc { get; set; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/internal/INeighborBasedOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/internal/INeighborBasedOperator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/internal/INeighborBasedOperator.cs	(revision 12764)
@@ -0,0 +1,30 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  internal interface INeighborBasedOperator : IEncodingOperator {
+    Func<Individual, IRandom, IEnumerable<Individual>> GetNeighborsFunc { get; set; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/internal/ISingleObjectiveAnalysisOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/internal/ISingleObjectiveAnalysisOperator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/internal/ISingleObjectiveAnalysisOperator.cs	(revision 12764)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  internal interface ISingleObjectiveAnalysisOperator : IEncodingOperator, ISingleObjectiveOperator {
+    Action<Individual[], double[], ResultCollection, IRandom> AnalyzeAction { get; set; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/internal/ISingleObjectiveEvaluationOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/internal/ISingleObjectiveEvaluationOperator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/internal/ISingleObjectiveEvaluationOperator.cs	(revision 12764)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  internal interface ISingleObjectiveEvaluationOperator : ISingleObjectiveEvaluator, IEncodingOperator {
+    Func<Individual, IRandom, double> EvaluateFunc { get; set; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/MultiEncoding.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/MultiEncoding.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/MultiEncoding.cs	(revision 12764)
@@ -0,0 +1,98 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Optimization {
+  [Item("MultiEncoding", "Describes a combined encoding consisting of multiple simpler encodings.")]
+  [StorableClass]
+  public sealed class MultiEncoding : Encoding<MultiEncodingCreator> {
+
+    private readonly List<IEncoding> encodings;
+    [Storable]
+    public IEnumerable<IEncoding> Encodings {
+      get { return encodings; }
+      private set { encodings.AddRange(value); }
+    }
+
+    [StorableConstructor]
+    private MultiEncoding(bool deserializing)
+      : base(deserializing) {
+      encodings = new List<IEncoding>();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) { return new MultiEncoding(this, cloner); }
+    private MultiEncoding(MultiEncoding original, Cloner cloner)
+      : base(original, cloner) {
+      encodings = new List<IEncoding>(original.Encodings.Select(cloner.Clone));
+    }
+    public MultiEncoding()
+      : base("MultiEncoding") {
+      encodings = new List<IEncoding>();
+      SolutionCreator = new MultiEncodingCreator();
+
+      foreach (var @operator in ApplicationManager.Manager.GetInstances<IMultiEncodingOperator>())
+        AddOperator(@operator);
+    }
+
+    public override Individual GetIndividual(IScope scope) {
+      return new MultiEncodingIndividual(this, scope);
+    }
+
+    public MultiEncoding Add(IEncoding encoding) {
+      if (encoding is MultiEncoding) throw new InvalidOperationException("Nesting of MultiEncodings is not supported.");
+      if (Encodings.Any(e => e.Name == encoding.Name)) throw new ArgumentException("Encoding name must be unique", "encoding.Name");
+      encodings.Add(encoding);
+
+      Parameters.AddRange(encoding.Parameters);
+
+      foreach (var @operator in Operators.OfType<IMultiEncodingOperator>()) {
+        @operator.AddEncoding(encoding);
+      }
+      OnEncodingsChanged();
+      return this;
+    }
+
+    public bool Remove(IEncoding encoding) {
+      var success = encodings.Remove(encoding);
+      Parameters.RemoveRange(encoding.Parameters);
+      foreach (var @operator in Operators.OfType<IMultiEncodingOperator>()) {
+        @operator.RemoveEncoding(encoding);
+      }
+      OnEncodingsChanged();
+      return success;
+    }
+
+    public override void ConfigureOperators(IEnumerable<IOperator> operators) {
+    }
+
+    public event EventHandler EncodingsChanged;
+    private void OnEncodingsChanged() {
+      var handler = EncodingsChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/MultiObjectiveBasicProblem.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/MultiObjectiveBasicProblem.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/MultiObjectiveBasicProblem.cs	(revision 12764)
@@ -0,0 +1,100 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [StorableClass]
+  public abstract class MultiObjectiveBasicProblem<TEncoding> : BasicProblem<TEncoding, MultiObjectiveEvaluator>, IMultiObjectiveHeuristicOptimizationProblem, IMultiObjectiveProblemDefinition
+  where TEncoding : class, IEncoding {
+    [StorableConstructor]
+    protected MultiObjectiveBasicProblem(bool deserializing) : base(deserializing) { }
+
+    protected MultiObjectiveBasicProblem(MultiObjectiveBasicProblem<TEncoding> original, Cloner cloner)
+      : base(original, cloner) {
+      ParameterizeOperators();
+    }
+
+    protected MultiObjectiveBasicProblem()
+      : base() {
+      Parameters.Add(new ValueParameter<BoolArray>("Maximization", "Set to false if the problem should be minimized.", (BoolArray)new BoolArray(Maximization).AsReadOnly()));
+
+      Operators.Add(Evaluator);
+      Operators.Add(new MultiObjectiveAnalyzer());
+
+      ParameterizeOperators();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      ParameterizeOperators();
+    }
+
+    public abstract bool[] Maximization { get; }
+    public abstract double[] Evaluate(Individual individual, IRandom random);
+    public virtual void Analyze(Individual[] individuals, double[][] qualities, ResultCollection results, IRandom random) { }
+
+    protected override void OnOperatorsChanged() {
+      base.OnOperatorsChanged();
+      if (Encoding != null) {
+        PruneSingleObjectiveOperators(Encoding);
+        var multiEncoding = Encoding as MultiEncoding;
+        if (multiEncoding != null) {
+          foreach (var encoding in multiEncoding.Encodings.ToList()) {
+            PruneSingleObjectiveOperators(encoding);
+          }
+        }
+      }
+    }
+
+    private void PruneSingleObjectiveOperators(IEncoding encoding) {
+      if (encoding != null && encoding.Operators.Any(x => x is ISingleObjectiveOperator && !(x is IMultiObjectiveOperator)))
+        encoding.Operators = encoding.Operators.Where(x => !(x is ISingleObjectiveOperator) || x is IMultiObjectiveOperator).ToList();
+    }
+
+    protected override void OnEvaluatorChanged() {
+      base.OnEvaluatorChanged();
+      ParameterizeOperators();
+    }
+
+    private void ParameterizeOperators() {
+      foreach (var op in Operators.OfType<IMultiObjectiveEvaluationOperator>())
+        op.EvaluateFunc = Evaluate;
+      foreach (var op in Operators.OfType<IMultiObjectiveAnalysisOperator>())
+        op.AnalyzeAction = Analyze;
+    }
+
+
+    #region IMultiObjectiveHeuristicOptimizationProblem Members
+    IParameter IMultiObjectiveHeuristicOptimizationProblem.MaximizationParameter {
+      get { return Parameters["Maximization"]; }
+    }
+    IMultiObjectiveEvaluator IMultiObjectiveHeuristicOptimizationProblem.Evaluator {
+      get { return Evaluator; }
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiEncodingCreator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiEncodingCreator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiEncodingCreator.cs	(revision 12764)
@@ -0,0 +1,65 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("MultiEncodingCreator", "Contains solution creators that together create a multi-encoding.")]
+  [StorableClass]
+  public sealed class MultiEncodingCreator : MultiEncodingOperator<ISolutionCreator>, ISolutionCreator {
+    [StorableConstructor]
+    private MultiEncodingCreator(bool deserializing) : base(deserializing) { }
+
+    private MultiEncodingCreator(MultiEncodingCreator original, Cloner cloner) : base(original, cloner) { }
+    public MultiEncodingCreator() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MultiEncodingCreator(this, cloner);
+    }
+
+    public override void AddEncoding(IEncoding encoding) {
+      base.AddEncoding(encoding);
+      var parameter = GetParameter(encoding);
+      parameter.Value = encoding.SolutionCreator;
+      encoding.SolutionCreatorChanged += Encoding_SolutionCreatorChanged;
+    }
+
+    public override bool RemoveEncoding(IEncoding encoding) {
+      var success = base.RemoveEncoding(encoding);
+      encoding.SolutionCreatorChanged -= Encoding_SolutionCreatorChanged;
+      return success;
+    }
+
+    private void Encoding_SolutionCreatorChanged(object sender, EventArgs e) {
+      var encoding = (IEncoding)sender;
+      var parameter = GetParameter(encoding);
+
+      var oldCreator = parameter.ValidValues.Single(creator => creator.GetType() == encoding.SolutionCreator.GetType());
+      parameter.ValidValues.Remove(oldCreator);
+      parameter.ValidValues.Add(encoding.SolutionCreator);
+      parameter.Value = encoding.SolutionCreator;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiEncodingCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiEncodingCrossover.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiEncodingCrossover.cs	(revision 12764)
@@ -0,0 +1,37 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("MultiEncoding Crossover", "Applies different crossovers to cross a multi-encoding.")]
+  [StorableClass]
+  public sealed class MultiEncodingCrossover : MultiEncodingOperator<ICrossover>, ICrossover {
+    [StorableConstructor]
+    private MultiEncodingCrossover(bool deserializing) : base(deserializing) { }
+    private MultiEncodingCrossover(MultiEncodingCrossover original, Cloner cloner) : base(original, cloner) { }
+    public MultiEncodingCrossover() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) { return new MultiEncodingCrossover(this, cloner); }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiEncodingManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiEncodingManipulator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiEncodingManipulator.cs	(revision 12764)
@@ -0,0 +1,39 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("MultiEncoding Manipulator", "Applies different manipulators to change a multi-encoding.")]
+  [StorableClass]
+  public sealed class MultiEncodingManipulator : MultiEncodingOperator<IManipulator>, IManipulator {
+    [StorableConstructor]
+    private MultiEncodingManipulator(bool deserializing) : base(deserializing) { }
+    private MultiEncodingManipulator(MultiEncodingManipulator original, Cloner cloner)
+      : base(original, cloner) { }
+    public MultiEncodingManipulator() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) { return new MultiEncodingManipulator(this, cloner); }
+
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiEncodingOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiEncodingOperator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiEncodingOperator.cs	(revision 12764)
@@ -0,0 +1,104 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [StorableClass]
+  public abstract class MultiEncodingOperator<T> : Operator, IMultiEncodingOperator where T : class,IOperator {
+    private List<IEncoding> encodings = new List<IEncoding>();
+    [Storable(Name = "Encodings")]
+    private IEnumerable<IEncoding> StorableEncodings {
+      get { return encodings; }
+      set { encodings = new List<IEncoding>(value); }
+    }
+
+    [StorableConstructor]
+    protected MultiEncodingOperator(bool deserializing)
+      : base(deserializing) {
+    }
+
+    protected MultiEncodingOperator(MultiEncodingOperator<T> original, Cloner cloner)
+      : base(original, cloner) {
+      encodings = new List<IEncoding>(original.encodings.Select(cloner.Clone));
+      foreach (var encoding in encodings)
+        encoding.OperatorsChanged += Encoding_OperatorsChanged;
+    }
+
+    protected MultiEncodingOperator() : base() { }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      foreach (var encoding in encodings)
+        encoding.OperatorsChanged += Encoding_OperatorsChanged;
+    }
+
+
+    public override IOperation Apply() {
+      var operations = Parameters.Select(p => p.ActualValue).OfType<IOperator>().Select(op => ExecutionContext.CreateOperation(op));
+      return new OperationCollection(operations);
+    }
+
+    public virtual void AddEncoding(IEncoding encoding) {
+      if (Parameters.ContainsKey(encoding.Name)) throw new ArgumentException(string.Format("Encoding {0} was already added.", encoding.Name));
+
+      encodings.Add(encoding);
+      encoding.OperatorsChanged += Encoding_OperatorsChanged;
+
+      var param = new ConstrainedValueParameter<T>(encoding.Name, new ItemSet<T>(encoding.Operators.OfType<T>()));
+      param.Value = param.ValidValues.First();
+      Parameters.Add(param);
+    }
+
+    public virtual bool RemoveEncoding(IEncoding encoding) {
+      if (!encodings.Remove(encoding)) throw new ArgumentException(string.Format("Encoding {0} was not added to the MultiEncoding.", encoding.Name));
+      encoding.OperatorsChanged -= Encoding_OperatorsChanged;
+      return Parameters.Remove(encoding.Name);
+    }
+
+    protected IConstrainedValueParameter<T> GetParameter(IEncoding encoding) {
+      if (!Parameters.ContainsKey(encoding.Name)) throw new ArgumentException(string.Format("Encoding {0} was not added to the MultiEncoding.", encoding.Name));
+
+      return (IConstrainedValueParameter<T>)Parameters[encoding.Name];
+    }
+
+    private void Encoding_OperatorsChanged(object sender, EventArgs e) {
+      var encoding = (IEncoding)sender;
+      var param = GetParameter(encoding);
+
+      var oldParameterValue = param.Value;
+      param.ValidValues.Clear();
+      foreach (var op in encoding.Operators.OfType<T>())
+        param.ValidValues.Add(op);
+
+      var newValue = param.ValidValues.FirstOrDefault(op => op.GetType() == oldParameterValue.GetType());
+      if (newValue == null) newValue = param.ValidValues.First();
+      param.Value = newValue;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiObjectiveAnalyzer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiObjectiveAnalyzer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiObjectiveAnalyzer.cs	(revision 12764)
@@ -0,0 +1,84 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("Multi-objective Analyzer", "Calls the Analyze method of the problem definition.")]
+  [StorableClass]
+  public class MultiObjectiveAnalyzer : SingleSuccessorOperator, IMultiObjectiveAnalysisOperator, IStochasticOperator {
+    public bool EnabledByDefault { get { return true; } }
+
+    public ILookupParameter<IEncoding> EncodingParameter {
+      get { return (ILookupParameter<IEncoding>)Parameters["Encoding"]; }
+    }
+
+    public IScopeTreeLookupParameter<DoubleArray> QualitiesParameter {
+      get { return (IScopeTreeLookupParameter<DoubleArray>)Parameters["Qualities"]; }
+    }
+
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    public Action<Individual[], double[][], ResultCollection, IRandom> AnalyzeAction { get; set; }
+
+    [StorableConstructor]
+    protected MultiObjectiveAnalyzer(bool deserializing) : base(deserializing) { }
+    protected MultiObjectiveAnalyzer(MultiObjectiveAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public MultiObjectiveAnalyzer() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+      Parameters.Add(new LookupParameter<IEncoding>("Encoding", "An item that holds the problem's encoding."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleArray>("Qualities", "The qualities of the parameter vector."));
+      Parameters.Add(new LookupParameter<ResultCollection>("Results", "The results collection to write to."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MultiObjectiveAnalyzer(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var encoding = EncodingParameter.ActualValue;
+      var results = ResultsParameter.ActualValue;
+      var random = RandomParameter.ActualValue;
+
+      IEnumerable<IScope> scopes = new[] { ExecutionContext.Scope };
+      for (var i = 0; i < QualitiesParameter.Depth; i++)
+        scopes = scopes.Select(x => (IEnumerable<IScope>)x.SubScopes).Aggregate((a, b) => a.Concat(b));
+
+      var individuals = scopes.Select(encoding.GetIndividual).ToArray();
+      AnalyzeAction(individuals, QualitiesParameter.ActualValue.Select(x => x.ToArray()).ToArray(), results, random);
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiObjectiveEvaluator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiObjectiveEvaluator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/MultiObjectiveEvaluator.cs	(revision 12764)
@@ -0,0 +1,70 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("Multi-objective Evaluator", "Calls the Evaluate method of the problem definition and writes the return value into the scope.")]
+  [StorableClass]
+  public class MultiObjectiveEvaluator : InstrumentedOperator, IMultiObjectiveEvaluationOperator, IStochasticOperator {
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    public ILookupParameter<IEncoding> EncodingParameter {
+      get { return (ILookupParameter<IEncoding>)Parameters["Encoding"]; }
+    }
+
+    public ILookupParameter<DoubleArray> QualitiesParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Qualities"]; }
+    }
+
+    public Func<Individual, IRandom, double[]> EvaluateFunc { get; set; }
+
+    [StorableConstructor]
+    protected MultiObjectiveEvaluator(bool deserializing) : base(deserializing) { }
+    protected MultiObjectiveEvaluator(MultiObjectiveEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public MultiObjectiveEvaluator() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+      Parameters.Add(new LookupParameter<IEncoding>("Encoding", "An item that holds the problem's encoding."));
+      Parameters.Add(new LookupParameter<DoubleArray>("Qualities", "The qualities of the parameter vector."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MultiObjectiveEvaluator(this, cloner);
+    }
+
+    public override IOperation InstrumentedApply() {
+      var random = RandomParameter.ActualValue;
+      var encoding = EncodingParameter.ActualValue;
+      var individual = encoding.GetIndividual(ExecutionContext.Scope);
+      QualitiesParameter.ActualValue = new DoubleArray(EvaluateFunc(individual, random));
+      return base.InstrumentedApply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveAnalyzer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveAnalyzer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveAnalyzer.cs	(revision 12764)
@@ -0,0 +1,84 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("Single-objective Analyzer", "Calls the script's Analyze method to be able to write into the results collection.")]
+  [StorableClass]
+  public sealed class SingleObjectiveAnalyzer : SingleSuccessorOperator, ISingleObjectiveAnalysisOperator, IAnalyzer, IStochasticOperator {
+    public bool EnabledByDefault { get { return true; } }
+
+    public ILookupParameter<IEncoding> EncodingParameter {
+      get { return (ILookupParameter<IEncoding>)Parameters["Encoding"]; }
+    }
+
+    public IScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    public Action<Individual[], double[], ResultCollection, IRandom> AnalyzeAction { get; set; }
+
+    [StorableConstructor]
+    private SingleObjectiveAnalyzer(bool deserializing) : base(deserializing) { }
+    private SingleObjectiveAnalyzer(SingleObjectiveAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public SingleObjectiveAnalyzer() {
+      Parameters.Add(new LookupParameter<IEncoding>("Encoding", "An item that holds the problem's encoding."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The quality of the parameter vector."));
+      Parameters.Add(new LookupParameter<ResultCollection>("Results", "The results collection to write to."));
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SingleObjectiveAnalyzer(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var encoding = EncodingParameter.ActualValue;
+      var results = ResultsParameter.ActualValue;
+      var random = RandomParameter.ActualValue;
+
+      IEnumerable<IScope> scopes = new[] { ExecutionContext.Scope };
+      for (var i = 0; i < QualityParameter.Depth; i++)
+        scopes = scopes.Select(x => (IEnumerable<IScope>)x.SubScopes).Aggregate((a, b) => a.Concat(b));
+
+      var individuals = scopes.Select(encoding.GetIndividual).ToArray();
+      AnalyzeAction(individuals, QualityParameter.ActualValue.Select(x => x.Value).ToArray(), results, random);
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveEvaluator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveEvaluator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveEvaluator.cs	(revision 12764)
@@ -0,0 +1,68 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("Single-objective Evaluator", "Calls the script's Evaluate method to get the quality value of the parameter vector.")]
+  [StorableClass]
+  public sealed class SingleObjectiveEvaluator : InstrumentedOperator, ISingleObjectiveEvaluationOperator, IStochasticOperator {
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    public ILookupParameter<IEncoding> EncodingParameter {
+      get { return (ILookupParameter<IEncoding>)Parameters["Encoding"]; }
+    }
+
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+
+    public Func<Individual, IRandom, double> EvaluateFunc { get; set; }
+
+    [StorableConstructor]
+    private SingleObjectiveEvaluator(bool deserializing) : base(deserializing) { }
+    private SingleObjectiveEvaluator(SingleObjectiveEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public SingleObjectiveEvaluator() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+      Parameters.Add(new LookupParameter<IEncoding>("Encoding", "An item that holds the problem's encoding."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of the parameter vector."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) { return new SingleObjectiveEvaluator(this, cloner); }
+
+    public override IOperation InstrumentedApply() {
+      var random = RandomParameter.ActualValue;
+      var encoding = EncodingParameter.ActualValue;
+      var individual = encoding.GetIndividual(ExecutionContext.Scope);
+      QualityParameter.ActualValue = new DoubleValue(EvaluateFunc(individual, random));
+      return base.InstrumentedApply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveImprover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveImprover.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveImprover.cs	(revision 12764)
@@ -0,0 +1,115 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("Single-objective Improver", "Improves a solution by calling GetNeighbors and Evaluate of the corresponding problem definition.")]
+  [StorableClass]
+  public sealed class SingleObjectiveImprover : SingleSuccessorOperator, INeighborBasedOperator, IImprovementOperator, ISingleObjectiveEvaluationOperator, IStochasticOperator {
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    public ILookupParameter<IEncoding> EncodingParameter {
+      get { return (ILookupParameter<IEncoding>)Parameters["Encoding"]; }
+    }
+
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+
+    public IValueLookupParameter<IntValue> ImprovementAttemptsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["ImprovementAttempts"]; }
+    }
+
+    public IValueLookupParameter<IntValue> SampleSizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["SampleSize"]; }
+    }
+
+    public ILookupParameter<IntValue> LocalEvaluatedSolutionsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["LocalEvaluatedSolutions"]; }
+    }
+
+    public Func<Individual, IRandom, double> EvaluateFunc { get; set; }
+    public Func<Individual, IRandom, IEnumerable<Individual>> GetNeighborsFunc { get; set; }
+
+    [StorableConstructor]
+    private SingleObjectiveImprover(bool deserializing) : base(deserializing) { }
+    private SingleObjectiveImprover(SingleObjectiveImprover original, Cloner cloner) : base(original, cloner) { }
+    public SingleObjectiveImprover() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+      Parameters.Add(new LookupParameter<IEncoding>("Encoding", "An item that holds the problem's encoding."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of the parameter vector."));
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "Whether the problem should be minimized or maximized."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("ImprovementAttempts", "The number of improvement attempts the operator should perform.", new IntValue(100)));
+      Parameters.Add(new ValueLookupParameter<IntValue>("SampleSize", "The number of samples to draw from the neighborhood function at maximum.", new IntValue(300)));
+      Parameters.Add(new LookupParameter<IntValue>("LocalEvaluatedSolutions", "The number of solution evaluations that have been performed."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SingleObjectiveImprover(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var random = RandomParameter.ActualValue;
+      var encoding = EncodingParameter.ActualValue;
+      var maximize = MaximizationParameter.ActualValue.Value;
+      var maxAttempts = ImprovementAttemptsParameter.ActualValue.Value;
+      var sampleSize = SampleSizeParameter.ActualValue.Value;
+      var individual = encoding.GetIndividual(ExecutionContext.Scope);
+      var quality = QualityParameter.ActualValue == null ? EvaluateFunc(individual, random) : QualityParameter.ActualValue.Value;
+
+      var count = 0;
+      for (var i = 0; i < maxAttempts; i++) {
+        Individual best = null;
+        var bestQuality = quality;
+        foreach (var neighbor in GetNeighborsFunc(individual, random).Take(sampleSize)) {
+          var q = EvaluateFunc(neighbor, random);
+          count++;
+          if (maximize && bestQuality > q || !maximize && bestQuality < q) continue;
+          best = neighbor;
+          bestQuality = q;
+        }
+        if (best == null) break;
+        individual = best;
+        quality = bestQuality;
+      }
+
+      LocalEvaluatedSolutionsParameter.ActualValue = new IntValue(count);
+      QualityParameter.ActualValue = new DoubleValue(quality);
+      individual.CopyToScope(ExecutionContext.Scope);
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveMoveEvaluator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveMoveEvaluator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveMoveEvaluator.cs	(revision 12764)
@@ -0,0 +1,75 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("Single-objective MoveEvaluator", "Evaluates a parameter vector that results from a move.")]
+  [StorableClass]
+  public class SingleObjectiveMoveEvaluator : SingleSuccessorOperator, ISingleObjectiveEvaluationOperator, ISingleObjectiveMoveEvaluator, IStochasticOperator, ISingleObjectiveMoveOperator {
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    public ILookupParameter<IEncoding> EncodingParameter {
+      get { return (ILookupParameter<IEncoding>)Parameters["Encoding"]; }
+    }
+
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+
+    public ILookupParameter<DoubleValue> MoveQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
+    }
+
+    public Func<Individual, IRandom, double> EvaluateFunc { get; set; }
+
+    [StorableConstructor]
+    protected SingleObjectiveMoveEvaluator(bool deserializing) : base(deserializing) { }
+    protected SingleObjectiveMoveEvaluator(SingleObjectiveMoveEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public SingleObjectiveMoveEvaluator() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+      Parameters.Add(new LookupParameter<IEncoding>("Encoding", "An item that holds the problem's encoding."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of the parameter vector."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The quality of the move."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SingleObjectiveMoveEvaluator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var random = RandomParameter.ActualValue;
+      var encoding = EncodingParameter.ActualValue;
+      var individual = encoding.GetIndividual(ExecutionContext.Scope);
+      MoveQualityParameter.ActualValue = new DoubleValue(EvaluateFunc(individual, random));
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveMoveGenerator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveMoveGenerator.cs	(revision 12764)
@@ -0,0 +1,82 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("Single-objective MoveGenerator", "Calls the GetNeighbors method of the problem definition to obtain the moves.")]
+  [StorableClass]
+  public class SingleObjectiveMoveGenerator : SingleSuccessorOperator, INeighborBasedOperator, IMultiMoveGenerator, IStochasticOperator, ISingleObjectiveMoveOperator {
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    public IValueLookupParameter<IntValue> SampleSizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["SampleSize"]; }
+    }
+
+    public ILookupParameter<IEncoding> EncodingParameter {
+      get { return (ILookupParameter<IEncoding>)Parameters["Encoding"]; }
+    }
+
+    public Func<Individual, IRandom, IEnumerable<Individual>> GetNeighborsFunc { get; set; }
+
+    [StorableConstructor]
+    protected SingleObjectiveMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected SingleObjectiveMoveGenerator(SingleObjectiveMoveGenerator original, Cloner cloner)
+      : base(original, cloner) { }
+    public SingleObjectiveMoveGenerator() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("SampleSize", "The number of moves to sample."));
+      Parameters.Add(new LookupParameter<IEncoding>("Encoding", "An item that holds the problem's encoding."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SingleObjectiveMoveGenerator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var random = RandomParameter.ActualValue;
+      var sampleSize = SampleSizeParameter.ActualValue.Value;
+      var encoding = EncodingParameter.ActualValue;
+      var individual = encoding.GetIndividual(ExecutionContext.Scope);
+      var nbhood = GetNeighborsFunc(individual, random).Take(sampleSize).ToList();
+
+      var moveScopes = new Scope[nbhood.Count];
+      for (int i = 0; i < moveScopes.Length; i++) {
+        moveScopes[i] = new Scope(i.ToString(CultureInfo.InvariantCulture.NumberFormat));
+        nbhood[i].CopyToScope(moveScopes[i]);
+      }
+      ExecutionContext.Scope.SubScopes.AddRange(moveScopes);
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveMoveMaker.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveMoveMaker.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveMoveMaker.cs	(revision 12764)
@@ -0,0 +1,72 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("Single-objective MoveMaker", "Applies a move.")]
+  [StorableClass]
+  public class SingleObjectiveMoveMaker : InstrumentedOperator, IMoveMaker, ISingleObjectiveMoveOperator {
+    public ILookupParameter<IEncoding> EncodingParameter {
+      get { return (ILookupParameter<IEncoding>)Parameters["Encoding"]; }
+    }
+
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+
+    public ILookupParameter<DoubleValue> MoveQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
+    }
+
+    [StorableConstructor]
+    protected SingleObjectiveMoveMaker(bool deserializing) : base(deserializing) { }
+    protected SingleObjectiveMoveMaker(SingleObjectiveMoveMaker original, Cloner cloner) : base(original, cloner) { }
+    public SingleObjectiveMoveMaker() {
+      Parameters.Add(new LookupParameter<IEncoding>("Encoding", "An item that holds the problem's encoding."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of the parameter vector."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The quality of the move."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SingleObjectiveMoveMaker(this, cloner);
+    }
+
+    public override IOperation InstrumentedApply() {
+      if (MoveQualityParameter.ActualValue == null) throw new InvalidOperationException("Move has not been evaluated!");
+
+      var encoding = EncodingParameter.ActualValue;
+      var individual = encoding.GetIndividual(ExecutionContext.Scope);
+      individual.CopyToScope(ExecutionContext.Scope.Parent.Parent);
+
+      if (QualityParameter.ActualValue == null) QualityParameter.ActualValue = new DoubleValue(MoveQualityParameter.ActualValue.Value);
+      else QualityParameter.ActualValue.Value = MoveQualityParameter.ActualValue.Value;
+
+      return base.InstrumentedApply();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/SingleObjectiveBasicProblem.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/SingleObjectiveBasicProblem.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/BasicProblems/SingleObjectiveBasicProblem.cs	(revision 12764)
@@ -0,0 +1,130 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [StorableClass]
+  public abstract class SingleObjectiveBasicProblem<TEncoding> : BasicProblem<TEncoding, SingleObjectiveEvaluator>,
+    ISingleObjectiveProblemDefinition, ISingleObjectiveHeuristicOptimizationProblem
+  where TEncoding : class, IEncoding {
+
+    protected IValueParameter<DoubleValue> BestKnownQualityParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
+    }
+
+    public double BestKnownQuality {
+      get {
+        if (BestKnownQualityParameter.Value == null) return double.NaN;
+        return BestKnownQualityParameter.Value.Value;
+      }
+      set {
+        if (BestKnownQualityParameter.Value == null) BestKnownQualityParameter.Value = new DoubleValue(value);
+        else BestKnownQualityParameter.Value.Value = value;
+      }
+    }
+
+    [StorableConstructor]
+    protected SingleObjectiveBasicProblem(bool deserializing) : base(deserializing) { }
+
+    protected SingleObjectiveBasicProblem(SingleObjectiveBasicProblem<TEncoding> original, Cloner cloner)
+      : base(original, cloner) {
+      ParameterizeOperators();
+    }
+
+    protected SingleObjectiveBasicProblem()
+      : base() {
+      Parameters.Add(new FixedValueParameter<BoolValue>("Maximization", "Set to false if the problem should be minimized.", (BoolValue)new BoolValue(Maximization).AsReadOnly()) { Hidden = true });
+      Parameters.Add(new OptionalValueParameter<DoubleValue>("BestKnownQuality", "The quality of the best known solution of this problem."));
+
+      Operators.Add(Evaluator);
+      Operators.Add(new SingleObjectiveAnalyzer());
+      Operators.Add(new SingleObjectiveImprover());
+      Operators.Add(new SingleObjectiveMoveEvaluator());
+      Operators.Add(new SingleObjectiveMoveGenerator());
+      Operators.Add(new SingleObjectiveMoveMaker());
+
+      ParameterizeOperators();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      ParameterizeOperators();
+    }
+
+    public abstract bool Maximization { get; }
+    public abstract double Evaluate(Individual individual, IRandom random);
+    public virtual void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random) { }
+    public virtual IEnumerable<Individual> GetNeighbors(Individual individual, IRandom random) {
+      return Enumerable.Empty<Individual>();
+    }
+
+    protected override void OnOperatorsChanged() {
+      base.OnOperatorsChanged();
+      if (Encoding != null) {
+        PruneMultiObjectiveOperators(Encoding);
+        var multiEncoding = Encoding as MultiEncoding;
+        if (multiEncoding != null) {
+          foreach (var encoding in multiEncoding.Encodings.ToList()) {
+            PruneMultiObjectiveOperators(encoding);
+          }
+        }
+      }
+    }
+
+    private void PruneMultiObjectiveOperators(IEncoding encoding) {
+      if (encoding.Operators.Any(x => x is IMultiObjectiveOperator && !(x is ISingleObjectiveOperator)))
+        encoding.Operators = encoding.Operators.Where(x => !(x is IMultiObjectiveOperator) || x is ISingleObjectiveOperator).ToList();
+    }
+
+    protected override void OnEvaluatorChanged() {
+      base.OnEvaluatorChanged();
+      ParameterizeOperators();
+    }
+
+    private void ParameterizeOperators() {
+      foreach (var op in Operators.OfType<ISingleObjectiveEvaluationOperator>())
+        op.EvaluateFunc = Evaluate;
+      foreach (var op in Operators.OfType<ISingleObjectiveAnalysisOperator>())
+        op.AnalyzeAction = Analyze;
+      foreach (var op in Operators.OfType<INeighborBasedOperator>())
+        op.GetNeighborsFunc = GetNeighbors;
+    }
+
+    #region ISingleObjectiveHeuristicOptimizationProblem Members
+    IParameter ISingleObjectiveHeuristicOptimizationProblem.MaximizationParameter {
+      get { return Parameters["Maximization"]; }
+    }
+    IParameter ISingleObjectiveHeuristicOptimizationProblem.BestKnownQualityParameter {
+      get { return Parameters["BestKnownQuality"]; }
+    }
+    ISingleObjectiveEvaluator ISingleObjectiveHeuristicOptimizationProblem.Evaluator {
+      get { return Evaluator; }
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 12764)
@@ -0,0 +1,345 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{14AB8D24-25BC-400C-A846-4627AA945192}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Optimization</RootNamespace>
+    <AssemblyName>HeuristicLab.Optimization-3.3</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation />
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>
+    </DocumentationFile>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <ItemGroup>
+    <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, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <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, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core-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.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+      <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\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+      <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\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+      <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\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Algorithms\BasicAlgorithm.cs" />
+    <Compile Include="BasicProblems\BasicProblem.cs" />
+    <Compile Include="BasicProblems\Encoding.cs" />
+    <Compile Include="BasicProblems\Individuals\Individual.cs" />
+    <Compile Include="BasicProblems\Individuals\MultiEncodingIndividual.cs" />
+    <Compile Include="BasicProblems\Individuals\SingleEncodingIndividual.cs" />
+    <Compile Include="BasicProblems\Interfaces\IEncoding.cs" />
+    <Compile Include="BasicProblems\Interfaces\IEncodingOperator.cs" />
+    <Compile Include="BasicProblems\Interfaces\IMultiEncodingOperator.cs" />
+    <Compile Include="BasicProblems\Interfaces\IMultiObjectiveProblemDefinition.cs" />
+    <Compile Include="BasicProblems\Interfaces\internal\IMultiObjectiveAnalysisOperator.cs" />
+    <Compile Include="BasicProblems\Interfaces\internal\IMultiObjectiveEvaluationOperator.cs" />
+    <Compile Include="BasicProblems\Interfaces\internal\INeighborBasedOperator.cs" />
+    <Compile Include="BasicProblems\Interfaces\internal\ISingleObjectiveAnalysisOperator.cs" />
+    <Compile Include="BasicProblems\Interfaces\internal\ISingleObjectiveEvaluationOperator.cs" />
+    <Compile Include="BasicProblems\Interfaces\IProblemDefinition.cs" />
+    <Compile Include="BasicProblems\Interfaces\ISingleObjectiveMoveOperator.cs" />
+    <Compile Include="BasicProblems\Interfaces\ISingleObjectiveProblemDefinition.cs" />
+    <Compile Include="BasicProblems\MultiEncoding.cs" />
+    <Compile Include="BasicProblems\MultiObjectiveBasicProblem.cs" />
+    <Compile Include="BasicProblems\Operators\MultiEncodingCreator.cs" />
+    <Compile Include="BasicProblems\Operators\MultiEncodingCrossover.cs" />
+    <Compile Include="BasicProblems\Operators\MultiEncodingManipulator.cs" />
+    <Compile Include="BasicProblems\Operators\MultiEncodingOperator.cs" />
+    <Compile Include="BasicProblems\Operators\MultiObjectiveAnalyzer.cs" />
+    <Compile Include="BasicProblems\Operators\MultiObjectiveEvaluator.cs" />
+    <Compile Include="BasicProblems\Operators\SingleObjectiveAnalyzer.cs" />
+    <Compile Include="BasicProblems\Operators\SingleObjectiveEvaluator.cs" />
+    <Compile Include="BasicProblems\Operators\SingleObjectiveImprover.cs" />
+    <Compile Include="BasicProblems\Operators\SingleObjectiveMoveEvaluator.cs" />
+    <Compile Include="BasicProblems\Operators\SingleObjectiveMoveGenerator.cs" />
+    <Compile Include="BasicProblems\Operators\SingleObjectiveMoveMaker.cs" />
+    <Compile Include="BasicProblems\SingleObjectiveBasicProblem.cs" />
+    <Compile Include="Interfaces\ILocalImprovementAlgorithmOperator.cs" />
+    <Compile Include="Interfaces\IMultiObjectiveOperator.cs" />
+    <Compile Include="Results\IResultParameter.cs" />
+    <Compile Include="Interfaces\ISingleObjectiveOperator.cs" />
+    <Compile Include="Interfaces\ISingleObjectivePathRelinker.cs" />
+    <Compile Include="Interfaces\ISingleObjectiveImprovementOperator.cs" />
+    <Compile Include="Interfaces\ISingleObjectiveSolutionSimilarityCalculator.cs" />
+    <Compile Include="Interfaces\IImprovementOperator.cs" />
+    <Compile Include="Interfaces\IPathRelinker.cs" />
+    <Compile Include="Interfaces\ISimilarityBasedOperator.cs" />
+    <Compile Include="Interfaces\ISolutionSimilarityCalculator.cs" />
+    <Compile Include="MetaOptimizers\BatchRun.cs" />
+    <Compile Include="MetaOptimizers\Experiment.cs" />
+    <Compile Include="MetaOptimizers\TimeLimitRun.cs" />
+    <Compile Include="Results\ResultParameter.cs" />
+    <Compile Include="RunCollectionModification\RunCollectionRunRemover.cs" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="RunCollectionModification\RunCollectionDiscretizer.cs" />
+    <Compile Include="RunCollectionModification\RunCollectionGroupCreater.cs" />
+    <Compile Include="RunCollectionModification\RunCollectionSorter.cs" />
+    <Compile Include="RunCollectionModification\RunCollectionValueRemover.cs" />
+    <Compile Include="Interfaces\IRunCollectionModifier.cs" />
+    <None Include="Plugin.cs.frame" />
+    <Compile Include="Algorithms\Algorithm.cs" />
+    <Compile Include="RunCollectionModification\Calculator.cs" />
+    <Compile Include="Interfaces\IDiscreteDoubleMatrixModifier.cs" />
+    <Compile Include="Algorithms\HeuristicOptimizationEngineAlgorithm.cs" />
+    <Compile Include="Interfaces\IGlobalParticleUpdater.cs" />
+    <Compile Include="Interfaces\ILocalImprovementOperator.cs" />
+    <Compile Include="Interfaces\ILocalParticleUpdater.cs" />
+    <Compile Include="Algorithms\HeuristicOptimizationAlgorithm.cs" />
+    <Compile Include="Interfaces\IMultiNeighborhoodShakingOperator.cs" />
+    <Compile Include="MoveHelper.cs" />
+    <Compile Include="Problems\MultiObjectiveHeuristicOptimizationProblem.cs" />
+    <Compile Include="Problems\HeuristicOptimizationProblem.cs" />
+    <Compile Include="Problems\SingleObjectiveHeuristicOptimizationProblem.cs" />
+    <Compile Include="Interfaces\IHeuristicOptimizationProblem.cs" />
+    <Compile Include="Interfaces\IMultiAnalyzer.cs" />
+    <Compile Include="Interfaces\IIterationBasedOperator.cs" />
+    <Compile Include="Interfaces\IParticleCreator.cs" />
+    <Compile Include="Interfaces\IParticleUpdater.cs" />
+    <Compile Include="Interfaces\ISwarmUpdater.cs" />
+    <Compile Include="Interfaces\ITopologyInitializer.cs" />
+    <Compile Include="Interfaces\ITopologyUpdater.cs" />
+    <Compile Include="Interfaces\IMultiObjectiveHeuristicOptimizationProblem.cs" />
+    <Compile Include="Interfaces\ISingleObjectiveHeuristicOptimizationProblem.cs" />
+    <Compile Include="Problems\Problem.cs" />
+    <Compile Include="RunCollectionModification\RunCollectionFormulaModifer.cs" />
+    <Compile Include="RunCollectionConstraints\RunCollectionComparisonConstraint.cs" />
+    <Compile Include="RunCollectionConstraints\RunCollectionConstraintCollection.cs" />
+    <Compile Include="RunCollectionConstraints\RunCollectionContentConstraint.cs" />
+    <Compile Include="RunCollectionConstraints\RunCollectionTypeCompatiblityConstraint.cs" />
+    <Compile Include="RunCollectionConstraints\RunCollectionEqualityConstraint.cs" />
+    <Compile Include="Interfaces\IAnalyzer.cs" />
+    <Compile Include="Interfaces\ISingleObjectiveReplacer.cs" />
+    <Compile Include="Interfaces\IMigrator.cs" />
+    <Compile Include="Interfaces\IReplacer.cs" />
+    <Compile Include="Interfaces\ISubScopesQualityComparator.cs" />
+    <Compile Include="Interfaces\IQualityComparator.cs" />
+    <Compile Include="Interfaces\ISelfAdaptiveManipulator.cs" />
+    <Compile Include="Interfaces\IStrategyParameterCrossover.cs" />
+    <Compile Include="Interfaces\IStrategyParameterManipulator.cs" />
+    <Compile Include="Interfaces\IStrategyParameterCreator.cs" />
+    <Compile Include="Interfaces\IRun.cs" />
+    <Compile Include="RunCollectionConstraints\IRunCollectionConstraint.cs" />
+    <Compile Include="OptimizerList.cs" />
+    <Compile Include="Interfaces\IOptimizer.cs" />
+    <Compile Include="RunCollection.cs" />
+    <Compile Include="Run.cs" />
+    <Compile Include="Results\IResult.cs" />
+    <Compile Include="Interfaces\IDiscreteDoubleValueModifier.cs" />
+    <Compile Include="Interfaces\IExhaustiveMoveGenerator.cs" />
+    <Compile Include="Interfaces\IMoveOperator.cs" />
+    <Compile Include="Interfaces\IMultiMoveGenerator.cs" />
+    <Compile Include="Interfaces\ISingleMoveGenerator.cs" />
+    <Compile Include="Interfaces\ISingleObjectiveMoveEvaluator.cs" />
+    <Compile Include="Interfaces\IMoveGenerator.cs" />
+    <Compile Include="Interfaces\IMoveMaker.cs" />
+    <Compile Include="Interfaces\IMultiObjectiveSelector.cs" />
+    <Compile Include="Interfaces\ISingleObjectiveSelector.cs" />
+    <Compile Include="Interfaces\IReducer.cs" />
+    <Compile Include="Interfaces\ISelector.cs" />
+    <Compile Include="Interfaces\IMultiObjectiveEvaluator.cs" />
+    <Compile Include="Interfaces\IAlgorithm.cs" />
+    <Compile Include="Interfaces\ICrossover.cs" />
+    <Compile Include="Interfaces\IEvaluator.cs" />
+    <Compile Include="Interfaces\IManipulator.cs" />
+    <Compile Include="Interfaces\IProblem.cs" />
+    <Compile Include="Interfaces\ISingleObjectiveEvaluator.cs" />
+    <Compile Include="Interfaces\ISolutionCreator.cs" />
+    <Compile Include="Interfaces\IStochasticOperator.cs" />
+    <Compile Include="Interfaces\ITabuChecker.cs" />
+    <Compile Include="Interfaces\ITabuMaker.cs" />
+    <Compile Include="Results\Result.cs" />
+    <Compile Include="Algorithms\UserDefinedAlgorithm.cs" />
+    <Compile Include="Algorithms\EngineAlgorithm.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Results\ResultCollection.cs" />
+    <Compile Include="Problems\UserDefinedProblem.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup />
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <PropertyGroup>
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd
+</PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IAlgorithm.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IAlgorithm.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IAlgorithm.cs	(revision 12764)
@@ -0,0 +1,41 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// Interface to represent an algorithm.
+  /// </summary>
+  public interface IAlgorithm : IParameterizedNamedItem, IOptimizer {
+    Type ProblemType { get; }
+    IProblem Problem { get; set; }
+    ResultCollection Results { get; }
+    bool StoreAlgorithmInEachRun { get; set; }
+
+    void CollectResultValues(IDictionary<string, IItem> values);
+
+    event EventHandler ProblemChanged;
+    event EventHandler StoreAlgorithmInEachRunChanged;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IAnalyzer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IAnalyzer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IAnalyzer.cs	(revision 12764)
@@ -0,0 +1,31 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface which represents an analysis operator.
+  /// </summary>
+  public interface IAnalyzer : IOperator {
+    bool EnabledByDefault { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ICrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ICrossover.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ICrossover.cs	(revision 12764)
@@ -0,0 +1,29 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface which represents an operator for crossing solutions.
+  /// </summary>
+  public interface ICrossover : IOperator { }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IDiscreteDoubleMatrixModifier.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IDiscreteDoubleMatrixModifier.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IDiscreteDoubleMatrixModifier.cs	(revision 12764)
@@ -0,0 +1,37 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+
+namespace HeuristicLab.Optimization {
+  public interface IDiscreteDoubleMatrixModifier : IOperator {
+    ILookupParameter<DoubleMatrix> ValueParameter { get; }
+    ILookupParameter<DoubleValue> ScaleParameter { get; }
+    ConstrainedValueParameter<IDiscreteDoubleValueModifier> ScalingOperatorParameter { get; }
+    IValueLookupParameter<DoubleValue> StartValueParameter { get; }
+    IValueLookupParameter<DoubleValue> EndValueParameter { get; }
+    ILookupParameter<IntValue> IndexParameter { get; }
+    IValueLookupParameter<IntValue> StartIndexParameter { get; }
+    IValueLookupParameter<IntValue> EndIndexParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IDiscreteDoubleValueModifier.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IDiscreteDoubleValueModifier.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IDiscreteDoubleValueModifier.cs	(revision 12764)
@@ -0,0 +1,49 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  public interface IDiscreteDoubleValueModifier : IOperator {
+    ILookupParameter<DoubleValue> ValueParameter { get; }
+    /// <summary>
+    /// The start value of the parameter, will be assigned to <see cref="ValueParameter"/> as soon as <see cref="IndexParamter"/> equals <see cref="StartIndexParameter"/>.
+    /// </summary>
+    IValueLookupParameter<DoubleValue> StartValueParameter { get; }
+    /// <summary>
+    /// The end value of the parameter, will be assigned to <see cref="ValueParameter"/> as soon as <see cref="IndexParamter"/> equals <see cref="EndIndexParameter"/>.
+    /// </summary>
+    IValueLookupParameter<DoubleValue> EndValueParameter { get; }
+    /// <summary>
+    /// The index that denotes from which point in the function (relative to <see cref="StartIndexParameter"/> and <see cref="EndIndexParameter"/> the value should be assigned.
+    /// </summary>
+    ILookupParameter<IntValue> IndexParameter { get; }
+    /// <summary>
+    /// As soon as <see cref="IndexParameter"/> is &gt;= this parameter the value will start to be modified.
+    /// </summary>
+    IValueLookupParameter<IntValue> StartIndexParameter { get; }
+    /// <summary>
+    /// As long as <see cref="IndexParameter"/> is &lt;= this parameter the value will start to be modified.
+    /// </summary>
+    IValueLookupParameter<IntValue> EndIndexParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IEvaluator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IEvaluator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IEvaluator.cs	(revision 12764)
@@ -0,0 +1,29 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface which represents an evaluation operator for optimization problems.
+  /// </summary>
+  public interface IEvaluator : IOperator { }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IExhaustiveMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IExhaustiveMoveGenerator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IExhaustiveMoveGenerator.cs	(revision 12764)
@@ -0,0 +1,25 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization {
+  public interface IExhaustiveMoveGenerator : IMoveGenerator {
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IGlobalParticleUpdater.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IGlobalParticleUpdater.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IGlobalParticleUpdater.cs	(revision 12764)
@@ -0,0 +1,25 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization {
+  public interface IGlobalParticleUpdater : IParticleUpdater {
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IHeuristicOptimizationProblem.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IHeuristicOptimizationProblem.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IHeuristicOptimizationProblem.cs	(revision 12764)
@@ -0,0 +1,38 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// Interface to represent a heuristic optimization problem.
+  /// </summary>
+  public interface IHeuristicOptimizationProblem : IProblem {
+    IParameter SolutionCreatorParameter { get; }
+    ISolutionCreator SolutionCreator { get; }
+    IParameter EvaluatorParameter { get; }
+    IEvaluator Evaluator { get; }
+
+    event EventHandler SolutionCreatorChanged;
+    event EventHandler EvaluatorChanged;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IImprovementOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IImprovementOperator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IImprovementOperator.cs	(revision 12764)
@@ -0,0 +1,30 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface which represents an operator for improvement.
+  /// </summary>
+  public interface IImprovementOperator : IOperator {
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IIterationBasedOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IIterationBasedOperator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IIterationBasedOperator.cs	(revision 12764)
@@ -0,0 +1,30 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  public interface IIterationBasedOperator : IOperator {
+    ILookupParameter<IntValue> IterationsParameter { get; }
+    IValueLookupParameter<IntValue> MaximumIterationsParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ILocalImprovementAlgorithmOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ILocalImprovementAlgorithmOperator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ILocalImprovementAlgorithmOperator.cs	(revision 12764)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+
+namespace HeuristicLab.Optimization {
+  public interface ILocalImprovementAlgorithmOperator : ILocalImprovementOperator {
+    Type ProblemType { get; }
+    IProblem Problem { get; set; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ILocalImprovementOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ILocalImprovementOperator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ILocalImprovementOperator.cs	(revision 12764)
@@ -0,0 +1,31 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  public interface ILocalImprovementOperator : IOperator {
+    IValueLookupParameter<IntValue> MaximumIterationsParameter { get; }
+    ILookupParameter<IntValue> EvaluatedSolutionsParameter { get; }
+    ILookupParameter<ResultCollection> ResultsParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ILocalParticleUpdater.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ILocalParticleUpdater.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ILocalParticleUpdater.cs	(revision 12764)
@@ -0,0 +1,25 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization {
+  public interface ILocalParticleUpdater : IParticleUpdater {
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IManipulator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IManipulator.cs	(revision 12764)
@@ -0,0 +1,29 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface which represents an operator for manipulating solutions.
+  /// </summary>
+  public interface IManipulator : IOperator { }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMigrator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMigrator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMigrator.cs	(revision 12764)
@@ -0,0 +1,26 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  public interface IMigrator : IOperator { }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMoveGenerator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMoveGenerator.cs	(revision 12764)
@@ -0,0 +1,33 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface which represents an operator for generating moves.
+  /// </summary>
+  /// <remarks>
+  /// Please read the remarks on <see cref="IMoveOperator"/> on how to implement moves.
+  /// </remarks>
+  public interface IMoveGenerator : IOperator {
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMoveMaker.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMoveMaker.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMoveMaker.cs	(revision 12764)
@@ -0,0 +1,30 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  public interface IMoveMaker : IOperator {
+    ILookupParameter<DoubleValue> QualityParameter { get; }
+    ILookupParameter<DoubleValue> MoveQualityParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMoveOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMoveOperator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMoveOperator.cs	(revision 12764)
@@ -0,0 +1,74 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// The basic interface that marks all move operators. Derived interfaces
+  /// are used to group move operators together.
+  /// </summary>
+  /// <remarks>
+  /// A group of move operators that belong together should derive a new
+  /// interface from IMoveOperator and implement the new interface in each
+  /// operator.<br />
+  /// 
+  /// E.g. a new move is to be implemented and INewMove is created as a derived
+  /// type of IMoveOperator. Then you create the additional following types<br />
+  /// <list type="bullet">
+  /// <item>
+  ///   <term>NewMoveGenerator</term>
+  ///   <description>
+  ///   implements INewMove as well as either IExhaustiveMoveGenerator,
+  ///   IMultiMoveGenerator or ISingleMoveGenerator
+  ///   </description>
+  /// </item>
+  /// <item>
+  ///   <term>NewMoveMaker</term>
+  ///   <description>
+  ///   implements INewMove as well as IMoveMaker
+  ///   </description>
+  /// </item>
+  /// <item>
+  ///   <term>NewMoveEvaluator</term>
+  ///   <description>
+  ///   (problem plugin) implements INewMove as well as ISingleObjectiveMoveEvaluator
+  ///   </description>
+  /// </item>
+  /// <item>
+  ///   <term>NewMoveTabuMaker</term>
+  ///   <description>
+  ///   (only for Tabu Search) implements INewMove as well as TabuMaker
+  ///   </description>
+  /// </item>
+  /// <item>
+  ///   <term>NewMoveTabuChecker</term>
+  ///   <description>
+  ///   (only for Tabu Search) implements INewMove as well as ITabuChecker
+  ///   </description>
+  /// </item>
+  /// </list>
+  /// 
+  /// These operators should not implement further move types. For further moves
+  /// a new interface derived from IMoveOperator should be created.
+  public interface IMoveOperator : IOperator {
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMultiAnalyzer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMultiAnalyzer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMultiAnalyzer.cs	(revision 12764)
@@ -0,0 +1,29 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+
+using HeuristicLab.Core;
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface which represents a multi analysis operator.
+  /// </summary>
+  public interface IMultiAnalyzer : ICheckedMultiOperator<IAnalyzer>, IAnalyzer { }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMultiMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMultiMoveGenerator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMultiMoveGenerator.cs	(revision 12764)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  public interface IMultiMoveGenerator : IMoveGenerator {
+    IValueLookupParameter<IntValue> SampleSizeParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMultiNeighborhoodShakingOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMultiNeighborhoodShakingOperator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMultiNeighborhoodShakingOperator.cs	(revision 12764)
@@ -0,0 +1,30 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  public interface IMultiNeighborhoodShakingOperator : IOperator {
+    IValueLookupParameter<IntValue> CurrentNeighborhoodIndexParameter { get; }
+    ILookupParameter<IntValue> NeighborhoodCountParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMultiObjectiveEvaluator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMultiObjectiveEvaluator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMultiObjectiveEvaluator.cs	(revision 12764)
@@ -0,0 +1,32 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface which represents an evaluation operator for multi-objective optimization problems.
+  /// </summary>
+  public interface IMultiObjectiveEvaluator : IEvaluator, IMultiObjectiveOperator {
+    ILookupParameter<DoubleArray> QualitiesParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMultiObjectiveHeuristicOptimizationProblem.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMultiObjectiveHeuristicOptimizationProblem.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMultiObjectiveHeuristicOptimizationProblem.cs	(revision 12764)
@@ -0,0 +1,32 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface to represent a multi-objective optimization problem.
+  /// </summary>
+  public interface IMultiObjectiveHeuristicOptimizationProblem : IHeuristicOptimizationProblem {
+    IParameter MaximizationParameter { get; }
+    new IMultiObjectiveEvaluator Evaluator { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMultiObjectiveOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMultiObjectiveOperator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMultiObjectiveOperator.cs	(revision 12764)
@@ -0,0 +1,52 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// This is only a marker interface to prevent operators that expect to work with multiple quality values
+  /// and/or multiple maximization flags to appear in single-objective algorithms.
+  /// </summary>
+  /// <remarks>
+  /// Marker interfaces are typically not a good design, however specifying a reasonable non-empty common
+  /// interface for all multi-objective operators is difficult. There are many different variants of
+  /// multi-ojective operators with specific needs that can currently only be abstracted by an empty interface.
+  /// In the following, please find a list of different kinds of multi-objective operators.
+  /// <list type="bullet">
+  ///   <item>
+  ///     <term>Evaluators</term>
+  ///     <description>These only need a qualities parameter, but not a maximization parameter.</description>
+  ///   </item>
+  ///   <item>
+  ///     <term>Population-based operators</term>
+  ///     <description>These require the qualities parameter to be a scope-tree lookup, e.g. analyzers, crossovers, multi-objective selectors.</description>
+  ///   </item>
+  ///   <item>
+  ///     <term>Problem-specific operators</term>
+  ///     <description>They may perform multiple operations on a solution, evaluate and select without taking into account maximization or the evaluator</description>
+  ///   </item>
+  ///   <item>
+  ///     <term>Other multi-objective operators</term>
+  ///     <description>They would need both a qualities, and a maximization parameter, and may be population-based or not.</description>
+  ///   </item>
+  /// </list>
+  /// </remarks>
+  public interface IMultiObjectiveOperator { }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMultiObjectiveSelector.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMultiObjectiveSelector.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IMultiObjectiveSelector.cs	(revision 12764)
@@ -0,0 +1,33 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface which represents a selection operator for selecting solutions of multi-objective optimization problems.
+  /// </summary>
+  public interface IMultiObjectiveSelector : ISelector, IMultiObjectiveOperator {
+    ILookupParameter<BoolArray> MaximizationParameter { get; }
+    ILookupParameter<ItemArray<DoubleArray>> QualitiesParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IOptimizer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IOptimizer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IOptimizer.cs	(revision 12764)
@@ -0,0 +1,36 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// Interface to represent optimizers such as algorithms, batch runs, or experiments.
+  /// </summary>
+  public interface IOptimizer : INamedItem, IExecutable {
+    RunCollection Runs { get; }
+
+    void Prepare(bool clearRuns);
+
+    IEnumerable<IOptimizer> NestedOptimizers { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IParticleCreator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IParticleCreator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IParticleCreator.cs	(revision 12764)
@@ -0,0 +1,30 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// Interface to represent an operator that generates a particle. 
+  /// </summary>
+  public interface IParticleCreator : ISolutionCreator {
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IParticleUpdater.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IParticleUpdater.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IParticleUpdater.cs	(revision 12764)
@@ -0,0 +1,35 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// Interface to represent an operator that updates a particle 
+  /// </summary>
+  public interface IParticleUpdater : IOperator {
+    ILookupParameter<DoubleValue> InertiaParameter { get; }
+    ILookupParameter<DoubleValue> NeighborBestAttractionParameter { get; }
+    ILookupParameter<DoubleValue> PersonalBestAttractionParameter { get; }
+    ILookupParameter<IRandom> RandomParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IPathRelinker.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IPathRelinker.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IPathRelinker.cs	(revision 12764)
@@ -0,0 +1,30 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface which represents an operator for path relinking.
+  /// </summary>
+  public interface IPathRelinker : IOperator {
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IProblem.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IProblem.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IProblem.cs	(revision 12764)
@@ -0,0 +1,38 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// Interface to represent an optimization problem.
+  /// </summary>
+  public interface IProblem : IParameterizedNamedItem {
+    IEnumerable<IItem> Operators { get; }
+
+
+    IEnumerable<IParameterizedItem> ExecutionContextItems { get; }
+    event EventHandler OperatorsChanged;
+    event EventHandler Reset;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IQualityComparator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IQualityComparator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IQualityComparator.cs	(revision 12764)
@@ -0,0 +1,32 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  public interface IQualityComparator {
+    ILookupParameter<DoubleValue> LeftSideParameter { get; }
+    IValueLookupParameter<DoubleValue> RightSideParameter { get; }
+    ILookupParameter<BoolValue> ResultParameter { get; }
+    IValueLookupParameter<BoolValue> MaximizationParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IReducer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IReducer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IReducer.cs	(revision 12764)
@@ -0,0 +1,29 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface which represents a reduction opertor.
+  /// </summary>
+  public interface IReducer : IOperator { }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IReplacer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IReplacer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IReplacer.cs	(revision 12764)
@@ -0,0 +1,33 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// Interface to mark operators that can be used as replacers.
+  /// Replacers are merging a remaining and a selected branch in several special ways.
+  /// </summary>
+  public interface IReplacer : IOperator {
+    IValueLookupParameter<ISelector> ReplacedSelectorParameter { get; }
+    IValueLookupParameter<ISelector> SelectedSelectorParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IResult.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IResult.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IResult.cs	(revision 12764)
@@ -0,0 +1,36 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// Represents a result which has a name and a data type and holds an IItem.
+  /// </summary>
+  public interface IResult : INamedItem {
+    Type DataType { get; }
+    IItem Value { get; set; }
+
+    /// <inheritdoc/>
+    event EventHandler ValueChanged;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IRun.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IRun.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IRun.cs	(revision 12764)
@@ -0,0 +1,39 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.ComponentModel;
+using System.Drawing;
+using HeuristicLab.Collections;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// Represents the parameters and results of an algorithm run.
+  /// </summary>
+  public interface IRun : INamedItem, INotifyPropertyChanged {
+    IAlgorithm Algorithm { get; }
+    IObservableDictionary<string, IItem> Parameters { get; }
+    IObservableDictionary<string, IItem> Results { get; }
+
+    Color Color { get; set; }
+    bool Visible { get; set; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IRunCollectionModifier.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IRunCollectionModifier.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IRunCollectionModifier.cs	(revision 12764)
@@ -0,0 +1,32 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  public interface IRunCollectionModifier : IItem {    
+    void Modify(List<IRun> runs);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISelector.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISelector.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISelector.cs	(revision 12764)
@@ -0,0 +1,33 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface which represents a selection operator.
+  /// </summary>
+  public interface ISelector : IOperator {
+    BoolValue CopySelected { get; set; }
+    IValueLookupParameter<IntValue> NumberOfSelectedSubScopesParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISelfAdaptiveManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISelfAdaptiveManipulator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISelfAdaptiveManipulator.cs	(revision 12764)
@@ -0,0 +1,33 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface which represents an operator for manipulating solutions, given a strategy parameter.
+  /// </summary>
+  public interface ISelfAdaptiveManipulator : IManipulator {
+    Type StrategyParameterType { get; }
+    IParameter StrategyParameterParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISimilarityBasedOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISimilarityBasedOperator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISimilarityBasedOperator.cs	(revision 12764)
@@ -0,0 +1,28 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  public interface ISimilarityBasedOperator : IOperator {
+    IConstrainedValueParameter<ISolutionSimilarityCalculator> SimilarityCalculatorParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleMoveGenerator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleMoveGenerator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleMoveGenerator.cs	(revision 12764)
@@ -0,0 +1,25 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization {
+  public interface ISingleMoveGenerator : IMoveGenerator, ISingleObjectiveOperator {
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveEvaluator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveEvaluator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveEvaluator.cs	(revision 12764)
@@ -0,0 +1,32 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface which represents an evaluation operator for single-objective optimization problems.
+  /// </summary>
+  public interface ISingleObjectiveEvaluator : IEvaluator, ISingleObjectiveOperator {
+    ILookupParameter<DoubleValue> QualityParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveHeuristicOptimizationProblem.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveHeuristicOptimizationProblem.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveHeuristicOptimizationProblem.cs	(revision 12764)
@@ -0,0 +1,33 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface to represent a single-objective optimization problem.
+  /// </summary>
+  public interface ISingleObjectiveHeuristicOptimizationProblem : IHeuristicOptimizationProblem {
+    IParameter MaximizationParameter { get; }
+    IParameter BestKnownQualityParameter { get; }
+    new ISingleObjectiveEvaluator Evaluator { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveImprovementOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveImprovementOperator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveImprovementOperator.cs	(revision 12764)
@@ -0,0 +1,31 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface which represents an operator for improvement of a single objective solution.
+  /// </summary>
+  public interface ISingleObjectiveImprovementOperator : IImprovementOperator, ISingleObjectiveOperator {
+    IValueLookupParameter<IItem> SolutionParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveMoveEvaluator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveMoveEvaluator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveMoveEvaluator.cs	(revision 12764)
@@ -0,0 +1,30 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  public interface ISingleObjectiveMoveEvaluator : IOperator, ISingleObjectiveOperator {
+    ILookupParameter<DoubleValue> QualityParameter { get; }
+    ILookupParameter<DoubleValue> MoveQualityParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveOperator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveOperator.cs	(revision 12764)
@@ -0,0 +1,52 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// This is only a marker interface to prevent operators that expect to work with a single quality value
+  /// and/or a single maximization flag to appear in multi-objective algorithms.
+  /// </summary>
+  /// <remarks>
+  /// Marker interfaces are typically not a good design, however specifying a reasonable non-empty common
+  /// interface for all single-objective operators is difficult. There are many different variants of
+  /// single-ojective operators with specific needs that can currently only be abstracted by an empty interface.
+  /// In the following, please find a list of different kinds of single-objective operators.
+  /// <list type="bullet">
+  ///   <item>
+  ///     <term>Evaluators</term>
+  ///     <description>These only need a quality parameter, but not a maximization parameter.</description>
+  ///   </item>
+  ///   <item>
+  ///     <term>Population-based operators</term>
+  ///     <description>These require the quality parameter to be a scope-tree lookup, e.g. analyzers, crossovers, single-objective replacers and selectors.</description>
+  ///   </item>
+  ///   <item>
+  ///     <term>Problem-specific operators</term>
+  ///     <description>They may perform multiple operations on a solution, evaluate and select without taking into account maximization or the evaluator, e.g. many improvement operators.</description>
+  ///   </item>
+  ///   <item>
+  ///     <term>Other single-objective operators</term>
+  ///     <description>They would need both a quality, and a maximization parameter, and may be population-based or not.</description>
+  ///   </item>
+  /// </list>
+  /// </remarks>
+  public interface ISingleObjectiveOperator { }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectivePathRelinker.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectivePathRelinker.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectivePathRelinker.cs	(revision 12764)
@@ -0,0 +1,31 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface which represents an operator for path relinking between single objective solutions.
+  /// </summary>
+  public interface ISingleObjectivePathRelinker : IPathRelinker, ISingleObjectiveOperator {
+    ILookupParameter<ItemArray<IItem>> ParentsParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveReplacer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveReplacer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveReplacer.cs	(revision 12764)
@@ -0,0 +1,33 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface which represents a replacement operator for replacing solutions of single-objective optimization problems.
+  /// </summary>
+  public interface ISingleObjectiveReplacer : IReplacer, ISingleObjectiveOperator {
+    IValueLookupParameter<BoolValue> MaximizationParameter { get; }
+    ILookupParameter<ItemArray<DoubleValue>> QualityParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveSelector.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveSelector.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveSelector.cs	(revision 12764)
@@ -0,0 +1,33 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface which represents a selection operator for selecting solutions of single-objective optimization problems.
+  /// </summary>
+  public interface ISingleObjectiveSelector : ISelector, ISingleObjectiveOperator {
+    IValueLookupParameter<BoolValue> MaximizationParameter { get; }
+    ILookupParameter<ItemArray<DoubleValue>> QualityParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveSolutionSimilarityCalculator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveSolutionSimilarityCalculator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISingleObjectiveSolutionSimilarityCalculator.cs	(revision 12764)
@@ -0,0 +1,36 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+
+namespace HeuristicLab.Optimization {
+  // use HeuristicLab.Optimization.ISolutionSimilarityCalculator instead
+  // BackwardsCompatibility3.3
+  #region Backwards compatible code, remove with 3.4
+  /// <summary>
+  /// An interface which represents an operator for similarity calculation between single objective solutions.
+  /// </summary>
+  [Obsolete("use HeuristicLab.Optimization.ISolutionSimilarityCalculator instead")]
+  public interface ISingleObjectiveSolutionSimilarityCalculator : ISolutionSimilarityCalculator, ISingleObjectiveOperator {
+
+  }
+  #endregion
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISolutionCreator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISolutionCreator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISolutionCreator.cs	(revision 12764)
@@ -0,0 +1,29 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface which represents an operator for creating new solutions.
+  /// </summary>
+  public interface ISolutionCreator : IOperator { }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISolutionSimilarityCalculator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISolutionSimilarityCalculator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISolutionSimilarityCalculator.cs	(revision 12764)
@@ -0,0 +1,56 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface which represents an operator for similarity calculation.
+  /// </summary>
+  public interface ISolutionSimilarityCalculator : IItem, IEqualityComparer<IScope> {
+    string SolutionVariableName { get; set; }
+    string QualityVariableName { get; set; }
+
+    /// <summary>
+    /// Calculates the similarity of two solutions.
+    /// </summary>
+    /// <param name="leftSolution">The first scope that contains a solution.</param>
+    /// <param name="rightSolution">The second scope that contains a solution.</param>
+    /// <returns>A double between zero and one. Zero means the two solutions differ in every aspect, one indicates that the two solutions are the same.</returns>
+    double CalculateSolutionSimilarity(IScope leftSolution, IScope rightSolution);
+
+    /// <summary>
+    /// Calculates the similarity of solutions in one scope.
+    /// </summary>
+    /// <param name="solutionCrowd">The scope that contains solutions.</param>
+    /// <returns>A similarity matrix. Zero means the two solutions differ in every aspect, one indicates that the two solutions are the same.</returns>
+    double[][] CalculateSolutionCrowdSimilarity(IScope solutionCrowd);
+
+    /// <summary>
+    /// Calculates the similarity of solutions in two scopes.
+    /// </summary>
+    /// <param name="leftSolutionCrowd">The first scope that contains solutions.</param>
+    /// <param name="rightSolutionCrowd">The second scope that contains solutions.</param>
+    /// <returns>A similarity matrix. Zero means the two solutions differ in every aspect, one indicates that the two solutions are the same.</returns>
+    double[][] CalculateSolutionCrowdSimilarity(IScope leftSolutionCrowd, IScope rightSolutionCrowd);
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IStochasticOperator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IStochasticOperator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IStochasticOperator.cs	(revision 12764)
@@ -0,0 +1,31 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An interface which represents a stochastic operator.
+  /// </summary>
+  public interface IStochasticOperator : IOperator {
+    ILookupParameter<IRandom> RandomParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IStrategyParameterCreator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IStrategyParameterCreator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IStrategyParameterCreator.cs	(revision 12764)
@@ -0,0 +1,27 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  public interface IStrategyParameterCreator : IOperator {
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IStrategyParameterCrossover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IStrategyParameterCrossover.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IStrategyParameterCrossover.cs	(revision 12764)
@@ -0,0 +1,27 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  public interface IStrategyParameterCrossover : IOperator {
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IStrategyParameterManipulator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IStrategyParameterManipulator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/IStrategyParameterManipulator.cs	(revision 12764)
@@ -0,0 +1,27 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  public interface IStrategyParameterManipulator : IOperator {
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISubScopesQualityComparator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISubScopesQualityComparator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISubScopesQualityComparator.cs	(revision 12764)
@@ -0,0 +1,32 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  public interface ISubScopesQualityComparator {
+    ILookupParameter<DoubleValue> LeftSideParameter { get; }
+    ILookupParameter<ItemArray<DoubleValue>> RightSideParameter { get; }
+    ILookupParameter<BoolValue> ResultParameter { get; }
+    IValueLookupParameter<BoolValue> MaximizationParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISwarmUpdater.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISwarmUpdater.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ISwarmUpdater.cs	(revision 12764)
@@ -0,0 +1,32 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  public interface ISwarmUpdater : IOperator {
+    IScopeTreeLookupParameter<DoubleValue> QualityParameter { get; }
+    IScopeTreeLookupParameter<DoubleValue> NeighborBestQualityParameter { get; }
+    IScopeTreeLookupParameter<DoubleValue> PersonalBestQualityParameter { get; }
+    ILookupParameter<BoolValue> MaximizationParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ITabuChecker.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ITabuChecker.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ITabuChecker.cs	(revision 12764)
@@ -0,0 +1,31 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  public interface ITabuChecker : IOperator {
+    ILookupParameter<BoolValue> MoveTabuParameter { get; }
+    ILookupParameter<DoubleValue> MoveQualityParameter { get; }
+    IValueLookupParameter<BoolValue> MaximizationParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ITabuMaker.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ITabuMaker.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ITabuMaker.cs	(revision 12764)
@@ -0,0 +1,31 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  public interface ITabuMaker : IOperator {
+    ILookupParameter<DoubleValue> MoveQualityParameter { get; }
+    ILookupParameter<DoubleValue> QualityParameter { get; }
+    IValueLookupParameter<BoolValue> MaximizationParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ITopologyInitializer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ITopologyInitializer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ITopologyInitializer.cs	(revision 12764)
@@ -0,0 +1,30 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  public interface ITopologyInitializer : IOperator {
+    IScopeTreeLookupParameter<IntArray> NeighborsParameter { get; }
+    ILookupParameter<IntValue> SwarmSizeParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ITopologyUpdater.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ITopologyUpdater.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Interfaces/ITopologyUpdater.cs	(revision 12764)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  public interface ITopologyUpdater : IOperator {
+    IScopeTreeLookupParameter<IntArray> NeighborsParameter { get; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/MetaOptimizers/BatchRun.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/MetaOptimizers/BatchRun.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/MetaOptimizers/BatchRun.cs	(revision 12764)
@@ -0,0 +1,454 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  internal enum BatchRunAction { None, Prepare, Start, Pause, Stop };
+
+  /// <summary>
+  /// A run in which an optimizer is executed a given number of times.
+  /// </summary>
+  [Item("Batch Run", "A run in which an optimizer is executed a given number of times.")]
+  [Creatable(CreatableAttribute.Categories.TestingAndAnalysis, Priority = 110)]
+  [StorableClass]
+  public sealed class BatchRun : NamedItem, IOptimizer, IStorableContent {
+    public string Filename { get; set; }
+
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Event; }
+    }
+    public override Image ItemImage {
+      get {
+        if (ExecutionState == ExecutionState.Prepared) return HeuristicLab.Common.Resources.VSImageLibrary.BatchRunPrepared;
+        else if (ExecutionState == ExecutionState.Started) return HeuristicLab.Common.Resources.VSImageLibrary.BatchRunStarted;
+        else if (ExecutionState == ExecutionState.Paused) return HeuristicLab.Common.Resources.VSImageLibrary.BatchRunPaused;
+        else if (ExecutionState == ExecutionState.Stopped) return HeuristicLab.Common.Resources.VSImageLibrary.BatchRunStopped;
+        else return base.ItemImage;
+      }
+    }
+
+    [Storable]
+    private ExecutionState executionState;
+    public ExecutionState ExecutionState {
+      get { return executionState; }
+      private set {
+        if (executionState != value) {
+          executionState = value;
+          OnExecutionStateChanged();
+          OnItemImageChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private TimeSpan executionTime;
+    public TimeSpan ExecutionTime {
+      get {
+        if ((Optimizer != null) && (Optimizer.ExecutionState != ExecutionState.Stopped))
+          return executionTime + Optimizer.ExecutionTime;
+        else
+          return executionTime;
+      }
+      private set {
+        executionTime = value;
+        OnExecutionTimeChanged();
+      }
+    }
+
+    [Storable]
+    private TimeSpan runsExecutionTime;
+
+    [Storable]
+    private IOptimizer optimizer;
+    public IOptimizer Optimizer {
+      get { return optimizer; }
+      set {
+        if (optimizer != value) {
+          if (optimizer != null) {
+            DeregisterOptimizerEvents();
+            IEnumerable<IRun> runs = optimizer.Runs;
+            optimizer = null; //necessary to avoid removing the runs from the old optimizer
+            Runs.RemoveRange(runs);
+          }
+          optimizer = value;
+          if (optimizer != null) {
+            RegisterOptimizerEvents();
+            Runs.AddRange(optimizer.Runs);
+          }
+          OnOptimizerChanged();
+          Prepare();
+        }
+      }
+    }
+    // BackwardsCompatibility3.3
+    #region Backwards compatible code (remove with 3.4)
+    [Storable(AllowOneWay = true)]
+    private IAlgorithm algorithm {
+      set { optimizer = value; }
+    }
+    #endregion
+
+    [Storable]
+    private int repetitions;
+    public int Repetitions {
+      get { return repetitions; }
+      set {
+        if (repetitions != value) {
+          repetitions = value;
+          OnRepetitionsChanged();
+          if ((Optimizer != null) && (Optimizer.ExecutionState == ExecutionState.Stopped))
+            Prepare();
+        }
+      }
+    }
+    [Storable]
+    private int repetitionsCounter;
+    public int RepetitionsCounter {
+      get { return repetitionsCounter; }
+      private set {
+        if (value != repetitionsCounter) {
+          repetitionsCounter = value;
+          OnRepetitionsCounterChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private RunCollection runs;
+    public RunCollection Runs {
+      get { return runs; }
+      private set {
+        if (value == null) throw new ArgumentNullException();
+        if (runs != value) {
+          if (runs != null) DeregisterRunsEvents();
+          runs = value;
+          if (runs != null) RegisterRunsEvents();
+        }
+      }
+    }
+
+    public IEnumerable<IOptimizer> NestedOptimizers {
+      get {
+        if (Optimizer == null) yield break;
+
+        yield return Optimizer;
+        foreach (IOptimizer opt in Optimizer.NestedOptimizers)
+          yield return opt;
+      }
+    }
+
+    private BatchRunAction batchRunAction = BatchRunAction.None;
+
+    public BatchRun()
+      : base() {
+      name = ItemName;
+      description = ItemDescription;
+      executionState = ExecutionState.Stopped;
+      executionTime = TimeSpan.Zero;
+      runsExecutionTime = TimeSpan.Zero;
+      repetitions = 10;
+      repetitionsCounter = 0;
+      Runs = new RunCollection { OptimizerName = Name };
+    }
+    public BatchRun(string name)
+      : base(name) {
+      description = ItemDescription;
+      executionState = ExecutionState.Stopped;
+      executionTime = TimeSpan.Zero;
+      runsExecutionTime = TimeSpan.Zero;
+      repetitions = 10;
+      repetitionsCounter = 0;
+      Runs = new RunCollection { OptimizerName = Name };
+    }
+    public BatchRun(string name, string description)
+      : base(name, description) {
+      executionState = ExecutionState.Stopped;
+      executionTime = TimeSpan.Zero;
+      runsExecutionTime = TimeSpan.Zero;
+      repetitions = 10;
+      repetitionsCounter = 0;
+      Runs = new RunCollection { OptimizerName = Name };
+    }
+    [StorableConstructor]
+    private BatchRun(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      Initialize();
+    }
+
+    private BatchRun(BatchRun original, Cloner cloner)
+      : base(original, cloner) {
+      executionState = original.executionState;
+      executionTime = original.executionTime;
+      runsExecutionTime = original.runsExecutionTime;
+      optimizer = cloner.Clone(original.optimizer);
+      repetitions = original.repetitions;
+      repetitionsCounter = original.repetitionsCounter;
+      runs = cloner.Clone(original.runs);
+      batchRunAction = original.batchRunAction;
+      Initialize();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      if (ExecutionState == ExecutionState.Started) throw new InvalidOperationException(string.Format("Clone not allowed in execution state \"{0}\".", ExecutionState));
+      return new BatchRun(this, cloner);
+    }
+
+    private void Initialize() {
+      if (optimizer != null) RegisterOptimizerEvents();
+      if (runs != null) RegisterRunsEvents();
+    }
+
+    public void Prepare() {
+      Prepare(false);
+    }
+    public void Prepare(bool clearRuns) {
+      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped))
+        throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState));
+      if (Optimizer != null) {
+        ExecutionTime = TimeSpan.Zero;
+        RepetitionsCounter = 0;
+        if (clearRuns) runs.Clear();
+        batchRunAction = BatchRunAction.Prepare;
+        // a race-condition may occur when the optimizer has changed the state by itself in the meantime
+        try { Optimizer.Prepare(clearRuns); }
+        catch (InvalidOperationException) { }
+      } else {
+        ExecutionState = ExecutionState.Stopped;
+      }
+    }
+    public void Start() {
+      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
+        throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
+      if (Optimizer == null) return;
+      batchRunAction = BatchRunAction.Start;
+      if (Optimizer.ExecutionState == ExecutionState.Stopped) Optimizer.Prepare();
+      // a race-condition may occur when the optimizer has changed the state by itself in the meantime
+      try { Optimizer.Start(); }
+      catch (InvalidOperationException) { }
+    }
+    public void Pause() {
+      if (ExecutionState != ExecutionState.Started)
+        throw new InvalidOperationException(string.Format("Pause not allowed in execution state \"{0}\".", ExecutionState));
+      if (Optimizer == null) return;
+      batchRunAction = BatchRunAction.Pause;
+      if (Optimizer.ExecutionState != ExecutionState.Started) return;
+      // a race-condition may occur when the optimizer has changed the state by itself in the meantime
+      try { Optimizer.Pause(); }
+      catch (InvalidOperationException) { }
+    }
+    public void Stop() {
+      if ((ExecutionState != ExecutionState.Started) && (ExecutionState != ExecutionState.Paused))
+        throw new InvalidOperationException(string.Format("Stop not allowed in execution state \"{0}\".", ExecutionState));
+      if (Optimizer == null) return;
+      batchRunAction = BatchRunAction.Stop;
+      if (Optimizer.ExecutionState != ExecutionState.Started && Optimizer.ExecutionState != ExecutionState.Paused) {
+        OnStopped();
+        return;
+      }
+      // a race-condition may occur when the optimizer has changed the state by itself in the meantime
+      try { Optimizer.Stop(); }
+      catch (InvalidOperationException) { }
+    }
+
+    #region Events
+    protected override void OnNameChanged() {
+      base.OnNameChanged();
+      runs.OptimizerName = Name;
+    }
+
+    public event EventHandler ExecutionStateChanged;
+    private void OnExecutionStateChanged() {
+      EventHandler handler = ExecutionStateChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ExecutionTimeChanged;
+    private void OnExecutionTimeChanged() {
+      EventHandler handler = ExecutionTimeChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler OptimizerChanged;
+    private void OnOptimizerChanged() {
+      EventHandler handler = OptimizerChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler RepetitionsChanged;
+    private void OnRepetitionsChanged() {
+      EventHandler handler = RepetitionsChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler RepetetionsCounterChanged;
+    private void OnRepetitionsCounterChanged() {
+      EventHandler handler = RepetetionsCounterChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Prepared;
+    private void OnPrepared() {
+      batchRunAction = BatchRunAction.None;
+      ExecutionState = ExecutionState.Prepared;
+      EventHandler handler = Prepared;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Started;
+    private void OnStarted() {
+      // no reset of BatchRunAction.Started, because we need to differ which of the two was started by the user
+      ExecutionState = ExecutionState.Started;
+      EventHandler handler = Started;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Paused;
+    private void OnPaused() {
+      batchRunAction = BatchRunAction.None;
+      ExecutionState = ExecutionState.Paused;
+      EventHandler handler = Paused;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Stopped;
+    private void OnStopped() {
+      batchRunAction = BatchRunAction.None;
+      ExecutionState = ExecutionState.Stopped;
+      EventHandler handler = Stopped;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
+    private void OnExceptionOccurred(Exception exception) {
+      EventHandler<EventArgs<Exception>> handler = ExceptionOccurred;
+      if (handler != null) handler(this, new EventArgs<Exception>(exception));
+    }
+
+    private void RegisterOptimizerEvents() {
+      optimizer.ExceptionOccurred += new EventHandler<EventArgs<Exception>>(Optimizer_ExceptionOccurred);
+      optimizer.ExecutionTimeChanged += new EventHandler(Optimizer_ExecutionTimeChanged);
+      optimizer.Paused += new EventHandler(Optimizer_Paused);
+      optimizer.Prepared += new EventHandler(Optimizer_Prepared);
+      optimizer.Started += new EventHandler(Optimizer_Started);
+      optimizer.Stopped += new EventHandler(Optimizer_Stopped);
+      optimizer.Runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_CollectionReset);
+      optimizer.Runs.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_ItemsAdded);
+      optimizer.Runs.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_ItemsRemoved);
+    }
+    private void DeregisterOptimizerEvents() {
+      optimizer.ExceptionOccurred -= new EventHandler<EventArgs<Exception>>(Optimizer_ExceptionOccurred);
+      optimizer.ExecutionTimeChanged -= new EventHandler(Optimizer_ExecutionTimeChanged);
+      optimizer.Paused -= new EventHandler(Optimizer_Paused);
+      optimizer.Prepared -= new EventHandler(Optimizer_Prepared);
+      optimizer.Started -= new EventHandler(Optimizer_Started);
+      optimizer.Stopped -= new EventHandler(Optimizer_Stopped);
+      optimizer.Runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_CollectionReset);
+      optimizer.Runs.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_ItemsAdded);
+      optimizer.Runs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_ItemsRemoved);
+    }
+    private void Optimizer_ExceptionOccurred(object sender, EventArgs<Exception> e) {
+      OnExceptionOccurred(e.Value);
+    }
+    private void Optimizer_ExecutionTimeChanged(object sender, EventArgs e) {
+      OnExecutionTimeChanged();
+    }
+    private void Optimizer_Paused(object sender, EventArgs e) {
+      if (ExecutionState == ExecutionState.Started) {
+        OnPaused();
+      }
+    }
+    private void Optimizer_Prepared(object sender, EventArgs e) {
+      if (batchRunAction == BatchRunAction.Prepare || ExecutionState == ExecutionState.Stopped) {
+        ExecutionTime = TimeSpan.Zero;
+        runsExecutionTime = TimeSpan.Zero;
+        RepetitionsCounter = 0;
+        OnPrepared();
+      }
+    }
+    private void Optimizer_Started(object sender, EventArgs e) {
+      if (ExecutionState != ExecutionState.Started)
+        OnStarted();
+    }
+    private void Optimizer_Stopped(object sender, EventArgs e) {
+      RepetitionsCounter++;
+      ExecutionTime += runsExecutionTime;
+      runsExecutionTime = TimeSpan.Zero;
+
+      if (batchRunAction == BatchRunAction.Stop) OnStopped();
+      else if (repetitionsCounter >= repetitions) OnStopped();
+      else if (batchRunAction == BatchRunAction.Pause) OnPaused();
+      else if (batchRunAction == BatchRunAction.Start) {
+        Optimizer.Prepare();
+        Optimizer.Start();
+      } else if (executionState == ExecutionState.Started) {
+        // if the batch run hasn't been started but the inner optimizer was run then pause
+        OnPaused();
+      } else OnStopped();
+    }
+    private void Optimizer_Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      Runs.RemoveRange(e.OldItems);
+      Runs.AddRange(e.Items);
+    }
+    private void Optimizer_Runs_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      Runs.AddRange(e.Items);
+    }
+    private void Optimizer_Runs_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      Runs.RemoveRange(e.Items);
+    }
+
+    private void RegisterRunsEvents() {
+      runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
+      runs.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsAdded);
+      runs.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsRemoved);
+    }
+
+    private void DeregisterRunsEvents() {
+      runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
+      runs.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsAdded);
+      runs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsRemoved);
+    }
+    private void Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      if (Optimizer != null) Optimizer.Runs.RemoveRange(e.OldItems);
+      foreach (IRun run in e.Items) {
+        IItem item;
+        run.Results.TryGetValue("Execution Time", out item);
+        TimeSpanValue executionTime = item as TimeSpanValue;
+        if (executionTime != null) ExecutionTime += executionTime.Value;
+      }
+    }
+    private void Runs_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      foreach (IRun run in e.Items) {
+        IItem item;
+        run.Results.TryGetValue("Execution Time", out item);
+        TimeSpanValue executionTime = item as TimeSpanValue;
+        if (executionTime != null) {
+          if (Optimizer.ExecutionState == ExecutionState.Started)
+            runsExecutionTime += executionTime.Value;
+          else
+            ExecutionTime += executionTime.Value;
+        }
+      }
+    }
+    private void Runs_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      if (Optimizer != null) Optimizer.Runs.RemoveRange(e.Items);
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/MetaOptimizers/Experiment.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/MetaOptimizers/Experiment.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/MetaOptimizers/Experiment.cs	(revision 12764)
@@ -0,0 +1,412 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// An experiment which contains multiple algorithms, batch runs or other experiments.
+  /// </summary>
+  [Item("Experiment", "An experiment which contains multiple algorithms, batch runs or other experiments.")]
+  [Creatable(CreatableAttribute.Categories.TestingAndAnalysis, Priority = 100)]
+  [StorableClass]
+  public sealed class Experiment : NamedItem, IOptimizer, IStorableContent {
+    public string Filename { get; set; }
+
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Event; }
+    }
+    public override Image ItemImage {
+      get {
+        if (ExecutionState == ExecutionState.Prepared) return HeuristicLab.Common.Resources.VSImageLibrary.ExperimentPrepared;
+        else if (ExecutionState == ExecutionState.Started) return HeuristicLab.Common.Resources.VSImageLibrary.ExperimentStarted;
+        else if (ExecutionState == ExecutionState.Paused) return HeuristicLab.Common.Resources.VSImageLibrary.ExperimentPaused;
+        else if (ExecutionState == ExecutionState.Stopped) return HeuristicLab.Common.Resources.VSImageLibrary.ExperimentStopped;
+        else return base.ItemImage;
+      }
+    }
+
+    [Storable]
+    private ExecutionState executionState;
+    public ExecutionState ExecutionState {
+      get { return executionState; }
+      private set {
+        if (executionState != value) {
+          executionState = value;
+          OnExecutionStateChanged();
+          OnItemImageChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private TimeSpan executionTime;
+    public TimeSpan ExecutionTime {
+      get { return executionTime; }
+      private set {
+        executionTime = value;
+        OnExecutionTimeChanged();
+      }
+    }
+
+    [Storable]
+    private OptimizerList optimizers;
+    public OptimizerList Optimizers {
+      get { return optimizers; }
+    }
+
+    [Storable]
+    private RunCollection runs;
+    public RunCollection Runs {
+      get { return runs; }
+      private set {
+        if (value == null) throw new ArgumentNullException();
+        if (runs != value) {
+          if (runs != null) DeregisterRunsEvents();
+          runs = value;
+          if (runs != null) RegisterRunsEvents();
+        }
+      }
+    }
+
+    public IEnumerable<IOptimizer> NestedOptimizers {
+      get {
+        if (Optimizers == null) yield break;
+
+        foreach (IOptimizer opt in Optimizers) {
+          yield return opt;
+          foreach (IOptimizer nestedOpt in opt.NestedOptimizers)
+            yield return nestedOpt;
+        }
+      }
+    }
+
+    private bool experimentStarted = false;
+    private bool experimentStopped = false;
+
+    public Experiment()
+      : base() {
+      name = ItemName;
+      description = ItemDescription;
+      executionState = ExecutionState.Stopped;
+      executionTime = TimeSpan.Zero;
+      optimizers = new OptimizerList();
+      Runs = new RunCollection { OptimizerName = Name };
+      Initialize();
+    }
+    public Experiment(string name)
+      : base(name) {
+      description = ItemDescription;
+      executionState = ExecutionState.Stopped;
+      executionTime = TimeSpan.Zero;
+      optimizers = new OptimizerList();
+      Runs = new RunCollection { OptimizerName = Name };
+      Initialize();
+    }
+    public Experiment(string name, string description)
+      : base(name, description) {
+      executionState = ExecutionState.Stopped;
+      executionTime = TimeSpan.Zero;
+      optimizers = new OptimizerList();
+      Runs = new RunCollection { OptimizerName = Name };
+      Initialize();
+    }
+    [StorableConstructor]
+    private Experiment(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      Initialize();
+    }
+    private Experiment(Experiment original, Cloner cloner)
+      : base(original, cloner) {
+      executionState = original.executionState;
+      executionTime = original.executionTime;
+      optimizers = cloner.Clone(original.optimizers);
+      runs = cloner.Clone(original.runs);
+
+      experimentStarted = original.experimentStarted;
+      experimentStopped = original.experimentStopped;
+      Initialize();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      if (ExecutionState == ExecutionState.Started) throw new InvalidOperationException(string.Format("Clone not allowed in execution state \"{0}\".", ExecutionState));
+      return new Experiment(this, cloner);
+    }
+
+    private void Initialize() {
+      RegisterOptimizersEvents();
+      foreach (IOptimizer optimizer in optimizers)
+        RegisterOptimizerEvents(optimizer);
+      if (runs != null) RegisterRunsEvents();
+    }
+
+    public void Prepare() {
+      Prepare(false);
+    }
+    public void Prepare(bool clearRuns) {
+      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped))
+        throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState));
+      if (Optimizers.Count == 0) return;
+
+      if (clearRuns) runs.Clear();
+
+      experimentStarted = false;
+      experimentStopped = false;
+      foreach (IOptimizer optimizer in Optimizers.Where(x => x.ExecutionState != ExecutionState.Started)) {
+        // a race-condition may occur when the optimizer has changed the state by itself in the meantime
+        try { optimizer.Prepare(clearRuns); }
+        catch (InvalidOperationException) { }
+      }
+    }
+    public void Start() {
+      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
+        throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
+      if (Optimizers.Count == 0) return;
+
+      experimentStarted = true;
+      experimentStopped = false;
+      IOptimizer optimizer = Optimizers.FirstOrDefault(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused));
+      if (optimizer != null) {
+        // a race-condition may occur when the optimizer has changed the state by itself in the meantime
+        try { optimizer.Start(); }
+        catch (InvalidOperationException) { }
+      }
+    }
+    public void Pause() {
+      if (ExecutionState != ExecutionState.Started)
+        throw new InvalidOperationException(string.Format("Pause not allowed in execution state \"{0}\".", ExecutionState));
+      if (Optimizers.Count == 0) return;
+
+      experimentStarted = false;
+      experimentStopped = false;
+      foreach (IOptimizer optimizer in Optimizers.Where(x => x.ExecutionState == ExecutionState.Started)) {
+        // a race-condition may occur when the optimizer has changed the state by itself in the meantime
+        try { optimizer.Pause(); }
+        catch (InvalidOperationException) { }
+      }
+    }
+    public void Stop() {
+      if ((ExecutionState != ExecutionState.Started) && (ExecutionState != ExecutionState.Paused))
+        throw new InvalidOperationException(string.Format("Stop not allowed in execution state \"{0}\".", ExecutionState));
+      if (Optimizers.Count == 0) return;
+
+      experimentStarted = false;
+      experimentStopped = true;
+      if (Optimizers.Any(x => (x.ExecutionState == ExecutionState.Started) || (x.ExecutionState == ExecutionState.Paused))) {
+        foreach (var optimizer in Optimizers.Where(x => (x.ExecutionState == ExecutionState.Started) || (x.ExecutionState == ExecutionState.Paused))) {
+          // a race-condition may occur when the optimizer has changed the state by itself in the meantime
+          try { optimizer.Stop(); }
+          catch (InvalidOperationException) { }
+        }
+      } else {
+        OnStopped();
+      }
+    }
+
+    #region Events
+    protected override void OnNameChanged() {
+      base.OnNameChanged();
+      Runs.OptimizerName = Name;
+    }
+
+    public event EventHandler ExecutionStateChanged;
+    private void OnExecutionStateChanged() {
+      EventHandler handler = ExecutionStateChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ExecutionTimeChanged;
+    private void OnExecutionTimeChanged() {
+      EventHandler handler = ExecutionTimeChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Prepared;
+    private void OnPrepared() {
+      ExecutionState = ExecutionState.Prepared;
+      EventHandler handler = Prepared;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Started;
+    private void OnStarted() {
+      ExecutionState = ExecutionState.Started;
+      EventHandler handler = Started;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Paused;
+    private void OnPaused() {
+      ExecutionState = ExecutionState.Paused;
+      EventHandler handler = Paused;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Stopped;
+    private void OnStopped() {
+      ExecutionState = ExecutionState.Stopped;
+      EventHandler handler = Stopped;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
+    private void OnExceptionOccurred(Exception exception) {
+      EventHandler<EventArgs<Exception>> handler = ExceptionOccurred;
+      if (handler != null) handler(this, new EventArgs<Exception>(exception));
+    }
+
+    private void RegisterOptimizersEvents() {
+      Optimizers.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_CollectionReset);
+      Optimizers.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
+      Optimizers.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsRemoved);
+      Optimizers.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
+    }
+    private void DeregisterOptimizersEvents() {
+      Optimizers.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_CollectionReset);
+      Optimizers.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsAdded);
+      Optimizers.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsRemoved);
+      Optimizers.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<IOptimizer>>(Optimizers_ItemsReplaced);
+    }
+    private void Optimizers_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
+      foreach (IndexedItem<IOptimizer> item in e.OldItems)
+        RemoveOptimizer(item.Value);
+      foreach (IndexedItem<IOptimizer> item in e.Items)
+        AddOptimizer(item.Value);
+    }
+    private void Optimizers_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
+      foreach (IndexedItem<IOptimizer> item in e.Items)
+        AddOptimizer(item.Value);
+    }
+    private void Optimizers_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
+      foreach (IndexedItem<IOptimizer> item in e.Items)
+        RemoveOptimizer(item.Value);
+    }
+    private void Optimizers_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
+      foreach (IndexedItem<IOptimizer> item in e.OldItems)
+        RemoveOptimizer(item.Value);
+      foreach (IndexedItem<IOptimizer> item in e.Items)
+        AddOptimizer(item.Value);
+    }
+    private void AddOptimizer(IOptimizer optimizer) {
+      RegisterOptimizerEvents(optimizer);
+      Runs.AddRange(optimizer.Runs);
+      optimizer.Prepare();
+      if (ExecutionState == ExecutionState.Stopped && optimizer.ExecutionState == ExecutionState.Prepared)
+        OnPrepared();
+    }
+    private void RemoveOptimizer(IOptimizer optimizer) {
+      DeregisterOptimizerEvents(optimizer);
+      Runs.RemoveRange(optimizer.Runs);
+      if (ExecutionState == ExecutionState.Prepared && !optimizers.Any(opt => opt.ExecutionState == ExecutionState.Prepared))
+        OnStopped();
+    }
+
+    private void RegisterOptimizerEvents(IOptimizer optimizer) {
+      optimizer.ExceptionOccurred += new EventHandler<EventArgs<Exception>>(optimizer_ExceptionOccurred);
+      optimizer.ExecutionTimeChanged += new EventHandler(optimizer_ExecutionTimeChanged);
+      optimizer.Paused += new EventHandler(optimizer_Paused);
+      optimizer.Prepared += new EventHandler(optimizer_Prepared);
+      optimizer.Started += new EventHandler(optimizer_Started);
+      optimizer.Stopped += new EventHandler(optimizer_Stopped);
+      optimizer.Runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(optimizer_Runs_CollectionReset);
+      optimizer.Runs.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(optimizer_Runs_ItemsAdded);
+      optimizer.Runs.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(optimizer_Runs_ItemsRemoved);
+    }
+    private void DeregisterOptimizerEvents(IOptimizer optimizer) {
+      optimizer.ExceptionOccurred -= new EventHandler<EventArgs<Exception>>(optimizer_ExceptionOccurred);
+      optimizer.ExecutionTimeChanged -= new EventHandler(optimizer_ExecutionTimeChanged);
+      optimizer.Paused -= new EventHandler(optimizer_Paused);
+      optimizer.Prepared -= new EventHandler(optimizer_Prepared);
+      optimizer.Started -= new EventHandler(optimizer_Started);
+      optimizer.Stopped -= new EventHandler(optimizer_Stopped);
+      optimizer.Runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(optimizer_Runs_CollectionReset);
+      optimizer.Runs.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(optimizer_Runs_ItemsAdded);
+      optimizer.Runs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(optimizer_Runs_ItemsRemoved);
+    }
+
+    private readonly object locker = new object();
+    private void optimizer_ExceptionOccurred(object sender, EventArgs<Exception> e) {
+      lock (locker)
+        OnExceptionOccurred(e.Value);
+    }
+    private void optimizer_ExecutionTimeChanged(object sender, EventArgs e) {
+      lock (locker)
+        ExecutionTime = Optimizers.Aggregate(TimeSpan.Zero, (t, o) => t + o.ExecutionTime);
+    }
+    private void optimizer_Paused(object sender, EventArgs e) {
+      lock (locker)
+        if (Optimizers.All(x => x.ExecutionState != ExecutionState.Started)) OnPaused();
+    }
+    private void optimizer_Prepared(object sender, EventArgs e) {
+      lock (locker)
+        if (Optimizers.All(x => x.ExecutionState == ExecutionState.Prepared)) OnPrepared();
+    }
+    private void optimizer_Started(object sender, EventArgs e) {
+      lock (locker)
+        if (ExecutionState != ExecutionState.Started) OnStarted();
+    }
+    private void optimizer_Stopped(object sender, EventArgs e) {
+      lock (locker) {
+        if (experimentStopped) {
+          if (Optimizers.All(x => (x.ExecutionState == ExecutionState.Stopped) || (x.ExecutionState == ExecutionState.Prepared))) OnStopped();
+        } else {
+          if (experimentStarted && Optimizers.Any(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused))) {
+            Optimizers.First(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused)).Start();
+          } else if (Optimizers.All(x => x.ExecutionState == ExecutionState.Stopped)) OnStopped();
+          else if (Optimizers.Any(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused)) && Optimizers.All(o => o.ExecutionState != ExecutionState.Started)) OnPaused();
+        }
+      }
+    }
+    private void optimizer_Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      lock (locker) {
+        Runs.RemoveRange(e.OldItems);
+        Runs.AddRange(e.Items);
+      }
+    }
+    private void optimizer_Runs_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      lock (locker)
+        Runs.AddRange(e.Items);
+    }
+    private void optimizer_Runs_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      lock (locker)
+        Runs.RemoveRange(e.Items);
+    }
+
+    private void RegisterRunsEvents() {
+      runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
+      runs.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsRemoved);
+    }
+    private void DeregisterRunsEvents() {
+      runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
+      runs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsRemoved);
+    }
+    private void Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      foreach (IOptimizer optimizer in Optimizers)
+        optimizer.Runs.RemoveRange(e.OldItems);
+    }
+    private void Runs_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      foreach (IOptimizer optimizer in Optimizers)
+        optimizer.Runs.RemoveRange(e.Items);
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/MetaOptimizers/TimeLimitRun.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/MetaOptimizers/TimeLimitRun.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/MetaOptimizers/TimeLimitRun.cs	(revision 12764)
@@ -0,0 +1,393 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Threading.Tasks;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Common.Resources;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// A run in which an algorithm is executed for a certain maximum time only.
+  /// </summary>
+  [Item("Timelimit Run", "A run in which an optimizer is executed a certain maximum time.")]
+  [Creatable(CreatableAttribute.Categories.TestingAndAnalysis, Priority = 115)]
+  [StorableClass]
+  public sealed class TimeLimitRun : NamedItem, IOptimizer, IStorableContent, INotifyPropertyChanged {
+    public string Filename { get; set; }
+
+    #region ItemImage
+    public static new Image StaticItemImage {
+      get { return VSImageLibrary.Event; }
+    }
+    public override Image ItemImage {
+      get { return (Algorithm != null) ? Algorithm.ItemImage : VSImageLibrary.ExecutableStopped; }
+    }
+    #endregion
+
+    private bool pausedForSnapshot = false;
+    private bool pausedForTermination = false;
+
+    [Storable]
+    private TimeSpan maximumExecutionTime;
+    public TimeSpan MaximumExecutionTime {
+      get { return maximumExecutionTime; }
+      set {
+        if (maximumExecutionTime == value) return;
+        maximumExecutionTime = value;
+        OnPropertyChanged("MaximumExecutionTime");
+      }
+    }
+
+    [Storable]
+    private int snapshotTimesIndex;
+    [Storable]
+    private ObservableList<TimeSpan> snapshotTimes;
+    public ObservableList<TimeSpan> SnapshotTimes {
+      get { return snapshotTimes; }
+      set {
+        if (snapshotTimes == value) return;
+        snapshotTimes = value;
+        snapshotTimes.Sort();
+        FindNextSnapshotTimeIndex(ExecutionTime);
+        OnPropertyChanged("SnapshotTimes");
+      }
+    }
+
+    [Storable]
+    private bool storeAlgorithmInEachSnapshot;
+    [Storable]
+    public bool StoreAlgorithmInEachSnapshot {
+      get { return storeAlgorithmInEachSnapshot; }
+      set {
+        if (storeAlgorithmInEachSnapshot == value) return;
+        storeAlgorithmInEachSnapshot = value;
+        OnPropertyChanged("StoreAlgorithmInEachSnapshot");
+      }
+    }
+
+    [Storable]
+    private RunCollection snapshots;
+    public RunCollection Snapshots {
+      get { return snapshots; }
+      set {
+        if (snapshots == value) return;
+        snapshots = value;
+        OnPropertyChanged("Snapshots");
+      }
+    }
+
+    #region Inherited Properties
+    public ExecutionState ExecutionState {
+      get { return (Algorithm != null) ? Algorithm.ExecutionState : ExecutionState.Stopped; }
+    }
+
+    public TimeSpan ExecutionTime {
+      get { return (Algorithm != null) ? Algorithm.ExecutionTime : TimeSpan.FromSeconds(0); }
+    }
+
+    [Storable]
+    private IAlgorithm algorithm;
+    public IAlgorithm Algorithm {
+      get { return algorithm; }
+      set {
+        if (algorithm == value) return;
+        if (algorithm != null) DeregisterAlgorithmEvents();
+        algorithm = value;
+        if (algorithm != null) {
+          RegisterAlgorithmEvents();
+        }
+        OnPropertyChanged("Algorithm");
+        Prepare();
+      }
+    }
+
+    [Storable]
+    private RunCollection runs;
+    public RunCollection Runs {
+      get { return runs; }
+      private set {
+        if (value == null) throw new ArgumentNullException();
+        if (runs == value) return;
+        runs = value;
+        OnPropertyChanged("Runs");
+      }
+    }
+
+    public IEnumerable<IOptimizer> NestedOptimizers {
+      get {
+        if (Algorithm == null) yield break;
+        yield return Algorithm;
+        foreach (var opt in Algorithm.NestedOptimizers)
+          yield return opt;
+      }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private TimeLimitRun(bool deserializing) : base(deserializing) { }
+    private TimeLimitRun(TimeLimitRun original, Cloner cloner)
+      : base(original, cloner) {
+      maximumExecutionTime = original.maximumExecutionTime;
+      snapshotTimes = new ObservableList<TimeSpan>(original.snapshotTimes);
+      snapshotTimesIndex = original.snapshotTimesIndex;
+      snapshots = cloner.Clone(original.snapshots);
+      storeAlgorithmInEachSnapshot = original.storeAlgorithmInEachSnapshot;
+      algorithm = cloner.Clone(original.algorithm);
+      runs = cloner.Clone(original.runs);
+
+      Initialize();
+    }
+    public TimeLimitRun()
+      : base() {
+      name = ItemName;
+      description = ItemDescription;
+      maximumExecutionTime = TimeSpan.FromMinutes(.5);
+      snapshotTimes = new ObservableList<TimeSpan>(new[] {
+          TimeSpan.FromSeconds(5),
+          TimeSpan.FromSeconds(10),
+          TimeSpan.FromSeconds(15) });
+      snapshotTimesIndex = 0;
+      snapshots = new RunCollection();
+      Runs = new RunCollection { OptimizerName = Name };
+      Initialize();
+    }
+    public TimeLimitRun(string name)
+      : base(name) {
+      description = ItemDescription;
+      maximumExecutionTime = TimeSpan.FromMinutes(.5);
+      snapshotTimes = new ObservableList<TimeSpan>(new[] {
+          TimeSpan.FromSeconds(5),
+          TimeSpan.FromSeconds(10),
+          TimeSpan.FromSeconds(15) });
+      snapshotTimesIndex = 0;
+      Runs = new RunCollection { OptimizerName = Name };
+      Initialize();
+    }
+    public TimeLimitRun(string name, string description)
+      : base(name, description) {
+      maximumExecutionTime = TimeSpan.FromMinutes(.5);
+      snapshotTimes = new ObservableList<TimeSpan>(new[] {
+          TimeSpan.FromSeconds(5),
+          TimeSpan.FromSeconds(10),
+          TimeSpan.FromSeconds(15) });
+      snapshotTimesIndex = 0;
+      Runs = new RunCollection { OptimizerName = Name };
+      Initialize();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      if (ExecutionState == ExecutionState.Started) throw new InvalidOperationException(string.Format("Clone not allowed in execution state \"{0}\".", ExecutionState));
+      return new TimeLimitRun(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      Initialize();
+    }
+
+    private void Initialize() {
+      if (algorithm != null) RegisterAlgorithmEvents();
+      snapshotTimes.ItemsAdded += snapshotTimes_Changed;
+      snapshotTimes.ItemsMoved += snapshotTimes_Changed;
+      snapshotTimes.ItemsRemoved += snapshotTimes_Changed;
+      snapshotTimes.ItemsReplaced += snapshotTimes_Changed;
+      snapshotTimes.CollectionReset += snapshotTimes_Changed;
+    }
+
+    private void snapshotTimes_Changed(object sender, CollectionItemsChangedEventArgs<IndexedItem<TimeSpan>> e) {
+      if (e.Items.Any()) snapshotTimes.Sort();
+      FindNextSnapshotTimeIndex(ExecutionTime);
+    }
+
+    public void Snapshot() {
+      if (Algorithm == null || Algorithm.ExecutionState != ExecutionState.Paused) throw new InvalidOperationException("Snapshot not allowed in execution states other than Paused");
+      Task.Factory.StartNew(MakeSnapshot);
+    }
+
+    public void Prepare() {
+      Prepare(false);
+    }
+    public void Prepare(bool clearRuns) {
+      Algorithm.Prepare(clearRuns);
+    }
+    public void Start() {
+      Algorithm.Start();
+    }
+    public void Pause() {
+      Algorithm.Pause();
+    }
+    public void Stop() {
+      Algorithm.Stop();
+    }
+
+    #region Events
+    protected override void OnNameChanged() {
+      base.OnNameChanged();
+      runs.OptimizerName = Name;
+    }
+
+    public event PropertyChangedEventHandler PropertyChanged;
+    private void OnPropertyChanged(string property) {
+      var handler = PropertyChanged;
+      if (handler != null) handler(this, new PropertyChangedEventArgs(property));
+    }
+
+    #region IExecutable Events
+    public event EventHandler ExecutionStateChanged;
+    private void OnExecutionStateChanged() {
+      var handler = ExecutionStateChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler ExecutionTimeChanged;
+    private void OnExecutionTimeChanged() {
+      var handler = ExecutionTimeChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Prepared;
+    private void OnPrepared() {
+      var handler = Prepared;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Started;
+    private void OnStarted() {
+      var handler = Started;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Paused;
+    private void OnPaused() {
+      var handler = Paused;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Stopped;
+    private void OnStopped() {
+      var handler = Stopped;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
+    private void OnExceptionOccurred(Exception exception) {
+      var handler = ExceptionOccurred;
+      if (handler != null) handler(this, new EventArgs<Exception>(exception));
+    }
+    #endregion
+
+    #region Algorithm Events
+    private void RegisterAlgorithmEvents() {
+      algorithm.ExceptionOccurred += Algorithm_ExceptionOccurred;
+      algorithm.ExecutionTimeChanged += Algorithm_ExecutionTimeChanged;
+      algorithm.ExecutionStateChanged += Algorithm_ExecutionStateChanged;
+      algorithm.Paused += Algorithm_Paused;
+      algorithm.Prepared += Algorithm_Prepared;
+      algorithm.Started += Algorithm_Started;
+      algorithm.Stopped += Algorithm_Stopped;
+    }
+    private void DeregisterAlgorithmEvents() {
+      algorithm.ExceptionOccurred -= Algorithm_ExceptionOccurred;
+      algorithm.ExecutionTimeChanged -= Algorithm_ExecutionTimeChanged;
+      algorithm.ExecutionStateChanged -= Algorithm_ExecutionStateChanged;
+      algorithm.Paused -= Algorithm_Paused;
+      algorithm.Prepared -= Algorithm_Prepared;
+      algorithm.Started -= Algorithm_Started;
+      algorithm.Stopped -= Algorithm_Stopped;
+    }
+    private void Algorithm_ExceptionOccurred(object sender, EventArgs<Exception> e) {
+      OnExceptionOccurred(e.Value);
+    }
+    private void Algorithm_ExecutionTimeChanged(object sender, EventArgs e) {
+      if (snapshotTimesIndex < SnapshotTimes.Count && ExecutionTime >= SnapshotTimes[snapshotTimesIndex]
+        && !pausedForSnapshot) {
+        pausedForSnapshot = true;
+        Algorithm.Pause();
+      }
+      if (ExecutionTime >= MaximumExecutionTime && !pausedForTermination) {
+        pausedForTermination = true;
+        if (!pausedForSnapshot) Algorithm.Pause();
+      }
+      OnExecutionTimeChanged();
+    }
+    private void Algorithm_ExecutionStateChanged(object sender, EventArgs e) {
+      OnExecutionStateChanged();
+    }
+    private void Algorithm_Paused(object sender, EventArgs e) {
+      var action = pausedForTermination ? ExecutionState.Stopped : (pausedForSnapshot ? ExecutionState.Started : ExecutionState.Paused);
+      if (pausedForSnapshot || pausedForTermination) {
+        pausedForSnapshot = pausedForTermination = false;
+        MakeSnapshot();
+        FindNextSnapshotTimeIndex(ExecutionTime);
+      }
+      OnPaused();
+      if (action == ExecutionState.Started) Algorithm.Start();
+      else if (action == ExecutionState.Stopped) Algorithm.Stop();
+    }
+    private void Algorithm_Prepared(object sender, EventArgs e) {
+      snapshotTimesIndex = 0;
+      snapshots.Clear();
+      OnPrepared();
+    }
+    private void Algorithm_Started(object sender, EventArgs e) {
+      OnStarted();
+    }
+    private void Algorithm_Stopped(object sender, EventArgs e) {
+      var cloner = new Cloner();
+      var algRun = cloner.Clone(Algorithm.Runs.Last());
+      var clonedSnapshots = cloner.Clone(snapshots);
+      algRun.Results.Add("TimeLimitRunSnapshots", clonedSnapshots);
+      Runs.Add(algRun);
+      Algorithm.Runs.Clear();
+      OnStopped();
+    }
+    #endregion
+    #endregion
+
+    private void FindNextSnapshotTimeIndex(TimeSpan reference) {
+      var index = 0;
+      while (index < snapshotTimes.Count && snapshotTimes[index] <= reference) {
+        index++;
+      };
+      snapshotTimesIndex = index;
+    }
+
+    private void MakeSnapshot() {
+      string time = Math.Round(ExecutionTime.TotalSeconds, 1).ToString("0.0");
+      string runName = "Snapshot " + time + "s " + algorithm.Name;
+      var changed = false;
+      if (StoreAlgorithmInEachSnapshot && !Algorithm.StoreAlgorithmInEachRun) {
+        Algorithm.StoreAlgorithmInEachRun = true;
+        changed = true;
+      } else if (!StoreAlgorithmInEachSnapshot && Algorithm.StoreAlgorithmInEachRun) {
+        Algorithm.StoreAlgorithmInEachRun = false;
+        changed = true;
+      }
+      var run = new Run(runName, Algorithm);
+      if (changed)
+        Algorithm.StoreAlgorithmInEachRun = !Algorithm.StoreAlgorithmInEachRun;
+
+      snapshots.Add(run);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/MoveHelper.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/MoveHelper.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/MoveHelper.cs	(revision 12764)
@@ -0,0 +1,66 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// This class provides some methods useful when dealing with moves, such as getting compatible move makers to a move generator.
+  /// Compatibility is generally ensured in that both the generator and the move maker implement the same specific interface which is derived from IMoveOperator
+  /// </summary>
+  public static class MoveHelper {
+
+    public static IEnumerable<IMoveMaker> GetCompatibleMoveMakers(IMoveGenerator generator, IEnumerable<IOperator> operators) {
+      return GetCompatibleOperators<IMoveMaker>(generator, operators);
+    }
+
+    public static IEnumerable<ISingleObjectiveMoveEvaluator> GetCompatibleSingleObjectiveMoveEvaluators(IMoveGenerator generator, IEnumerable<IOperator> operators) {
+      return GetCompatibleOperators<ISingleObjectiveMoveEvaluator>(generator, operators);
+    }
+
+    public static IEnumerable<ITabuChecker> GetCompatibleTabuChekers(IMoveGenerator generator, IEnumerable<IOperator> operators) {
+      return GetCompatibleOperators<ITabuChecker>(generator, operators);
+    }
+
+    public static IEnumerable<ITabuMaker> GetCompatibleTabuMakers(IMoveGenerator generator, IEnumerable<IOperator> operators) {
+      return GetCompatibleOperators<ITabuMaker>(generator, operators);
+    }
+
+    private static IEnumerable<T> GetCompatibleOperators<T>(IMoveGenerator generator, IEnumerable<IOperator> operators) where T : IOperator {
+      foreach (Type type in GetMostSpecificMoveOperatorTypes(generator)) {
+        foreach (T op in operators.Where(x => type.IsAssignableFrom(x.GetType())).OfType<T>())
+          yield return op;
+      }
+    }
+
+    private static List<Type> GetMostSpecificMoveOperatorTypes(IMoveGenerator generator) {
+      List<Type> moveTypes = generator.GetType().GetInterfaces().Where(x => typeof(IMoveOperator).IsAssignableFrom(x)).ToList();
+      foreach (Type type in moveTypes.ToList()) {
+        if (moveTypes.Any(t => t != type && type.IsAssignableFrom(t)))
+          moveTypes.Remove(type);
+      }
+      return moveTypes;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/OptimizerList.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/OptimizerList.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/OptimizerList.cs	(revision 12764)
@@ -0,0 +1,43 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("Optimizer List", "Represents a list of optimizers.")]
+  [StorableClass]
+  public class OptimizerList : ItemList<IOptimizer> {
+    public OptimizerList() : base() { }
+    public OptimizerList(int capacity) : base(capacity) { }
+    public OptimizerList(IEnumerable<IOptimizer> collection) : base(collection) { }
+    [StorableConstructor]
+    protected OptimizerList(bool deserializing) : base(deserializing) { }
+    protected OptimizerList(OptimizerList original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OptimizerList(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Plugin.cs.frame
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Plugin.cs.frame	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Plugin.cs.frame	(revision 12764)
@@ -0,0 +1,40 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// Plugin class for HeuristicLab.Optimization plugin.
+  /// </summary>
+  [Plugin("HeuristicLab.Optimization", "3.3.12.$WCREV$")]
+  [PluginFile("HeuristicLab.Optimization-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  public class HeuristicLabOptimizationPlugin : PluginBase {
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Problems/HeuristicOptimizationProblem.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Problems/HeuristicOptimizationProblem.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Problems/HeuristicOptimizationProblem.cs	(revision 12764)
@@ -0,0 +1,112 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("Heuristic Optimization Problem", "Represents the base class for a heuristic optimization problem.")]
+  [StorableClass]
+  public abstract class HeuristicOptimizationProblem<T, U> : Problem, IHeuristicOptimizationProblem
+    where T : class,IEvaluator
+    where U : class,ISolutionCreator {
+    private const string EvaluatorParameterName = "Evaluator";
+    private const string SolutionCreateParameterName = "SolutionCreator";
+
+    [StorableConstructor]
+    protected HeuristicOptimizationProblem(bool deserializing) : base(deserializing) { }
+    protected HeuristicOptimizationProblem(HeuristicOptimizationProblem<T, U> original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterEventHandlers();
+    }
+
+    protected HeuristicOptimizationProblem()
+      : base() {
+      Parameters.Add(new ValueParameter<T>(EvaluatorParameterName, "The operator used to evaluate a solution."));
+      Parameters.Add(new ValueParameter<U>(SolutionCreateParameterName, "The operator to create a solution."));
+      RegisterEventHandlers();
+    }
+
+    protected HeuristicOptimizationProblem(T evaluator, U solutionCreator)
+      : base() {
+      Parameters.Add(new ValueParameter<T>(EvaluatorParameterName, "The operator used to evaluate a solution.", evaluator));
+      Parameters.Add(new ValueParameter<U>(SolutionCreateParameterName, "The operator to create a solution.", solutionCreator));
+      RegisterEventHandlers();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEventHandlers();
+    }
+
+    private void RegisterEventHandlers() {
+      EvaluatorParameter.ValueChanged += new EventHandler(EvaluatorParameter_ValueChanged);
+      SolutionCreatorParameter.ValueChanged += new EventHandler(SolutionCreatorParameter_ValueChanged);
+    }
+
+    #region properties
+    public T Evaluator {
+      get { return EvaluatorParameter.Value; }
+      protected set { EvaluatorParameter.Value = value; }
+    }
+    public ValueParameter<T> EvaluatorParameter {
+      get { return (ValueParameter<T>)Parameters[EvaluatorParameterName]; }
+    }
+    IEvaluator IHeuristicOptimizationProblem.Evaluator { get { return Evaluator; } }
+    IParameter IHeuristicOptimizationProblem.EvaluatorParameter { get { return EvaluatorParameter; } }
+
+    public U SolutionCreator {
+      get { return (U)SolutionCreatorParameter.Value; }
+      protected set { SolutionCreatorParameter.Value = value; }
+    }
+    public IValueParameter SolutionCreatorParameter {
+      get { return (IValueParameter)Parameters[SolutionCreateParameterName]; }
+    }
+    ISolutionCreator IHeuristicOptimizationProblem.SolutionCreator { get { return SolutionCreator; } }
+    IParameter IHeuristicOptimizationProblem.SolutionCreatorParameter { get { return SolutionCreatorParameter; } }
+    #endregion
+
+    #region events
+    private void EvaluatorParameter_ValueChanged(object sender, EventArgs e) {
+      OnEvaluatorChanged();
+    }
+    public event EventHandler EvaluatorChanged;
+    protected virtual void OnEvaluatorChanged() {
+      EventHandler handler = EvaluatorChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+
+    protected virtual void SolutionCreatorParameter_ValueChanged(object sender, EventArgs e) {
+      OnSolutionCreatorChanged();
+    }
+    public event EventHandler SolutionCreatorChanged;
+    protected virtual void OnSolutionCreatorChanged() {
+      EventHandler handler = SolutionCreatorChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Problems/MultiObjectiveHeuristicOptimizationProblem.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Problems/MultiObjectiveHeuristicOptimizationProblem.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Problems/MultiObjectiveHeuristicOptimizationProblem.cs	(revision 12764)
@@ -0,0 +1,64 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("Multi-Objective Heuristic Optimization Problem", "A base class for multi-objective heuristic optimization problems.")]
+  [StorableClass]
+  public abstract class MultiObjectiveHeuristicOptimizationProblem<T, U> : HeuristicOptimizationProblem<T, U>, IMultiObjectiveHeuristicOptimizationProblem
+    where T : class, IMultiObjectiveEvaluator
+    where U : class, ISolutionCreator {
+    private const string MaximizationParameterName = "Maximization";
+
+    [StorableConstructor]
+    protected MultiObjectiveHeuristicOptimizationProblem(bool deserializing) : base(deserializing) { }
+    protected MultiObjectiveHeuristicOptimizationProblem(MultiObjectiveHeuristicOptimizationProblem<T, U> original, Cloner cloner) : base(original, cloner) { }
+    protected MultiObjectiveHeuristicOptimizationProblem()
+      : base() {
+      Parameters.Add(new ValueParameter<BoolArray>(MaximizationParameterName, "Determines for each objective whether it should be maximized or minimized."));
+    }
+
+    protected MultiObjectiveHeuristicOptimizationProblem(T evaluator, U solutionCreator)
+      : base(evaluator, solutionCreator) {
+      Parameters.Add(new ValueParameter<BoolArray>(MaximizationParameterName, "Determines for each objective whether it should be maximized or minimized."));
+    }
+
+    public ValueParameter<BoolArray> MaximizationParameter {
+      get { return (ValueParameter<BoolArray>)Parameters[MaximizationParameterName]; }
+    }
+    IParameter IMultiObjectiveHeuristicOptimizationProblem.MaximizationParameter {
+      get { return MaximizationParameter; }
+    }
+    public BoolArray Maximization {
+      get { return MaximizationParameter.Value; }
+      protected set { MaximizationParameter.Value = value; }
+    }
+
+    IMultiObjectiveEvaluator IMultiObjectiveHeuristicOptimizationProblem.Evaluator {
+      get { return Evaluator; }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Problems/Problem.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Problems/Problem.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Problems/Problem.cs	(revision 12764)
@@ -0,0 +1,155 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("Problem", "Represents the base class for a problem.")]
+  [StorableClass]
+  public abstract class Problem : ParameterizedNamedItem, IProblem {
+    private const string OperatorsParameterName = "Operators";
+    public IFixedValueParameter<ItemCollection<IItem>> OperatorsParameter {
+      get { return (IFixedValueParameter<ItemCollection<IItem>>)Parameters[OperatorsParameterName]; }
+    }
+
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Type; }
+    }
+
+    [StorableConstructor]
+    protected Problem(bool deserializing) : base(deserializing) { }
+    protected Problem(Problem original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterEventHandlers();
+    }
+
+    protected Problem()
+      : base() {
+      Parameters.Add(new FixedValueParameter<ItemCollection<IItem>>(OperatorsParameterName, "The operators and items that the problem provides to the algorithms.", new ItemCollection<IItem>(), false));
+      OperatorsParameter.Hidden = true;
+      RegisterEventHandlers();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code, remove with 3.4
+      IParameter operatorsParam;
+      if (Parameters.TryGetValue(OperatorsParameterName, out operatorsParam)) {
+        var operators = operatorsParam.ActualValue as OperatorCollection;
+        if (operators != null) {
+          Parameters.Remove(OperatorsParameterName);
+          Parameters.Add(new FixedValueParameter<ItemCollection<IItem>>(OperatorsParameterName, "The operators and items that the problem provides to the algorithms.", new ItemCollection<IItem>(operators), false));
+          OperatorsParameter.Hidden = true;
+        }
+      }
+      #endregion
+
+      RegisterEventHandlers();
+    }
+
+    private void RegisterEventHandlers() {
+      Operators.ItemsAdded += new CollectionItemsChangedEventHandler<IItem>(Operators_Changed);
+      Operators.ItemsRemoved += new CollectionItemsChangedEventHandler<IItem>(Operators_Changed);
+      Operators.CollectionReset += new CollectionItemsChangedEventHandler<IItem>(Operators_Changed);
+    }
+
+    #region properties
+    // BackwardsCompatibility3.3
+    #region Backwards compatible code, remove with 3.4
+    [Storable(Name = "Operators", AllowOneWay = true)]
+    private IEnumerable<IOperator> StorableOperators {
+      set {
+        IParameter operatorsParam;
+        if (Parameters.TryGetValue(OperatorsParameterName, out operatorsParam)) {
+          var items = operatorsParam.ActualValue as ItemCollection<IItem>;
+          if (items == null) Parameters.Remove(operatorsParam);
+        }
+
+        //necessary to convert old experiments files where no parameter was used for saving the operators
+        if (!Parameters.ContainsKey(OperatorsParameterName)) {
+          Parameters.Add(new FixedValueParameter<ItemCollection<IItem>>(OperatorsParameterName, "The operators and items that the problem provides to the algorithms.", new ItemCollection<IItem>(), false));
+          OperatorsParameter.Hidden = true;
+        }
+        if (value != null) Operators.AddRange(value);
+      }
+    }
+    #endregion
+    protected ItemCollection<IItem> Operators {
+      get {
+        // BackwardsCompatibility3.3
+        #region Backwards compatible code, remove with 3.4
+        if (!Parameters.ContainsKey(OperatorsParameterName)) {
+          Parameters.Add(new FixedValueParameter<ItemCollection<IItem>>(OperatorsParameterName, "The operators and items that the problem provides to the algorithms.", new ItemCollection<IItem>(), false));
+          OperatorsParameter.Hidden = true;
+        }
+        #endregion
+        return OperatorsParameter.Value;
+      }
+    }
+    IEnumerable<IItem> IProblem.Operators { get { return GetOperators(); } }
+
+    protected virtual IEnumerable<IItem> GetOperators() {
+      return Operators;
+    }
+
+    public virtual IEnumerable<IParameterizedItem> ExecutionContextItems {
+      get { yield return this; }
+    }
+    #endregion
+
+    protected override IEnumerable<KeyValuePair<string, IItem>> GetCollectedValues(IValueParameter param) {
+      var children = base.GetCollectedValues(param);
+      foreach (var child in children) {
+        if (child.Value is IOperator)
+          yield return new KeyValuePair<string, IItem>(child.Key, new StringValue(((IOperator)child.Value).Name));
+        else yield return child;
+      }
+    }
+
+    #region events
+    private void Operators_Changed(object sender, EventArgs e) {
+      OnOperatorsChanged();
+    }
+    public event EventHandler OperatorsChanged;
+    protected virtual void OnOperatorsChanged() {
+      EventHandler handler = OperatorsChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler Reset;
+    protected virtual void OnReset() {
+      EventHandler handler = Reset;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Problems/SingleObjectiveHeuristicOptimizationProblem.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Problems/SingleObjectiveHeuristicOptimizationProblem.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Problems/SingleObjectiveHeuristicOptimizationProblem.cs	(revision 12764)
@@ -0,0 +1,88 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("Single-Objective Heuristic OptimizationProblem", "A base class for single-objective heuristic optimization problems.")]
+  [StorableClass]
+  public abstract class SingleObjectiveHeuristicOptimizationProblem<T, U> : HeuristicOptimizationProblem<T, U>, ISingleObjectiveHeuristicOptimizationProblem
+    where T : class, ISingleObjectiveEvaluator
+    where U : class, ISolutionCreator {
+    private const string MaximizationParameterName = "Maximization";
+    private const string BestKnownQualityParameterName = "BestKnownQuality";
+
+    [StorableConstructor]
+    protected SingleObjectiveHeuristicOptimizationProblem(bool deserializing) : base(deserializing) { }
+    protected SingleObjectiveHeuristicOptimizationProblem(SingleObjectiveHeuristicOptimizationProblem<T, U> original, Cloner cloner) : base(original, cloner) { }
+    protected SingleObjectiveHeuristicOptimizationProblem()
+      : base() {
+      Parameters.Add(new ValueParameter<BoolValue>(MaximizationParameterName, "Set to false if the problem should be minimized.", new BoolValue()));
+      Parameters.Add(new OptionalValueParameter<DoubleValue>(BestKnownQualityParameterName, "The quality of the best known solution of this problem."));
+    }
+
+    protected SingleObjectiveHeuristicOptimizationProblem(T evaluator, U solutionCreator)
+      : base(evaluator, solutionCreator) {
+      Parameters.Add(new ValueParameter<BoolValue>(MaximizationParameterName, "Set to false if the problem should be minimized.", new BoolValue()));
+      Parameters.Add(new OptionalValueParameter<DoubleValue>(BestKnownQualityParameterName, "The quality of the best known solution of this problem."));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code (remove with 3.4)
+      if (BestKnownQualityParameter is ValueParameter<DoubleValue>) {
+        Parameters.Remove(BestKnownQualityParameterName);
+        Parameters.Add(new OptionalValueParameter<DoubleValue>(BestKnownQualityParameterName, "The quality of the best known solution of this problem."));
+      }
+      #endregion
+    }
+    public ValueParameter<BoolValue> MaximizationParameter {
+      get { return (ValueParameter<BoolValue>)Parameters[MaximizationParameterName]; }
+    }
+    IParameter ISingleObjectiveHeuristicOptimizationProblem.MaximizationParameter {
+      get { return MaximizationParameter; }
+    }
+    public BoolValue Maximization {
+      get { return MaximizationParameter.Value; }
+      set { MaximizationParameter.Value = value; }
+    }
+
+    public IValueParameter<DoubleValue> BestKnownQualityParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters[BestKnownQualityParameterName]; }
+    }
+    IParameter ISingleObjectiveHeuristicOptimizationProblem.BestKnownQualityParameter {
+      get { return BestKnownQualityParameter; }
+    }
+    public DoubleValue BestKnownQuality {
+      get { return BestKnownQualityParameter.Value; }
+      set { BestKnownQualityParameter.Value = value; }
+    }
+
+    ISingleObjectiveEvaluator ISingleObjectiveHeuristicOptimizationProblem.Evaluator {
+      get { return Evaluator; }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Problems/UserDefinedProblem.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Problems/UserDefinedProblem.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Problems/UserDefinedProblem.cs	(revision 12764)
@@ -0,0 +1,283 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// A problem which can be defined by the user.
+  /// </summary>
+  [Item("User-Defined Problem", "A problem which can be defined by the user.")]
+  [Creatable(CreatableAttribute.Categories.Problems, Priority = 120)]
+  [StorableClass]
+  public sealed class UserDefinedProblem : ParameterizedNamedItem, ISingleObjectiveHeuristicOptimizationProblem, IStorableContent {
+    public string Filename { get; set; }
+
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Type; }
+    }
+    public new ParameterCollection Parameters {
+      get { return base.Parameters; }
+    }
+    IKeyedItemCollection<string, IParameter> IParameterizedItem.Parameters {
+      get { return Parameters; }
+    }
+
+    #region Parameters
+    public IValueParameter<ISingleObjectiveEvaluator> EvaluatorParameter {
+      get { return (IValueParameter<ISingleObjectiveEvaluator>)Parameters["Evaluator"]; }
+    }
+    public ValueParameter<BoolValue> MaximizationParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    IParameter ISingleObjectiveHeuristicOptimizationProblem.MaximizationParameter {
+      get { return MaximizationParameter; }
+    }
+    public ValueParameter<ISolutionCreator> SolutionCreatorParameter {
+      get { return (ValueParameter<ISolutionCreator>)Parameters["SolutionCreator"]; }
+    }
+    IParameter IHeuristicOptimizationProblem.SolutionCreatorParameter {
+      get { return SolutionCreatorParameter; }
+    }
+    IParameter IHeuristicOptimizationProblem.EvaluatorParameter {
+      get { return EvaluatorParameter; }
+    }
+    public OptionalValueParameter<DoubleValue> BestKnownQualityParameter {
+      get { return (OptionalValueParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
+    }
+    IParameter ISingleObjectiveHeuristicOptimizationProblem.BestKnownQualityParameter {
+      get { return BestKnownQualityParameter; }
+    }
+    public OptionalValueParameter<IScope> BestKnownSolutionParameter {
+      get { return (OptionalValueParameter<IScope>)Parameters["BestKnownSolution"]; }
+    }
+    public ValueParameter<ItemList<IItem>> OperatorsParameter {
+      get { return (ValueParameter<ItemList<IItem>>)Parameters["Operators"]; }
+    }
+    #endregion
+
+    #region Properties
+    public BoolValue Maximization {
+      get { return MaximizationParameter.Value; }
+      set { MaximizationParameter.Value = value; }
+    }
+    public ISolutionCreator SolutionCreator {
+      get { return SolutionCreatorParameter.Value; }
+      set { SolutionCreatorParameter.Value = value; }
+    }
+    ISolutionCreator IHeuristicOptimizationProblem.SolutionCreator {
+      get { return SolutionCreatorParameter.Value; }
+    }
+    public ISingleObjectiveEvaluator Evaluator {
+      get { return EvaluatorParameter.Value; }
+      set { EvaluatorParameter.Value = value; }
+    }
+    ISingleObjectiveEvaluator ISingleObjectiveHeuristicOptimizationProblem.Evaluator {
+      get { return EvaluatorParameter.Value; }
+    }
+    IEvaluator IHeuristicOptimizationProblem.Evaluator {
+      get { return EvaluatorParameter.Value; }
+    }
+    public DoubleValue BestKnownQuality {
+      get { return BestKnownQualityParameter.Value; }
+      set { BestKnownQualityParameter.Value = value; }
+    }
+    public IEnumerable<IItem> Operators {
+      get { return OperatorsParameter.Value; }
+    }
+
+    public IEnumerable<IParameterizedItem> ExecutionContextItems {
+      get { yield return this; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private UserDefinedProblem(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code, remove with 3.4
+      if (Parameters.ContainsKey("Operators") && Parameters["Operators"] is ValueParameter<ItemList<IOperator>>) {
+        ItemList<IOperator> tmp = ((ValueParameter<ItemList<IOperator>>)Parameters["Operators"]).Value;
+        Parameters.Remove("Operators");
+        Parameters.Add(new ValueParameter<ItemList<IItem>>("Operators", "The operators and items that the problem provides to the algorithms.", new ItemList<IItem>(tmp), false));
+      }
+      #endregion
+
+      RegisterEventHandlers();
+    }
+    public UserDefinedProblem()
+      : base() {
+      Parameters.Add(new ValueParameter<ISingleObjectiveEvaluator>("Evaluator", "The evaluator that collects the values to exchange.", new EmptyUserDefinedProblemEvaluator()));
+      Parameters.Add(new ValueParameter<ISolutionCreator>("SolutionCreator", "An operator to create the solution components."));
+      Parameters.Add(new ValueParameter<BoolValue>("Maximization", "Set to false as most test functions are minimization problems.", new BoolValue(false)));
+      Parameters.Add(new OptionalValueParameter<DoubleValue>("BestKnownQuality", "The quality of the best known solution of this problem."));
+      Parameters.Add(new OptionalValueParameter<IScope>("BestKnownSolution", "The best known solution for this external evaluation problem."));
+      Parameters.Add(new ValueParameter<ItemList<IItem>>("Operators", "The operators and items that the problem provides to the algorithms.", new ItemList<IItem>()));
+
+      RegisterEventHandlers();
+    }
+
+    private UserDefinedProblem(UserDefinedProblem original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterEventHandlers();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new UserDefinedProblem(this, cloner);
+    }
+
+    #region Events
+    public event EventHandler SolutionCreatorChanged;
+    private void OnSolutionCreatorChanged() {
+      EventHandler handler = SolutionCreatorChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler EvaluatorChanged;
+    private void OnEvaluatorChanged() {
+      EventHandler handler = EvaluatorChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler OperatorsChanged;
+    private void OnOperatorsChanged() {
+      EventHandler handler = OperatorsChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler Reset;
+    private void OnReset() {
+      EventHandler handler = Reset;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    #endregion
+
+    #region Event handlers
+    private void SolutionCreatorParameter_ValueChanged(object sender, EventArgs e) {
+      OnSolutionCreatorChanged();
+    }
+    private void EvaluatorParameter_ValueChanged(object sender, EventArgs e) {
+      if (Evaluator != null)
+        Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
+      ParameterizeOperators();
+      OnEvaluatorChanged();
+    }
+    private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
+      ParameterizeOperators();
+    }
+    private void OperatorsParameter_ValueChanged(object sender, EventArgs e) {
+      OnOperatorsChanged();
+    }
+    private void OperatorsParameter_Value_ItemsAdded(object sender, EventArgs e) {
+      OnOperatorsChanged();
+    }
+    private void OperatorsParameter_Value_ItemsRemoved(object sender, EventArgs e) {
+      OnOperatorsChanged();
+    }
+    private void OperatorsParameter_Value_CollectionReset(object sender, EventArgs e) {
+      OnOperatorsChanged();
+    }
+    #endregion
+
+    #region Helpers
+    private void RegisterEventHandlers() {
+      SolutionCreatorParameter.ValueChanged += new EventHandler(SolutionCreatorParameter_ValueChanged);
+      EvaluatorParameter.ValueChanged += new EventHandler(EvaluatorParameter_ValueChanged);
+      if (Evaluator != null)
+        Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
+      OperatorsParameter.ValueChanged += new EventHandler(OperatorsParameter_ValueChanged);
+      OperatorsParameter.Value.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<IItem>>(OperatorsParameter_Value_ItemsAdded);
+      OperatorsParameter.Value.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<IItem>>(OperatorsParameter_Value_ItemsRemoved);
+      OperatorsParameter.Value.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<IItem>>(OperatorsParameter_Value_CollectionReset);
+    }
+
+    private void ParameterizeOperators() {
+      // A best effort approach to wiring
+      if (Evaluator != null) {
+        string qualityName = Evaluator.QualityParameter.ActualName;
+        foreach (IOperator op in OperatorsParameter.Value.OfType<IOperator>()) {
+          foreach (ILookupParameter<DoubleValue> param in op.Parameters.OfType<ILookupParameter<DoubleValue>>()) {
+            if (param.Name.Equals("Quality")) param.ActualName = qualityName;
+          }
+          foreach (IScopeTreeLookupParameter<DoubleValue> param in op.Parameters.OfType<IScopeTreeLookupParameter<DoubleValue>>()) {
+            if (param.Name.Equals("Quality")) param.ActualName = qualityName;
+          }
+        }
+      }
+    }
+    #endregion
+
+    [Item("EmptyUserDefinedProblemEvaluator", "A dummy evaluator that will throw an exception when executed.")]
+    [StorableClass]
+    [NonDiscoverableType]
+    private sealed class EmptyUserDefinedProblemEvaluator : ParameterizedNamedItem, ISingleObjectiveEvaluator {
+
+      [StorableConstructor]
+      private EmptyUserDefinedProblemEvaluator(bool deserializing) : base(deserializing) { }
+      private EmptyUserDefinedProblemEvaluator(EmptyUserDefinedProblemEvaluator original, Cloner cloner)
+        : base(original, cloner) {
+      }
+      public override IDeepCloneable Clone(Cloner cloner) {
+        return new EmptyUserDefinedProblemEvaluator(this, cloner);
+      }
+
+      #region ISingleObjectiveEvaluator Members
+
+      public ILookupParameter<DoubleValue> QualityParameter {
+        get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+      }
+
+      #endregion
+
+      public EmptyUserDefinedProblemEvaluator() {
+        Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The solution quality."));
+      }
+
+      #region IOperator Members
+
+      public bool Breakpoint { get; set; }
+
+      public IOperation Execute(IExecutionContext context, CancellationToken cancellationToken) {
+        throw new InvalidOperationException("Please choose an appropriate evaluation operator.");
+      }
+
+#pragma warning disable 67
+      public event EventHandler BreakpointChanged;
+
+      public event EventHandler Executed;
+#pragma warning restore 67
+
+      #endregion
+
+      public static new Image StaticItemImage {
+        get { return HeuristicLab.Common.Resources.VSImageLibrary.Method; }
+      }
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Properties/AssemblyInfo.cs.frame	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Properties/AssemblyInfo.cs.frame	(revision 12764)
@@ -0,0 +1,56 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.Optimization")]
+[assembly: AssemblyDescription("HeuristicLab optimization classes")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2015 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("4b3c29b7-1df7-41d2-aebf-b20fab8de1ee")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.12.$WCREV$")]
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Result.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Result.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Result.cs	(revision 12764)
@@ -0,0 +1,157 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// Represents a result which has a name and a data type and holds an IItem.
+  /// </summary>
+  [Item("Result", "A result which has a name and a data type and holds an IItem.")]
+  [StorableClass]
+  public sealed class Result : NamedItem, IResult, IStorableContent {
+    public string Filename { get; set; }
+
+    public override Image ItemImage {
+      get {
+        if (value != null) return value.ItemImage;
+        else return base.ItemImage;
+      }
+    }
+
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public override bool CanChangeDescription {
+      get { return false; }
+    }
+
+    [Storable]
+    private Type dataType;
+    public Type DataType {
+      get { return dataType; }
+    }
+
+    [Storable]
+    private IItem value;
+    public IItem Value {
+      get { return value; }
+      set {
+        if (this.value != value) {
+          if ((value != null) && (!dataType.IsInstanceOfType(value)))
+            throw new ArgumentException(
+              string.Format("Type mismatch. Value is not a \"{0}\".",
+                            dataType.GetPrettyName())
+            );
+
+          DeregisterValueEvents();
+          this.value = value;
+          RegisterValueEvents();
+          OnValueChanged();
+        }
+      }
+    }
+
+    [StorableConstructor]
+    private Result(bool deserializing) : base(deserializing) { }
+    private Result(Result original, Cloner cloner)
+      : base(original, cloner) {
+      dataType = original.dataType;
+      value = cloner.Clone(original.value);
+      Initialize();
+    }
+    public Result()
+      : base("Anonymous") {
+      this.dataType = typeof(IItem);
+      this.value = null;
+    }
+    public Result(string name, Type dataType)
+      : base(name) {
+      this.dataType = dataType;
+      this.value = null;
+    }
+    public Result(string name, string description, Type dataType)
+      : base(name, description) {
+      this.dataType = dataType;
+      this.value = null;
+    }
+    public Result(string name, IItem value)
+      : base(name) {
+      this.dataType = value == null ? typeof(IItem) : value.GetType();
+      this.value = value;
+      Initialize();
+    }
+    public Result(string name, string description, IItem value)
+      : base(name, description) {
+      this.dataType = value == null ? typeof(IItem) : value.GetType();
+      this.value = value;
+      Initialize();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      Initialize();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Result(this, cloner);
+    }
+
+    private void Initialize() {
+      RegisterValueEvents();
+    }
+
+    public override string ToString() {
+      return string.Format("{0}: {1}", Name, Value == null ? "null" : Value.ToString());
+    }
+
+    public event EventHandler ValueChanged;
+    private void OnValueChanged() {
+      var handler = ValueChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+      OnItemImageChanged();
+      OnToStringChanged();
+    }
+
+    private void RegisterValueEvents() {
+      if (value != null) {
+        value.ItemImageChanged += new EventHandler(Value_ItemImageChanged);
+        value.ToStringChanged += new EventHandler(Value_ToStringChanged);
+      }
+    }
+    private void DeregisterValueEvents() {
+      if (value != null) {
+        value.ItemImageChanged -= new EventHandler(Value_ItemImageChanged);
+        value.ToStringChanged -= new EventHandler(Value_ToStringChanged);
+      }
+    }
+    private void Value_ItemImageChanged(object sender, EventArgs e) {
+      OnItemImageChanged();
+    }
+    private void Value_ToStringChanged(object sender, EventArgs e) {
+      OnToStringChanged();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Results/IResult.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Results/IResult.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Results/IResult.cs	(revision 12764)
@@ -0,0 +1,36 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// Represents a result which has a name and a data type and holds an IItem.
+  /// </summary>
+  public interface IResult : INamedItem {
+    Type DataType { get; }
+    IItem Value { get; set; }
+
+    /// <inheritdoc/>
+    event EventHandler ValueChanged;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Results/IResultParameter.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Results/IResultParameter.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Results/IResultParameter.cs	(revision 12764)
@@ -0,0 +1,35 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  public interface IResultParameter : ILookupParameter {
+    string ResultName { get; set; }
+    event EventHandler ResultNameChanged;
+  }
+
+  public interface IResultParameter<T> : ILookupParameter<ResultCollection>, IResultParameter where T : class, IItem, new() {
+    T DefaultValue { get; set; }
+    T ResultValue { get; set; }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Results/Result.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Results/Result.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Results/Result.cs	(revision 12764)
@@ -0,0 +1,157 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// Represents a result which has a name and a data type and holds an IItem.
+  /// </summary>
+  [Item("Result", "A result which has a name and a data type and holds an IItem.")]
+  [StorableClass]
+  public sealed class Result : NamedItem, IResult, IStorableContent {
+    public string Filename { get; set; }
+
+    public override Image ItemImage {
+      get {
+        if (value != null) return value.ItemImage;
+        else return base.ItemImage;
+      }
+    }
+
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public override bool CanChangeDescription {
+      get { return false; }
+    }
+
+    [Storable]
+    private Type dataType;
+    public Type DataType {
+      get { return dataType; }
+    }
+
+    [Storable]
+    private IItem value;
+    public IItem Value {
+      get { return value; }
+      set {
+        if (this.value != value) {
+          if ((value != null) && (!dataType.IsInstanceOfType(value)))
+            throw new ArgumentException(
+              string.Format("Type mismatch. Value is not a \"{0}\".",
+                            dataType.GetPrettyName())
+            );
+
+          DeregisterValueEvents();
+          this.value = value;
+          RegisterValueEvents();
+          OnValueChanged();
+        }
+      }
+    }
+
+    [StorableConstructor]
+    private Result(bool deserializing) : base(deserializing) { }
+    private Result(Result original, Cloner cloner)
+      : base(original, cloner) {
+      dataType = original.dataType;
+      value = cloner.Clone(original.value);
+      Initialize();
+    }
+    public Result()
+      : base("Anonymous") {
+      this.dataType = typeof(IItem);
+      this.value = null;
+    }
+    public Result(string name, Type dataType)
+      : base(name) {
+      this.dataType = dataType;
+      this.value = null;
+    }
+    public Result(string name, string description, Type dataType)
+      : base(name, description) {
+      this.dataType = dataType;
+      this.value = null;
+    }
+    public Result(string name, IItem value)
+      : base(name) {
+      this.dataType = value == null ? typeof(IItem) : value.GetType();
+      this.value = value;
+      Initialize();
+    }
+    public Result(string name, string description, IItem value)
+      : base(name, description) {
+      this.dataType = value == null ? typeof(IItem) : value.GetType();
+      this.value = value;
+      Initialize();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      Initialize();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Result(this, cloner);
+    }
+
+    private void Initialize() {
+      RegisterValueEvents();
+    }
+
+    public override string ToString() {
+      return string.Format("{0}: {1}", Name, Value == null ? "null" : Value.ToString());
+    }
+
+    public event EventHandler ValueChanged;
+    private void OnValueChanged() {
+      var handler = ValueChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+      OnItemImageChanged();
+      OnToStringChanged();
+    }
+
+    private void RegisterValueEvents() {
+      if (value != null) {
+        value.ItemImageChanged += new EventHandler(Value_ItemImageChanged);
+        value.ToStringChanged += new EventHandler(Value_ToStringChanged);
+      }
+    }
+    private void DeregisterValueEvents() {
+      if (value != null) {
+        value.ItemImageChanged -= new EventHandler(Value_ItemImageChanged);
+        value.ToStringChanged -= new EventHandler(Value_ToStringChanged);
+      }
+    }
+    private void Value_ItemImageChanged(object sender, EventArgs e) {
+      OnItemImageChanged();
+    }
+    private void Value_ToStringChanged(object sender, EventArgs e) {
+      OnToStringChanged();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Results/ResultCollection.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Results/ResultCollection.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Results/ResultCollection.cs	(revision 12764)
@@ -0,0 +1,78 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [StorableClass]
+  [Item("ResultCollection", "Represents a collection of results.")]
+  public class ResultCollection : NamedItemCollection<IResult> {
+    public ResultCollection() : base() { }
+    public ResultCollection(int capacity) : base(capacity) { }
+    public ResultCollection(IEnumerable<IResult> collection) : base(collection) { }
+    [StorableConstructor]
+    protected ResultCollection(bool deserializing) : base(deserializing) { }
+    protected ResultCollection(ResultCollection original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ResultCollection(this, cloner);
+    }
+
+    public static new System.Drawing.Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Object; }
+    }
+
+    public virtual void CollectResultValues(IDictionary<string, IItem> values) {
+      CollectResultValues(values, string.Empty);
+    }
+
+    public virtual void CollectResultValues(IDictionary<string, IItem> values, string rootPath) {
+      foreach (IResult result in this) {
+        var children = GetCollectedResults(result);
+        string path = string.Empty;
+        if (!string.IsNullOrWhiteSpace(rootPath))
+          path = rootPath + ".";
+        foreach (var c in children) {
+          if (string.IsNullOrEmpty(c.Key))
+            values.Add(path + result.Name, c.Value);
+          else values.Add(path + result.Name + "." + c.Key, c.Value);
+        }
+      }
+    }
+
+    protected virtual IEnumerable<KeyValuePair<string, IItem>> GetCollectedResults(IResult result) {
+      if (result.Value == null) yield break;
+      yield return new KeyValuePair<string, IItem>(string.Empty, result.Value);
+
+      var resultCollection = result.Value as ResultCollection;
+      if (resultCollection != null) {
+        var children = new Dictionary<string, IItem>();
+        resultCollection.CollectResultValues(children);
+        foreach (var child in children) yield return child;
+      }
+    }
+
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Results/ResultParameter.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Results/ResultParameter.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Results/ResultParameter.cs	(revision 12764)
@@ -0,0 +1,141 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Optimization {
+  [Item("ResultParameter", "A parameter whose value is written to a result collection.")]
+  [StorableClass]
+  [NonDiscoverableType]
+  public sealed class ResultParameter<T> : LookupParameter<ResultCollection>, IResultParameter<T> where T : class, IItem, new() {
+
+    [Storable]
+    private string resultName;
+    public string ResultName {
+      get { return resultName; }
+      set {
+        if (value == null) throw new ArgumentNullException();
+        if (string.IsNullOrWhiteSpace(value)) {
+          resultName = Name;
+          OnResultNameChanged();
+        } else if (!resultName.Equals(value)) {
+          resultName = value;
+          OnResultNameChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private T defaultValue;
+    public T DefaultValue {
+      get { return defaultValue; }
+      set {
+        if (value != defaultValue) {
+          defaultValue = value;
+          OnDefaultValueChanged();
+        }
+      }
+    }
+
+    public T ResultValue {
+      get { return GetResultValue(); }
+      set { SetResultValue(value); }
+    }
+
+    [StorableConstructor]
+    private ResultParameter(bool deserializing) : base(deserializing) { }
+    private ResultParameter(ResultParameter<T> original, Cloner cloner)
+      : base(original, cloner) {
+      resultName = original.resultName;
+      defaultValue = cloner.Clone(original.defaultValue);
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ResultParameter<T>(this, cloner);
+    }
+    public ResultParameter() : this("Anonymous") { }
+    public ResultParameter(string name)
+      : base(name, string.Empty, "Results") {
+      resultName = Name;
+      defaultValue = new T();
+    }
+    public ResultParameter(string name, string description) : this(name, description, new T()) { }
+    public ResultParameter(string name, string description, T defaultValue)
+      : base(name, description, "Results") {
+      if (defaultValue == null) throw new ArgumentNullException("defaultValue");
+      resultName = Name;
+      this.defaultValue = defaultValue;
+    }
+    public ResultParameter(string name, string description, string resultName) : this(name, description, new T(), resultName) { }
+    public ResultParameter(string name, string description, T defaultValue, string resultName)
+      : base(name, description, "Results") {
+      if (defaultValue == null) throw new ArgumentNullException("defaultValue");
+      this.resultName = string.IsNullOrWhiteSpace(resultName) ? Name : resultName;
+      this.defaultValue = defaultValue;
+    }
+
+    public override string ToString() {
+      if (Name.Equals(ResultName)) return Name;
+      return Name + ": " + ResultName;
+    }
+
+    private T GetResultValue() {
+      var results = ActualValue;
+      if (results == null)
+        throw new InvalidOperationException("ResultParameter (" + ResultName + "): ResultCollection " + ActualName + " not found.");
+
+      if (!results.ContainsKey(ResultName)) results.Add(new Result(ResultName, (T)DefaultValue.Clone()));
+      var resultValue = results[ResultName].Value as T;
+      if (resultValue == null)
+        throw new InvalidOperationException(string.Format("Type mismatch. Result \"{0}\" does not contain a \"{1}\".", ResultName, typeof(T).GetPrettyName()));
+
+      return resultValue;
+    }
+
+    private void SetResultValue(T value) {
+      var results = ActualValue;
+      if (results == null)
+        throw new InvalidOperationException("ResultParameter (" + ResultName + "): ResultCollection " + ActualName + " not found.");
+
+      if (!results.ContainsKey(ResultName))
+        results.Add(new Result(ResultName, value));
+      else results[ResultName].Value = value;
+    }
+
+    public event EventHandler ResultNameChanged;
+    private void OnResultNameChanged() {
+      var handler = ResultNameChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+      OnToStringChanged();
+    }
+
+    public event EventHandler DefaultValueChanged;
+    private void OnDefaultValueChanged() {
+      EventHandler handler = DefaultValueChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+      OnItemImageChanged();
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Run.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Run.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/Run.cs	(revision 12764)
@@ -0,0 +1,190 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// Represents the parameters and results of an algorithm run.
+  /// </summary>
+  [Item("Run", "The parameters and results of an algorithm run.")]
+  [StorableClass]
+  public sealed class Run : NamedItem, IRun, IStorableContent {
+    public string Filename { get; set; }
+
+    [StorableConstructor]
+    private Run(bool deserializing) : base(deserializing) { }
+    private Run(Run original, Cloner cloner)
+      : base(original, cloner) {
+      color = original.color;
+      algorithm = cloner.Clone(original.algorithm);
+
+      parameters = new ObservableDictionary<string, IItem>();
+      foreach (string key in original.parameters.Keys)
+        parameters.Add(key, cloner.Clone(original.parameters[key]));
+
+      results = new ObservableDictionary<string, IItem>();
+      foreach (string key in original.results.Keys)
+        results.Add(key, cloner.Clone(original.results[key]));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Run(this, cloner);
+    }
+
+    public Run()
+      : base() {
+      name = ItemName;
+      description = ItemDescription;
+      color = Color.Black;
+      algorithm = null;
+      parameters = new ObservableDictionary<string, IItem>();
+      results = new ObservableDictionary<string, IItem>();
+    }
+    public Run(IAlgorithm algorithm)
+      : base() {
+      if (algorithm == null) throw new ArgumentNullException();
+      name = algorithm.Name + " Run (" + algorithm.ExecutionTime.ToString() + ")";
+      description = ItemDescription;
+      color = Color.Black;
+      Initialize(algorithm);
+    }
+    public Run(string name, IAlgorithm algorithm)
+      : base(name) {
+      if (algorithm == null) throw new ArgumentNullException();
+      color = Color.Black;
+      description = ItemDescription;
+      Initialize(algorithm);
+    }
+    public Run(string name, string description, IAlgorithm algorithm)
+      : base(name, description) {
+      if (algorithm == null) throw new ArgumentNullException();
+      color = Color.Black;
+      Initialize(algorithm);
+    }
+
+    private void Initialize(IAlgorithm algorithm) {
+      parameters = new ObservableDictionary<string, IItem>();
+      results = new ObservableDictionary<string, IItem>();
+
+      if (algorithm.StoreAlgorithmInEachRun) {
+        var clone = (IAlgorithm)algorithm.Clone();
+        clone.CollectParameterValues(parameters);
+        clone.CollectResultValues(results);
+        clone.Runs.Clear();
+        this.algorithm = clone;
+      } else {
+        var par = new Dictionary<string, IItem>();
+        var res = new Dictionary<string, IItem>();
+        algorithm.CollectParameterValues(par);
+        algorithm.CollectResultValues(res);
+        var cloner = new Cloner();
+        foreach (var k in par) parameters.Add(k.Key, cloner.Clone(k.Value));
+        foreach (var k in res) results.Add(k.Key, cloner.Clone(k.Value));
+      }
+    }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (color == Color.Empty) color = Color.Black;
+    }
+
+    [Storable]
+    private IAlgorithm algorithm;
+    public IAlgorithm Algorithm {
+      get { return algorithm; }
+    }
+
+    [Storable(Name = "parameters")]
+    private IDictionary<string, IItem> StorableParameters {
+      get { return parameters; }
+      set {
+        if (!(value is IObservableDictionary<string, IItem>))
+          parameters = new ObservableDictionary<string, IItem>(value);
+        else parameters = (IObservableDictionary<string, IItem>)value;
+      }
+    }
+    private IObservableDictionary<string, IItem> parameters;
+    public IObservableDictionary<string, IItem> Parameters {
+      get { return parameters; }
+      private set {
+        if (parameters != value) {
+          parameters = value;
+          OnPropertyChanged("Parameters");
+        }
+      }
+    }
+
+    [Storable(Name = "results")]
+    private IDictionary<string, IItem> StorableResults {
+      get { return results; }
+      set {
+        if (!(value is IObservableDictionary<string, IItem>))
+          results = new ObservableDictionary<string, IItem>(value);
+        else results = (IObservableDictionary<string, IItem>)value;
+      }
+    }
+    private IObservableDictionary<string, IItem> results;
+    public IObservableDictionary<string, IItem> Results {
+      get { return results; }
+      private set {
+        if (results != value) {
+          results = value;
+          OnPropertyChanged("Results");
+        }
+      }
+    }
+
+    [Storable]
+    private Color color;
+    public Color Color {
+      get { return this.color; }
+      set {
+        if (color != value) {
+          this.color = value;
+          OnPropertyChanged("Color");
+        }
+      }
+    }
+    private bool visible = true;
+    public bool Visible {
+      get { return this.visible; }
+      set {
+        if (visible != value) {
+          this.visible = value;
+          OnPropertyChanged("Visible");
+        }
+      }
+    }
+
+    public event PropertyChangedEventHandler PropertyChanged;
+    private void OnPropertyChanged(string property) {
+      var handler = PropertyChanged;
+      if (handler != null) handler(this, new PropertyChangedEventArgs(property));
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollection.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollection.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollection.cs	(revision 12764)
@@ -0,0 +1,591 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("Run Collection", "Represents a collection of runs.")]
+  [Creatable(CreatableAttribute.Categories.TestingAndAnalysis, Priority = 120)]
+  [StorableClass]
+  public class RunCollection : ItemCollection<IRun>, IStringConvertibleMatrix, IStorableContent {
+    public string Filename { get; set; }
+
+    [StorableConstructor]
+    protected RunCollection(bool deserializing)
+      : base(deserializing) {
+      updateOfRunsInProgress = false;
+    }
+    protected RunCollection(RunCollection original, Cloner cloner)
+      : base(original, cloner) {
+      updateOfRunsInProgress = false;
+      optimizerName = original.optimizerName;
+
+      resultNames = new List<string>(original.resultNames);
+      parameterNames = new List<string>(original.parameterNames);
+      dataTypes = new Dictionary<string, HashSet<Type>>();
+      foreach (string s in original.dataTypes.Keys)
+        dataTypes[s] = new HashSet<Type>(original.dataTypes[s]);
+
+      constraints = new RunCollectionConstraintCollection(original.constraints.Select(x => cloner.Clone(x)));
+      modifiers = new CheckedItemList<IRunCollectionModifier>(original.modifiers.Select(cloner.Clone));
+      foreach (IRunCollectionConstraint constraint in constraints)
+        constraint.ConstrainedValue = this;
+      RegisterConstraintsEvents();
+      RegisterConstraintEvents(constraints);
+
+      foreach (var run in this) {
+        RegisterRunParametersEvents(run);
+        RegisterRunResultsEvents(run);
+      }
+
+      UpdateFiltering(true);
+    }
+    public RunCollection() : base() { Initialize(); }
+    public RunCollection(int capacity) : base(capacity) { Initialize(); }
+    public RunCollection(IEnumerable<IRun> collection) : base(collection) { Initialize(); this.OnItemsAdded(collection); }
+    private void Initialize() {
+      updateOfRunsInProgress = false;
+      parameterNames = new List<string>();
+      resultNames = new List<string>();
+      dataTypes = new Dictionary<string, HashSet<Type>>();
+      constraints = new RunCollectionConstraintCollection();
+      modifiers = new CheckedItemList<IRunCollectionModifier>();
+      RegisterConstraintsEvents();
+    }
+
+    [Storable]
+    private Dictionary<string, HashSet<Type>> dataTypes;
+    public IEnumerable<Type> GetDataType(string columnName) {
+      if (!dataTypes.ContainsKey(columnName))
+        return new Type[0];
+      return dataTypes[columnName];
+    }
+
+    [Storable]
+    private RunCollectionConstraintCollection constraints;
+    public RunCollectionConstraintCollection Constraints {
+      get { return constraints; }
+    }
+
+    [Storable]
+    private CheckedItemList<IRunCollectionModifier> modifiers;
+    public CheckedItemList<IRunCollectionModifier> Modifiers {
+      get { return modifiers; }
+    }
+
+
+    private bool updateOfRunsInProgress;
+    public bool UpdateOfRunsInProgress {
+      get { return updateOfRunsInProgress; }
+      set {
+        if (updateOfRunsInProgress != value) {
+          updateOfRunsInProgress = value;
+          OnUpdateOfRunsInProgressChanged();
+        }
+      }
+    }
+
+    private string optimizerName = string.Empty;
+    [Storable]
+    public string OptimizerName {
+      get { return optimizerName; }
+      set {
+        if (value != optimizerName && !string.IsNullOrEmpty(value)) {
+          optimizerName = value;
+          OnOptimizerNameChanged();
+        }
+      }
+    }
+
+    // BackwardsCompatibility3.3
+    #region Backwards compatible code, remove with 3.4
+    [Storable(AllowOneWay = true)]
+    private string AlgorithmName {
+      set { optimizerName = value; }
+    }
+    #endregion
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (constraints == null) constraints = new RunCollectionConstraintCollection();
+      if (modifiers == null) modifiers = new CheckedItemList<IRunCollectionModifier>();
+      RegisterConstraintsEvents();
+      RegisterConstraintEvents(constraints);
+
+      foreach (var run in this) {
+        RegisterRunParametersEvents(run);
+        RegisterRunResultsEvents(run);
+      }
+      UpdateFiltering(true);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RunCollection(this, cloner);
+    }
+
+    public event EventHandler UpdateOfRunsInProgressChanged;
+    protected virtual void OnUpdateOfRunsInProgressChanged() {
+      var handler = UpdateOfRunsInProgressChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler OptimizerNameChanged;
+    protected virtual void OnOptimizerNameChanged() {
+      var handler = OptimizerNameChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    protected override void OnCollectionReset(IEnumerable<IRun> items, IEnumerable<IRun> oldItems) {
+      parameterNames.Clear();
+      resultNames.Clear();
+      dataTypes.Clear();
+      foreach (IRun run in items) {
+        foreach (KeyValuePair<string, IItem> parameter in run.Parameters)
+          AddParameter(parameter.Key, parameter.Value);
+        foreach (KeyValuePair<string, IItem> result in run.Results)
+          AddResult(result.Key, result.Value);
+        run.PropertyChanged += RunOnPropertyChanged;
+        RegisterRunParametersEvents(run);
+        RegisterRunResultsEvents(run);
+      }
+      foreach (IRun run in oldItems) {
+        run.PropertyChanged -= RunOnPropertyChanged;
+        DeregisterRunParametersEvents(run);
+        DeregisterRunResultsEvents(run);
+      }
+      columnNameCache = null;
+      OnColumnsChanged();
+      OnColumnNamesChanged();
+      rowNamesCache = null;
+      base.OnCollectionReset(items, oldItems);
+      OnRowsChanged();
+      OnRowNamesChanged();
+      OnReset();
+      UpdateFiltering(false);
+    }
+    protected override void OnItemsAdded(IEnumerable<IRun> items) {
+      bool columnsChanged = false;
+      foreach (IRun run in items) {
+        foreach (KeyValuePair<string, IItem> parameter in run.Parameters)
+          columnsChanged |= AddParameter(parameter.Key, parameter.Value);
+        foreach (KeyValuePair<string, IItem> result in run.Results)
+          columnsChanged |= AddResult(result.Key, result.Value);
+        run.PropertyChanged += RunOnPropertyChanged;
+        RegisterRunParametersEvents(run);
+        RegisterRunResultsEvents(run);
+      }
+      if (columnsChanged) columnNameCache = null;
+      rowNamesCache = null;
+      base.OnItemsAdded(items);
+      OnReset();
+      OnRowsChanged();
+      OnRowNamesChanged();
+      if (columnsChanged) {
+        OnColumnsChanged();
+        OnColumnNamesChanged();
+      }
+      UpdateFiltering(false);
+    }
+    protected override void OnItemsRemoved(IEnumerable<IRun> items) {
+      bool columnsChanged = false;
+      foreach (IRun run in items) {
+        foreach (string parameterName in run.Parameters.Keys)
+          columnsChanged |= RemoveParameterName(parameterName);
+        foreach (string resultName in run.Results.Keys)
+          columnsChanged |= RemoveResultName(resultName);
+        run.PropertyChanged -= RunOnPropertyChanged;
+        DeregisterRunParametersEvents(run);
+        DeregisterRunResultsEvents(run);
+      }
+      if (columnsChanged) columnNameCache = null;
+      rowNamesCache = null;
+      base.OnItemsRemoved(items);
+      OnReset();
+      OnRowsChanged();
+      OnRowNamesChanged();
+      if (columnsChanged) {
+        OnColumnsChanged();
+        OnColumnNamesChanged();
+      }
+    }
+
+    private void RunOnPropertyChanged(object sender, PropertyChangedEventArgs e) {
+      if (e.PropertyName == "Parameters") {
+        RegisterRunParametersEvents((IRun)sender);
+      } else if (e.PropertyName == "Results") {
+        RegisterRunResultsEvents((IRun)sender);
+      }
+    }
+
+    private void RegisterRunParametersEvents(IRun run) {
+      IObservableDictionary<string, IItem> dict = run.Parameters;
+      dict.ItemsAdded += RunOnParameterChanged;
+      dict.ItemsRemoved += RunOnParameterRemoved;
+      dict.ItemsReplaced += RunOnParameterChanged;
+      dict.CollectionReset += RunOnParameterChanged;
+    }
+
+    private void RegisterRunResultsEvents(IRun run) {
+      IObservableDictionary<string, IItem> dict = run.Results;
+      dict.ItemsAdded += RunOnResultChanged;
+      dict.ItemsRemoved += RunOnResultRemoved;
+      dict.ItemsReplaced += RunOnResultChanged;
+      dict.CollectionReset += RunOnResultChanged;
+    }
+
+    private void DeregisterRunParametersEvents(IRun run) {
+      IObservableDictionary<string, IItem> dict = run.Parameters;
+      dict.ItemsAdded -= RunOnParameterChanged;
+      dict.ItemsRemoved -= RunOnParameterRemoved;
+      dict.ItemsReplaced -= RunOnParameterChanged;
+      dict.CollectionReset -= RunOnParameterChanged;
+    }
+
+    private void DeregisterRunResultsEvents(IRun run) {
+      IObservableDictionary<string, IItem> dict = run.Results;
+      dict.ItemsAdded -= RunOnResultChanged;
+      dict.ItemsRemoved -= RunOnResultRemoved;
+      dict.ItemsReplaced -= RunOnResultChanged;
+      dict.CollectionReset -= RunOnResultChanged;
+    }
+
+    private void RunOnParameterChanged(object sender, CollectionItemsChangedEventArgs<KeyValuePair<string, IItem>> e) {
+      bool columnsChanged = false;
+      foreach (var param in e.Items)
+        columnsChanged |= AddParameter(param.Key, param.Value);
+      foreach (var param in e.OldItems)
+        columnsChanged |= RemoveParameterName(param.Key);
+      if (columnsChanged) columnNameCache = null;
+      OnReset();
+      if (columnsChanged) {
+        OnColumnsChanged();
+        OnColumnNamesChanged();
+      }
+    }
+
+    private void RunOnParameterRemoved(object sender, CollectionItemsChangedEventArgs<KeyValuePair<string, IItem>> e) {
+      bool columnsChanged = false;
+      foreach (var param in e.Items)
+        columnsChanged |= RemoveParameterName(param.Key);
+      if (columnsChanged) columnNameCache = null;
+      OnReset();
+      if (columnsChanged) {
+        OnColumnsChanged();
+        OnColumnNamesChanged();
+      }
+    }
+
+    private void RunOnResultChanged(object sender, CollectionItemsChangedEventArgs<KeyValuePair<string, IItem>> e) {
+      bool columnsChanged = false;
+      foreach (var result in e.Items)
+        columnsChanged |= AddResult(result.Key, result.Value);
+      foreach (var result in e.OldItems)
+        columnsChanged |= RemoveResultName(result.Key);
+      if (columnsChanged) columnNameCache = null;
+      OnReset();
+      if (columnsChanged) {
+        OnColumnsChanged();
+        OnColumnNamesChanged();
+      }
+    }
+
+    private void RunOnResultRemoved(object sender, CollectionItemsChangedEventArgs<KeyValuePair<string, IItem>> e) {
+      bool columnsChanged = false;
+      foreach (var result in e.Items)
+        columnsChanged |= RemoveResultName(result.Key);
+      if (columnsChanged) columnNameCache = null;
+      OnReset();
+      if (columnsChanged) {
+        OnColumnsChanged();
+        OnColumnNamesChanged();
+      }
+    }
+
+    private bool AddParameter(string name, IItem value) {
+      if (value == null)
+        return false;
+      if (!parameterNames.Contains(name)) {
+        parameterNames.Add(name);
+        dataTypes[name] = new HashSet<Type>();
+        dataTypes[name].Add(value.GetType());
+        return true;
+      }
+      dataTypes[name].Add(value.GetType());
+      return false;
+    }
+    private bool AddResult(string name, IItem value) {
+      if (value == null)
+        return false;
+      if (!resultNames.Contains(name)) {
+        resultNames.Add(name);
+        dataTypes[name] = new HashSet<Type>();
+        dataTypes[name].Add(value.GetType());
+        return true;
+      }
+      dataTypes[name].Add(value.GetType());
+      return false;
+    }
+    private bool RemoveParameterName(string name) {
+      if (!list.Any(x => x.Parameters.ContainsKey(name))) {
+        parameterNames.Remove(name);
+        return true;
+      }
+      return false;
+    }
+    private bool RemoveResultName(string name) {
+      if (!list.Any(x => x.Results.ContainsKey(name))) {
+        resultNames.Remove(name);
+        return true;
+      }
+      return false;
+    }
+
+    public IItem GetValue(int rowIndex, int columnIndex) {
+      IRun run = this.list[rowIndex];
+      return GetValue(run, columnIndex);
+    }
+
+    public IItem GetValue(IRun run, int columnIndex) {
+      string name = ((IStringConvertibleMatrix)this).ColumnNames.ElementAt(columnIndex);
+      return GetValue(run, name);
+    }
+
+    public IItem GetValue(IRun run, string columnName) {
+      IItem value = null;
+      if (run.Parameters.ContainsKey(columnName))
+        value = run.Parameters[columnName];
+      else if (run.Results.ContainsKey(columnName))
+        value = run.Results[columnName];
+      return value;
+    }
+
+    #region IStringConvertibleMatrix Members
+    [Storable]
+    private List<string> parameterNames;
+    public IEnumerable<string> ParameterNames {
+      get { return this.parameterNames; }
+    }
+    [Storable]
+    private List<string> resultNames;
+    public IEnumerable<string> ResultNames {
+      get { return this.resultNames; }
+    }
+    int IStringConvertibleMatrix.Rows {
+      get { return this.Count; }
+      set { throw new NotSupportedException(); }
+    }
+    int IStringConvertibleMatrix.Columns {
+      get { return parameterNames.Count + resultNames.Count; }
+      set { throw new NotSupportedException(); }
+    }
+    private List<string> columnNameCache;
+    IEnumerable<string> IStringConvertibleMatrix.ColumnNames {
+      get {
+        if (columnNameCache == null) {
+          columnNameCache = new List<string>(parameterNames);
+          columnNameCache.AddRange(resultNames);
+          columnNameCache.Sort();
+        }
+        return columnNameCache;
+      }
+      set { throw new NotSupportedException(); }
+    }
+    private List<string> rowNamesCache;
+    IEnumerable<string> IStringConvertibleMatrix.RowNames {
+      get {
+        if (rowNamesCache == null)
+          rowNamesCache = list.Select(x => x.Name).ToList();
+        return rowNamesCache;
+      }
+      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) {
+      IItem value = GetValue(rowIndex, columnIndex);
+      if (value == null)
+        return string.Empty;
+      return value.ToString();
+    }
+
+    public event EventHandler<EventArgs<int, int>> ItemChanged;
+    protected virtual void OnItemChanged(int rowIndex, int columnIndex) {
+      EventHandler<EventArgs<int, int>> handler = ItemChanged;
+      if (handler != null) handler(this, new EventArgs<int, int>(rowIndex, columnIndex));
+    }
+    public event EventHandler Reset;
+    protected virtual void OnReset() {
+      EventHandler 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() {
+      EventHandler handler = ColumnNamesChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler RowNamesChanged;
+    protected virtual void OnRowNamesChanged() {
+      EventHandler handler = RowNamesChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler SortableViewChanged;
+    protected virtual void OnSortableViewChanged() {
+      EventHandler handler = SortableViewChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public bool Validate(string value, out string errorMessage) { throw new NotSupportedException(); }
+    public bool SetValue(string value, int rowIndex, int columnIndex) { throw new NotSupportedException(); }
+    #endregion
+
+    #region Filtering
+    private void UpdateFiltering(bool reset) {
+      var oldUpateRuns = UpdateOfRunsInProgress;
+      UpdateOfRunsInProgress = true;
+      if (reset)
+        list.ForEach(r => r.Visible = true);
+      foreach (IRunCollectionConstraint constraint in this.constraints)
+        constraint.Check();
+      UpdateOfRunsInProgress = oldUpateRuns;
+    }
+
+    private void RegisterConstraintsEvents() {
+      constraints.ItemsAdded += new CollectionItemsChangedEventHandler<IRunCollectionConstraint>(Constraints_ItemsAdded);
+      constraints.ItemsRemoved += new CollectionItemsChangedEventHandler<IRunCollectionConstraint>(Constraints_ItemsRemoved);
+      constraints.CollectionReset += new CollectionItemsChangedEventHandler<IRunCollectionConstraint>(Constraints_CollectionReset);
+    }
+
+    private void RegisterConstraintEvents(IEnumerable<IRunCollectionConstraint> constraints) {
+      foreach (IRunCollectionConstraint constraint in constraints) {
+        constraint.ActiveChanged += new EventHandler(Constraint_ActiveChanged);
+        constraint.ConstrainedValueChanged += new EventHandler(Constraint_ConstrainedValueChanged);
+        constraint.ConstraintOperationChanged += new EventHandler(Constraint_ConstraintOperationChanged);
+        constraint.ConstraintDataChanged += new EventHandler(Constraint_ConstraintDataChanged);
+      }
+    }
+    private void DeregisterConstraintEvents(IEnumerable<IRunCollectionConstraint> constraints) {
+      foreach (IRunCollectionConstraint constraint in constraints) {
+        constraint.ActiveChanged -= new EventHandler(Constraint_ActiveChanged);
+        constraint.ConstrainedValueChanged -= new EventHandler(Constraint_ConstrainedValueChanged);
+        constraint.ConstraintOperationChanged -= new EventHandler(Constraint_ConstraintOperationChanged);
+        constraint.ConstraintDataChanged -= new EventHandler(Constraint_ConstraintDataChanged);
+      }
+    }
+
+    protected virtual void Constraints_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRunCollectionConstraint> e) {
+      DeregisterConstraintEvents(e.OldItems);
+      RegisterConstraintEvents(e.Items);
+      this.UpdateFiltering(true);
+    }
+    protected virtual void Constraints_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRunCollectionConstraint> e) {
+      RegisterConstraintEvents(e.Items);
+      foreach (IRunCollectionConstraint constraint in e.Items)
+        constraint.ConstrainedValue = this;
+      this.UpdateFiltering(false);
+    }
+    protected virtual void Constraints_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRunCollectionConstraint> e) {
+      DeregisterConstraintEvents(e.Items);
+      this.UpdateFiltering(true);
+    }
+    protected virtual void Constraint_ActiveChanged(object sender, EventArgs e) {
+      IRunCollectionConstraint constraint = (IRunCollectionConstraint)sender;
+      this.UpdateFiltering(!constraint.Active);
+    }
+    protected virtual void Constraint_ConstrainedValueChanged(object sender, EventArgs e) {
+      //mkommend: this method is intentionally left empty, because the constrainedValue is set in the ItemsAdded method
+    }
+    protected virtual void Constraint_ConstraintOperationChanged(object sender, EventArgs e) {
+      IRunCollectionConstraint constraint = (IRunCollectionConstraint)sender;
+      if (constraint.Active)
+        this.UpdateFiltering(true);
+    }
+    protected virtual void Constraint_ConstraintDataChanged(object sender, EventArgs e) {
+      IRunCollectionConstraint constraint = (IRunCollectionConstraint)sender;
+      if (constraint.Active)
+        this.UpdateFiltering(true);
+    }
+    #endregion
+
+    #region Modification
+    public void Modify() {
+      var oldUpateRuns = UpdateOfRunsInProgress;
+      UpdateOfRunsInProgress = true;
+      var runs = this.ToList();
+      var selectedRuns = runs.Where(r => r.Visible).ToList();
+      int nSelected = selectedRuns.Count;
+      if (nSelected > 0) {
+        foreach (var modifier in Modifiers.CheckedItems)
+          modifier.Value.Modify(selectedRuns);
+        if (nSelected != selectedRuns.Count || HaveDifferentOrder(selectedRuns, runs.Where(r => r.Visible))) {
+          Clear();
+          AddRange(ReplaceVisibleRuns(runs, selectedRuns));
+        } else if (runs.Count > 0) {
+          OnCollectionReset(this, runs);
+        }
+      }
+      UpdateOfRunsInProgress = oldUpateRuns;
+    }
+
+    private static IEnumerable<IRun> ReplaceVisibleRuns(IEnumerable<IRun> runs, IEnumerable<IRun> visibleRuns) {
+      var newRuns = new List<IRun>();
+      var runIt = runs.GetEnumerator();
+      var visibleRunIt = visibleRuns.GetEnumerator();
+      while (runIt.MoveNext()) {
+        if (runIt.Current != null && !runIt.Current.Visible)
+          newRuns.Add(runIt.Current);
+        else if (visibleRunIt.MoveNext())
+          newRuns.Add(visibleRunIt.Current);
+      }
+      while (visibleRunIt.MoveNext())
+        newRuns.Add(visibleRunIt.Current);
+      return newRuns;
+    }
+
+    private static bool HaveDifferentOrder(IEnumerable<IRun> l1, IEnumerable<IRun> l2) {
+      return l1.Zip(l2, (r1, r2) => r1 != r2).Any();
+    }
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionConstraints/IRunCollectionConstraint.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionConstraints/IRunCollectionConstraint.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionConstraints/IRunCollectionConstraint.cs	(revision 12764)
@@ -0,0 +1,34 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  public interface IRunCollectionConstraint : IConstraint {
+    new RunCollection ConstrainedValue { get; set; }
+  }
+
+  public interface IRunCollectionColumnConstraint : IRunCollectionConstraint {
+    string ConstraintColumn { get; set; }
+    event EventHandler ConstraintColumnChanged;
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionConstraints/RunCollectionComparisonConstraint.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionConstraints/RunCollectionComparisonConstraint.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionConstraints/RunCollectionComparisonConstraint.cs	(revision 12764)
@@ -0,0 +1,139 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [StorableClass]
+  [Item("RunCollectionComparisonConstraint", "A constraint which compares the members of the contained runs with the constraint data.")]
+  public class RunCollectionComparisonConstraint : ComparisonConstraint, IRunCollectionColumnConstraint {
+    [StorableConstructor]
+    protected RunCollectionComparisonConstraint(bool deserializing) : base(deserializing) { }
+
+    protected RunCollectionComparisonConstraint(RunCollectionComparisonConstraint original, Cloner cloner)
+      : base(original, cloner) {
+      constraintColumn = original.constraintColumn;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RunCollectionComparisonConstraint(this, cloner);
+    }
+
+    public RunCollectionComparisonConstraint() : base() { }
+    public RunCollectionComparisonConstraint(RunCollection constrainedValue, ConstraintOperation constraintOperation, object constraintData)
+      : base(constrainedValue, constraintOperation, constraintData) {
+    }
+    public RunCollectionComparisonConstraint(RunCollection constrainedValue, ConstraintOperation constraintOperation, object constraintData, bool active)
+      : base(constrainedValue, constraintOperation, constraintData, active) {
+    }
+
+    public new RunCollection ConstrainedValue {
+      get { return (RunCollection)base.ConstrainedValue; }
+      set { base.ConstrainedValue = value; }
+    }
+
+    public new IStringConvertibleValue ConstraintData {
+      get { return (IStringConvertibleValue)base.ConstraintData; }
+      set {
+        if (!(value is IComparable))
+          throw new ArgumentException("Only IComparables allowed for ConstraintData");
+        base.ConstraintData = value;
+      }
+    }
+
+    [Storable]
+    private string constraintColumn;
+    public string ConstraintColumn {
+      get { return constraintColumn; }
+      set {
+        if (!((IStringConvertibleMatrix)ConstrainedValue).ColumnNames.Contains(value))
+          throw new ArgumentException("Could not set ConstraintData to not existing column index.");
+        if (constraintColumn != value) {
+          constraintColumn = value;
+          this.OnConstraintColumnChanged();
+          this.OnToStringChanged();
+        }
+      }
+    }
+
+    public event EventHandler ConstraintColumnChanged;
+    protected virtual void OnConstraintColumnChanged() {
+      EventHandler handler = ConstraintColumnChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+
+    protected override void OnConstrainedValueChanged() {
+      base.OnConstrainedValueChanged();
+      IStringConvertibleMatrix matrix = (IStringConvertibleMatrix)ConstrainedValue;
+      if (constraintColumn == null && ConstrainedValue != null && matrix.Columns != 0)
+        constraintColumn = matrix.ColumnNames.ElementAt(0);
+    }
+
+    protected override bool Check(object constrainedMember) {
+      if (!Active)
+        return true;
+
+      foreach (IRun run in ConstrainedValue.Where(r => r.Visible)) {
+        IItem item = ConstrainedValue.GetValue(run, constraintColumn);
+        if (!base.Check(item))
+          run.Visible = false;
+      }
+      return true;
+    }
+
+    protected override bool Check(object constrainedMember, out string errorMessage) {
+      errorMessage = string.Empty;
+      if (!Active)
+        return true;
+
+      foreach (IRun run in ConstrainedValue.Where(r => r.Visible)) {
+        IItem item = ConstrainedValue.GetValue(run, constraintColumn);
+        if (!base.Check(item))
+          run.Visible = false;
+      }
+      return true;
+    }
+
+    public override string ToString() {
+      string s = string.Empty;
+      IStringConvertibleMatrix matrix = ConstrainedValue;
+      if (matrix != null && matrix.ColumnNames.Count() != 0)
+        s += constraintColumn + " ";
+      else
+        return "ComparisonConstraint";
+
+      if (ConstraintOperation != null)
+        s += ConstraintOperation.ToString() + " ";
+
+      if (ConstraintData != null)
+        s += ConstraintData.GetValue();
+      else
+        s += "null";
+
+      return s;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionConstraints/RunCollectionConstraintCollection.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionConstraints/RunCollectionConstraintCollection.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionConstraints/RunCollectionConstraintCollection.cs	(revision 12764)
@@ -0,0 +1,42 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [StorableClass]
+  [Item("RunCollectionConstraintCollection", "Represents a collection of constraints.")]
+  public class RunCollectionConstraintCollection : ItemCollection<IRunCollectionConstraint> {
+    public RunCollectionConstraintCollection() : base() { }
+    public RunCollectionConstraintCollection(int capacity) : base(capacity) { }
+    public RunCollectionConstraintCollection(IEnumerable<IRunCollectionConstraint> collection) : base(collection) { }
+    [StorableConstructor]
+    protected RunCollectionConstraintCollection(bool deserializing) : base(deserializing) { }
+    protected RunCollectionConstraintCollection(RunCollectionConstraintCollection original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RunCollectionConstraintCollection(this, cloner);
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionConstraints/RunCollectionContentConstraint.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionConstraints/RunCollectionContentConstraint.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionConstraints/RunCollectionContentConstraint.cs	(revision 12764)
@@ -0,0 +1,107 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [StorableClass]
+  public class RunCollectionContentConstraint : Constraint, IRunCollectionConstraint {
+    public new RunCollection ConstrainedValue {
+      get { return (RunCollection)base.ConstrainedValue; }
+      set { base.ConstrainedValue = value; }
+    }
+
+    public new ItemSet<IRun> ConstraintData {
+      get { return (ItemSet<IRun>)base.ConstraintData; }
+      set { base.ConstraintData = value; }
+    }
+
+    public override IEnumerable<ConstraintOperation> AllowedConstraintOperations {
+      get { return new List<ConstraintOperation>() { ConstraintOperation.Equal }; }
+    }
+
+    [StorableConstructor]
+    protected RunCollectionContentConstraint(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterConstraintDataEvents();
+    }
+    protected RunCollectionContentConstraint(RunCollectionContentConstraint original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterConstraintDataEvents();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) { return new RunCollectionContentConstraint(this, cloner); }
+
+    public RunCollectionContentConstraint()
+      : base() {
+      ConstraintData = new ItemSet<IRun>();
+    }
+    public RunCollectionContentConstraint(RunCollection constrainedValue, IObservableSet<IRun> constraintData)
+      : base(constrainedValue, ConstraintOperation.Equal, constraintData) {
+    }
+    public RunCollectionContentConstraint(RunCollection constrainedValue, IObservableSet<IRun> constraintData, bool active)
+      : base(constrainedValue, ConstraintOperation.Equal, constraintData, active) {
+    }
+
+    protected override void OnConstraintDataChanged() {
+      RegisterConstraintDataEvents();
+      base.OnConstraintDataChanged();
+    }
+    private void RegisterConstraintDataEvents() {
+      if (ConstraintData != null) {
+        ConstraintData.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(ConstraintData_ItemsAdded);
+        ConstraintData.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(ConstraintData_ItemsRemoved);
+        ConstraintData.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(ConstraintData_CollectionReset);
+      }
+    }
+    private void ConstraintData_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      base.OnConstraintDataChanged();
+    }
+    private void ConstraintData_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      base.OnConstraintDataChanged();
+    }
+    private void ConstraintData_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      base.OnConstraintDataChanged();
+    }
+
+    protected override bool Check(object constrainedMember) {
+      if (!Active) return true;
+
+      foreach (IRun run in ConstrainedValue.Where(r => r.Visible))
+        run.Visible = !ConstraintData.Contains(run);
+      return true;
+    }
+
+    protected override bool Check(object constrainedMember, out string errorMessage) {
+      errorMessage = string.Empty;
+      if (!Active) return true;
+
+      foreach (IRun run in ConstrainedValue.Where(r => r.Visible))
+        run.Visible = !ConstraintData.Contains(run);
+      return true;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionConstraints/RunCollectionEqualityConstraint.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionConstraints/RunCollectionEqualityConstraint.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionConstraints/RunCollectionEqualityConstraint.cs	(revision 12764)
@@ -0,0 +1,140 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [StorableClass]
+  [Item("RunCollectionEqualityConstraint", "A constraint which checks the members of the contained runs for equality to the constraint data.")]
+  public class RunCollectionEqualityConstraint : EqualityConstraint, IRunCollectionColumnConstraint {
+    [StorableConstructor]
+    protected RunCollectionEqualityConstraint(bool deserializing) : base(deserializing) { }
+
+    protected RunCollectionEqualityConstraint(RunCollectionEqualityConstraint original, Cloner cloner)
+      : base(original, cloner) {
+      ConstraintData = original.ConstraintData;
+      ConstraintOperation = original.ConstraintOperation;
+      constraintColumn = original.constraintColumn;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RunCollectionEqualityConstraint(this, cloner);
+    }
+
+    public RunCollectionEqualityConstraint()
+      : base() {
+      this.ConstraintData = string.Empty;
+    }
+    public RunCollectionEqualityConstraint(RunCollection constrainedValue, ConstraintOperation constraintOperation, string constraintData)
+      : base(constrainedValue, constraintOperation, constraintData) {
+    }
+    public RunCollectionEqualityConstraint(RunCollection constrainedValue, ConstraintOperation constraintOperation, string constraintData, bool active)
+      : base(constrainedValue, constraintOperation, constraintData, active) {
+    }
+
+    public new RunCollection ConstrainedValue {
+      get { return (RunCollection)base.ConstrainedValue; }
+      set { base.ConstrainedValue = value; }
+    }
+
+    public new string ConstraintData {
+      get { return (string)base.ConstraintData; }
+      set { base.ConstraintData = value; }
+    }
+
+    [Storable]
+    private string constraintColumn;
+    public string ConstraintColumn {
+      get { return constraintColumn; }
+      set {
+        if (!((IStringConvertibleMatrix)ConstrainedValue).ColumnNames.Contains(value))
+          throw new ArgumentException("Could not set ConstraintData to not existing column index.");
+        if (constraintColumn != value) {
+          constraintColumn = value;
+          this.OnConstraintColumnChanged();
+          this.OnToStringChanged();
+        }
+      }
+    }
+
+    public event EventHandler ConstraintColumnChanged;
+    protected virtual void OnConstraintColumnChanged() {
+      EventHandler handler = ConstraintColumnChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+
+    protected override void OnConstrainedValueChanged() {
+      base.OnConstrainedValueChanged();
+      IStringConvertibleMatrix matrix = (IStringConvertibleMatrix)ConstrainedValue;
+      if (constraintColumn == null && ConstrainedValue != null && matrix.Columns != 0)
+        constraintColumn = matrix.ColumnNames.ElementAt(0);
+    }
+
+    protected override bool Check(object constrainedMember) {
+      if (!Active)
+        return true;
+
+      foreach (IRun run in ConstrainedValue.Where(r => r.Visible)) {
+        IItem item = ConstrainedValue.GetValue(run, constraintColumn);
+        if (item != null && !base.Check(item.ToString()))
+          run.Visible = false;
+      }
+      return true;
+    }
+
+    protected override bool Check(object constrainedMember, out string errorMessage) {
+      errorMessage = string.Empty;
+      if (!Active)
+        return true;
+
+      foreach (IRun run in ConstrainedValue.Where(r => r.Visible)) {
+        IItem item = ConstrainedValue.GetValue(run, constraintColumn);
+        if (!base.Check(item))
+          run.Visible = false;
+      }
+      return true;
+    }
+
+    public override string ToString() {
+      string s = string.Empty;
+      IStringConvertibleMatrix matrix = ConstrainedValue;
+      if (matrix != null && matrix.ColumnNames.Count() != 0)
+        s += constraintColumn + " ";
+      else
+        return "EqualityConstraint";
+
+      if (ConstraintOperation != null)
+        s += ConstraintOperation.ToString() + " ";
+
+      if (!string.IsNullOrEmpty(ConstraintData))
+        s += ConstraintData;
+      else
+        s += "null";
+
+      return s;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionConstraints/RunCollectionTypeCompatiblityConstraint.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionConstraints/RunCollectionTypeCompatiblityConstraint.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionConstraints/RunCollectionTypeCompatiblityConstraint.cs	(revision 12764)
@@ -0,0 +1,133 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [StorableClass]
+  [Item("RunCollectionTypeCompatibilityConstraint", "A constraint which checks the members of the contained runs for type compabitiliby to the constraint data.")]
+  public class RunCollectionTypeCompatibilityConstraint : TypeCompatibilityConstraint, IRunCollectionColumnConstraint {
+    [StorableConstructor]
+    protected RunCollectionTypeCompatibilityConstraint(bool deserializing) {
+    }
+    protected RunCollectionTypeCompatibilityConstraint(RunCollectionTypeCompatibilityConstraint original, Cloner cloner)
+      : base(original, cloner) {
+      ConstraintData = original.ConstraintData;
+      ConstraintOperation = original.ConstraintOperation;
+      constraintColumn = original.constraintColumn;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RunCollectionTypeCompatibilityConstraint(this, cloner);
+    }
+
+    public RunCollectionTypeCompatibilityConstraint()
+      : base() {
+    }
+    public RunCollectionTypeCompatibilityConstraint(RunCollection constrainedValue, ConstraintOperation constraintOperation, Type constraintData)
+      : base(constrainedValue, constraintOperation, constraintData) {
+    }
+    public RunCollectionTypeCompatibilityConstraint(RunCollection constrainedValue, ConstraintOperation constraintOperation, Type constraintData, bool active)
+      : base(constrainedValue, constraintOperation, constraintData, active) {
+    }
+
+    public new RunCollection ConstrainedValue {
+      get { return (RunCollection)base.ConstrainedValue; }
+      set { base.ConstrainedValue = value; }
+    }
+    [Storable]
+    private string constraintColumn;
+    public string ConstraintColumn {
+      get { return constraintColumn; }
+      set {
+        if (!((IStringConvertibleMatrix)ConstrainedValue).ColumnNames.Contains(value))
+          throw new ArgumentException("Could not set ConstraintData to not existing column index.");
+        if (constraintColumn != value) {
+          constraintColumn = value;
+          this.OnConstraintColumnChanged();
+          this.OnToStringChanged();
+        }
+      }
+    }
+
+    public event EventHandler ConstraintColumnChanged;
+    protected virtual void OnConstraintColumnChanged() {
+      EventHandler handler = ConstraintColumnChanged;
+      if (handler != null)
+        handler(this, EventArgs.Empty);
+    }
+
+    protected override void OnConstrainedValueChanged() {
+      base.OnConstrainedValueChanged();
+      IStringConvertibleMatrix matrix = (IStringConvertibleMatrix)ConstrainedValue;
+      if (constraintColumn == null && ConstrainedValue != null && matrix.Columns != 0)
+        constraintColumn = matrix.ColumnNames.ElementAt(0);
+    }
+
+    protected override bool Check(object constrainedMember) {
+      if (!Active)
+        return true;
+
+      foreach (IRun run in ConstrainedValue.Where(r => r.Visible)) {
+        IItem item = ConstrainedValue.GetValue(run, constraintColumn);
+        if (item == null || !base.Check(item))
+          run.Visible = false;
+      }
+      return true;
+    }
+
+    protected override bool Check(object constrainedMember, out string errorMessage) {
+      errorMessage = string.Empty;
+      if (!Active)
+        return true;
+
+      foreach (IRun run in ConstrainedValue.Where(r => r.Visible)) {
+        IItem item = ConstrainedValue.GetValue(run, constraintColumn);
+        if (!base.Check(item))
+          run.Visible = false;
+      }
+      return true;
+    }
+
+    public override string ToString() {
+      string s = string.Empty;
+      IStringConvertibleMatrix matrix = ConstrainedValue;
+      if (matrix != null && matrix.ColumnNames.Count() != 0)
+        s += constraintColumn + " ";
+      else
+        return "TypeCompabitilityConstraint";
+
+      if (ConstraintOperation != null)
+        s += ConstraintOperation.ToString() + " ";
+
+      if (ConstraintData != null)
+        s += ConstraintData;
+      else
+        s += "null";
+
+      return s;
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionModification/Calculator.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionModification/Calculator.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionModification/Calculator.cs	(revision 12764)
@@ -0,0 +1,287 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+
+  [StorableClass]
+  public class Calculator : IDeepCloneable {
+
+    #region Fields & Properties
+
+    private List<string> tokens;
+
+    [Storable]
+    public string Formula {
+      get { return tokens == null ? string.Empty : string.Join(" ", tokens); }
+      set { tokens = Tokenize(value).ToList(); }
+    }
+
+    private static readonly Regex TokenRegex =
+      new Regex(@"""(\\""|[^""])*""|'(\\'|[^'])*'|[^\s]+");
+
+    #endregion
+
+    #region Construction & Cloning
+
+    [StorableConstructor]
+    protected Calculator(bool deserializing) { }
+    public Calculator() { }
+    protected Calculator(Calculator original, Cloner cloner) {
+      cloner.RegisterClonedObject(original, this);
+      if (original.tokens != null)
+        tokens = original.tokens.ToList();
+    }
+    public IDeepCloneable Clone(Cloner cloner) {
+      return new Calculator(this, cloner);
+    }
+    public object Clone() {
+      return Clone(new Cloner());
+    }
+    #endregion
+
+    private static IEnumerable<string> Tokenize(string s) {
+      return TokenRegex.Matches(s).Cast<Match>().Select(m => m.Value);
+    }
+
+    public IItem GetValue(IDictionary<string, IItem> variables) {
+      var stack = new Stack<object>();
+      int i = 0;
+      try {
+        for (; i < tokens.Count; i++) {
+          var token = tokens[i];
+          double d;
+          if (TryParse(token, out d)) {
+            stack.Push(d);
+          } else if (token.StartsWith("\"")) {
+            stack.Push(GetVariableValue(variables, token.Substring(1, token.Length - 2).Replace("\\\"", "\"")));
+          } else if (token.StartsWith("'")) {
+            stack.Push(token.Substring(1, token.Length - 2).Replace("\\'", "'"));
+          } else {
+            Apply(token, stack, variables);
+          }
+        }
+      } catch (Exception x) {
+        throw new Exception(string.Format(
+          "Calculation of '{1}'{0}failed at token #{2}: {3} {0}current stack is: {0}{4}", Environment.NewLine,
+          Formula, i, TokenWithContext(tokens, i, 3),
+          string.Join(Environment.NewLine, stack.Select(AsString))),
+          x);
+      }
+      if (stack.Count != 1)
+        throw new Exception(
+          string.Format("Invalid final evaluation stack size {0} (should be 1) in formula '{1}'",
+          stack.Count, Formula));
+      var result = stack.Pop();
+      if (result is string) return new StringValue((string)result);
+      if (result is int) return new IntValue((int)result);
+      if (result is double) return new DoubleValue((double)result);
+      if (result is bool) return new BoolValue((bool)result);
+      return null;
+    }
+
+    private string TokenWithContext(List<string> tokens, int i, int context) {
+      var sb = new StringBuilder();
+      if (i > context + 1)
+        sb.Append("... ");
+      int prefix = Math.Max(0, i - context);
+      sb.Append(string.Join(" ", tokens.GetRange(prefix, i - prefix)));
+      sb.Append("   ---> ").Append(tokens[i]).Append(" <---   ");
+      int postfix = Math.Min(tokens.Count, i + 1 + context);
+      sb.Append(string.Join(" ", tokens.GetRange(i + 1, postfix - (i + 1))));
+      if (postfix < tokens.Count)
+        sb.Append(" ...");
+      return sb.ToString();
+    }
+
+
+    private static void Apply(string token, Stack<object> stack, IDictionary<string, IItem> variables) {
+      switch (token) {
+        case "null": stack.Push(null); break;
+        case "true": stack.Push(true); break;
+        case "false": stack.Push(false); break;
+
+        case "drop": stack.Pop(); break;
+        case "dup": stack.Push(stack.Peek()); break;
+        case "swap":
+          var top = stack.Pop();
+          var next = stack.Pop();
+          stack.Push(top);
+          stack.Push(next);
+          break;
+
+        case "log": Apply(stack, x => Math.Log(Convert.ToDouble(x))); break;
+        case "+": Apply(stack, (x, y) => Convert.ToDouble(x) + Convert.ToDouble(y)); break;
+        case "-": Apply(stack, (x, y) => Convert.ToDouble(x) - Convert.ToDouble(y)); break;
+        case "*": Apply(stack, (x, y) => Convert.ToDouble(x) * Convert.ToDouble(y)); break;
+        case "/": Apply(stack, (x, y) => Convert.ToDouble(x) / Convert.ToDouble(y)); break;
+        case "^": Apply(stack, (x, y) => Math.Pow(Convert.ToDouble(x), Convert.ToDouble(y))); break;
+        case "<": Apply(stack, (x, y) => Convert.ToDouble(x) < Convert.ToDouble(y)); break;
+        case ">": Apply(stack, (x, y) => Convert.ToDouble(x) > Convert.ToDouble(y)); break;
+
+        case "toint": Apply(stack, x => Convert.ToInt32(x)); break;
+        case "todouble": Apply(stack, x => Convert.ToDouble(x)); break;
+
+        case "[]": Apply(stack, (a, i) => GetArrayValueAtIndex(a, Convert.ToInt32(i))); break;
+
+        case "==": Apply(stack, (x, y) => Equal(x, y)); break;
+        case "not": Apply(stack, x => !Convert.ToBoolean(x)); break;
+        case "isnull": Apply(stack, x => x == null); break;
+        case "if": Apply(stack, (then, else_, cond) => Convert.ToBoolean(cond) ? then : else_); break;
+
+        case "ismatch": Apply(stack, (s, p) => new Regex(Convert.ToString(p)).IsMatch(Convert.ToString(s))); break;
+        case "rename": Apply(stack, (s, p, r) => new Regex(Convert.ToString(p)).Replace(Convert.ToString(s), Convert.ToString(r))); break;
+
+        default: stack.Push(GetVariableValue(variables, token)); break;
+      }
+    }
+
+    #region Auxiliary Functions
+
+    #region IItem value conversion
+    private static object GetIntValue(IItem value) {
+      var v = value as IntValue;
+      if (v != null) return (double)v.Value;
+      return null;
+    }
+
+    private static object GetDoubleValue(IItem value) {
+      var v = value as DoubleValue;
+      if (v != null) return v.Value;
+      return null;
+    }
+
+    private static object GetBoolValue(IItem value) {
+      var v = value as BoolValue;
+      if (v != null) return v.Value;
+      return null;
+    }
+
+    private static object GetArrayValue(IItem value) {
+      if (value is IntArray || value is DoubleArray || value is BoolArray || value is StringArray)
+        return value;
+      return null;
+    }
+
+    private static object GetVariableValue(IDictionary<string, IItem> variables, string name) {
+      if (variables.ContainsKey(name)) {
+        var item = variables[name];
+        return
+          GetIntValue(item) ??
+          GetDoubleValue(item) ??
+          GetBoolValue(item) ??
+          GetArrayValue(item) ??
+          item.ToString();
+      }
+      return null;
+    }
+
+    private static object GetArrayValueAtIndex(object array, int index) {
+      if (array is IntArray)
+        return ((IntArray)array)[index];
+      if (array is DoubleArray)
+        return ((DoubleArray)array)[index];
+      if (array is BoolArray)
+        return ((BoolArray)array)[index];
+      if (array is StringArray)
+        return ((StringArray)array)[index];
+      throw new NotSupportedException(string.Format("Type {0} is not a supported array type", array.GetType().Name));
+    }
+    #endregion
+
+    #region variadic equality
+    private static bool Equal(object a, object b) { return EqualIntegerNumber(a, b) || EqualFloatingNumber(a, b) || EqualBool(a, b) || EqualString(a, b) || a == b; }
+    private static bool EqualIntegerNumber(object a, object b) { return a is int && b is int && (int)a == (int)b; }
+    private static bool EqualFloatingNumber(object a, object b) { return a is double && b is double && (double)a == (double)b; }
+    private static bool EqualBool(object a, object b) { return a is bool && b is bool && (bool)a == (bool)b; }
+    private static bool EqualString(object a, object b) { return a is string && b is string && ((string)a).Equals((string)b); }
+    #endregion
+
+    #region stack calculation
+    private static void Apply(Stack<object> stack, Func<object, object> func) {
+      if (stack.Count < 1)
+        throw new InvalidOperationException("Stack is empty");
+      var a = stack.Pop();
+      try {
+        stack.Push(func(a));
+      } catch (Exception) {
+        stack.Push(a);
+        throw;
+      }
+    }
+
+    private static void Apply(Stack<object> stack, Func<object, object, object> func) {
+      if (stack.Count < 2)
+        throw new InvalidOperationException("Stack contains less than two elements");
+      var b = stack.Pop();
+      var a = stack.Pop();
+      try {
+        stack.Push(func(a, b));
+      } catch (Exception) {
+        stack.Push(b);
+        stack.Push(a);
+        throw;
+      }
+    }
+
+    private static void Apply(Stack<object> stack, Func<object, object, object, object> func) {
+      if (stack.Count < 3)
+        throw new InvalidOperationException("Stack contains less than three elements");
+      var c = stack.Pop();
+      var b = stack.Pop();
+      var a = stack.Pop();
+      try {
+        stack.Push(func(a, b, c));
+      } catch (Exception) {
+        stack.Push(a);
+        stack.Push(b);
+        stack.Push(c);
+        throw;
+      }
+    }
+    #endregion
+
+    private static bool TryParse(string token, out double d) {
+      return double.TryParse(token,
+                             NumberStyles.AllowDecimalPoint |
+                             NumberStyles.AllowExponent |
+                             NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture, out d);
+    }
+
+    private static string AsString(object o) {
+      if (o == null) return "null";
+      if (o is string) return string.Format("'{0}'", o);
+      return o.ToString();
+    }
+
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionModification/RunCollectionDiscretizer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionModification/RunCollectionDiscretizer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionModification/RunCollectionDiscretizer.cs	(revision 12764)
@@ -0,0 +1,203 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("RunCollection Discretizer",
+    "Creates several levels from the distribution of a certain result accross a run collection and " +
+    "assigns a discretized value. Non-existing numbers as well as NaN and infinities are excluded from the caluclation.")]
+  [StorableClass]
+  public class RunCollectionDiscretizer : ParameterizedNamedItem, IRunCollectionModifier {
+
+    public override bool CanChangeName { get { return false; } }
+    public override bool CanChangeDescription { get { return false; } }
+
+    #region Parameters
+    public ValueParameter<StringValue> SourceParameter {
+      get { return (ValueParameter<StringValue>)Parameters["Source"]; }
+    }
+    public ValueParameter<StringValue> TargetParameter {
+      get { return (ValueParameter<StringValue>)Parameters["Target"]; }
+    }
+    public ValueParameter<DoubleValue> SpreadParameter {
+      get { return (ValueParameter<DoubleValue>)Parameters["Spread"]; }
+    }
+    public ValueParameter<StringValue> GroupByParameter {
+      get { return (ValueParameter<StringValue>)Parameters["GroupBy"]; }
+    }    
+    public ValueParameter<ItemList<StringValue>> LevelsParameter {
+      get { return (ValueParameter<ItemList<StringValue>>)Parameters["Levels"]; }
+    }    
+    #endregion
+
+    private string Source { get { return SourceParameter.Value.Value; } }
+    private string Target {
+      get { return TargetParameter.Value.Value; }
+      set { TargetParameter.Value.Value = value; }
+    }    
+    private double Spread { get { return SpreadParameter.Value.Value; } }
+    private string GroupBy { get { return GroupByParameter.Value.Value; } }
+    private List<string> Levels { get { return LevelsParameter.Value.Select(v => v.Value).ToList(); } }
+
+      #region Construction & Cloning
+    [StorableConstructor]
+    protected RunCollectionDiscretizer(bool deserializing) : base(deserializing) { }
+    protected RunCollectionDiscretizer(RunCollectionDiscretizer original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterEvents();
+    }
+    public RunCollectionDiscretizer() {
+      Parameters.Add(new ValueParameter<StringValue>("Source", "Source value name to be fuzzified.", new StringValue("Value")));
+      Parameters.Add(new ValueParameter<StringValue>("Target", "Target value name. The new, fuzzified variable to be created.", new StringValue("Calc.Value")));
+      Parameters.Add(new ValueParameter<DoubleValue>("Spread", "The number of standard deviations considered one additional level. Set to zero to use empirical distribution instead.", new DoubleValue(1)));
+      Parameters.Add(new ValueParameter<StringValue>("GroupBy", "Create separate analyzes for different values of this variable.", new StringValue("")));
+      Parameters.Add(new ValueParameter<ItemList<StringValue>>("Levels", "The list of levels to be assigned.",
+        new ItemList<StringValue> {
+          new StringValue("Very Low"),
+          new StringValue("Low"),
+          new StringValue("Average"),
+          new StringValue("High"),
+          new StringValue("Very High"),
+        }));     
+      RegisterEvents();
+      UpdateName();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RunCollectionDiscretizer(this, cloner);
+    }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+    #endregion
+
+    private void RegisterEvents() {
+      SourceParameter.ToStringChanged += SourceParameter_NameChanged;
+      TargetParameter.ToStringChanged += Parameter_NameChanged;
+      GroupByParameter.ToStringChanged += Parameter_NameChanged;
+    }
+
+    private void SourceParameter_NameChanged(object sender, EventArgs e) {
+      Target = string.Format("{0}/Level", Source);
+    }
+
+    private void Parameter_NameChanged(object sender, EventArgs e) {
+      UpdateName();
+    }
+
+    private void UpdateName() {
+      name = string.Format("{0} := Discrete({1}{2})",
+        Target,
+        Source,
+        string.IsNullOrWhiteSpace(GroupBy) ? "" : string.Format("/{0}", GroupBy));        
+      OnNameChanged();
+    }
+
+    #region IRunCollectionModifier Members
+
+    public void Modify(List<IRun> runs) {
+      foreach (var group in runs
+        .Select(r => new {Run=r, Value=GetSourceValue(r)})
+        .Where(r => r.Value.HasValue && !double.IsNaN(r.Value.Value) && !double.IsInfinity(r.Value.Value))
+        .Select(r => new {r.Run, r.Value.Value, Bin=GetGroupByValue(r.Run)})
+        .GroupBy(r => r.Bin).ToList()) {
+        var values = group.Select(r => r.Value).ToList();
+        if (values.Count > 0) {
+          if (Spread > 0) {
+            var avg = values.Average();
+            var stdDev = values.StandardDeviation();
+            foreach (var r in group) {
+              r.Run.Results[Target] = new StringValue(Discretize(r.Value, avg, stdDev));
+            }
+          } else {
+            values.Sort();
+            var a = values.ToArray();
+            foreach (var r in group) {
+              r.Run.Results[Target] = new StringValue(Discretize(r.Value, a));
+            }
+          }
+        }
+      }      
+    }
+
+    private double? GetSourceValue(IRun run) {
+      return CastSourceValue(run.Results) ?? CastSourceValue(run.Parameters);
+    }
+
+    private string GetGroupByValue(IRun run) {
+      if (string.IsNullOrWhiteSpace(GroupBy))
+        return String.Empty;
+      IItem value;
+      run.Results.TryGetValue(GroupBy, out value);
+      if (value == null)
+        run.Parameters.TryGetValue(GroupBy, out value);
+      if (value != null)
+        return value.ToString();
+      else
+        return String.Empty;
+    }
+
+    private double? CastSourceValue(IDictionary<string, IItem> variables) {
+      IItem value;
+      variables.TryGetValue(Source, out value);
+      var intValue = value as IntValue;
+      if (intValue != null) 
+        return intValue.Value;
+      var doubleValue = value as DoubleValue;
+      if (doubleValue != null)
+        return doubleValue.Value;
+      return null;
+    }
+
+    private string Discretize(double value, double avg, double stdDev) {
+      double dev = (value - avg)/(stdDev*Spread);
+      int index;
+      if (Levels.Count % 2 == 1) {
+        index = (int) Math.Floor(Math.Abs(dev));
+        index = (Levels.Count - 1)/2 + Math.Sign(dev) * index;
+      } else {
+        index = (int) Math.Ceiling(Math.Abs(dev));
+        if (dev > 0)
+          index = Levels.Count/2 + index;
+        else
+          index = Levels.Count/2 + 1 - index;
+      }
+      return Levels[Math.Min(Levels.Count - 1, Math.Max(0, index))];
+    }
+
+    private string Discretize(double value, double[] values) {
+      var index = Array.BinarySearch(values, value);
+      var pos = 1.0*(index < 0 ? ~index : index)/(values.Length-1);
+      return Levels[Math.Min(Levels.Count - 1, Math.Max(0, (int) Math.Round(pos*(Levels.Count-1))))];
+    }
+
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionModification/RunCollectionFormulaModifer.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionModification/RunCollectionFormulaModifer.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionModification/RunCollectionFormulaModifer.cs	(revision 12764)
@@ -0,0 +1,136 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+
+  [Item("RunCollection Formula Modifier", "Modifies a RunCollection by adding results using the given formula.")]
+  [StorableClass]
+  public class RunCollectionFormulaModifer : ParameterizedNamedItem, IRunCollectionModifier {
+
+    public override bool CanChangeName { get { return false; } }
+    public override bool CanChangeDescription { get { return false; } }
+
+    public ValueParameter<StringValue> ResultNameParameter {
+      get { return (ValueParameter<StringValue>)Parameters["ResultName"]; }
+    }
+
+    public ValueParameter<StringValue> FormulaParameter {
+      get { return (ValueParameter<StringValue>)Parameters["Formula"]; }
+    }
+
+    private string ResultName { get { return ResultNameParameter.Value.Value; } }
+    private string Formula { get { return FormulaParameter.Value.Value; } }
+
+    #region Construction & Cloning
+    [StorableConstructor]
+    protected RunCollectionFormulaModifer(bool deserializing) : base(deserializing) { }
+    protected RunCollectionFormulaModifer(RunCollectionFormulaModifer original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterEvents();
+    }
+    public RunCollectionFormulaModifer() {
+      Parameters.Add(new ValueParameter<StringValue>("ResultName", "The name of the result to be generated by this formula.", new StringValue("Calc.Value")));
+      Parameters.Add(new ValueParameter<StringValue>("Formula",
+@"RPN formula for new value in postfix notation.
+
+This can contain the following elements:
+
+literals:
+  numbers, true, false, null and strings in single quotes
+variables (run parameters or results):
+  unquoted or in double quotes if they contain special characters or whitespace
+mathematical functions (resulting in double values):
+  +, -, *, /, ^ (power), log
+predicates:
+  ==, <, >, isnull, not
+conversions:
+  toint, todouble
+array indexing:
+  []
+stack manipulation:
+  drop swap dup
+string matching:
+  <string> <pattern> ismatch
+string replacing:
+  <string> <pattern> <replacement> rename
+conditionals:
+  <then> <else> <condition> if
+
+If the final value is null, the result variable is removed if it exists.",
+        new StringValue("1 1 +")));
+      UpdateName();
+      RegisterEvents();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RunCollectionFormulaModifer(this, cloner);
+    }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+    #endregion
+
+    private void RegisterEvents() {
+      ResultNameParameter.ToStringChanged += Parameter_NameChanged;
+      FormulaParameter.ToStringChanged += Parameter_NameChanged;
+    }
+
+    void Parameter_NameChanged(object sender, EventArgs e) {
+      UpdateName();
+    }
+
+    private void UpdateName() {
+      name = string.Format("{0} := {1}", ResultName, Formula);
+      OnNameChanged();
+    }
+
+    public void Modify(List<IRun> runs) {
+      var calc = new Calculator { Formula = Formula };
+      foreach (var run in runs) {
+        var variables = new Dictionary<string, IItem>();
+        foreach (var param in run.Parameters)
+          variables[param.Key] = param.Value;
+        foreach (var result in run.Results)
+          variables[result.Key] = result.Value;
+        try {
+          var value = calc.GetValue(variables);
+          if (value != null)
+            run.Results[ResultName] = value;
+          else
+            run.Results.Remove(ResultName);
+        } catch (Exception x) {
+          throw new Exception(string.Format("Calculation failed at Run {0}", run.Name), x);
+        }
+      }
+    }
+
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionModification/RunCollectionGroupCreater.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionModification/RunCollectionGroupCreater.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionModification/RunCollectionGroupCreater.cs	(revision 12764)
@@ -0,0 +1,105 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+
+  [Item("RunCollection Group Creater", "Regroups existing runs according to equal values in GroupBy and prefixes them according to their value in Prefix.")]
+  [StorableClass]
+  public class RunCollectionGroupCreater : ParameterizedNamedItem, IRunCollectionModifier {
+    
+    public ValueParameter<ItemCollection<StringValue>> GroupByParameter {
+      get { return (ValueParameter<ItemCollection<StringValue>>)Parameters["GroupBy"]; }
+    }
+
+    public ValueParameter<StringValue> PrefixParameter {
+      get { return (ValueParameter<StringValue>)Parameters["Prefix"]; }
+    }
+
+    private IEnumerable<string> GroupBy { get { return GroupByParameter.Value.Select(v => v.Value); } }
+    private string Prefix { get { return PrefixParameter.Value.Value; } }
+
+    #region Construction & Cloning
+    [StorableConstructor]
+    protected RunCollectionGroupCreater(bool deserializing) : base(deserializing) { }
+    protected RunCollectionGroupCreater(RunCollectionGroupCreater original, Cloner cloner) : base(original, cloner) { }
+    public RunCollectionGroupCreater() {
+      Parameters.Add(new ValueParameter<ItemCollection<StringValue>>("GroupBy", "The variable that has to be the same for all members of a group.",
+        new ItemCollection<StringValue>(new[] { new StringValue("Problem Name") })));
+      Parameters.Add(new ValueParameter<StringValue>("Prefix", "The distinguishing prefix values for the individual runs.",
+        new StringValue("Algorithm Name")));      
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RunCollectionGroupCreater(this, cloner);
+    }
+    #endregion    
+
+    private static string GetStringValue(string name, IRun r) {
+      IItem item;
+      r.Results.TryGetValue(name, out item);
+      if (item != null)
+        return item.ToString();
+      r.Parameters.TryGetValue(name, out item);
+      return item != null ? item.ToString() : "<none>";
+    }
+
+    private static string GetValues(IEnumerable<string> names, IRun r) {
+      return string.Join("/", names.Select(n => GetStringValue(n, r)));
+    }
+
+    public void Modify(List<IRun> runs) {
+      var groups = runs.GroupBy(r => GetValues(GroupBy, r).ToString()).ToList();
+      runs.Clear();
+      foreach (var group in groups) {
+        var run = new Run { Name = string.Format(group.Key) };
+        foreach (var r in group) {
+          var prefix = GetStringValue(Prefix, r);
+          foreach (var result in r.Results) {
+            InsertNew(run.Results, prefix, result.Key, result.Value);
+          }
+          foreach (var parameter in r.Parameters) {
+            InsertNew(run.Parameters, prefix, parameter.Key, parameter.Value);
+          }
+        }
+        runs.Add(run);
+      }
+    }
+
+    private static void InsertNew(IDictionary<string, IItem> dict, string prefix, string key, IItem value) {
+      if (prefix == null)
+        prefix = "<null>";
+      var n = 0;
+      var name = string.Format("{0}.{1}", prefix, key);
+      while (dict.ContainsKey(name)) {
+        name = string.Format("{0}_{1}.{2}", prefix, ++n, key);
+      }
+      dict.Add(name, value);      
+    }
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionModification/RunCollectionRunRemover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionModification/RunCollectionRunRemover.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionModification/RunCollectionRunRemover.cs	(revision 12764)
@@ -0,0 +1,49 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("RunCollection Run Remover", "Removes all currently visible runs. Use the filtering tab to selectively remove runs.")]
+  [StorableClass]
+  public class RunCollectionRunRemover : ParameterizedNamedItem, IRunCollectionModifier {
+
+    #region Construction & Cloning
+    [StorableConstructor]
+    protected RunCollectionRunRemover(bool deserializing) : base(deserializing) { }
+    protected RunCollectionRunRemover(RunCollectionRunRemover original, Cloner cloner) : base(original, cloner) {}
+    public RunCollectionRunRemover() {}
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RunCollectionRunRemover(this, cloner);
+    }
+    #endregion
+
+    #region IRunCollectionModifier Members
+    public void Modify(List<IRun> runs) {
+      runs.Clear();
+    }
+    #endregion
+
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionModification/RunCollectionSorter.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionModification/RunCollectionSorter.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionModification/RunCollectionSorter.cs	(revision 12764)
@@ -0,0 +1,129 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [Item("RunCollection Sorter", "Sorts a run collection according the specified key variable.")]
+  [StorableClass]
+  public class RunCollectionSorter : ParameterizedNamedItem, IRunCollectionModifier {
+
+    public override bool CanChangeName { get { return false; } }
+    public override bool CanChangeDescription { get { return false; } }
+
+    #region Parameters
+    public ValueParameter<StringValue> ValueParameter {
+      get { return (ValueParameter<StringValue>)Parameters["Value"]; }
+    }
+    #endregion
+
+    private string Value { get { return ValueParameter.Value.Value; } }
+
+    #region Construction & Cloning
+    [StorableConstructor]
+    protected RunCollectionSorter(bool deserializing) : base(deserializing) { }
+    protected RunCollectionSorter(RunCollectionSorter original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterEvents();
+    }
+    public RunCollectionSorter() {
+      Parameters.Add(new ValueParameter<StringValue>("Value", "The variable name used as sorting key.", new StringValue("Value")));
+      RegisterEvents();
+      UpdateName();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RunCollectionSorter(this, cloner);
+    }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEvents();
+    }
+    #endregion
+
+    private void RegisterEvents() {
+      ValueParameter.ToStringChanged += Parameter_NameChanged;
+    }
+
+    private void Parameter_NameChanged(object sender, EventArgs e) {
+      UpdateName();
+    }
+
+    private void UpdateName() {
+      name = string.Format("Sort by {0}", Value);
+      OnNameChanged();
+    }
+
+    private class ValueComparer : IComparer<IComparable> {
+
+      #region IComparer<IComparable> Members
+
+      public int Compare(IComparable x, IComparable y) {
+        if (x == null && y == null) return 0;
+        if (x == null) return -1;
+        if (y == null) return 1;
+        return x.CompareTo(y);
+      }
+
+      #endregion
+    }
+
+    private static readonly ValueComparer Comparer = new ValueComparer();
+
+    #region IRunCollectionModifier Members
+
+    public void Modify(List<IRun> runs) {
+      var sortedRuns = runs
+        .Select(r => new {Run = r, Key = GetValue(r)})
+        .OrderBy(r => r.Key, Comparer)
+        .Select(r => r.Run).ToList();
+      runs.Clear();
+      runs.AddRange(sortedRuns);
+    }
+
+    private IComparable GetValue(IRun run) {
+      return GetValue(run.Results) ?? GetValue(run.Parameters);
+    }
+
+    private IComparable GetValue(IDictionary<string, IItem> variables) {
+      IItem value;
+      variables.TryGetValue(Value, out value);
+      var intValue = value as IntValue;
+      if (intValue != null)
+        return intValue;
+      var doubleValue = value as DoubleValue;
+      if (doubleValue != null)
+        return doubleValue;
+      if (value != null)
+        return value.ToString();
+      return null;
+    }
+
+    #endregion
+  }
+}
Index: /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionModification/RunCollectionValueRemover.cs
===================================================================
--- /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionModification/RunCollectionValueRemover.cs	(revision 12764)
+++ /branches/PerformanceComparison/HeuristicLab.Optimization/3.3/RunCollectionModification/RunCollectionValueRemover.cs	(revision 12764)
@@ -0,0 +1,70 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+
+  [Item("RunCollection Value Remover", "Modifies a RunCollection by removing results or parameters.")]
+  [StorableClass]
+  public class RunCollectionValueRemover : ParameterizedNamedItem, IRunCollectionModifier {
+    
+    public ValueParameter<CheckedItemCollection<StringValue>> ValuesParameter {
+      get { return (ValueParameter<CheckedItemCollection<StringValue>>)Parameters["Values"]; }
+    }
+
+    public IEnumerable<string> Values {
+      get { return ValuesParameter.Value.CheckedItems.Select(v => v.Value); }
+    }
+
+    #region Construction & Cloning    
+    [StorableConstructor]
+    protected RunCollectionValueRemover(bool deserializing) : base(deserializing) { }
+    protected RunCollectionValueRemover(RunCollectionValueRemover original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public RunCollectionValueRemover() {
+      Parameters.Add(new ValueParameter<CheckedItemCollection<StringValue>>("Values", "The result or parameter values to be removed from each run."));      
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RunCollectionValueRemover(this, cloner);
+    }    
+    #endregion    
+
+    public void Modify(List<IRun> runs) {      
+      foreach (var run in runs) {
+        foreach (var value in Values) {
+          run.Parameters.Remove(value);
+          run.Results.Remove(value);
+        }        
+      }      
+    }
+    
+  }
+}
Index: /branches/PerformanceComparison/PerformanceComparison.sln
===================================================================
--- /branches/PerformanceComparison/PerformanceComparison.sln	(revision 12764)
+++ /branches/PerformanceComparison/PerformanceComparison.sln	(revision 12764)
@@ -0,0 +1,76 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.31101.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Analysis-3.3", "HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj", "{887425B4-4348-49ED-A457-B7D2C26DDBF9}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Analysis.Views-3.3", "HeuristicLab.Analysis.Views\3.3\HeuristicLab.Analysis.Views-3.3.csproj", "{76945D76-CA61-4147-9DC2-0ACDCDDF87F9}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Optimization-3.3", "HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj", "{14AB8D24-25BC-400C-A846-4627AA945192}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Optimization.Views-3.3", "HeuristicLab.Optimization.Views\3.3\HeuristicLab.Optimization.Views-3.3.csproj", "{662B4B15-8F4D-4AE5-B3EB-D91C215F5AF2}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|Any CPU = Release|Any CPU
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{887425B4-4348-49ED-A457-B7D2C26DDBF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{887425B4-4348-49ED-A457-B7D2C26DDBF9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{887425B4-4348-49ED-A457-B7D2C26DDBF9}.Debug|x64.ActiveCfg = Debug|x64
+		{887425B4-4348-49ED-A457-B7D2C26DDBF9}.Debug|x64.Build.0 = Debug|x64
+		{887425B4-4348-49ED-A457-B7D2C26DDBF9}.Debug|x86.ActiveCfg = Debug|x86
+		{887425B4-4348-49ED-A457-B7D2C26DDBF9}.Debug|x86.Build.0 = Debug|x86
+		{887425B4-4348-49ED-A457-B7D2C26DDBF9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{887425B4-4348-49ED-A457-B7D2C26DDBF9}.Release|Any CPU.Build.0 = Release|Any CPU
+		{887425B4-4348-49ED-A457-B7D2C26DDBF9}.Release|x64.ActiveCfg = Release|x64
+		{887425B4-4348-49ED-A457-B7D2C26DDBF9}.Release|x64.Build.0 = Release|x64
+		{887425B4-4348-49ED-A457-B7D2C26DDBF9}.Release|x86.ActiveCfg = Release|x86
+		{887425B4-4348-49ED-A457-B7D2C26DDBF9}.Release|x86.Build.0 = Release|x86
+		{76945D76-CA61-4147-9DC2-0ACDCDDF87F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{76945D76-CA61-4147-9DC2-0ACDCDDF87F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{76945D76-CA61-4147-9DC2-0ACDCDDF87F9}.Debug|x64.ActiveCfg = Debug|x64
+		{76945D76-CA61-4147-9DC2-0ACDCDDF87F9}.Debug|x64.Build.0 = Debug|x64
+		{76945D76-CA61-4147-9DC2-0ACDCDDF87F9}.Debug|x86.ActiveCfg = Debug|x86
+		{76945D76-CA61-4147-9DC2-0ACDCDDF87F9}.Debug|x86.Build.0 = Debug|x86
+		{76945D76-CA61-4147-9DC2-0ACDCDDF87F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{76945D76-CA61-4147-9DC2-0ACDCDDF87F9}.Release|Any CPU.Build.0 = Release|Any CPU
+		{76945D76-CA61-4147-9DC2-0ACDCDDF87F9}.Release|x64.ActiveCfg = Release|x64
+		{76945D76-CA61-4147-9DC2-0ACDCDDF87F9}.Release|x64.Build.0 = Release|x64
+		{76945D76-CA61-4147-9DC2-0ACDCDDF87F9}.Release|x86.ActiveCfg = Release|x86
+		{76945D76-CA61-4147-9DC2-0ACDCDDF87F9}.Release|x86.Build.0 = Release|x86
+		{14AB8D24-25BC-400C-A846-4627AA945192}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{14AB8D24-25BC-400C-A846-4627AA945192}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{14AB8D24-25BC-400C-A846-4627AA945192}.Debug|x64.ActiveCfg = Debug|x64
+		{14AB8D24-25BC-400C-A846-4627AA945192}.Debug|x64.Build.0 = Debug|x64
+		{14AB8D24-25BC-400C-A846-4627AA945192}.Debug|x86.ActiveCfg = Debug|x86
+		{14AB8D24-25BC-400C-A846-4627AA945192}.Debug|x86.Build.0 = Debug|x86
+		{14AB8D24-25BC-400C-A846-4627AA945192}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{14AB8D24-25BC-400C-A846-4627AA945192}.Release|Any CPU.Build.0 = Release|Any CPU
+		{14AB8D24-25BC-400C-A846-4627AA945192}.Release|x64.ActiveCfg = Release|x64
+		{14AB8D24-25BC-400C-A846-4627AA945192}.Release|x64.Build.0 = Release|x64
+		{14AB8D24-25BC-400C-A846-4627AA945192}.Release|x86.ActiveCfg = Release|x86
+		{14AB8D24-25BC-400C-A846-4627AA945192}.Release|x86.Build.0 = Release|x86
+		{662B4B15-8F4D-4AE5-B3EB-D91C215F5AF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{662B4B15-8F4D-4AE5-B3EB-D91C215F5AF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{662B4B15-8F4D-4AE5-B3EB-D91C215F5AF2}.Debug|x64.ActiveCfg = Debug|x64
+		{662B4B15-8F4D-4AE5-B3EB-D91C215F5AF2}.Debug|x64.Build.0 = Debug|x64
+		{662B4B15-8F4D-4AE5-B3EB-D91C215F5AF2}.Debug|x86.ActiveCfg = Debug|x86
+		{662B4B15-8F4D-4AE5-B3EB-D91C215F5AF2}.Debug|x86.Build.0 = Debug|x86
+		{662B4B15-8F4D-4AE5-B3EB-D91C215F5AF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{662B4B15-8F4D-4AE5-B3EB-D91C215F5AF2}.Release|Any CPU.Build.0 = Release|Any CPU
+		{662B4B15-8F4D-4AE5-B3EB-D91C215F5AF2}.Release|x64.ActiveCfg = Release|x64
+		{662B4B15-8F4D-4AE5-B3EB-D91C215F5AF2}.Release|x64.Build.0 = Release|x64
+		{662B4B15-8F4D-4AE5-B3EB-D91C215F5AF2}.Release|x86.ActiveCfg = Release|x86
+		{662B4B15-8F4D-4AE5-B3EB-D91C215F5AF2}.Release|x86.Build.0 = Release|x86
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
Index: /branches/PerformanceComparison/PreBuildEvent.cmd
===================================================================
--- /branches/PerformanceComparison/PreBuildEvent.cmd	(revision 12764)
+++ /branches/PerformanceComparison/PreBuildEvent.cmd	(revision 12764)
@@ -0,0 +1,11 @@
+IF EXIST "%ProjectDir%\Properties\AssemblyInfo.cs.frame" SubWCRev "%ProjectDir%\" "%ProjectDir%\Properties\AssemblyInfo.cs.frame" "%ProjectDir%\Properties\AssemblyInfo.cs"
+IF %ERRORLEVEL% NEQ 0 GOTO Error_Handling
+IF EXIST "%ProjectDir%\Plugin.cs.frame" SubWCRev "%ProjectDir%\" "%ProjectDir%\Plugin.cs.frame" "%ProjectDir%\Plugin.cs"
+IF %ERRORLEVEL% NEQ 0 GOTO Error_Handling
+GOTO Done
+
+:Error_Handling
+ECHO There was an error while running subwcrev. Please verify that the *.cs.frame files have been correctly converted to *.cs files, otherwise HeuristicLab won't build. 
+exit 0
+
+:Done
