Index: /trunk/sources/HeuristicLab.Optimization.Views/3.3/BatchRunListView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Optimization.Views/3.3/BatchRunListView.Designer.cs	(revision 3267)
+++ /trunk/sources/HeuristicLab.Optimization.Views/3.3/BatchRunListView.Designer.cs	(revision 3267)
@@ -0,0 +1,53 @@
+﻿#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.Optimization.Views {
+  partial class BatchRunListView {
+    /// <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.Font;
+    }
+
+    #endregion
+  }
+}
Index: /trunk/sources/HeuristicLab.Optimization.Views/3.3/BatchRunListView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Optimization.Views/3.3/BatchRunListView.cs	(revision 3267)
+++ /trunk/sources/HeuristicLab.Optimization.Views/3.3/BatchRunListView.cs	(revision 3267)
@@ -0,0 +1,52 @@
+﻿#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.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("BatchRunList View")]
+  [Content(typeof(BatchRunList), true)]
+  public partial class BatchRunListView : ItemListView<BatchRun> {
+    /// <summary>
+    /// Initializes a new instance of <see cref="VariablesScopeView"/> with caption "Variables Scope View".
+    /// </summary>
+    public BatchRunListView() {
+      InitializeComponent();
+      Caption = "BatchRunList";
+      itemsGroupBox.Text = "Batch Runs";
+    }
+    /// <summary>
+    /// Initializes a new instance of <see cref="VariablesScopeView"/> with 
+    /// the given <paramref name="scope"/>.
+    /// </summary>
+    /// <remarks>Calls <see cref="VariablesScopeView()"/>.</remarks>
+    /// <param name="scope">The scope whose variables should be represented visually.</param>
+    public BatchRunListView(BatchRunList content)
+      : this() {
+      Content = content;
+    }
+
+    protected override BatchRun CreateItem() {
+      return new BatchRun();
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Optimization.Views/3.3/ExperimentView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Optimization.Views/3.3/ExperimentView.Designer.cs	(revision 3267)
+++ /trunk/sources/HeuristicLab.Optimization.Views/3.3/ExperimentView.Designer.cs	(revision 3267)
@@ -0,0 +1,247 @@
+#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.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 System.Windows.Forms.TabControl();
+      this.batchRunsTabPage = new System.Windows.Forms.TabPage();
+      this.resultsTabPage = new System.Windows.Forms.TabPage();
+      this.runsView = new HeuristicLab.Optimization.Views.RunCollectionView();
+      this.startButton = new System.Windows.Forms.Button();
+      this.stopButton = new System.Windows.Forms.Button();
+      this.resetButton = new System.Windows.Forms.Button();
+      this.executionTimeLabel = new System.Windows.Forms.Label();
+      this.executionTimeTextBox = new System.Windows.Forms.TextBox();
+      this.pauseButton = new System.Windows.Forms.Button();
+      this.batchRunListView = new HeuristicLab.Optimization.Views.BatchRunListView();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.tabControl.SuspendLayout();
+      this.batchRunsTabPage.SuspendLayout();
+      this.resultsTabPage.SuspendLayout();
+      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(607, 20);
+      // 
+      // descriptionTextBox
+      // 
+      this.descriptionTextBox.Size = new System.Drawing.Size(607, 20);
+      // 
+      // 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.batchRunsTabPage);
+      this.tabControl.Controls.Add(this.resultsTabPage);
+      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, 400);
+      this.tabControl.TabIndex = 4;
+      // 
+      // batchRunsTabPage
+      // 
+      this.batchRunsTabPage.Controls.Add(this.batchRunListView);
+      this.batchRunsTabPage.Location = new System.Drawing.Point(4, 22);
+      this.batchRunsTabPage.Name = "batchRunsTabPage";
+      this.batchRunsTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.batchRunsTabPage.Size = new System.Drawing.Size(671, 374);
+      this.batchRunsTabPage.TabIndex = 1;
+      this.batchRunsTabPage.Text = "Batch Runs";
+      this.batchRunsTabPage.UseVisualStyleBackColor = true;
+      // 
+      // resultsTabPage
+      // 
+      this.resultsTabPage.Controls.Add(this.runsView);
+      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, 374);
+      this.resultsTabPage.TabIndex = 2;
+      this.resultsTabPage.Text = "Results";
+      this.resultsTabPage.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";
+      this.runsView.Content = null;
+      this.runsView.Location = new System.Drawing.Point(6, 6);
+      this.runsView.Name = "runsView";
+      this.runsView.Size = new System.Drawing.Size(659, 362);
+      this.runsView.TabIndex = 0;
+      // 
+      // startButton
+      // 
+      this.startButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.startButton.Image = HeuristicLab.Common.Resources.VS2008ImageLibrary.Play;
+      this.startButton.Location = new System.Drawing.Point(0, 458);
+      this.startButton.Name = "startButton";
+      this.startButton.Size = new System.Drawing.Size(24, 24);
+      this.startButton.TabIndex = 5;
+      this.toolTip.SetToolTip(this.startButton, "Start/Resume Experiment");
+      this.startButton.UseVisualStyleBackColor = true;
+      this.startButton.Click += new System.EventHandler(this.startButton_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.VS2008ImageLibrary.Stop;
+      this.stopButton.Location = new System.Drawing.Point(60, 458);
+      this.stopButton.Name = "stopButton";
+      this.stopButton.Size = new System.Drawing.Size(24, 24);
+      this.stopButton.TabIndex = 7;
+      this.toolTip.SetToolTip(this.stopButton, "Stop Experiment");
+      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.VS2008ImageLibrary.Restart;
+      this.resetButton.Location = new System.Drawing.Point(90, 458);
+      this.resetButton.Name = "resetButton";
+      this.resetButton.Size = new System.Drawing.Size(24, 24);
+      this.resetButton.TabIndex = 8;
+      this.toolTip.SetToolTip(this.resetButton, "Reset Experiment");
+      this.resetButton.UseVisualStyleBackColor = true;
+      this.resetButton.Click += new System.EventHandler(this.resetButton_Click);
+      // 
+      // 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(453, 465);
+      this.executionTimeLabel.Name = "executionTimeLabel";
+      this.executionTimeLabel.Size = new System.Drawing.Size(83, 13);
+      this.executionTimeLabel.TabIndex = 9;
+      this.executionTimeLabel.Text = "&Execution Time:";
+      // 
+      // 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(542, 462);
+      this.executionTimeTextBox.Name = "executionTimeTextBox";
+      this.executionTimeTextBox.ReadOnly = true;
+      this.executionTimeTextBox.Size = new System.Drawing.Size(137, 20);
+      this.executionTimeTextBox.TabIndex = 10;
+      // 
+      // pauseButton
+      // 
+      this.pauseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.pauseButton.Image = HeuristicLab.Common.Resources.VS2008ImageLibrary.Pause;
+      this.pauseButton.Location = new System.Drawing.Point(30, 458);
+      this.pauseButton.Name = "pauseButton";
+      this.pauseButton.Size = new System.Drawing.Size(24, 24);
+      this.pauseButton.TabIndex = 6;
+      this.toolTip.SetToolTip(this.pauseButton, "Pause Experiment");
+      this.pauseButton.UseVisualStyleBackColor = true;
+      this.pauseButton.Click += new System.EventHandler(this.pauseButton_Click);
+      // 
+      // batchRunListView
+      // 
+      this.batchRunListView.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.batchRunListView.Caption = "BatchRunList";
+      this.batchRunListView.Content = null;
+      this.batchRunListView.Location = new System.Drawing.Point(6, 6);
+      this.batchRunListView.Name = "batchRunListView";
+      this.batchRunListView.Size = new System.Drawing.Size(659, 362);
+      this.batchRunListView.TabIndex = 0;
+      // 
+      // ExperimentView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.tabControl);
+      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 = "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.executionTimeLabel, 0);
+      this.Controls.SetChildIndex(this.executionTimeTextBox, 0);
+      this.Controls.SetChildIndex(this.startButton, 0);
+      this.Controls.SetChildIndex(this.tabControl, 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();
+      this.tabControl.ResumeLayout(false);
+      this.batchRunsTabPage.ResumeLayout(false);
+      this.resultsTabPage.ResumeLayout(false);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+    #endregion
+
+    private System.Windows.Forms.TabControl tabControl;
+    private System.Windows.Forms.TabPage batchRunsTabPage;
+    private System.Windows.Forms.Button startButton;
+    private System.Windows.Forms.Button stopButton;
+    private System.Windows.Forms.Button resetButton;
+    private System.Windows.Forms.Label executionTimeLabel;
+    private System.Windows.Forms.TextBox executionTimeTextBox;
+    private System.Windows.Forms.TabPage resultsTabPage;
+    private RunCollectionView runsView;
+    private System.Windows.Forms.Button pauseButton;
+    private BatchRunListView batchRunListView;
+
+  }
+}
Index: /trunk/sources/HeuristicLab.Optimization.Views/3.3/ExperimentView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Optimization.Views/3.3/ExperimentView.cs	(revision 3267)
+++ /trunk/sources/HeuristicLab.Optimization.Views/3.3/ExperimentView.cs	(revision 3267)
@@ -0,0 +1,149 @@
+#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.Windows.Forms;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Optimization.Views {
+  /// <summary>
+  /// The base class for visual representations of items.
+  /// </summary>
+  [View("Experiment View")]
+  [Content(typeof(Experiment), true)]
+  public sealed partial class ExperimentView : NamedItemView {
+    public new Experiment Content {
+      get { return (Experiment)base.Content; }
+      set { base.Content = value; }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of <see cref="ItemBaseView"/>.
+    /// </summary>
+    public ExperimentView() {
+      InitializeComponent();
+    }
+    /// <summary>
+    /// Intializes a new instance of <see cref="ItemBaseView"/> with the given <paramref name="item"/>.
+    /// </summary>
+    /// <param name="item">The item that should be displayed.</param>
+    public ExperimentView(Experiment content)
+      : this() {
+      Content = content;
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.ExceptionOccurred -= new EventHandler<EventArgs<Exception>>(Content_ExceptionOccurred);
+      Content.ExecutionStateChanged -= new EventHandler(Content_ExecutionStateChanged);
+      Content.ExecutionTimeChanged -= new EventHandler(Content_ExecutionTimeChanged);
+      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);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        batchRunListView.Content = null;
+        runsView.Content = null;
+        tabControl.Enabled = false;
+        startButton.Enabled = pauseButton.Enabled = stopButton.Enabled = resetButton.Enabled = false;
+        executionTimeTextBox.Text = "-";
+        executionTimeTextBox.Enabled = false;
+      } else {
+        batchRunListView.Content = Content.BatchRuns;
+        runsView.Content = Content.Runs;
+        tabControl.Enabled = true;
+        EnableDisableButtons();
+        executionTimeTextBox.Text = Content.ExecutionTime.ToString();
+        executionTimeTextBox.Enabled = true;
+      }
+    }
+
+    protected override void OnClosed(FormClosedEventArgs e) {
+      if ((Content != null) && (Content.ExecutionState == ExecutionState.Started)) Content.Stop();
+      base.OnClosed(e);
+    }
+
+    #region Content Events
+    private void Content_ExecutionStateChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_ExecutionStateChanged), sender, e);
+      else {
+        nameTextBox.Enabled = Content.ExecutionState != ExecutionState.Started;
+        descriptionTextBox.Enabled = Content.ExecutionState != ExecutionState.Started;
+        SaveEnabled = Content.ExecutionState != ExecutionState.Started;
+        EnableDisableButtons();
+      }
+    }
+    private void Content_ExecutionTimeChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_ExecutionTimeChanged), sender, e);
+      else
+        executionTimeTextBox.Text = Content.ExecutionTime.ToString();
+    }
+    private void Content_ExceptionOccurred(object sender, EventArgs<Exception> e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler<EventArgs<Exception>>(Content_ExceptionOccurred), sender, e);
+      else
+        Auxiliary.ShowErrorMessageBox(e.Value);
+    }
+    #endregion
+
+    #region Control events
+    private void startButton_Click(object sender, EventArgs e) {
+      Content.Start();
+    }
+    private void pauseButton_Click(object sender, EventArgs e) {
+      Content.Pause();
+    }
+    private void stopButton_Click(object sender, EventArgs e) {
+      Content.Stop();
+    }
+    private void resetButton_Click(object sender, EventArgs e) {
+      if (Content.Runs.Count > 0) {
+        if (MessageBox.Show(this, "Clear all runs executed so far?", "Clear All Runs?", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
+          Content.Prepare(true);
+        else
+          Content.Prepare(false);
+      } else {
+        Content.Prepare();
+      }
+    }
+    #endregion
+
+    #region Helpers
+    private void EnableDisableButtons() {
+      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: /trunk/sources/HeuristicLab.Optimization.Views/3.3/HeuristicLab.Optimization.Views-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Optimization.Views/3.3/HeuristicLab.Optimization.Views-3.3.csproj	(revision 3266)
+++ /trunk/sources/HeuristicLab.Optimization.Views/3.3/HeuristicLab.Optimization.Views-3.3.csproj	(revision 3267)
@@ -98,4 +98,16 @@
       <DependentUpon>BatchRunView.cs</DependentUpon>
     </Compile>
+    <Compile Include="BatchRunListView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="BatchRunListView.Designer.cs">
+      <DependentUpon>BatchRunListView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="ExperimentView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ExperimentView.Designer.cs">
+      <DependentUpon>ExperimentView.cs</DependentUpon>
+    </Compile>
     <Compile Include="RunCollectionView.cs">
       <SubType>UserControl</SubType>
Index: /trunk/sources/HeuristicLab.Optimization/3.3/BatchRunList.cs
===================================================================
--- /trunk/sources/HeuristicLab.Optimization/3.3/BatchRunList.cs	(revision 3267)
+++ /trunk/sources/HeuristicLab.Optimization/3.3/BatchRunList.cs	(revision 3267)
@@ -0,0 +1,41 @@
+#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.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization {
+  [StorableClass]
+  [Item("BatchRunList", "Represents a list of batch runs.")]
+  public sealed class BatchRunList : ItemList<BatchRun> {
+    public BatchRunList() : base() { }
+    public BatchRunList(int capacity) : base(capacity) { }
+    public BatchRunList(IEnumerable<BatchRun> collection) : base(collection) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      BatchRunList clone = new BatchRunList(this.Select(x => (BatchRun)cloner.Clone(x)));
+      cloner.RegisterClonedObject(this, clone);
+      return clone;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Optimization/3.3/Experiment.cs
===================================================================
--- /trunk/sources/HeuristicLab.Optimization/3.3/Experiment.cs	(revision 3267)
+++ /trunk/sources/HeuristicLab.Optimization/3.3/Experiment.cs	(revision 3267)
@@ -0,0 +1,290 @@
+#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.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 batch runs of algorithms.
+  /// </summary>
+  [Item("Experiment", "An experiment which contains multiple batch runs of algorithms.")]
+  [Creatable("Testing & Analysis")]
+  [StorableClass]
+  public sealed class Experiment : NamedItem, IExecutable {
+    public override Image ItemImage {
+      get { return HeuristicLab.Common.Resources.VS2008ImageLibrary.Event; }
+    }
+
+    [Storable]
+    private ExecutionState executionState;
+    public ExecutionState ExecutionState {
+      get { return executionState; }
+      private set {
+        if (executionState != value) {
+          executionState = value;
+          OnExecutionStateChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private TimeSpan executionTime;
+    public TimeSpan ExecutionTime {
+      get { return executionTime; }
+      private set {
+        executionTime = value;
+        OnExecutionTimeChanged();
+      }
+    }
+
+    private BatchRunList batchRuns;
+    [Storable]
+    public BatchRunList BatchRuns {
+      get { return batchRuns; }
+      private set {
+        if (batchRuns != value) {
+          if (batchRuns != null) DeregisterBatchRunsEvents();
+          batchRuns = value;
+          if (batchRuns != null) RegisterBatchRunsEvents();
+          foreach (BatchRun batchRun in batchRuns)
+            RegisterBatchRunEvents(batchRun);
+        }
+      }
+    }
+
+    [Storable]
+    private RunCollection runs;
+    public RunCollection Runs {
+      get { return runs; }
+    }
+
+    private bool stopPending;
+
+    public Experiment()
+      : base() {
+      executionState = ExecutionState.Stopped;
+      executionTime = TimeSpan.Zero;
+      BatchRuns = new BatchRunList();
+      runs = new RunCollection();
+      stopPending = false;
+    }
+    public Experiment(string name) : base(name) {
+      executionState = ExecutionState.Stopped;
+      executionTime = TimeSpan.Zero;
+      BatchRuns = new BatchRunList();
+      runs = new RunCollection();
+      stopPending = false;
+    }
+    public Experiment(string name, string description) : base(name, description) {
+      executionState = ExecutionState.Stopped;
+      executionTime = TimeSpan.Zero;
+      BatchRuns = new BatchRunList();
+      runs = new RunCollection();
+      stopPending = false;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      Experiment clone = (Experiment)base.Clone(cloner);
+      clone.executionState = executionState;
+      clone.executionTime = executionTime;
+      clone.BatchRuns = (BatchRunList)cloner.Clone(batchRuns);
+      clone.runs = (RunCollection)cloner.Clone(runs);
+      clone.stopPending = stopPending;
+      return clone;
+    }
+
+    public void Prepare() {
+      Prepare(true);
+    }
+    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 (BatchRuns.Count > 0) {
+        if (clearRuns) {
+          ExecutionTime = TimeSpan.Zero;
+          runs.Clear();
+        }
+        foreach (BatchRun batchRun in BatchRuns.Where(x => x.ExecutionState != ExecutionState.Started))
+          batchRun.Prepare(clearRuns);
+      }
+    }
+    public void Start() {
+      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
+        throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
+      stopPending = false;
+      if (BatchRuns.Count > 0) {
+        BatchRun batchRun = BatchRuns.FirstOrDefault(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused));
+        if (batchRun != null) batchRun.Start();
+      }
+    }
+    public void Pause() {
+      if (ExecutionState != ExecutionState.Started)
+        throw new InvalidOperationException(string.Format("Pause not allowed in execution state \"{0}\".", ExecutionState));
+      if (BatchRuns.Count > 0) {
+        foreach (BatchRun batchRun in BatchRuns.Where(x => x.ExecutionState == ExecutionState.Started))
+          batchRun.Pause();
+      }
+    }
+    public void Stop() {
+      if ((ExecutionState != ExecutionState.Started) && (ExecutionState != ExecutionState.Paused))
+        throw new InvalidOperationException(string.Format("Stop not allowed in execution state \"{0}\".", ExecutionState));
+      stopPending = true;
+      if (BatchRuns.Count > 0) {
+        foreach (BatchRun batchRun in BatchRuns.Where(x => (x.ExecutionState == ExecutionState.Started) || (x.ExecutionState == ExecutionState.Paused)))
+          batchRun.Stop();
+      }
+    }
+
+    #region Events
+    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 RegisterBatchRunsEvents() {
+      BatchRuns.CollectionReset += new CollectionItemsChangedEventHandler<IndexedItem<BatchRun>>(BatchRuns_CollectionReset);
+      BatchRuns.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<BatchRun>>(BatchRuns_ItemsAdded);
+      BatchRuns.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<BatchRun>>(BatchRuns_ItemsRemoved);
+      BatchRuns.ItemsReplaced += new CollectionItemsChangedEventHandler<IndexedItem<BatchRun>>(BatchRuns_ItemsReplaced);
+    }
+    private void DeregisterBatchRunsEvents() {
+      BatchRuns.CollectionReset -= new CollectionItemsChangedEventHandler<IndexedItem<BatchRun>>(BatchRuns_CollectionReset);
+      BatchRuns.ItemsAdded -= new CollectionItemsChangedEventHandler<IndexedItem<BatchRun>>(BatchRuns_ItemsAdded);
+      BatchRuns.ItemsRemoved -= new CollectionItemsChangedEventHandler<IndexedItem<BatchRun>>(BatchRuns_ItemsRemoved);
+      BatchRuns.ItemsReplaced -= new CollectionItemsChangedEventHandler<IndexedItem<BatchRun>>(BatchRuns_ItemsReplaced);
+    }
+    private void BatchRuns_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<BatchRun>> e) {
+      foreach (IndexedItem<BatchRun> item in e.OldItems) {
+        DeregisterBatchRunEvents(item.Value);
+      }
+      foreach (IndexedItem<BatchRun> item in e.Items) {
+        RegisterBatchRunEvents(item.Value);
+      }
+    }
+    private void BatchRuns_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<BatchRun>> e) {
+      foreach (IndexedItem<BatchRun> item in e.Items) {
+        RegisterBatchRunEvents(item.Value);
+      }
+    }
+    private void BatchRuns_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<BatchRun>> e) {
+      foreach (IndexedItem<BatchRun> item in e.Items) {
+        DeregisterBatchRunEvents(item.Value);
+      }
+    }
+    private void BatchRuns_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<BatchRun>> e) {
+      foreach (IndexedItem<BatchRun> item in e.OldItems) {
+        DeregisterBatchRunEvents(item.Value);
+      }
+      foreach (IndexedItem<BatchRun> item in e.Items) {
+        RegisterBatchRunEvents(item.Value);
+      }
+    }
+
+    private void RegisterBatchRunEvents(BatchRun batchRun) {
+      batchRun.ExceptionOccurred += new EventHandler<EventArgs<Exception>>(batchRun_ExceptionOccurred);
+      batchRun.Paused += new EventHandler(batchRun_Paused);
+      batchRun.Prepared += new EventHandler(batchRun_Prepared);
+      batchRun.Started += new EventHandler(batchRun_Started);
+      batchRun.Stopped += new EventHandler(batchRun_Stopped);
+    }
+    private void DeregisterBatchRunEvents(BatchRun batchRun) {
+      batchRun.ExceptionOccurred -= new EventHandler<EventArgs<Exception>>(batchRun_ExceptionOccurred);
+      batchRun.Paused -= new EventHandler(batchRun_Paused);
+      batchRun.Prepared -= new EventHandler(batchRun_Prepared);
+      batchRun.Started -= new EventHandler(batchRun_Started);
+      batchRun.Stopped -= new EventHandler(batchRun_Stopped);
+    }
+    private void batchRun_ExceptionOccurred(object sender, EventArgs<Exception> e) {
+      OnExceptionOccurred(e.Value);
+    }
+    private void batchRun_Paused(object sender, EventArgs e) {
+      if (BatchRuns.All(x => x.ExecutionState != ExecutionState.Started))
+        OnPaused();
+    }
+    void batchRun_Prepared(object sender, EventArgs e) {
+      if (ExecutionState == ExecutionState.Stopped)
+        OnPrepared();
+    }
+    private void batchRun_Started(object sender, EventArgs e) {
+      if (ExecutionState != ExecutionState.Started)
+        OnStarted();
+    }
+    private void batchRun_Stopped(object sender, EventArgs e) {
+      bool stop = stopPending;
+      BatchRun batchRun = (BatchRun)sender;
+      ExecutionTime += batchRun.ExecutionTime;
+      runs.AddRange(batchRun.Runs);
+
+      if (BatchRuns.All(x => (x.ExecutionState != ExecutionState.Started) && (x.ExecutionState != ExecutionState.Paused))) {
+        stopPending = false;
+        OnStopped();
+      }
+
+      if (!stop) {
+        BatchRun next = BatchRuns.FirstOrDefault(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused));
+        if (next != null)
+          next.Start();
+      }
+    }
+    #endregion
+  }
+}
Index: /trunk/sources/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 3266)
+++ /trunk/sources/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 3267)
@@ -87,4 +87,6 @@
     <Compile Include="Algorithm.cs" />
     <Compile Include="BatchRun.cs" />
+    <Compile Include="BatchRunList.cs" />
+    <Compile Include="Experiment.cs" />
     <Compile Include="RunCollection.cs" />
     <Compile Include="Run.cs" />
