Index: trunk/sources/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.Designer.cs	(revision 6471)
+++ trunk/sources/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.Designer.cs	(revision 6471)
@@ -0,0 +1,240 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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.optimizerTreeView = new System.Windows.Forms.TreeView();
+      this.imageList = new System.Windows.Forms.ImageList(this.components);
+      this.detailsGroupBox = new System.Windows.Forms.GroupBox();
+      this.detailsViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      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.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.optimizerTreeView);
+      // 
+      // 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.optimizerTreeView.AllowDrop = true;
+      this.optimizerTreeView.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.optimizerTreeView.HideSelection = false;
+      this.optimizerTreeView.ImageIndex = 0;
+      this.optimizerTreeView.ImageList = this.imageList;
+      this.optimizerTreeView.Location = new System.Drawing.Point(4, 34);
+      this.optimizerTreeView.Name = "optimizerTreeView";
+      this.optimizerTreeView.SelectedImageIndex = 0;
+      this.optimizerTreeView.Size = new System.Drawing.Size(191, 402);
+      this.optimizerTreeView.TabIndex = 10;
+      this.optimizerTreeView.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.optimizerTreeView_ItemDrag);
+      this.optimizerTreeView.DragDrop += new System.Windows.Forms.DragEventHandler(this.optimizerTreeView_DragDrop);
+      this.optimizerTreeView.DragEnter += new System.Windows.Forms.DragEventHandler(this.optimizerTreeView_DragEnter);
+      this.optimizerTreeView.DragOver += new System.Windows.Forms.DragEventHandler(this.optimizerTreeView_DragOver);
+      this.optimizerTreeView.MouseClick += new System.Windows.Forms.MouseEventHandler(this.optimizerTreeview_MouseClick);
+      this.optimizerTreeView.MouseDown += new System.Windows.Forms.MouseEventHandler(this.optimizerTreeView_MouseDown);
+      // 
+      // 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;
+      // 
+      // ExperimentTreeView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      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.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.GroupBox optimizersGroupBox;
+    private System.Windows.Forms.SplitContainer splitContainer;
+    private System.Windows.Forms.TreeView optimizerTreeView;
+    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;
+
+  }
+}
Index: trunk/sources/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.cs
===================================================================
--- trunk/sources/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.cs	(revision 6471)
+++ trunk/sources/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.cs	(revision 6471)
@@ -0,0 +1,634 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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.Views;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Optimization.Views {
+  public sealed partial class ExperimentTreeView : ItemView {
+    private TypeSelectorDialog typeSelectorDialog;
+    private Dictionary<IOptimizer, List<TreeNode>> optimizerTreeViewMapping;
+
+    public ExperimentTreeView() {
+      InitializeComponent();
+      optimizerTreeViewMapping = new Dictionary<IOptimizer, List<TreeNode>>();
+    }
+
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (typeSelectorDialog != null) typeSelectorDialog.Dispose();
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    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 optimizerTreeViewMapping.Keys)
+        DeregisterOptimizerEvents(optimizer);
+      base.DeregisterContentEvents();
+    }
+
+    private void RegisterOptimizerEvents(IOptimizer optimizer) {
+      optimizer.ToStringChanged += new EventHandler(optimizer_ToStringChanged);
+      optimizer.ExecutionStateChanged += new EventHandler(optimizer_ExecutionStateChanged);
+
+      var batchRun = optimizer as BatchRun;
+      var experiment = optimizer as Experiment;
+      if (batchRun != null) {
+        batchRun.OptimizerChanged += new EventHandler(batchRun_OptimizerChanged);
+      }
+      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 DeregisterOptimizerEvents(IOptimizer optimizer) {
+      optimizer.ToStringChanged -= new EventHandler(optimizer_ToStringChanged);
+      optimizer.ExecutionStateChanged -= new EventHandler(optimizer_ExecutionStateChanged);
+
+      var batchRun = optimizer as BatchRun;
+      var experiment = optimizer as Experiment;
+      if (batchRun != null) {
+        batchRun.OptimizerChanged -= new EventHandler(batchRun_OptimizerChanged);
+      }
+      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) {
+        optimizerTreeView.Nodes.Clear();
+      } else {
+        UpdateOptimizerTreeView();
+        optimizerTreeView.ExpandAll();
+      }
+    }
+
+    #region content events
+    private void Content_ExecutionStateChanged(object sender, EventArgs e) {
+      if (InvokeRequired) {
+        Invoke((Action<object, EventArgs>)Content_ExecutionStateChanged, sender, e);
+        return;
+      }
+      RebuildImageList();
+      SetEnabledStateOfControls();
+    }
+
+    private void optimizer_ExecutionStateChanged(object sender, EventArgs e) {
+      if (InvokeRequired) {
+        Invoke((Action<object, EventArgs>)optimizer_ExecutionStateChanged, sender, e);
+        return;
+      }
+      RebuildImageList();
+    }
+
+    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 optimizerTreeViewMapping[batchRun]) {
+        foreach (TreeNode childNode in node.Nodes) {
+          DisposeTreeNode(childNode);
+          childNode.Remove();
+        }
+
+        if (batchRun.Optimizer != null) {
+          TreeNode childNode = CreateTreeNode(batchRun.Optimizer);
+          UpdateChildTreeNodes(childNode.Nodes, batchRun.Optimizer);
+          node.Nodes.Add(childNode);
+          node.Expand();
+        }
+      }
+      RebuildImageList();
+    }
+
+    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>() { optimizerTreeView.Nodes };
+      else {
+        Experiment experiment = optimizerTreeViewMapping.Keys.OfType<Experiment>().Where(exp => exp.Optimizers == optimizerList).First();
+        parentNodes = optimizerTreeViewMapping[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>() { optimizerTreeView.Nodes };
+      else {
+        Experiment experiment = optimizerTreeViewMapping.Keys.OfType<Experiment>().Where(exp => exp.Optimizers == optimizerList).First();
+        parentNodes = optimizerTreeViewMapping[experiment].Select(node => node.Nodes);
+      }
+
+      foreach (TreeNodeCollection parentNode in parentNodes) {
+        //get all effected child nodes
+        foreach (TreeNode childNode in parentNode.OfType<TreeNode>()
+          .Where(n => e.OldItems.Select(x => x.Value).Contains((IOptimizer)n.Tag)).ToList()) {
+          DisposeTreeNode(childNode);
+          childNode.Remove();
+        }
+
+        foreach (var childOptimizer in e.Items) {
+          TreeNode childNode = CreateTreeNode(childOptimizer.Value);
+          UpdateChildTreeNodes(childNode.Nodes, childOptimizer.Value);
+          childNode.ExpandAll();
+          parentNode.Insert(childOptimizer.Index, childNode);
+        }
+      }
+      RebuildImageList();
+    }
+    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>() { optimizerTreeView.Nodes };
+      else {
+        Experiment experiment = optimizerTreeViewMapping.Keys.OfType<Experiment>().Where(exp => exp.Optimizers == optimizerList).First();
+        parentNodes = optimizerTreeViewMapping[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();
+    }
+    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>() { optimizerTreeView.Nodes };
+      else {
+        Experiment experiment = optimizerTreeViewMapping.Keys.OfType<Experiment>().Where(exp => exp.Optimizers == optimizerList).First();
+        parentNodes = optimizerTreeViewMapping[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();
+    }
+    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>() { optimizerTreeView.Nodes };
+      else {
+        Experiment experiment = optimizerTreeViewMapping.Keys.OfType<Experiment>().Where(exp => exp.Optimizers == optimizerList).First();
+        parentNodes = optimizerTreeViewMapping[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();
+    }
+
+    private void optimizer_ToStringChanged(object sender, EventArgs e) {
+      if (InvokeRequired) {
+        Invoke((Action<object, EventArgs>)optimizer_ToStringChanged, sender, e);
+        return;
+      }
+      var optimizer = (IOptimizer)sender;
+      foreach (TreeNode node in optimizerTreeViewMapping[optimizer])
+        node.Text = optimizer.ToString();
+    }
+    #endregion
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      BatchRun batchRun = null;
+      BatchRun parentBatchRun = null;
+      Experiment experiment = null;
+      if (optimizerTreeView.SelectedNode != null) {
+        batchRun = optimizerTreeView.SelectedNode.Tag as BatchRun;
+        experiment = optimizerTreeView.SelectedNode.Tag as Experiment;
+        if (optimizerTreeView.SelectedNode.Parent != null)
+          parentBatchRun = optimizerTreeView.SelectedNode.Parent.Tag as BatchRun;
+      }
+
+      optimizerTreeView.Enabled = Content != null;
+      detailsViewHost.Enabled = Content != null && optimizerTreeView.SelectedNode != null;
+
+      addButton.Enabled = Content != null && !Locked && !ReadOnly &&
+        (optimizerTreeView.SelectedNode == null || experiment != null || (batchRun != null && batchRun.Optimizer == null));
+      moveUpButton.Enabled = Content != null && !Locked && !ReadOnly &&
+        optimizerTreeView.SelectedNode != null && optimizerTreeView.SelectedNode.PrevNode != null && parentBatchRun == null;
+      moveDownButton.Enabled = Content != null && !Locked && !ReadOnly &&
+        optimizerTreeView.SelectedNode != null && optimizerTreeView.SelectedNode.NextNode != null && parentBatchRun == null;
+      removeButton.Enabled = Content != null && !Locked && !ReadOnly &&
+        optimizerTreeView.SelectedNode != null;
+    }
+
+    private void UpdateOptimizerTreeView() {
+      optimizerTreeView.Nodes.Clear();
+      UpdateChildTreeNodes(optimizerTreeView.Nodes, Content);
+      RebuildImageList();
+    }
+
+
+    private void UpdateChildTreeNodes(TreeNodeCollection collection, IOptimizer optimizer) {
+      var batchRun = optimizer as BatchRun;
+      var experiment = optimizer as Experiment;
+      if (experiment != null) UpdateChildTreeNodes(collection, experiment.Optimizers);
+      else if (batchRun != null && batchRun.Optimizer != null) UpdateChildTreeNodes(collection, new List<IOptimizer>() { batchRun.Optimizer });
+    }
+    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 optimizer = (IOptimizer)selectedNode.Tag;
+      DataObject data = new DataObject();
+      data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, optimizer);
+      validDragOperation = true;
+
+      if (ReadOnly) {
+        DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link);
+      } else {
+        DragDropEffects result = DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link | DragDropEffects.Move);
+        if ((result & DragDropEffects.Move) == DragDropEffects.Move) {
+          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());
+          }
+          if (optimizerTreeView.SelectedNode != null)
+            detailsViewHost.Content = (IOptimizer)optimizerTreeView.SelectedNode.Tag;
+          SetEnabledStateOfControls();
+          RebuildImageList();
+        }
+      }
+    }
+
+    private bool validDragOperation = false;
+    private void optimizerTreeView_DragEnter(object sender, DragEventArgs e) {
+      validDragOperation = false;
+      if (!ReadOnly) {
+        if ((e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IOptimizer)) validDragOperation = true;
+        else if (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 IOptimizer);
+        }
+      }
+    }
+    private void optimizerTreeView_DragOver(object sender, DragEventArgs e) {
+      e.Effect = DragDropEffects.None;
+      if (validDragOperation) {
+        Point coordinates = optimizerTreeView.PointToClient(new Point(e.X, e.Y));
+        TreeNode node = optimizerTreeView.GetNodeAt(coordinates);
+        Experiment experiment = null;
+        BatchRun batchRun = null;
+
+        if (node == null) experiment = Content;
+        else {
+          experiment = node.Tag as Experiment;
+          batchRun = node.Tag as BatchRun;
+        }
+
+        if (batchRun == null && experiment == null) return;
+        if (batchRun != null) {
+          var optimizer = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as IOptimizer;
+          if (optimizer == null) return;
+          if (batchRun.Optimizer != null) return;
+          if (optimizer.GetObjectGraphObjects().OfType<IOptimizer>().Contains(batchRun)) return;
+        }
+
+        //do not allow recursive nesting of contents
+        if (experiment != null) {
+          var optimizer = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as IOptimizer;
+          IEnumerable<IOptimizer> optimizers = null;
+          var enumerable = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as IEnumerable;
+          if (enumerable != null) optimizers = enumerable.Cast<IOptimizer>();
+
+          if (optimizer != null && optimizer.GetObjectGraphObjects().OfType<IOptimizer>().Contains(experiment)) return;
+          if (optimizers != null && optimizers.GetObjectGraphObjects().OfType<IOptimizer>().Contains(experiment)) return;
+        }
+
+        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 optimizerTreeView_DragDrop(object sender, DragEventArgs e) {
+      Point coordinates = optimizerTreeView.PointToClient(new Point(e.X, e.Y));
+      TreeNode node = optimizerTreeView.GetNodeAt(coordinates);
+      Experiment experiment = null;
+      BatchRun batchRun = null;
+
+      if (node == null) experiment = Content;
+      else {
+        experiment = node.Tag as Experiment;
+        batchRun = node.Tag as BatchRun;
+      }
+
+      if (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IOptimizer) {
+        IOptimizer optimizer = (IOptimizer)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+        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 (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IEnumerable) {
+        IEnumerable<IOptimizer> optimizers = ((IEnumerable)e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat)).Cast<IOptimizer>();
+        if (e.Effect.HasFlag(DragDropEffects.Copy)) {
+          Cloner cloner = new Cloner();
+          optimizers = optimizers.Select(o => (IOptimizer)o.Clone(cloner));
+        }
+        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 optimizerTreeview_MouseClick(object sender, MouseEventArgs e) {
+      Point coordinates = new Point(e.X, e.Y);
+      TreeNode selectedNode = optimizerTreeView.GetNodeAt(coordinates);
+      if (selectedNode != null) {
+        optimizerTreeView.SelectedNode = selectedNode;
+        detailsViewHost.Content = (IOptimizer)selectedNode.Tag;
+        SetEnabledStateOfControls();
+      }
+    }
+    private void optimizerTreeView_MouseDown(object sender, MouseEventArgs e) {
+      // enables deselection of treeNodes
+      if (optimizerTreeView.SelectedNode == null) return;
+      Point coordinates = new Point(e.X, e.Y);
+      if (e.Button == System.Windows.Forms.MouseButtons.Left && optimizerTreeView.GetNodeAt(coordinates) == null) {
+        optimizerTreeView.SelectedNode = null;
+        detailsViewHost.Content = null;
+        SetEnabledStateOfControls();
+      }
+    }
+
+    private void addButton_Click(object sender, System.EventArgs e) {
+      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 {
+          IOptimizer optimizer = (IOptimizer)typeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
+          if (optimizerTreeView.SelectedNode == null) Content.Optimizers.Add(optimizer);
+          else {
+            var batchRun = optimizerTreeView.SelectedNode.Tag as BatchRun;
+            var experiment = optimizerTreeView.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" + optimizerTreeView.SelectedNode.Tag.GetType());
+          }
+        }
+        catch (Exception ex) {
+          ErrorHandling.ShowErrorDialog(this, ex);
+        }
+      }
+    }
+
+    private void moveUpButton_Click(object sender, EventArgs e) {
+      var optimizer = optimizerTreeView.SelectedNode.Tag as IOptimizer;
+      Experiment experiment = null;
+      if (optimizerTreeView.SelectedNode.Parent == null) experiment = Content;
+      else experiment = (Experiment)optimizerTreeView.SelectedNode.Parent.Tag;
+
+      detailsViewHost.SuspendRepaint();
+      int index = optimizerTreeView.SelectedNode.Index;
+      experiment.Optimizers.Reverse(index - 1, 2);
+      optimizerTreeView.SelectedNode = optimizerTreeViewMapping[optimizer].First();
+      detailsViewHost.Content = (IOptimizer)optimizerTreeView.SelectedNode.Tag;
+      SetEnabledStateOfControls();
+      detailsViewHost.ResumeRepaint(true);
+    }
+    private void moveDownButton_Click(object sender, EventArgs e) {
+      var optimizer = optimizerTreeView.SelectedNode.Tag as IOptimizer;
+      Experiment experiment = null;
+      if (optimizerTreeView.SelectedNode.Parent == null) experiment = Content;
+      else experiment = (Experiment)optimizerTreeView.SelectedNode.Parent.Tag;
+
+      int index = optimizerTreeView.SelectedNode.Index;
+      experiment.Optimizers.Reverse(index, 2);
+      optimizerTreeView.SelectedNode = optimizerTreeViewMapping[optimizer].First();
+      detailsViewHost.Content = (IOptimizer)optimizerTreeView.SelectedNode.Tag;
+      SetEnabledStateOfControls();
+    }
+
+    private void removeButton_Click(object sender, System.EventArgs e) {
+      var treeNode = optimizerTreeView.SelectedNode;
+      var optimizer = (IOptimizer)treeNode.Tag;
+
+      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" + optimizerTreeView.SelectedNode.Tag.GetType());
+      }
+      SetEnabledStateOfControls();
+      detailsViewHost.Content = (IOptimizer)optimizerTreeView.SelectedNode.Tag;
+    }
+
+    private void showDetailsCheckBox_CheckedChanged(object sender, System.EventArgs e) {
+      if (showDetailsCheckBox.Checked) {
+        splitContainer.Panel2Collapsed = false;
+        detailsGroupBox.Enabled = optimizerTreeView.SelectedNode != null;
+        detailsViewHost.Content = optimizerTreeView.SelectedNode != null ? (IOptimizer)optimizerTreeView.SelectedNode.Tag : null;
+      } else {
+        splitContainer.Panel2Collapsed = true;
+        detailsViewHost.Content = null;
+      }
+    }
+    #endregion
+
+    #region helpers
+    private TreeNode CreateTreeNode(IOptimizer optimizer) {
+      TreeNode node = new TreeNode(optimizer.ToString());
+      node.Tag = optimizer;
+      List<TreeNode> nodes;
+      if (!optimizerTreeViewMapping.TryGetValue(optimizer, out nodes)) {
+        nodes = new List<TreeNode>();
+        optimizerTreeViewMapping.Add(optimizer, nodes);
+        RegisterOptimizerEvents(optimizer);
+      }
+      nodes.Add(node);
+      return node;
+    }
+
+    private void DisposeTreeNode(TreeNode node) {
+      var optimizer = (IOptimizer)node.Tag;
+      List<TreeNode> nodes;
+      if (!optimizerTreeViewMapping.TryGetValue(optimizer, out nodes))
+        throw new ArgumentException();
+      nodes.Remove(node);
+      if (nodes.Count == 0) {
+        optimizerTreeViewMapping.Remove(optimizer);
+        DeregisterOptimizerEvents(optimizer);
+      }
+    }
+
+    private IEnumerable<TreeNode> IterateTreeNodes(TreeNode node = null) {
+      TreeNodeCollection nodes;
+      if (node == null)
+        nodes = optimizerTreeView.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 void RebuildImageList() {
+      if (InvokeRequired) {
+        Invoke((Action)RebuildImageList);
+        return;
+      }
+
+      optimizerTreeView.ImageList.Images.Clear();
+      foreach (TreeNode treeNode in IterateTreeNodes()) {
+        var optimizer = (IOptimizer)treeNode.Tag;
+        optimizerTreeView.ImageList.Images.Add(optimizer == null ? HeuristicLab.Common.Resources.VSImageLibrary.Nothing : optimizer.ItemImage);
+        treeNode.ImageIndex = optimizerTreeView.ImageList.Images.Count - 1;
+        treeNode.SelectedImageIndex = treeNode.ImageIndex;
+      }
+    }
+    #endregion
+  }
+}
Index: trunk/sources/HeuristicLab.Optimization.Views/3.3/ExperimentView.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.Optimization.Views/3.3/ExperimentView.Designer.cs	(revision 6425)
+++ trunk/sources/HeuristicLab.Optimization.Views/3.3/ExperimentView.Designer.cs	(revision 6471)
@@ -47,7 +47,7 @@
       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();
+      this.experimentTreeView = new HeuristicLab.Optimization.Views.ExperimentTreeView();
       ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
       this.tabControl.SuspendLayout();
@@ -111,5 +111,5 @@
       // optimizersTabPage
       // 
-      this.optimizersTabPage.Controls.Add(this.optimizerListView);
+      this.optimizersTabPage.Controls.Add(this.experimentTreeView);
       this.optimizersTabPage.Location = new System.Drawing.Point(4, 22);
       this.optimizersTabPage.Name = "optimizersTabPage";
@@ -119,17 +119,4 @@
       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
@@ -159,4 +146,15 @@
       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
@@ -189,7 +187,7 @@
     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;
+    private ExperimentTreeView experimentTreeView;
 
   }
Index: trunk/sources/HeuristicLab.Optimization.Views/3.3/ExperimentView.cs
===================================================================
--- trunk/sources/HeuristicLab.Optimization.Views/3.3/ExperimentView.cs	(revision 6425)
+++ trunk/sources/HeuristicLab.Optimization.Views/3.3/ExperimentView.cs	(revision 6471)
@@ -41,8 +41,8 @@
       base.OnContentChanged();
       if (Content == null) {
-        optimizerListView.Content = null;
+        experimentTreeView.Content = null;
         runsViewHost.Content = null;
       } else {
-        optimizerListView.Content = Content.Optimizers;
+        experimentTreeView.Content = Content;
         runsViewHost.Content = Content.Runs;
       }
@@ -51,5 +51,5 @@
     protected override void SetEnabledStateOfControls() {
       base.SetEnabledStateOfControls();
-      optimizerListView.Enabled = Content != null;
+      experimentTreeView.Enabled = Content != null;
       runsViewHost.Enabled = Content != null;
     }
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 6425)
+++ trunk/sources/HeuristicLab.Optimization.Views/3.3/HeuristicLab.Optimization.Views-3.3.csproj	(revision 6471)
@@ -128,4 +128,10 @@
       <DependentUpon>BatchRunView.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>
