Index: trunk/sources/HeuristicLab.Algorithms.SGA/3.3/SGAOperator.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.SGA/3.3/SGAOperator.cs	(revision 2907)
+++ trunk/sources/HeuristicLab.Algorithms.SGA/3.3/SGAOperator.cs	(revision 2908)
@@ -96,4 +96,6 @@
 
       #region Create operator graph
+      VariableCreator variableCreator = new VariableCreator();
+      ResultsCollector resultsCollector1 = new ResultsCollector();
       SubScopesSorter subScopesSorter1 = new SubScopesSorter();
       Placeholder selector = new Placeholder();
@@ -114,10 +116,21 @@
       Comparator comparator = new Comparator();
       BestAverageWorstQualityCalculator bestAverageWorstQualityCalculator = new BestAverageWorstQualityCalculator();
-      ResultsCollector resultsCollector = new ResultsCollector();
+      ResultsCollector resultsCollector2 = new ResultsCollector();
+      DataTableValuesCollector dataTableValuesCollector = new DataTableValuesCollector();
       ConditionalBranch conditionalBranch = new ConditionalBranch();
+
+      OperatorGraph.InitialOperator = variableCreator;
+
+      variableCreator.CollectedValues.Add(new ValueParameter<DataTable>("Qualities", new DataTable("Qualities")));
+      variableCreator.Successor = resultsCollector1;
+
+      LookupParameter<DataTable> qualities = new LookupParameter<DataTable>("Qualities");
+      qualities.ActualName = "Qualities";
+      resultsCollector1.CollectedValues.Add(qualities);
+      resultsCollector1.ResultsParameter.ActualName = "Results";
+      resultsCollector1.Successor = subScopesSorter1;
 
       subScopesSorter1.DescendingParameter.ActualName = "Maximization";
       subScopesSorter1.ValueParameter.ActualName = "Quality";
-      OperatorGraph.InitialOperator = subScopesSorter1;
       subScopesSorter1.Successor = selector;
 
@@ -188,17 +201,29 @@
       bestAverageWorstQualityCalculator.QualityParameter.ActualName = "Quality";
       bestAverageWorstQualityCalculator.WorstQualityParameter.ActualName = "WorstQuality";
-      bestAverageWorstQualityCalculator.Successor = resultsCollector;
+      bestAverageWorstQualityCalculator.Successor = dataTableValuesCollector;
 
       LookupParameter<DoubleData> bestQuality = new LookupParameter<DoubleData>("BestQuality");
       bestQuality.ActualName = "BestQuality";
-      resultsCollector.CollectedValues.Add(bestQuality);
+      dataTableValuesCollector.CollectedValues.Add(bestQuality);
       LookupParameter<DoubleData> averageQuality = new LookupParameter<DoubleData>("AverageQuality");
       averageQuality.ActualName = "AverageQuality";
-      resultsCollector.CollectedValues.Add(averageQuality);
+      dataTableValuesCollector.CollectedValues.Add(averageQuality);
       LookupParameter<DoubleData> worstQuality = new LookupParameter<DoubleData>("WorstQuality");
       worstQuality.ActualName = "WorstQuality";
-      resultsCollector.CollectedValues.Add(worstQuality);
-      resultsCollector.ResultsParameter.ActualName = "Results";
-      resultsCollector.Successor = conditionalBranch;
+      dataTableValuesCollector.CollectedValues.Add(worstQuality);
+      dataTableValuesCollector.DataTableParameter.ActualName = "Qualities";
+      dataTableValuesCollector.Successor = resultsCollector2;
+
+      bestQuality = new LookupParameter<DoubleData>("BestQuality");
+      bestQuality.ActualName = "BestQuality";
+      resultsCollector2.CollectedValues.Add(bestQuality);
+      averageQuality = new LookupParameter<DoubleData>("AverageQuality");
+      averageQuality.ActualName = "AverageQuality";
+      resultsCollector2.CollectedValues.Add(averageQuality);
+      worstQuality = new LookupParameter<DoubleData>("WorstQuality");
+      worstQuality.ActualName = "WorstQuality";
+      resultsCollector2.CollectedValues.Add(worstQuality);
+      resultsCollector2.ResultsParameter.ActualName = "Results";
+      resultsCollector2.Successor = conditionalBranch;
 
       conditionalBranch.ConditionParameter.ActualName = "Terminate";
Index: trunk/sources/HeuristicLab.Analysis.Views/3.3/DataTableView.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.Analysis.Views/3.3/DataTableView.Designer.cs	(revision 2908)
+++ trunk/sources/HeuristicLab.Analysis.Views/3.3/DataTableView.Designer.cs	(revision 2908)
@@ -0,0 +1,110 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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();
+      this.chart = new System.Windows.Forms.DataVisualization.Charting.Chart();
+      ((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.Size = new System.Drawing.Size(287, 20);
+      // 
+      // descriptionTextBox
+      // 
+      this.descriptionTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.descriptionTextBox.Size = new System.Drawing.Size(287, 62);
+      // 
+      // 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);
+      legend1.Name = "Legend1";
+      this.chart.Legends.Add(legend1);
+      this.chart.Location = new System.Drawing.Point(0, 94);
+      this.chart.Name = "chart";
+      series1.ChartArea = "ChartArea1";
+      series1.Legend = "Legend1";
+      series1.Name = "Series1";
+      this.chart.Series.Add(series1);
+      this.chart.Size = new System.Drawing.Size(359, 180);
+      this.chart.TabIndex = 4;
+      this.chart.Text = "chart1";
+      // 
+      // ChartView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.chart);
+      this.Name = "ChartView";
+      this.Size = new System.Drawing.Size(359, 274);
+      this.Controls.SetChildIndex(this.chart, 0);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.descriptionLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      this.Controls.SetChildIndex(this.descriptionTextBox, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.DataVisualization.Charting.Chart chart;
+
+  }
+}
Index: trunk/sources/HeuristicLab.Analysis.Views/3.3/DataTableView.cs
===================================================================
--- trunk/sources/HeuristicLab.Analysis.Views/3.3/DataTableView.cs	(revision 2908)
+++ trunk/sources/HeuristicLab.Analysis.Views/3.3/DataTableView.cs	(revision 2908)
@@ -0,0 +1,254 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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.DataVisualization.Charting;
+using HeuristicLab.Collections;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Analysis.Views {
+  /// <summary>
+  /// The visual representation of a <see cref="Variable"/>.
+  /// </summary>
+  [Content(typeof(DataTable), true)]
+  public sealed partial class DataTableView : NamedItemView {
+    Dictionary<IObservableList<double>, DataRow> 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 DataTable Content {
+      get { return (DataTable)base.Content; }
+      set { base.Content = value; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of <see cref="VariableView"/> with caption "Variable".
+    /// </summary>
+    public DataTableView() {
+      InitializeComponent();
+      Caption = "DataTable";
+      valuesRowsTable = new Dictionary<IObservableList<double>, DataRow>();
+    }
+    /// <summary>
+    /// Initializes a new instance of <see cref="VariableView"/> with the given <paramref name="variable"/>.
+    /// </summary>
+    /// <remarks>Calls <see cref="VariableView()"/>.</remarks>
+    /// <param name="variable">The variable to represent visually.</param>
+    public DataTableView(DataTable content)
+      : this() {
+      Content = content;
+    }
+
+    /// <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 (DataRow row in Content.Rows)
+        DeregisterDataRowEvents(row);
+      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();
+    }
+
+    /// <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.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);
+      foreach (DataRow row in Content.Rows)
+        RegisterDataRowEvents(row);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      chart.Titles.Clear();
+      chart.Series.Clear();
+      if (Content == null) {
+        Caption = "DataTable";
+        chart.Enabled = false;
+      } else {
+        Caption = Content.Name + " (" + Content.GetType().Name + ")";
+        chart.Enabled = true;
+        chart.Titles.Add(new Title(Content.Name, Docking.Top));
+        foreach (DataRow row in Content.Rows)
+          AddDataRow(row);
+      }
+    }
+
+    private void AddDataRow(DataRow row) {
+      Series series = new Series(row.Name);
+      series.ChartType = SeriesChartType.FastLine;
+      for (int i = 0; i < row.Values.Count; i++)
+        series.Points.Add(row.Values[i]);
+      chart.Series.Add(series);
+    }
+    private void RemoveDataRow(DataRow row) {
+      Series series = chart.Series[row.Name];
+      chart.Series.Remove(series);
+    }
+
+    #region Content Events
+    private void RegisterDataRowEvents(DataRow row) {
+      row.NameChanged += new EventHandler(Row_NameChanged);
+      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);
+    }
+    private 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.NameChanged -= new EventHandler(Row_NameChanged);
+    }
+    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 Rows_ItemsAdded(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsAdded), sender, e);
+      else {
+        foreach (DataRow row in e.Items) {
+          AddDataRow(row);
+          RegisterDataRowEvents(row);
+        }
+      }
+    }
+    private void Rows_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsRemoved), sender, e);
+      else {
+        foreach (DataRow row in e.Items) {
+          DeregisterDataRowEvents(row);
+          RemoveDataRow(row);
+        }
+      }
+    }
+    private void Rows_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_ItemsReplaced), sender, e);
+      else {
+        foreach (DataRow row in e.OldItems) {
+          DeregisterDataRowEvents(row);
+          RemoveDataRow(row);
+        }
+        foreach (DataRow row in e.Items) {
+          AddDataRow(row);
+          RegisterDataRowEvents(row);
+        }
+      }
+    }
+    private void Rows_CollectionReset(object sender, CollectionItemsChangedEventArgs<DataRow> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<DataRow>(Rows_CollectionReset), sender, e);
+      else {
+        foreach (DataRow row in e.OldItems) {
+          DeregisterDataRowEvents(row);
+          RemoveDataRow(row);
+        }
+        foreach (DataRow row in e.Items) {
+          AddDataRow(row);
+          RegisterDataRowEvents(row);
+        }
+      }
+    }
+    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;
+      }
+    }
+    private void Values_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsAdded), sender, e);
+      else {
+        DataRow row = valuesRowsTable[(IObservableList<double>)sender];
+        foreach (IndexedItem<double> item in e.Items)
+          chart.Series[row.Name].Points.InsertY(item.Index, item.Value);
+      }
+    }
+    private void Values_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsRemoved), sender, e);
+      else {
+        DataRow row = valuesRowsTable[(IObservableList<double>)sender];
+        List<DataPoint> points = new List<DataPoint>();
+        foreach (IndexedItem<double> item in e.Items)
+          points.Add(chart.Series[row.Name].Points[item.Index]);
+        foreach (DataPoint point in points)
+          chart.Series[row.Name].Points.Remove(point);
+      }
+    }
+    private void Values_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsReplaced), sender, e);
+      else {
+        DataRow row = valuesRowsTable[(IObservableList<double>)sender];
+        foreach (IndexedItem<double> item in e.Items)
+          chart.Series[row.Name].Points[item.Index].YValues = new double[] { item.Value };
+      }
+    }
+    private void Values_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_ItemsMoved), sender, e);
+      else {
+        DataRow row = valuesRowsTable[(IObservableList<double>)sender];
+        foreach (IndexedItem<double> item in e.Items)
+          chart.Series[row.Name].Points[item.Index].YValues = new double[] { item.Value };
+      }
+    }
+    private void Values_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<double>> e) {
+      if (InvokeRequired)
+        Invoke(new CollectionItemsChangedEventHandler<IndexedItem<double>>(Values_CollectionReset), sender, e);
+      else {
+        DataRow row = valuesRowsTable[(IObservableList<double>)sender];
+        chart.Series[row.Name].Points.Clear();
+        foreach (IndexedItem<double> item in e.Items)
+          chart.Series[row.Name].Points[item.Index].YValues = new double[] { item.Value };
+      }
+    }
+    #endregion
+  }
+}
Index: trunk/sources/HeuristicLab.Analysis.Views/3.3/HeuristicLab.Analysis.Views-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.Analysis.Views/3.3/HeuristicLab.Analysis.Views-3.3.csproj	(revision 2907)
+++ trunk/sources/HeuristicLab.Analysis.Views/3.3/HeuristicLab.Analysis.Views-3.3.csproj	(revision 2908)
@@ -75,4 +75,5 @@
     <Reference Include="System.Drawing" />
     <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Windows.Forms.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
     <Reference Include="System.Xml.Linq">
       <RequiredTargetFramework>3.5</RequiredTargetFramework>
@@ -88,4 +89,10 @@
     <Compile Include="HeuristicLabAnalysisViewsPlugin.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="DataTableView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="DataTableView.Designer.cs">
+      <DependentUpon>DataTableView.cs</DependentUpon>
+    </Compile>
   </ItemGroup>
   <ItemGroup>
@@ -98,7 +105,15 @@
       <Name>HeuristicLab.Analysis-3.3</Name>
     </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Collections\3.3\HeuristicLab.Collections-3.3.csproj">
+      <Project>{958B43BC-CC5C-4FA2-8628-2B3B01D890B6}</Project>
+      <Name>HeuristicLab.Collections-3.3</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Core.Views\3.3\HeuristicLab.Core.Views-3.3.csproj">
       <Project>{E226881D-315F-423D-B419-A766FE0D8685}</Project>
       <Name>HeuristicLab.Core.Views-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Core\3.3\HeuristicLab.Core-3.3.csproj">
+      <Project>{C36BD924-A541-4A00-AFA8-41701378DDC5}</Project>
+      <Name>HeuristicLab.Core-3.3</Name>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.MainForm.WindowsForms\3.2\HeuristicLab.MainForm.WindowsForms-3.2.csproj">
Index: trunk/sources/HeuristicLab.Analysis.Views/3.3/HeuristicLabAnalysisViewsPlugin.cs.frame
===================================================================
--- trunk/sources/HeuristicLab.Analysis.Views/3.3/HeuristicLabAnalysisViewsPlugin.cs.frame	(revision 2907)
+++ trunk/sources/HeuristicLab.Analysis.Views/3.3/HeuristicLabAnalysisViewsPlugin.cs.frame	(revision 2908)
@@ -29,4 +29,6 @@
   [PluginFile("HeuristicLab.Analysis.Views-3.3.dll", PluginFileType.Assembly)]
   [PluginDependency("HeuristicLab.Analysis", "3.3")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
   [PluginDependency("HeuristicLab.Core.Views", "3.3")]
   [PluginDependency("HeuristicLab.MainForm", "3.2")]
Index: trunk/sources/HeuristicLab.Analysis/3.3/DataRow.cs
===================================================================
--- trunk/sources/HeuristicLab.Analysis/3.3/DataRow.cs	(revision 2908)
+++ trunk/sources/HeuristicLab.Analysis/3.3/DataRow.cs	(revision 2908)
@@ -0,0 +1,59 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// A row of data values.
+  /// </summary>
+  [Item("DataRow", "A row of data values.")]
+  [Creatable("Test")]
+  public sealed class DataRow : NamedItem {
+    [Storable]
+    private ObservableList<double> values;
+    public IObservableList<double> Values {
+      get { return values; }
+    }
+
+    public DataRow()
+      : base() {
+      values = new ObservableList<double>();
+    }
+    public DataRow(string name)
+      : base(name) {
+      values = new ObservableList<double>();
+    }
+    public DataRow(string name, string description)
+      : base(name, description) {
+      values = new ObservableList<double>();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      DataRow clone = new DataRow(Name, Description);
+      cloner.RegisterClonedObject(this, clone);
+      clone.values.AddRange(values);
+      return clone;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Analysis/3.3/DataTable.cs
===================================================================
--- trunk/sources/HeuristicLab.Analysis/3.3/DataTable.cs	(revision 2908)
+++ trunk/sources/HeuristicLab.Analysis/3.3/DataTable.cs	(revision 2908)
@@ -0,0 +1,58 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// A table of data values.
+  /// </summary>
+  [Item("DataTable", "A table of data values.")]
+  [Creatable("Test")]
+  public sealed class DataTable : NamedItem {
+    [Storable]
+    private NamedItemCollection<DataRow> rows;
+    public NamedItemCollection<DataRow> Rows {
+      get { return rows; }
+    }
+
+    public DataTable()
+      : base() {
+      rows = new NamedItemCollection<DataRow>();
+    }
+    public DataTable(string name)
+      : base(name) {
+      rows = new NamedItemCollection<DataRow>();
+    }
+    public DataTable(string name, string description)
+      : base(name, description) {
+      rows = new NamedItemCollection<DataRow>();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      DataTable clone = new DataTable(Name, Description);
+      cloner.RegisterClonedObject(this, clone);
+      clone.rows = (NamedItemCollection<DataRow>)cloner.Clone(rows);
+      return clone;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Analysis/3.3/DataTableValuesCollector.cs
===================================================================
--- trunk/sources/HeuristicLab.Analysis/3.3/DataTableValuesCollector.cs	(revision 2908)
+++ trunk/sources/HeuristicLab.Analysis/3.3/DataTableValuesCollector.cs	(revision 2908)
@@ -0,0 +1,70 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You 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.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.")]
+  [Creatable("Test")]
+  [EmptyStorableClass]
+  public class DataTableValuesCollector : ValuesCollector {
+    public ValueLookupParameter<DataTable> DataTableParameter {
+      get { return (ValueLookupParameter<DataTable>)Parameters["DataTable"]; }
+    }
+
+    public DataTableValuesCollector()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<DataTable>("DataTable", "The table of data values where the collected values should be stored."));
+    }
+
+    public override IOperation Apply() {
+      DataTable table = DataTableParameter.ActualValue;
+      if (table == null) {
+        table = new DataTable(DataTableParameter.ActualName);
+        DataTableParameter.ActualValue = table;
+      }
+
+      foreach (IParameter param in CollectedValues) {
+        DoubleData data = param.ActualValue as DoubleData;
+        if (data == null) throw new InvalidOperationException("Only double data values can be collected by a DataTableValuesCollector.");
+
+        DataRow row;
+        table.Rows.TryGetValue(param.Name, out row);
+        if (row == null) {
+          row = new DataRow(param.Name);
+          row.Values.Add(data.Value);
+          table.Rows.Add(row);
+        } else {
+          row.Values.Add(data.Value);
+        }
+      }
+      return base.Apply();
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 2907)
+++ trunk/sources/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 2908)
@@ -85,9 +85,14 @@
     <None Include="HeuristicLabAnalysisPlugin.cs.frame" />
     <Compile Include="BestAverageWorstQualityCalculator.cs" />
+    <Compile Include="DataRow.cs" />
     <Compile Include="HeuristicLabAnalysisPlugin.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="DataTable.cs" />
+    <Compile Include="DataTableValuesCollector.cs" />
   </ItemGroup>
   <ItemGroup>
     <None Include="HeuristicLab.snk" />
+    <None Include="Microsoft Chart Controls\DataVisChartControl.chm" />
+    <None Include="Microsoft Chart Controls\WinSamples.zip" />
     <None Include="Properties\AssemblyInfo.frame" />
   </ItemGroup>
@@ -122,4 +127,8 @@
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup>
+    <None Include="Microsoft Chart Controls\MSChart.exe" />
+    <None Include="Microsoft Chart Controls\MSChart_VisualStudioAddOn.exe" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
Index: trunk/sources/HeuristicLab.Operators/3.3/ResultsCollector.cs
===================================================================
--- trunk/sources/HeuristicLab.Operators/3.3/ResultsCollector.cs	(revision 2907)
+++ trunk/sources/HeuristicLab.Operators/3.3/ResultsCollector.cs	(revision 2908)
@@ -26,7 +26,7 @@
 namespace HeuristicLab.Operators {
   /// <summary>
-  /// An operator which collects the actual values of parameters and clones them into a collection of variables.
+  /// An operator which collects the actual values of parameters and adds them to a collection of variables.
   /// </summary>
-  [Item("ResultsCollector", "An operator which collects the actual values of parameters and clones them into a collection of variables.")]
+  [Item("ResultsCollector", "An operator which collects the actual values of parameters and adds them to a collection of variables.")]
   [Creatable("Test")]
   [EmptyStorableClass]
@@ -47,7 +47,7 @@
         results.TryGetValue(param.Name, out var);
         if (var != null)
-          var.Value = (IItem)param.ActualValue.Clone();
+          var.Value = (IItem)param.ActualValue;
         else
-          results.Add(new Variable(param.Name, (IItem)param.ActualValue.Clone()));
+          results.Add(new Variable(param.Name, param.ActualValue));
       }
       return base.Apply();
