Index: /trunk/sources/HeuristicLab.Core/3.3/OperatorGraph.cs
===================================================================
--- /trunk/sources/HeuristicLab.Core/3.3/OperatorGraph.cs	(revision 3385)
+++ /trunk/sources/HeuristicLab.Core/3.3/OperatorGraph.cs	(revision 3386)
@@ -90,7 +90,16 @@
     protected OperatorGraph(bool deserializing) : base(deserializing) { }
 
+    //mkommend: IMPROTANT DO NOT REMOVE THIS PRIVATE EVENT
+    //needed to register OperatorGraph events in GraphVisualizationInfo
+    public event EventHandler DeserializationFinished;
+    private void OnOperatorGraphDeserializationFinished() {
+      EventHandler handler = DeserializationFinished;
+      if(handler != null)
+        handler(this,EventArgs.Empty);
+    }
     [StorableHook(HookType.AfterDeserialization)]
     private void Initialize() {
       RegisterOperatorsEvents();
+      OnOperatorGraphDeserializationFinished();
     }
 
Index: /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/ConnectionInfo.cs
===================================================================
--- /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/ConnectionInfo.cs	(revision 3386)
+++ /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/ConnectionInfo.cs	(revision 3386)
@@ -0,0 +1,87 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+#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.Operators.Views.GraphVisualization {
+  [StorableClass]
+  public class ConnectionInfo : DeepCloneable, IConnectionInfo {
+    private ConnectionInfo() {
+    }
+    public ConnectionInfo(IShapeInfo from, string connectorFrom, IShapeInfo to, string connectorTo)
+      : this() {
+      if (from == to)
+        throw new ArgumentException("Could not create connections between the same shape info.");
+      if (!from.Connectors.Contains(connectorFrom) || !to.Connectors.Contains(connectorTo))
+        throw new ArgumentException("Could not create connection between not existent connectors.");
+
+      this.from = from;
+      this.connectorFrom = connectorFrom;
+      this.to = to;
+      this.connectorTo = connectorTo;
+    }
+
+    [Storable]
+    private IShapeInfo from;
+    public IShapeInfo From {
+      get { return from; }
+    }
+
+    [Storable]
+    private string connectorFrom;
+    public string ConnectorFrom {
+      get { return this.connectorFrom; }
+    }
+
+    [Storable]
+    private IShapeInfo to;
+    public IShapeInfo To {
+      get { return this.to; }
+    }
+
+    [Storable]
+    private string connectorTo;
+    public string ConnectorTo {
+      get { return this.connectorTo; }
+    }
+
+    public event EventHandler Changed;
+    protected virtual void OnChanged() {
+      EventHandler handler = this.Changed;
+      if (handler != null)
+        this.Changed(this, EventArgs.Empty);
+    }
+
+    public override  IDeepCloneable Clone(Cloner cloner) {
+      ConnectionInfo clone = (ConnectionInfo)base.Clone(cloner);
+      clone.from = (IShapeInfo)cloner.Clone(this.from);
+      clone.connectorFrom = this.ConnectorFrom;
+      clone.to = (IShapeInfo)cloner.Clone(this.To);
+      clone.connectorTo = this.ConnectorTo;
+      return clone;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/GraphVisualizationInfo.cs
===================================================================
--- /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/GraphVisualizationInfo.cs	(revision 3386)
+++ /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/GraphVisualizationInfo.cs	(revision 3386)
@@ -0,0 +1,108 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Operators.Views.GraphVisualization {
+  [StorableClass]
+  public class GraphVisualizationInfo : DeepCloneable, IGraphVisualizationInfo {
+    public GraphVisualizationInfo() {
+      this.shapeInfos = new ObservableSet<IShapeInfo>();
+      this.connectionInfos = new ObservableSet<IConnectionInfo>();
+    }
+    #region IGraphVisualizationInfo Members
+    [Storable]
+    private IShapeInfo initialShape;
+    public virtual IShapeInfo InitialShape {
+      get { return this.initialShape; }
+      set {
+        if (this.initialShape != value) {
+          this.initialShape = value;
+          this.OnInitialShapeChanged();
+        }
+      }
+    }
+
+    [Storable]
+    protected ObservableSet<IShapeInfo> shapeInfos;
+    public INotifyObservableCollectionItemsChanged<IShapeInfo> ObserveableShapeInfos {
+      get { return shapeInfos; }
+    }
+    public IEnumerable<IShapeInfo> ShapeInfos {
+      get { return shapeInfos; }
+    }
+
+    [Storable]
+    protected ObservableSet<IConnectionInfo> connectionInfos;
+    public INotifyObservableCollectionItemsChanged<IConnectionInfo> ObservableConnectionInfos {
+      get { return connectionInfos; }
+    }
+    public IEnumerable<IConnectionInfo> ConnectionInfos {
+      get { return connectionInfos; }
+    }
+
+    public virtual void AddShapeInfo(IShapeInfo shapeInfo) {
+      this.shapeInfos.Add(shapeInfo);
+    }
+    public virtual void RemoveShapeInfo(IShapeInfo shapeInfo) {
+      this.shapeInfos.Remove(shapeInfo);
+      this.connectionInfos.RemoveWhere(c => c.From == shapeInfo); 
+      this.connectionInfos.RemoveWhere(c => c.To == shapeInfo);
+    }
+
+    public virtual void AddConnectionInfo(IConnectionInfo connectionInfo) {
+      this.connectionInfos.Add(connectionInfo);
+    }
+    public virtual void RemoveConnectionInfo(IConnectionInfo connectionInfo) {
+      this.connectionInfos.Remove(connectionInfo);
+    }
+
+    public IEnumerable<IConnectionInfo> GetConnectionInfos(IShapeInfo shapeInfo) {
+      return this.ConnectionInfos.Where(c => c.From == shapeInfo || c.To == shapeInfo);
+    }
+    public IEnumerable<IConnectionInfo> GetConnectionInfos(IShapeInfo shapeInfo, string connector) {
+      return this.ConnectionInfos.Where(c => (c.From == shapeInfo && c.ConnectorFrom == connector) ||
+        (c.To == shapeInfo && c.ConnectorTo == connector));
+    }
+
+    public event EventHandler InitialShapeChanged;
+    protected virtual void OnInitialShapeChanged() {
+      EventHandler handler = this.InitialShapeChanged;
+      if (handler != null)
+        this.InitialShapeChanged(this, EventArgs.Empty);
+    }
+    #endregion
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      GraphVisualizationInfo clone = (GraphVisualizationInfo)base.Clone(cloner);
+      clone.shapeInfos = new ObservableSet<IShapeInfo>(this.shapeInfos.Select(x => (IShapeInfo)cloner.Clone(x)));
+      clone.connectionInfos = new ObservableSet<IConnectionInfo>(this.connectionInfos.Select(x => (IConnectionInfo)cloner.Clone(x)));
+      if (this.initialShape != null)
+        clone.initialShape = (IShapeInfo)this.initialShape.Clone(cloner);
+      return clone;
+    }
+
+    #region IContent Members
+    [Storable]
+    private bool readOnlyView;
+    public virtual bool ReadOnlyView {
+      get { return readOnlyView; }
+      set {
+        if (readOnlyView != value) {
+          readOnlyView = value;
+          OnReadOnlyViewChanged();
+        }
+      }
+    }
+    public event EventHandler ReadOnlyViewChanged;
+    protected virtual void OnReadOnlyViewChanged() {
+      EventHandler handler = ReadOnlyViewChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    #endregion
+  }
+}
Index: /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/GraphVisualizationInfoView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/GraphVisualizationInfoView.Designer.cs	(revision 3386)
+++ /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/GraphVisualizationInfoView.Designer.cs	(revision 3386)
@@ -0,0 +1,67 @@
+﻿namespace HeuristicLab.Operators.Views.GraphVisualization {
+  partial class GraphVisualizationInfoView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      this.graphVisualization = new HeuristicLab.Netron.NetronVisualization();
+      ((System.ComponentModel.ISupportInitialize)(this.graphVisualization)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // graphVisualization
+      // 
+      this.graphVisualization.AllowDrop = false;
+      this.graphVisualization.AutoScroll = true;
+      this.graphVisualization.BackColor = System.Drawing.Color.DarkGray;
+      this.graphVisualization.BackgroundType = global::Netron.Diagramming.Core.CanvasBackgroundTypes.FlatColor;
+      this.graphVisualization.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.graphVisualization.EnableAddConnection = true;
+      this.graphVisualization.FileName = "";
+      this.graphVisualization.Location = new System.Drawing.Point(0, 0);
+      this.graphVisualization.Magnification = new System.Drawing.SizeF(80F, 80F);
+      this.graphVisualization.Name = "graphVisualization";
+      this.graphVisualization.Origin = new System.Drawing.Point(0, 0);
+      this.graphVisualization.PageSize = new System.Drawing.Size(100000, 100000);
+      this.graphVisualization.ShowConnectors = true;
+      this.graphVisualization.ShowRulers = false;
+      this.graphVisualization.Size = new System.Drawing.Size(665, 444);
+      this.graphVisualization.TabIndex = 0;
+      this.graphVisualization.OnEntityRemoved += new System.EventHandler<global::Netron.Diagramming.Core.EntityEventArgs>(this.graphVisualization_OnEntityRemoved);
+      this.graphVisualization.OnEntityAdded += new System.EventHandler<global::Netron.Diagramming.Core.EntityEventArgs>(this.graphVisualization_OnEntityAdded);
+     
+      // 
+      // GraphVisualizationInfoView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.graphVisualization);
+      this.Name = "GraphVisualizationInfoView";
+      this.Size = new System.Drawing.Size(665, 444);
+      ((System.ComponentModel.ISupportInitialize)(this.graphVisualization)).EndInit();
+      this.ResumeLayout(false);
+    }
+    #endregion
+
+    private HeuristicLab.Netron.NetronVisualization graphVisualization;
+  }
+}
Index: /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/GraphVisualizationInfoView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/GraphVisualizationInfoView.cs	(revision 3386)
+++ /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/GraphVisualizationInfoView.cs	(revision 3386)
@@ -0,0 +1,360 @@
+﻿#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.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using Netron.Diagramming.Core;
+using HeuristicLab.Parameters;
+using HeuristicLab.MainForm.WindowsForms;
+using HeuristicLab.Collections;
+using System.Diagnostics;
+using System.Threading;
+using System.Drawing.Drawing2D;
+
+namespace HeuristicLab.Operators.Views.GraphVisualization {
+  [View("GraphVisualizationInfo View")]
+  [Content(typeof(IGraphVisualizationInfo), true)]
+  public partial class GraphVisualizationInfoView : ContentView {
+    private BidirectionalLookup<IShapeInfo, IShape> shapeInfoShapeMapping;
+    private BidirectionalLookup<IConnectionInfo, IConnection> connectionInfoConnectionMapping;
+    private LinePenStyle connectionPenStyle;
+
+    public GraphVisualizationInfoView() {
+      InitializeComponent();
+      this.shapeInfoShapeMapping = new BidirectionalLookup<IShapeInfo, IShape>();
+      this.connectionInfoConnectionMapping = new BidirectionalLookup<IConnectionInfo, IConnection>();
+      this.connectionPenStyle = new LinePenStyle();
+      this.connectionPenStyle.EndCap = LineCap.ArrowAnchor;
+    }
+
+    public GraphVisualizationInfoView(IGraphVisualizationInfo content)
+      : this() {
+      this.Content = content;
+    }
+
+    public IController Controller {
+      get { return this.graphVisualization.Controller; }
+    }
+
+    public new IGraphVisualizationInfo Content {
+      get { return (IGraphVisualizationInfo)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      this.UpdateContent();
+    }
+
+    protected override void OnReadOnlyChanged() {
+      base.OnReadOnlyChanged();
+      this.SetEnabledStateOfControls();
+    }
+    private void SetEnabledStateOfControls() {
+      DeleteTool deleteTool = (DeleteTool)this.Controller.Tools.Where(t => t.Name == ControllerBase.DeleteToolName).FirstOrDefault();
+      HeuristicLab.Netron.Controller controller = this.Controller as HeuristicLab.Netron.Controller;
+      if (Content == null && deleteTool != null && controller != null)
+        controller.RemoveTool(deleteTool);
+      else {
+        if (ReadOnly && deleteTool != null && controller != null)
+          controller.RemoveTool(deleteTool);
+        else if (!ReadOnly && deleteTool == null)
+          this.Controller.AddTool(new DeleteTool(ControllerBase.DeleteToolName));
+      }
+    }
+
+    private void UpdateContent() {
+      foreach (IConnectionInfo connectionInfo in this.connectionInfoConnectionMapping.FirstValues)
+        this.RemoveConnectionInfo(connectionInfo);
+      this.connectionInfoConnectionMapping.Clear();
+      foreach (IShapeInfo shapeInfo in this.shapeInfoShapeMapping.FirstValues)
+        this.RemoveShapeInfo(shapeInfo);
+      this.shapeInfoShapeMapping.Clear();
+
+      if (Content != null) {
+        foreach (IShapeInfo shapeInfo in this.Content.ShapeInfos)
+          this.AddShapeInfo(shapeInfo);
+        foreach (IConnectionInfo connectionInfo in this.Content.ConnectionInfos)
+          this.AddConnectionInfo(connectionInfo);
+        this.UpdateLayoutRoot();
+      }
+      this.SetEnabledStateOfControls();
+    }
+    private void UpdateLayoutRoot() {
+      IShapeInfo shapeInfo = this.Content.InitialShape;
+      if (shapeInfo != null)
+        this.graphVisualization.Controller.Model.LayoutRoot = this.shapeInfoShapeMapping.GetByFirst(shapeInfo);
+      else
+        this.graphVisualization.Controller.Model.LayoutRoot = null;
+    }
+    private void VisualizationInfo_InitialShapeChanged(object sender, EventArgs e) {
+      this.UpdateLayoutRoot();
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      this.Content.InitialShapeChanged += new EventHandler(VisualizationInfo_InitialShapeChanged);
+
+      this.Content.ObserveableShapeInfos.ItemsAdded += new CollectionItemsChangedEventHandler<IShapeInfo>(ShapeInfos_ItemsAdded);
+      this.Content.ObserveableShapeInfos.ItemsRemoved += new CollectionItemsChangedEventHandler<IShapeInfo>(ShapeInfos_ItemsRemoved);
+      this.Content.ObserveableShapeInfos.CollectionReset += new CollectionItemsChangedEventHandler<IShapeInfo>(ShapeInfos_CollectionReset);
+
+      this.Content.ObservableConnectionInfos.ItemsAdded += new CollectionItemsChangedEventHandler<IConnectionInfo>(ConnectionInfos_ItemsAdded);
+      this.Content.ObservableConnectionInfos.ItemsRemoved += new CollectionItemsChangedEventHandler<IConnectionInfo>(ConnectionInfos_ItemsRemoved);
+      this.Content.ObservableConnectionInfos.CollectionReset += new CollectionItemsChangedEventHandler<IConnectionInfo>(ConnectionInfos_CollectionReset);
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      this.Content.InitialShapeChanged -= new EventHandler(VisualizationInfo_InitialShapeChanged);
+
+      this.Content.ObserveableShapeInfos.ItemsAdded -= new CollectionItemsChangedEventHandler<IShapeInfo>(ShapeInfos_ItemsAdded);
+      this.Content.ObserveableShapeInfos.ItemsRemoved -= new CollectionItemsChangedEventHandler<IShapeInfo>(ShapeInfos_ItemsRemoved);
+      this.Content.ObserveableShapeInfos.CollectionReset -= new CollectionItemsChangedEventHandler<IShapeInfo>(ShapeInfos_CollectionReset);
+
+      this.Content.ObservableConnectionInfos.ItemsAdded -= new CollectionItemsChangedEventHandler<IConnectionInfo>(ConnectionInfos_ItemsAdded);
+      this.Content.ObservableConnectionInfos.ItemsRemoved -= new CollectionItemsChangedEventHandler<IConnectionInfo>(ConnectionInfos_ItemsRemoved);
+      this.Content.ObservableConnectionInfos.CollectionReset -= new CollectionItemsChangedEventHandler<IConnectionInfo>(ConnectionInfos_CollectionReset);
+    }
+
+    #region ShapeInfos
+    private void ShapeInfos_CollectionReset(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IShapeInfo> e) {
+      foreach (IShapeInfo shapeInfo in e.OldItems)
+        this.RemoveShapeInfo(shapeInfo);
+      foreach (IShapeInfo shapeInfo in e.Items)
+        this.AddShapeInfo(shapeInfo);
+    }
+    private void ShapeInfos_ItemsAdded(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IShapeInfo> e) {
+      foreach (IShapeInfo shapeInfo in e.Items)
+        this.AddShapeInfo(shapeInfo);
+    }
+    private void ShapeInfos_ItemsRemoved(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IShapeInfo> e) {
+      foreach (IShapeInfo shapeInfo in e.Items)
+        this.RemoveShapeInfo(shapeInfo);
+    }
+
+    private void AddShapeInfo(IShapeInfo shapeInfo) {
+      this.RegisterShapeInfoEvents(shapeInfo);
+      IShape shape = shapeInfo.CreateShape();
+      this.RegisterShapeEvents(shape);
+      this.shapeInfoShapeMapping.Add(shapeInfo, shape);
+
+      this.graphVisualization.Controller.Model.AddShape(shape);
+      this.graphVisualization.Invalidate();
+    }
+    private void RemoveShapeInfo(IShapeInfo shapeInfo) {
+        this.DeregisterShapeInfoEvents(shapeInfo);
+        IShape shape = this.shapeInfoShapeMapping.GetByFirst(shapeInfo);
+        this.DeregisterShapeEvents(shape);
+        this.shapeInfoShapeMapping.RemoveByFirst(shapeInfo);
+
+        if (this.graphVisualization.Controller.Model.Shapes.Contains(shape)) {
+          this.graphVisualization.Controller.Model.RemoveShape(shape);
+          this.graphVisualization.Invalidate();
+        }
+    }
+
+    private void RegisterShapeInfoEvents(IShapeInfo shapeInfo) {
+      shapeInfo.Changed += new EventHandler(shapeInfo_Changed);
+    }
+    private void DeregisterShapeInfoEvents(IShapeInfo shapeInfo) {
+      shapeInfo.Changed -= new EventHandler(shapeInfo_Changed);
+    }
+
+    private void shapeInfo_Changed(object sender, EventArgs e) {
+      IShapeInfo shapeInfo = (IShapeInfo)sender;
+      IShape shape = this.shapeInfoShapeMapping.GetByFirst(shapeInfo);
+      this.DeregisterShapeEvents(shape);
+      shapeInfo.UpdateShape(shape);
+      shape.Invalidate();
+      this.RegisterShapeEvents(shape);
+    }
+    #endregion
+
+    #region ConnectionInfos
+    private void ConnectionInfos_CollectionReset(object sender, CollectionItemsChangedEventArgs<IConnectionInfo> e) {
+      foreach (IConnectionInfo connectionInfo in e.Items)
+        this.RemoveConnectionInfo(connectionInfo);
+      foreach (IConnectionInfo connectionInfo in e.Items)
+        this.AddConnectionInfo(connectionInfo);
+    }
+    private void ConnectionInfos_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IConnectionInfo> e) {
+      foreach (IConnectionInfo connectionInfo in e.Items)
+        this.AddConnectionInfo(connectionInfo);
+    }
+    private void ConnectionInfos_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IConnectionInfo> e) {
+      foreach (IConnectionInfo connectionInfo in e.Items)
+        this.RemoveConnectionInfo(connectionInfo);
+    }
+
+    private void AddConnectionInfo(IConnectionInfo connectionInfo) {
+      this.RegisterConnectionInfoEvents(connectionInfo);
+      IShape shapeFrom = this.shapeInfoShapeMapping.GetByFirst(connectionInfo.From);
+      IShape shapeTo = this.shapeInfoShapeMapping.GetByFirst(connectionInfo.To);
+
+      IConnector connectorFrom = shapeFrom.Connectors.Where(c => c.Name == connectionInfo.ConnectorFrom).FirstOrDefault();
+      IConnector connectorTo = shapeTo.Connectors.Where(c => c.Name == connectionInfo.ConnectorTo).FirstOrDefault();
+      if (connectorFrom != null && connectorTo != null) {
+        Connection connection = new Connection(connectorFrom.Point, connectorTo.Point);
+        connection.From.AllowMove = false;
+        connection.To.AllowMove = false;
+        connectorFrom.AttachConnector(connection.From);
+        connectorTo.AttachConnector(connection.To);
+        connection.PenStyle = this.connectionPenStyle;
+        this.connectionInfoConnectionMapping.Add(connectionInfo, connection);
+        this.graphVisualization.Controller.Model.AddConnection(connection);
+        this.graphVisualization.Invalidate();
+      }
+    }
+
+    private void RemoveConnectionInfo(IConnectionInfo connectionInfo) {
+      DeregisterConnectionInfoEvents(connectionInfo);
+      IConnection connection = this.connectionInfoConnectionMapping.GetByFirst(connectionInfo);
+      this.connectionInfoConnectionMapping.RemoveByFirst(connectionInfo);
+      this.RemoveConnection(connection);
+      
+    }
+    private void RemoveConnection(IConnection connection) {
+      if (connection.From.AttachedTo != null)
+        connection.From.DetachFromParent();
+      if (connection.To.AttachedTo != null)
+        connection.To.DetachFromParent();
+      if (this.Controller.Model.Connections.Contains(connection)) {
+        this.graphVisualization.Controller.Model.Remove(connection);
+        this.graphVisualization.Invalidate();
+      }
+    }
+
+    private void RegisterConnectionInfoEvents(IConnectionInfo connectionInfo) {
+      connectionInfo.Changed += new EventHandler(connectionInfo_Changed);
+    }
+    private void DeregisterConnectionInfoEvents(IConnectionInfo connectionInfo) {
+      connectionInfo.Changed -= new EventHandler(connectionInfo_Changed);
+    }
+    private void connectionInfo_Changed(object sender, EventArgs e) {
+      IConnectionInfo connectionInfo = (IConnectionInfo)sender;
+      IConnection connection = this.connectionInfoConnectionMapping.GetByFirst(connectionInfo);
+      this.RemoveConnectionInfo(connectionInfo);
+      this.AddConnectionInfo(connectionInfo);
+    }
+    #endregion
+
+    #region netron events - shapes, graphvisualization
+    private void RegisterShapeEvents(IShape shape) {
+      shape.OnEntityChange += new EventHandler<EntityEventArgs>(shape_OnEntityChange);
+      shape.OnMouseEnter += new EventHandler<EntityMouseEventArgs>(shape_OnMouseEnter);
+      shape.OnMouseLeave += new EventHandler<EntityMouseEventArgs>(shape_OnMouseLeave);
+    }
+
+    private void DeregisterShapeEvents(IShape shape) {
+      shape.OnEntityChange -= new EventHandler<EntityEventArgs>(shape_OnEntityChange);
+      shape.OnMouseEnter -= new EventHandler<EntityMouseEventArgs>(shape_OnMouseEnter);
+      shape.OnMouseLeave -= new EventHandler<EntityMouseEventArgs>(shape_OnMouseLeave);
+    }
+
+    private Cursor oldCursor;
+    private void shape_OnMouseEnter(object sender, EntityMouseEventArgs e) {
+      this.oldCursor = this.Cursor;
+      this.Controller.View.CurrentCursor = CursorPalette.Move;
+    }
+
+    private void shape_OnMouseLeave(object sender, EntityMouseEventArgs e) {
+      this.Controller.View.CurrentCursor = this.oldCursor;
+      this.oldCursor = null;
+    }
+
+    private void shape_OnEntityChange(object sender, EntityEventArgs e) {
+      IShape shape = e.Entity as IShape;
+      IShapeInfo shapeInfo = this.shapeInfoShapeMapping.GetBySecond(shape);
+      this.DeregisterShapeInfoEvents(shapeInfo);
+      shapeInfo.UpdateShapeInfo(shape);
+      this.RegisterShapeInfoEvents(shapeInfo);
+      this.graphVisualization.Invalidate();
+    }
+
+
+    private void graphVisualization_OnEntityAdded(object sender, EntityEventArgs e) {
+      IConnection connection = e.Entity as IConnection;
+      if (connection != null && !this.connectionInfoConnectionMapping.ContainsSecond(connection)) {
+        IConnector connectorFrom = connection.From.AttachedTo;
+        IConnector connectorTo = connection.To.AttachedTo;
+        this.RemoveConnection(connection); //is added again by the model events
+
+        if (connectorFrom != null && connectorTo != null) {
+          IShape shapeFrom = (IShape)connectorFrom.Parent;
+          IShape shapeTo = (IShape)connectorTo.Parent;
+          IShapeInfo shapeInfoFrom = this.shapeInfoShapeMapping.GetBySecond(shapeFrom);
+          IShapeInfo shapeInfoTo = this.shapeInfoShapeMapping.GetBySecond(shapeTo);
+          string connectorFromName = connectorFrom.Name;
+          string connectorToName = connectorTo.Name;
+
+          if (shapeInfoFrom != shapeInfoTo) //avoid self references
+            this.Content.AddConnectionInfo(new ConnectionInfo(shapeInfoFrom, connectorFromName, shapeInfoTo, connectorToName));
+        }
+      }
+    }
+
+    private void graphVisualization_OnEntityRemoved(object sender, EntityEventArgs e) {
+      IShape shape = e.Entity as IShape;
+      if (shape != null && this.shapeInfoShapeMapping.ContainsSecond(shape)) {
+        IShapeInfo shapeInfo = this.shapeInfoShapeMapping.GetBySecond(shape);
+        this.Content.RemoveShapeInfo(shapeInfo);
+      }
+
+      IConnection connection = e.Entity as IConnection;
+      if (connection != null && this.connectionInfoConnectionMapping.ContainsSecond(connection)) {
+        IConnectionInfo connectionInfo = connectionInfoConnectionMapping.GetBySecond(connection);
+        this.Content.RemoveConnectionInfo(connectionInfo);
+      }
+    }
+    #endregion
+
+    public void RelayoutGraph() {
+      if (this.shapeInfoShapeMapping.Count > 0
+        && this.connectionInfoConnectionMapping.Count > 0
+        && this.Content.InitialShape != null) { //otherwise the layout does not work
+        string layoutName = "Standard TreeLayout";
+        this.graphVisualization.Controller.RunActivity(layoutName);
+        this.graphVisualization.Invalidate();
+
+        //fix to avoid negative shape positions after layouting
+        Thread.Sleep(300);
+        int minX = this.graphVisualization.Controller.Model.Shapes.Min(s => s.Location.X);
+        int shiftX = minX < 0 ? Math.Abs(minX) + 50 : 0;
+        int minY = this.graphVisualization.Controller.Model.Shapes.Min(s => s.Location.Y);
+        int shiftY = minY < 0 ? Math.Abs(minY) + 50 : 0;
+        if (minX < 0 || minY < 0) {
+          foreach (IShape s in this.Controller.Model.Shapes)
+            s.MoveBy(new Point(shiftX, shiftY));
+        }
+      }
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/IConnectionInfo.cs
===================================================================
--- /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/IConnectionInfo.cs	(revision 3386)
+++ /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/IConnectionInfo.cs	(revision 3386)
@@ -0,0 +1,37 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Operators.Views.GraphVisualization {
+  public interface IConnectionInfo : IDeepCloneable {
+    IShapeInfo From { get; }
+    string ConnectorFrom { get; }
+    IShapeInfo To { get; }
+    string ConnectorTo { get; }
+
+    event EventHandler Changed;
+  }
+}
Index: /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/IGraphVisualizationInfo.cs
===================================================================
--- /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/IGraphVisualizationInfo.cs	(revision 3386)
+++ /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/IGraphVisualizationInfo.cs	(revision 3386)
@@ -0,0 +1,49 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Common;
+using HeuristicLab.Collections;
+
+namespace HeuristicLab.Operators.Views.GraphVisualization {
+  public interface IGraphVisualizationInfo : IDeepCloneable,IContent {
+    IShapeInfo InitialShape { get; set; }
+    event EventHandler InitialShapeChanged;
+
+    INotifyObservableCollectionItemsChanged<IShapeInfo> ObserveableShapeInfos { get; }
+    IEnumerable<IShapeInfo> ShapeInfos { get; }
+
+    INotifyObservableCollectionItemsChanged<IConnectionInfo> ObservableConnectionInfos { get; }
+    IEnumerable<IConnectionInfo> ConnectionInfos { get; }
+
+    void AddShapeInfo(IShapeInfo shapeInfo);
+    void RemoveShapeInfo(IShapeInfo shapeInfo);
+    void AddConnectionInfo(IConnectionInfo connectionInfo);
+    void RemoveConnectionInfo(IConnectionInfo connectionInfo);
+
+    IEnumerable<IConnectionInfo> GetConnectionInfos(IShapeInfo shapeInfo);
+    IEnumerable<IConnectionInfo> GetConnectionInfos(IShapeInfo shapeInfo, string connector);
+  }
+}
Index: /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/IShapeInfo.cs
===================================================================
--- /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/IShapeInfo.cs	(revision 3386)
+++ /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/IShapeInfo.cs	(revision 3386)
@@ -0,0 +1,44 @@
+﻿#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.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using System.Drawing;
+using Netron.Diagramming.Core;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Operators.Views.GraphVisualization {
+  public interface IShapeInfo : IDeepCloneable{
+    Type ShapeType { get; }
+    Point Location { get; set; }
+
+    IShape CreateShape();
+    IEnumerable<string> Connectors { get; }
+    void UpdateShape(IShape shape);
+    void UpdateShapeInfo(IShape shape);
+
+    event EventHandler Changed;
+  }
+}
Index: /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/ShapeInfo.cs
===================================================================
--- /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/ShapeInfo.cs	(revision 3386)
+++ /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/General/ShapeInfo.cs	(revision 3386)
@@ -0,0 +1,94 @@
+﻿#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.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using System.Drawing;
+using Netron.Diagramming.Core;
+using HeuristicLab.Collections;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Operators.Views.GraphVisualization {
+  [StorableClass]
+  public abstract class ShapeInfo : DeepCloneable, IShapeInfo {
+    private ShapeInfo() {
+    }
+
+    protected ShapeInfo(Type shapeType) {
+      if (!typeof(IShape).IsAssignableFrom(shapeType))
+        throw new ArgumentException("The passed shape type " + shapeType + " must be derived from IShape.");
+      this.shapeType = shapeType;
+    }
+
+    [Storable]
+    private Type shapeType;
+    public Type ShapeType {
+      get { return this.shapeType; }
+    }
+
+    [Storable]
+    private Point location;
+    public Point Location {
+      get { return this.location; }
+      set {
+        if (this.location != value) {
+          this.location = value;
+          this.OnChanged();
+        }
+      }
+    }
+
+    public abstract IEnumerable<string> Connectors { get; }
+
+    public event EventHandler Changed;
+    protected virtual void OnChanged() {
+      EventHandler handler = this.Changed;
+      if (handler != null)
+        this.Changed(this, EventArgs.Empty);
+    }
+
+    public virtual IShape CreateShape() {
+      IShape shape = (IShape)Activator.CreateInstance(this.shapeType);
+      shape.Tag = this;
+      shape.Location = this.Location;
+      return shape;
+    }
+
+    public virtual void UpdateShape(IShape shape) {
+      shape.Location = this.Location;
+    }
+
+    public virtual void UpdateShapeInfo(IShape shape) {
+      this.Location = shape.Location;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      ShapeInfo clone = (ShapeInfo)base.Clone(cloner);
+      clone.shapeType = this.shapeType;
+      clone.location = this.location;
+      return clone;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/HeuristicLab.Operators.Views.GraphVisualization-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/HeuristicLab.Operators.Views.GraphVisualization-3.3.csproj	(revision 3385)
+++ /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/HeuristicLab.Operators.Views.GraphVisualization-3.3.csproj	(revision 3386)
@@ -86,10 +86,4 @@
   <ItemGroup>
     <Compile Include="HeuristicLabOperatorsViewsGraphVisualizationPlugin.cs" />
-    <Compile Include="OperatorGraphView.cs">
-      <SubType>UserControl</SubType>
-    </Compile>
-    <Compile Include="OperatorGraphView.Designer.cs">
-      <DependentUpon>OperatorGraphView.cs</DependentUpon>
-    </Compile>
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
@@ -98,20 +92,32 @@
     <None Include="HeuristicLabOperatorsViewsGraphVisualizationPlugin.cs.frame" />
     <None Include="Properties\AssemblyInfo.frame" />
-    <Compile Include="GraphVisualizationInfoView.cs">
+    <Compile Include="General\GraphVisualizationInfo.cs" />
+    <Compile Include="General\GraphVisualizationInfoView.cs">
       <SubType>UserControl</SubType>
     </Compile>
-    <Compile Include="GraphVisualizationInfoView.Designer.cs">
+    <Compile Include="General\GraphVisualizationInfoView.Designer.cs">
       <DependentUpon>GraphVisualizationInfoView.cs</DependentUpon>
     </Compile>
-    <Compile Include="Model\IOperatorShapeInfo.cs" />
-    <Compile Include="Model\OperatorShapeInfo.cs" />
-    <Compile Include="Model\GraphVisualizationInfo.cs" />
+    <Compile Include="General\ConnectionInfo.cs" />
+    <Compile Include="General\IConnectionInfo.cs" />
+    <Compile Include="General\IGraphVisualizationInfo.cs" />
+    <Compile Include="OperatorGraphVisualization\IOperatorShapeInfo.cs" />
+    <Compile Include="OperatorGraphVisualization\OperatorGraphView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="OperatorGraphVisualization\OperatorGraphView.Designer.cs">
+      <DependentUpon>OperatorGraphView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="OperatorGraphVisualization\OperatorGraphVisualizationInfo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="OperatorGraphVisualization\OperatorShapeInfo.cs" />
     <Compile Include="BidirectionalLookup.cs" />
-    <Compile Include="Model\IShapeInfo.cs" />
-    <Compile Include="Model\OperatorShape.cs" />
-    <Compile Include="Model\ShapeInfo.cs">
+    <Compile Include="General\IShapeInfo.cs" />
+    <Compile Include="OperatorGraphVisualization\OperatorShape.cs" />
+    <Compile Include="General\ShapeInfo.cs">
       <SubType>Code</SubType>
     </Compile>
-    <Compile Include="Model\ShapeInfoFactory.cs" />
+    <Compile Include="OperatorGraphVisualization\OperatorShapeInfoFactory.cs" />
   </ItemGroup>
   <ItemGroup>
Index: /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/IOperatorShapeInfo.cs
===================================================================
--- /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/IOperatorShapeInfo.cs	(revision 3386)
+++ /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/IOperatorShapeInfo.cs	(revision 3386)
@@ -0,0 +1,42 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Drawing;
+
+namespace HeuristicLab.Operators.Views.GraphVisualization {
+  public interface IOperatorShapeInfo : IShapeInfo{
+    bool Collapsed { get; set; }
+    string Title { get; set; }
+    Color Color { get; set; }
+    Color LineColor { get; set; }
+    float LineWidth { get; set; }
+    Bitmap Icon { get; set; }
+
+    void AddConnector(string connectorName);
+    void RemoveConnector(string connectorName);
+
+    void UpdateLabels(IEnumerable<string> labels);
+  }
+}
Index: /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/OperatorGraphView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/OperatorGraphView.Designer.cs	(revision 3386)
+++ /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/OperatorGraphView.Designer.cs	(revision 3386)
@@ -0,0 +1,267 @@
+﻿namespace HeuristicLab.Operators.Views.GraphVisualization {
+  partial class OperatorGraphView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      this.graphVisualizationInfoView = new HeuristicLab.Operators.Views.GraphVisualization.GraphVisualizationInfoView();
+      this.shapeContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
+      this.openViewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.initialToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.breakPointToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.splitContainer = new System.Windows.Forms.SplitContainer();
+      this.detailsGroupBox = new System.Windows.Forms.GroupBox();
+      this.detailsViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.selectButton = new System.Windows.Forms.Button();
+      this.panButton = new System.Windows.Forms.Button();
+      this.connectButton = new System.Windows.Forms.Button();
+      this.relayoutButton = new System.Windows.Forms.Button();
+      this.zoomAreaButton = new System.Windows.Forms.Button();
+      this.zoomInButton = new System.Windows.Forms.Button();
+      this.zoomOutButton = new System.Windows.Forms.Button();
+      this.screenshotButton = new System.Windows.Forms.Button();
+      this.buttonToolTip = new System.Windows.Forms.ToolTip();
+      this.shapeContextMenu.SuspendLayout();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.detailsGroupBox.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // graphVisualizationInfoView
+      // 
+      this.graphVisualizationInfoView.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.graphVisualizationInfoView.Caption = null;
+      this.graphVisualizationInfoView.Content = null;
+      this.graphVisualizationInfoView.Location = new System.Drawing.Point(3, 30);
+      this.graphVisualizationInfoView.Name = "graphVisualizationInfoView";
+      this.graphVisualizationInfoView.Size = new System.Drawing.Size(662, 248);
+      this.graphVisualizationInfoView.TabIndex = 0;
+      // 
+      // shapeContextMenu
+      // 
+      this.shapeContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.openViewToolStripMenuItem,
+            this.initialToolStripMenuItem,
+            this.breakPointToolStripMenuItem});
+      this.shapeContextMenu.Name = "shapeContextMenu";
+      this.shapeContextMenu.Size = new System.Drawing.Size(154, 70);
+      this.shapeContextMenu.Opening += new System.ComponentModel.CancelEventHandler(this.shapeContextMenu_Opening);
+      // 
+      // openViewToolStripMenuItem
+      // 
+      this.openViewToolStripMenuItem.Name = "openViewToolStripMenuItem";
+      this.openViewToolStripMenuItem.Size = new System.Drawing.Size(153, 22);
+      this.openViewToolStripMenuItem.Text = "Open View";
+      this.openViewToolStripMenuItem.Click += new System.EventHandler(this.openViewToolStripMenuItem_Click);
+      // 
+      // initialToolStripMenuItem
+      // 
+      this.initialToolStripMenuItem.Name = "initialToolStripMenuItem";
+      this.initialToolStripMenuItem.Size = new System.Drawing.Size(153, 22);
+      this.initialToolStripMenuItem.Text = "Initial Operator";
+      this.initialToolStripMenuItem.Click += new System.EventHandler(this.initialOperatorToolStripMenuItem_Click);
+      // 
+      // breakPointToolStripMenuItem
+      // 
+      this.breakPointToolStripMenuItem.Name = "breakPointToolStripMenuItem";
+      this.breakPointToolStripMenuItem.Size = new System.Drawing.Size(153, 22);
+      this.breakPointToolStripMenuItem.Text = "Break Point";
+      this.breakPointToolStripMenuItem.Click += new System.EventHandler(this.breakPointToolStripMenuItem_Click);
+      // 
+      // splitContainer
+      // 
+      this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.splitContainer.Location = new System.Drawing.Point(0, 0);
+      this.splitContainer.Name = "splitContainer";
+      this.splitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.screenshotButton);
+      this.splitContainer.Panel1.Controls.Add(this.zoomOutButton);
+      this.splitContainer.Panel1.Controls.Add(this.zoomInButton);
+      this.splitContainer.Panel1.Controls.Add(this.zoomAreaButton);
+      this.splitContainer.Panel1.Controls.Add(this.relayoutButton);
+      this.splitContainer.Panel1.Controls.Add(this.connectButton);
+      this.splitContainer.Panel1.Controls.Add(this.panButton);
+      this.splitContainer.Panel1.Controls.Add(this.selectButton);
+      this.splitContainer.Panel1.Controls.Add(this.graphVisualizationInfoView);
+      // 
+      // splitContainer.Panel2
+      // 
+      this.splitContainer.Panel2.Controls.Add(this.detailsGroupBox);
+      this.splitContainer.Size = new System.Drawing.Size(665, 444);
+      this.splitContainer.SplitterDistance = 279;
+      this.splitContainer.TabIndex = 1;
+      // 
+      // detailsGroupBox
+      // 
+      this.detailsGroupBox.Controls.Add(this.detailsViewHost);
+      this.detailsGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.detailsGroupBox.Location = new System.Drawing.Point(0, 0);
+      this.detailsGroupBox.Name = "detailsGroupBox";
+      this.detailsGroupBox.Size = new System.Drawing.Size(665, 161);
+      this.detailsGroupBox.TabIndex = 0;
+      this.detailsGroupBox.TabStop = false;
+      this.detailsGroupBox.Text = "Details";
+      // 
+      // detailsViewHost
+      // 
+      this.detailsViewHost.Content = null;
+      this.detailsViewHost.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.detailsViewHost.Location = new System.Drawing.Point(3, 16);
+      this.detailsViewHost.Name = "detailsViewHost";
+      this.detailsViewHost.Size = new System.Drawing.Size(659, 142);
+      this.detailsViewHost.TabIndex = 0;
+      this.detailsViewHost.ViewType = null;
+      // 
+      // selectButton
+      // 
+      this.selectButton.Image = HeuristicLab.Common.Resources.VS2008ImageLibrary.Pointer;
+      this.selectButton.Location = new System.Drawing.Point(3, 3);
+      this.selectButton.Name = "selectButton";
+      this.selectButton.Size = new System.Drawing.Size(24, 24);
+      this.selectButton.TabIndex = 1;
+      this.selectButton.UseVisualStyleBackColor = true;
+      this.selectButton.Click += new System.EventHandler(selectButton_Click);
+      this.buttonToolTip.SetToolTip(this.selectButton, "Select Tool");
+      // 
+      // panButton
+      // 
+      this.panButton.Image = HeuristicLab.Common.Resources.VS2008ImageLibrary.Breakpoint;
+      this.panButton.Location = new System.Drawing.Point(33, 3);
+      this.panButton.Name = "panButton";
+      this.panButton.Size = new System.Drawing.Size(24, 24);
+      this.panButton.TabIndex = 2;
+      this.panButton.UseVisualStyleBackColor = true;
+      this.panButton.Click += new System.EventHandler(panButton_Click);
+      this.buttonToolTip.SetToolTip(this.panButton, "Pan Tool");
+      // 
+      // connectButton
+      // 
+      this.connectButton.Image = HeuristicLab.Common.Resources.VS2008ImageLibrary.Interface;
+      this.connectButton.Location = new System.Drawing.Point(63, 3);
+      this.connectButton.Name = "connectButton";
+      this.connectButton.Size = new System.Drawing.Size(24, 24);
+      this.connectButton.TabIndex = 3;
+      this.connectButton.UseVisualStyleBackColor = true;
+      this.connectButton.Click += new System.EventHandler(connectButton_Click);
+      this.buttonToolTip.SetToolTip(this.connectButton, "Connection Tool");
+      // 
+      // relayoutButton
+      // 
+      this.relayoutButton.Image = HeuristicLab.Common.Resources.VS2008ImageLibrary.RefreshDocument;
+      this.relayoutButton.Location = new System.Drawing.Point(123, 3);
+      this.relayoutButton.Name = "relayoutButton";
+      this.relayoutButton.Size = new System.Drawing.Size(24, 24);
+      this.relayoutButton.TabIndex = 4;
+      this.relayoutButton.UseVisualStyleBackColor = true;
+      this.relayoutButton.Click += new System.EventHandler(relayoutButton_Click);
+      this.buttonToolTip.SetToolTip(this.relayoutButton, "Relayout Graph");
+      // 
+      // zoomAreaButton
+      // 
+      this.zoomAreaButton.Image = HeuristicLab.Common.Resources.VS2008ImageLibrary.Zoom;
+      this.zoomAreaButton.Location = new System.Drawing.Point(153, 3);
+      this.zoomAreaButton.Name = "zoomAreaButton";
+      this.zoomAreaButton.Size = new System.Drawing.Size(24, 24);
+      this.zoomAreaButton.TabIndex = 5;
+      this.zoomAreaButton.UseVisualStyleBackColor = true;
+      this.zoomAreaButton.Click += new System.EventHandler(zoomAreaButton_Click);
+      this.buttonToolTip.SetToolTip(this.zoomAreaButton, "Zoom Area Tool");
+      // 
+      // zoomInButton
+      // 
+      this.zoomInButton.Image = HeuristicLab.Common.Resources.VS2008ImageLibrary.ZoomIn;
+      this.zoomInButton.Location = new System.Drawing.Point(183, 3);
+      this.zoomInButton.Name = "zoomInButton";
+      this.zoomInButton.Size = new System.Drawing.Size(24, 24);
+      this.zoomInButton.TabIndex = 6;
+      this.zoomInButton.UseVisualStyleBackColor = true;
+      this.zoomInButton.Click += new System.EventHandler(zoomInButton_Click);
+      this.buttonToolTip.SetToolTip(this.zoomInButton, "Zoom In");
+      // 
+      // zoomOutButton
+      // 
+      this.zoomOutButton.Image = HeuristicLab.Common.Resources.VS2008ImageLibrary.ZoomOut;
+      this.zoomOutButton.Location = new System.Drawing.Point(213, 3);
+      this.zoomOutButton.Name = "zoomOutButton";
+      this.zoomOutButton.Size = new System.Drawing.Size(24, 24);
+      this.zoomOutButton.TabIndex = 7;
+      this.zoomOutButton.UseVisualStyleBackColor = true;
+      this.zoomOutButton.Click += new System.EventHandler(zoomOutButton_Click);
+      this.buttonToolTip.SetToolTip(this.zoomOutButton, "Zoom Out");
+      // 
+      // screenshotButton
+      // 
+      this.screenshotButton.Image = HeuristicLab.Common.Resources.VS2008ImageLibrary.Copy;
+      this.screenshotButton.Location = new System.Drawing.Point(243, 3);
+      this.screenshotButton.Name = "screenshotButton";
+      this.screenshotButton.Size = new System.Drawing.Size(24, 24);
+      this.screenshotButton.TabIndex = 8;
+      this.screenshotButton.UseVisualStyleBackColor = true;
+      this.screenshotButton.Click += new System.EventHandler(screenshotButton_Click);
+      this.buttonToolTip.SetToolTip(this.screenshotButton, "Screenshot");
+      // 
+      // OperatorGraphView
+      // 
+      this.AllowDrop = true;
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.splitContainer);
+      this.Name = "OperatorGraphView";
+      this.Size = new System.Drawing.Size(665, 444);
+      this.DragDrop += new System.Windows.Forms.DragEventHandler(this.OperatorGraphView_DragDrop);
+      this.DragEnter += new System.Windows.Forms.DragEventHandler(this.OperatorGraphView_DragEnter);
+      this.shapeContextMenu.ResumeLayout(false);
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel2.ResumeLayout(false);
+      this.splitContainer.ResumeLayout(false);
+      this.detailsGroupBox.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+    #endregion
+
+    private GraphVisualizationInfoView graphVisualizationInfoView;
+    private System.Windows.Forms.ContextMenuStrip shapeContextMenu;
+    private System.Windows.Forms.ToolStripMenuItem openViewToolStripMenuItem;
+    private System.Windows.Forms.ToolStripMenuItem initialToolStripMenuItem;
+    private System.Windows.Forms.ToolStripMenuItem breakPointToolStripMenuItem;
+    private System.Windows.Forms.SplitContainer splitContainer;
+    private System.Windows.Forms.GroupBox detailsGroupBox;
+    private HeuristicLab.MainForm.WindowsForms.ViewHost detailsViewHost;
+    private System.Windows.Forms.Button selectButton;
+    private System.Windows.Forms.Button zoomOutButton;
+    private System.Windows.Forms.Button zoomInButton;
+    private System.Windows.Forms.Button zoomAreaButton;
+    private System.Windows.Forms.Button relayoutButton;
+    private System.Windows.Forms.Button connectButton;
+    private System.Windows.Forms.Button panButton;
+    private System.Windows.Forms.Button screenshotButton;
+    private System.Windows.Forms.ToolTip buttonToolTip;
+  }
+}
Index: /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/OperatorGraphView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/OperatorGraphView.cs	(revision 3386)
+++ /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/OperatorGraphView.cs	(revision 3386)
@@ -0,0 +1,320 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using Netron.Diagramming.Core;
+using HeuristicLab.Parameters;
+using HeuristicLab.MainForm.WindowsForms;
+using HeuristicLab.Collections;
+
+namespace HeuristicLab.Operators.Views.GraphVisualization {
+  [View("OperatorGraph View (Chart)")]
+  [Content(typeof(OperatorGraph), true)]
+  public partial class OperatorGraphView : ContentView {
+    public OperatorGraphView() {
+      InitializeComponent();
+      Caption = "Operator Graph Visualization";
+
+      this.graphVisualizationInfoView.Controller.OnShowContextMenu += new EventHandler<EntityMenuEventArgs>(Controller_OnShowContextMenu);
+      this.graphVisualizationInfoView.Controller.Model.Selection.OnNewSelection += new EventHandler(Controller_SelectionChanged);
+      this.graphVisualizationInfoView.Controller.OnMouseDown += new EventHandler<MouseEventArgs>(Controller_OnMouseDown);
+      foreach (ITool tool in this.graphVisualizationInfoView.Controller.Tools) {
+        tool.OnToolActivate += new EventHandler<ToolEventArgs>(tool_OnToolActivate);
+        tool.OnToolDeactivate += new EventHandler<ToolEventArgs>(tool_OnToolDeactivate);
+      }
+    }
+
+    public OperatorGraphView(OperatorGraph content)
+      : this() {
+      this.Content = content;
+    }
+
+    public new OperatorGraph Content {
+      get { return (OperatorGraph)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      bool createdVisualizationInfo = false;
+      if (this.VisualizationInfo == null) {
+        this.VisualizationInfo = new OperatorGraphVisualizationInfo(this.Content);
+        createdVisualizationInfo = true;
+      }
+      this.graphVisualizationInfoView.Content = this.VisualizationInfo;
+      if (createdVisualizationInfo)
+        this.graphVisualizationInfoView.RelayoutGraph();
+
+      this.SetEnabledStateOfControls();
+    }
+
+    protected override void OnReadOnlyChanged() {
+      base.OnReadOnlyChanged();
+      this.SetEnabledStateOfControls();
+    }
+
+    private void SetEnabledStateOfControls() {
+      if (Content == null) {
+        selectButton.Enabled = false;
+        panButton.Enabled = false;
+        relayoutButton.Enabled = false;
+        zoomAreaButton.Enabled = false;
+        zoomInButton.Enabled = false;
+        zoomOutButton.Enabled = false;
+        screenshotButton.Enabled = false;
+        detailsViewHost.Enabled = false;
+        graphVisualizationInfoView.ReadOnly = true;
+        connectButton.Enabled = false;
+      } else {
+        selectButton.Enabled = true;
+        panButton.Enabled = true;
+        relayoutButton.Enabled = true;
+        zoomAreaButton.Enabled = true;
+        zoomInButton.Enabled = true;
+        zoomOutButton.Enabled = true;
+        screenshotButton.Enabled = true;
+        detailsViewHost.Enabled = true;
+        detailsViewHost.ReadOnly = ReadOnly;
+        graphVisualizationInfoView.ReadOnly = ReadOnly;
+        connectButton.Enabled = !ReadOnly;
+      }
+    } 
+
+    private OperatorGraphVisualizationInfo VisualizationInfo {
+      get { return Content.VisualizationInfo as OperatorGraphVisualizationInfo; }
+      set { this.Content.VisualizationInfo = value; }
+    }
+
+    private void Controller_SelectionChanged(object sender, EventArgs e) {
+      CollectionBase<IDiagramEntity> selectedObjects = this.graphVisualizationInfoView.Controller.Model.Selection.SelectedItems;
+      this.detailsViewHost.ViewType = null;
+      if (selectedObjects.Count == 1) {
+        IShape shape = selectedObjects[0] as IShape;
+        if (shape != null) {
+          IOperatorShapeInfo shapeInfo = shape.Tag as IOperatorShapeInfo;
+          IOperator op = this.VisualizationInfo.GetOperatorForShapeInfo(shapeInfo);
+          this.detailsViewHost.ViewType = null;
+          this.detailsViewHost.Content = op;
+          return;
+        }
+      }
+      IConnector connector = this.graphVisualizationInfoView.Controller.Model.Selection.Connector;
+      if (connector != null) {
+        IShape shape = connector.Parent as IShape;
+        string connectorName = connector.Name;
+        if (shape == null) {
+          shape = connector.AttachedTo.Parent as IShape; //connection connector selected
+          connectorName = connector.AttachedTo.Name;
+        }
+        if (shape != null) {
+          IOperatorShapeInfo shapeInfo = shape.Tag as IOperatorShapeInfo;
+          IOperator op = this.VisualizationInfo.GetOperatorForShapeInfo(shapeInfo);
+          if (connectorName != "Predecessor") {
+            IParameter parameter = op.Parameters.Where(p => p.Name == connectorName).First();
+            this.detailsViewHost.ViewType = null;
+            this.detailsViewHost.Content = parameter;
+            return;
+          }
+        }
+      }
+      this.detailsViewHost.ViewType = null;
+      this.detailsViewHost.Content = null;
+    }
+
+    private void Controller_OnMouseDown(object sender, MouseEventArgs e) {
+      if (e.Clicks >= 2) {
+        IShape shape = this.graphVisualizationInfoView.Controller.Model.GetShapeAt(e.Location);
+        if (shape != null) {
+          IOperatorShapeInfo shapeInfo = shape.Tag as IOperatorShapeInfo;
+          if (shapeInfo != null) {
+            IOperator op = this.VisualizationInfo.GetOperatorForShapeInfo(shapeInfo);
+            MainFormManager.CreateDefaultView(op).Show();
+            HandledMouseEventArgs eventArgs = e as HandledMouseEventArgs;
+            if (eventArgs != null)
+              eventArgs.Handled = true;
+          }
+        }
+      }
+    }
+
+    #region context menu
+    private void Controller_OnShowContextMenu(object sender, EntityMenuEventArgs e) {
+      IShape shape = this.graphVisualizationInfoView.Controller.Model.GetShapeAt(e.MouseEventArgs.Location);
+      if (shape != null) {
+        IShapeInfo shapeInfo = shape.Tag as IShapeInfo;
+        this.shapeContextMenu.Tag = shapeInfo;
+        PointF worldPoint = this.graphVisualizationInfoView.Controller.View.WorldToView(e.MouseEventArgs.Location);
+        this.shapeContextMenu.Show(this, Point.Round(worldPoint));
+      }
+    }
+
+    private void shapeContextMenu_Opening(object sender, System.ComponentModel.CancelEventArgs e) {
+      IOperatorShapeInfo shapeInfo = this.shapeContextMenu.Tag as IOperatorShapeInfo;
+      if (shapeInfo != null) {
+        IOperator op = this.VisualizationInfo.GetOperatorForShapeInfo(shapeInfo);
+        this.initialToolStripMenuItem.Checked = this.Content.InitialOperator == op;
+        this.breakPointToolStripMenuItem.Checked = op.Breakpoint;
+      }
+    }
+
+    private void openViewToolStripMenuItem_Click(object sender, EventArgs e) {
+      IOperatorShapeInfo shapeInfo = this.shapeContextMenu.Tag as IOperatorShapeInfo;
+      if (shapeInfo != null) {
+        IOperator op = this.VisualizationInfo.GetOperatorForShapeInfo(shapeInfo);
+        MainFormManager.CreateDefaultView(op).Show();
+      }
+    }
+
+    private void initialOperatorToolStripMenuItem_Click(object sender, EventArgs e) {
+      if (!ReadOnly) {
+        IOperatorShapeInfo shapeInfo = this.shapeContextMenu.Tag as IOperatorShapeInfo;
+        if (this.VisualizationInfo.InitialShape == shapeInfo)
+          this.VisualizationInfo.InitialShape = null;
+        else
+          this.VisualizationInfo.InitialShape = shapeInfo;
+      }
+    }
+
+    private void breakPointToolStripMenuItem_Click(object sender, EventArgs e) {
+      if (!ReadOnly) {
+        IOperatorShapeInfo shapeInfo = this.shapeContextMenu.Tag as IOperatorShapeInfo;
+        if (shapeInfo != null) {
+          IOperator op = this.VisualizationInfo.GetOperatorForShapeInfo(shapeInfo);
+          op.Breakpoint = !op.Breakpoint;
+        }
+      }
+    }
+    #endregion
+
+    #region drag and drop
+    private void OperatorGraphView_DragEnter(object sender, DragEventArgs e) {
+      e.Effect = DragDropEffects.None;
+      if (ReadOnly)
+        return;
+      Type type = e.Data.GetData("Type") as Type;
+      if ((type != null) && (typeof(IOperator).IsAssignableFrom(type))) {
+        e.Effect = DragDropEffects.Copy;
+      }
+    }
+
+    private void OperatorGraphView_DragDrop(object sender, DragEventArgs e) {
+      if (e.Effect != DragDropEffects.None) {
+        IOperator op = e.Data.GetData("Value") as IOperator;
+        IOperatorShapeInfo shapeInfo = OperatorShapeInfoFactory.CreateOperatorShapeInfo(op);
+        Point mouse = new Point(MousePosition.X, MousePosition.Y);
+        Point screen = this.graphVisualizationInfoView.PointToScreen(new Point(0, 0));
+        Point control = new Point(mouse.X - screen.X, mouse.Y - screen.Y);
+        PointF worldPoint = this.graphVisualizationInfoView.Controller.View.ViewToWorld(control);
+
+        if (worldPoint.X < 0)
+          worldPoint.X = 0;
+        if (worldPoint.Y < 0)
+          worldPoint.Y = 0;
+
+        shapeInfo.Location = Point.Round(worldPoint);
+        this.VisualizationInfo.AddShapeInfo(op, shapeInfo);
+      }
+    }
+    #endregion
+
+    private void tool_OnToolActivate(object sender, ToolEventArgs e) {
+      Button button = GetButtonForTool(e.Properties.Name);
+      if (button != null)
+        button.Enabled = false;
+    }
+
+    private void tool_OnToolDeactivate(object sender, ToolEventArgs e) {
+      Button button = GetButtonForTool(e.Properties.Name);
+      if (button != null)
+        button.Enabled = true;
+    }
+
+    private Button GetButtonForTool(string toolName) {
+      Button button = null;
+      switch (toolName) {
+        case ControllerBase.SelectionToolName:
+          button = this.selectButton;
+          break;
+        case ControllerBase.PanToolName:
+          button = this.panButton;
+          break;
+        case ControllerBase.ConnectionToolName:
+          button = this.connectButton;
+          break;
+        case ControllerBase.ZoomAreaToolName:
+          button = this.zoomAreaButton;
+          break;
+      }
+      return button;
+    }
+
+    private void selectButton_Click(object sender, EventArgs e) {
+      ITool tool = this.graphVisualizationInfoView.Controller.Tools.Where(t => t.Name == ControllerBase.SelectionToolName).First();
+      this.graphVisualizationInfoView.Controller.DeactivateAllTools();
+    }
+
+    private void panButton_Click(object sender, EventArgs e) {
+      this.graphVisualizationInfoView.Controller.ActivateTool(ControllerBase.PanToolName);
+    }
+
+    private void connectButton_Click(object sender, EventArgs e) {
+      this.graphVisualizationInfoView.Controller.ActivateTool(ControllerBase.ConnectionToolName);
+    }
+
+    private void relayoutButton_Click(object sender, EventArgs e) {
+      this.graphVisualizationInfoView.RelayoutGraph();
+    }
+
+    private void zoomAreaButton_Click(object sender, EventArgs e) {
+      this.graphVisualizationInfoView.Controller.View.ZoomFit();
+    }
+
+    private void zoomInButton_Click(object sender, EventArgs e) {
+      this.graphVisualizationInfoView.Controller.ActivateTool(ControllerBase.ZoomInToolName);
+    }
+
+    private void zoomOutButton_Click(object sender, EventArgs e) {
+      this.graphVisualizationInfoView.Controller.ActivateTool(ControllerBase.ZoomOutToolName);
+    }
+
+    private void screenshotButton_Click(object sender, EventArgs e) {
+      Bitmap bitmap = ImageExporter.FromBundle(new Bundle(this.graphVisualizationInfoView.Controller.Model.Paintables), this.graphVisualizationInfoView.Controller.View.Graphics);
+      SaveFileDialog saveFileDialog = new SaveFileDialog();
+      saveFileDialog.Title = "Save Screenshot";
+      saveFileDialog.DefaultExt = "bmp";
+      saveFileDialog.Filter = "Bitmap|*.bmp|All Files|*.*";
+      saveFileDialog.FilterIndex = 1;
+
+      if (saveFileDialog.ShowDialog() == DialogResult.OK) {
+        bitmap.Save(saveFileDialog.FileName);
+      }
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/OperatorGraphVisualizationInfo.cs
===================================================================
--- /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/OperatorGraphVisualizationInfo.cs	(revision 3386)
+++ /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/OperatorGraphVisualizationInfo.cs	(revision 3386)
@@ -0,0 +1,437 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using Netron.Diagramming.Core;
+using System.Drawing;
+using HeuristicLab.Collections;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Operators.Views.GraphVisualization {
+  [StorableClass]
+  public sealed class OperatorGraphVisualizationInfo : GraphVisualizationInfo {
+    [Storable]
+    private BidirectionalLookup<IOperator, IOperatorShapeInfo> operatorShapeInfoMapping;
+    private BidirectionalLookup<IOperator, IObservableKeyedCollection<string, IParameter>> operatorParameterCollectionMapping;
+    private Dictionary<IParameter, IOperator> parameterOperatorMapping;
+
+    private OperatorGraphVisualizationInfo()
+      : base() {
+      this.operatorShapeInfoMapping = new BidirectionalLookup<IOperator, IOperatorShapeInfo>();
+      this.operatorParameterCollectionMapping = new BidirectionalLookup<IOperator, IObservableKeyedCollection<string, IParameter>>();
+      this.parameterOperatorMapping = new Dictionary<IParameter, IOperator>();
+    }
+
+    [StorableConstructor]
+    private OperatorGraphVisualizationInfo(bool deserializing)
+      : base() {
+      this.operatorParameterCollectionMapping = new BidirectionalLookup<IOperator, IObservableKeyedCollection<string, IParameter>>();
+      this.parameterOperatorMapping = new Dictionary<IParameter, IOperator>();
+    }
+
+    public OperatorGraphVisualizationInfo(OperatorGraph operatorGraph)
+      : this() {
+      this.operatorGraph = operatorGraph;
+      this.RegisterOperatorGraphEvents();
+
+      foreach (IOperator op in operatorGraph.Operators)
+        if (!this.operatorShapeInfoMapping.ContainsFirst(op))  //could be added by referencing parameters
+          this.AddOperator(op);
+
+      this.UpdateInitialShape();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void DeserializationHook() {
+      this.operatorGraph.DeserializationFinished += new EventHandler(operatorGraph_DeserializationFinished);
+
+      IOperator op;
+      IOperatorShapeInfo shapeInfo;
+      foreach (KeyValuePair<IOperator, IOperatorShapeInfo> pair in this.operatorShapeInfoMapping.FirstEnumerable) {
+        op = pair.Key;
+        shapeInfo = pair.Value;
+        shapeInfo.Icon = new Bitmap(op.ItemImage);
+        this.RegisterOperatorEvents(op);
+        this.operatorParameterCollectionMapping.Add(op, op.Parameters);
+      }
+
+      foreach (IOperator oper in this.operatorShapeInfoMapping.FirstValues) {
+        foreach (IParameter param in oper.Parameters) {
+          this.parameterOperatorMapping.Add(param, oper);
+          IValueParameter<IOperator> opParam = param as IValueParameter<IOperator>;
+          if (opParam != null)
+            this.RegisterOperatorParameterEvents(opParam);
+          else
+            this.RegisterParameterEvents(param);
+        }
+      }
+    }
+
+    private void operatorGraph_DeserializationFinished(object sender, EventArgs e) {
+      this.RegisterOperatorGraphEvents();
+      if (this.operatorGraph.InitialOperator != null) {
+        IOperatorShapeInfo newInitialShapeInfo = this.operatorShapeInfoMapping.GetByFirst(this.operatorGraph.InitialOperator);
+        if (newInitialShapeInfo != null) {
+          oldInitialShapeColor = newInitialShapeInfo.Color;
+          newInitialShapeInfo.Color = Color.LightGreen;
+        }
+        oldInitialShape = this.InitialShape;
+        this.OnInitialShapeChanged();
+      }
+      this.operatorGraph.DeserializationFinished -= new EventHandler(operatorGraph_DeserializationFinished);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      OperatorGraphVisualizationInfo clone = (OperatorGraphVisualizationInfo)base.Clone(cloner);
+      clone.operatorGraph = (OperatorGraph)cloner.Clone(this.operatorGraph);
+      clone.RegisterOperatorGraphEvents();
+      clone.oldInitialShape = (IOperatorShapeInfo)cloner.Clone(this.oldInitialShape);
+      clone.oldInitialShapeColor = this.oldInitialShapeColor;
+
+      IOperator op;
+      IOperatorShapeInfo shapeInfo;
+      foreach (KeyValuePair<IOperator, IOperatorShapeInfo> pair in this.operatorShapeInfoMapping.FirstEnumerable) {
+        op = (IOperator)cloner.Clone(pair.Key);
+        shapeInfo = (IOperatorShapeInfo)cloner.Clone(pair.Value);
+        clone.RegisterOperatorEvents(op);
+        clone.operatorParameterCollectionMapping.Add(op, pair.Key.Parameters);
+        clone.operatorShapeInfoMapping.Add(op, shapeInfo);
+      }
+
+      foreach (IOperator oper in clone.operatorShapeInfoMapping.FirstValues) {
+        foreach (IParameter param in oper.Parameters) {
+          clone.parameterOperatorMapping.Add(param, oper);
+          IValueParameter<IOperator> opParam = param as IValueParameter<IOperator>;
+          if (opParam != null)
+            clone.RegisterOperatorParameterEvents(opParam);
+          else
+            clone.RegisterParameterEvents(param);
+        }
+      }
+      if (this.operatorGraph.InitialOperator != null) {
+        IOperatorShapeInfo newInitialShapeInfo = this.operatorShapeInfoMapping.GetByFirst(this.operatorGraph.InitialOperator);
+        if (newInitialShapeInfo != null) {
+          oldInitialShapeColor = newInitialShapeInfo.Color;
+          newInitialShapeInfo.Color = Color.LightGreen;
+        }
+        oldInitialShape = this.InitialShape;
+        this.OnInitialShapeChanged();
+      }
+      return clone;
+    }
+
+    internal IOperator GetOperatorForShapeInfo(IOperatorShapeInfo shapeInfo) {
+      return this.operatorShapeInfoMapping.GetBySecond(shapeInfo);
+    }
+
+    private void operatorGraph_InitialOperatorChanged(object sender, EventArgs e) {
+      this.UpdateInitialShape();
+    }
+
+    private void UpdateInitialShape() {
+      IOperatorShapeInfo old = this.oldInitialShape as OperatorShapeInfo;
+      if (old != null)
+        old.Color = oldInitialShapeColor;
+
+      OperatorShapeInfo newInitialShapeInfo = this.InitialShape as OperatorShapeInfo;
+      if (newInitialShapeInfo != null) {
+        oldInitialShapeColor = newInitialShapeInfo.Color;
+        newInitialShapeInfo.Color = Color.LightGreen;
+      }
+
+      oldInitialShape = this.InitialShape;
+      this.OnInitialShapeChanged();
+    }
+
+    private IShapeInfo oldInitialShape;
+    private Color oldInitialShapeColor;
+    public override IShapeInfo InitialShape {
+      get {
+        IOperator op = this.operatorGraph.InitialOperator;
+        if (op == null)
+          return null;
+        return this.operatorShapeInfoMapping.GetByFirst(op);
+      }
+      set {
+        if (value == null)
+          this.OperatorGraph.InitialOperator = null;
+        else {
+          IOperatorShapeInfo shapeInfo = (IOperatorShapeInfo)value;
+          this.OperatorGraph.InitialOperator = this.operatorShapeInfoMapping.GetBySecond(shapeInfo);
+        }
+      }
+    }
+
+    [Storable]
+    private OperatorGraph operatorGraph;
+    public OperatorGraph OperatorGraph {
+      get { return this.operatorGraph; }
+    }
+
+    private void RegisterOperatorGraphEvents() {
+      this.operatorGraph.InitialOperatorChanged += new EventHandler(operatorGraph_InitialOperatorChanged);
+      this.operatorGraph.Operators.ItemsAdded += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IOperator>(Operators_ItemsAdded);
+      this.operatorGraph.Operators.ItemsRemoved += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IOperator>(Operators_ItemsRemoved);
+      this.operatorGraph.Operators.CollectionReset += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IOperator>(Operators_CollectionReset);
+    }
+
+    private void DeregisterOperatorGraphEvents() {
+      this.operatorGraph.InitialOperatorChanged -= new EventHandler(operatorGraph_InitialOperatorChanged);
+      this.operatorGraph.Operators.ItemsAdded -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IOperator>(Operators_ItemsAdded);
+      this.operatorGraph.Operators.ItemsRemoved -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IOperator>(Operators_ItemsRemoved);
+      this.operatorGraph.Operators.CollectionReset -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IOperator>(Operators_CollectionReset);
+    }
+
+    #region methods to manipulate operatorgraph by the shape info
+    internal void AddShapeInfo(IOperator op, IOperatorShapeInfo shapeInfo) {
+      this.RegisterOperatorEvents(op);
+      this.operatorParameterCollectionMapping.Add(op, op.Parameters);
+      this.operatorShapeInfoMapping.Add(op, shapeInfo);
+      this.shapeInfos.Add(shapeInfo);
+
+      foreach (IParameter param in op.Parameters)
+        this.AddParameter(op, param);
+
+      this.operatorGraph.Operators.Add(op);
+    }
+
+    public override void RemoveShapeInfo(IShapeInfo shapeInfo) {
+      IOperatorShapeInfo opShapeInfo = (IOperatorShapeInfo)shapeInfo;
+      if (this.operatorShapeInfoMapping.ContainsSecond(opShapeInfo)) {
+        IOperator op = this.operatorShapeInfoMapping.GetBySecond(opShapeInfo);
+        this.operatorGraph.Operators.Remove(op);
+      }
+    }
+
+    public override void RemoveConnectionInfo(IConnectionInfo connectionInfo) {
+      IOperatorShapeInfo shapeInfo = (IOperatorShapeInfo)connectionInfo.From;
+      IOperator op = this.operatorShapeInfoMapping.GetBySecond(shapeInfo);
+      IValueParameter<IOperator> param = (IValueParameter<IOperator>)op.Parameters[connectionInfo.ConnectorFrom];
+      param.Value = null;
+    }
+    #endregion
+
+    #region operator events
+    private void AddOperator(IOperator op) {
+      if (!this.operatorShapeInfoMapping.ContainsFirst(op)) {
+        this.RegisterOperatorEvents(op);
+        IOperatorShapeInfo shapeInfo = OperatorShapeInfoFactory.CreateOperatorShapeInfo(op);
+        this.operatorParameterCollectionMapping.Add(op, op.Parameters);
+        this.operatorShapeInfoMapping.Add(op, shapeInfo);
+        this.shapeInfos.Add(shapeInfo);
+        foreach (IParameter param in op.Parameters)
+          this.AddParameter(op, param);
+      }
+    }
+    private void RemoveOperator(IOperator op) {
+      this.DeregisterOperatorEvents(op);
+      foreach (IParameter param in op.Parameters)
+        this.RemoveParameter(op, param);
+
+      IOperatorShapeInfo shapeInfo = this.operatorShapeInfoMapping.GetByFirst(op);
+      this.operatorParameterCollectionMapping.RemoveByFirst(op);
+      this.operatorShapeInfoMapping.RemoveByFirst(op);
+      this.shapeInfos.Remove(shapeInfo);
+    }
+
+    private void OperatorBreakpointChanged(object sender, EventArgs e) {
+      IOperator op = (IOperator)sender;
+      IOperatorShapeInfo operatorShapeInfo = this.operatorShapeInfoMapping.GetByFirst(op);
+      if (op.Breakpoint) {
+        operatorShapeInfo.LineColor = Color.Red;
+        operatorShapeInfo.LineWidth = 2;
+      } else {
+        operatorShapeInfo.LineColor = Color.Black;
+        operatorShapeInfo.LineWidth = 1;
+      }
+    }
+
+    private void OperatorItemImageChanged(object sender, EventArgs e) {
+      IOperator op = (IOperator)sender;
+      IOperatorShapeInfo operatorShapeInfo = this.operatorShapeInfoMapping.GetByFirst(op);
+      operatorShapeInfo.Icon = new Bitmap(op.ItemImage);
+    }
+
+    private void OperatorNameChanged(object sender, EventArgs e) {
+      IOperator op = (IOperator)sender;
+      IOperatorShapeInfo operatorShapeInfo = this.operatorShapeInfoMapping.GetByFirst(op);
+      operatorShapeInfo.Title = op.Name;
+    }
+
+    private void Operators_ItemsAdded(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IOperator> e) {
+      foreach (IOperator op in e.Items)
+        this.AddOperator(op);
+    }
+    private void Operators_ItemsRemoved(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IOperator> e) {
+      foreach (IOperator op in e.Items)
+        this.RemoveOperator(op);
+    }
+    private void Operators_CollectionReset(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IOperator> e) {
+      foreach (IOperator op in e.OldItems)
+        this.RemoveOperator(op);
+      foreach (IOperator op in e.Items)
+        this.AddOperator(op);
+    }
+
+    private void RegisterOperatorEvents(IOperator op) {
+      op.Parameters.ItemsAdded += new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsAdded);
+      op.Parameters.ItemsRemoved += new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsRemoved);
+      op.Parameters.ItemsReplaced += new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsReplaced);
+      op.Parameters.CollectionReset += new CollectionItemsChangedEventHandler<IParameter>(Parameters_CollectionReset);
+      op.NameChanged += new EventHandler(OperatorNameChanged);
+      op.ItemImageChanged += new EventHandler(OperatorItemImageChanged);
+      op.BreakpointChanged += new EventHandler(OperatorBreakpointChanged);
+    }
+
+    private void DeregisterOperatorEvents(IOperator op) {
+      op.Parameters.ItemsAdded -= new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsAdded);
+      op.Parameters.ItemsRemoved -= new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsRemoved);
+      op.Parameters.ItemsReplaced -= new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsReplaced);
+      op.Parameters.CollectionReset -= new CollectionItemsChangedEventHandler<IParameter>(Parameters_CollectionReset);
+      op.NameChanged -= new EventHandler(OperatorNameChanged);
+      op.ItemImageChanged -= new EventHandler(OperatorItemImageChanged);
+      op.BreakpointChanged -= new EventHandler(OperatorBreakpointChanged);
+    }
+    #endregion
+
+    #region parameter events
+    private void AddParameter(IOperator op, IParameter param) {
+      this.parameterOperatorMapping.Add(param, op);
+      IValueParameter<IOperator> opParam = param as IValueParameter<IOperator>;
+      if (opParam != null) {
+        this.RegisterOperatorParameterEvents(opParam);
+        IOperatorShapeInfo shapeInfoFrom = this.operatorShapeInfoMapping.GetByFirst(op);
+        shapeInfoFrom.AddConnector(param.Name);
+
+        if (opParam.Value != null) {
+          if (!this.operatorShapeInfoMapping.ContainsFirst(opParam.Value))
+            this.AddOperator(opParam.Value);
+          IOperatorShapeInfo shapeInfoTo = this.operatorShapeInfoMapping.GetByFirst(opParam.Value);
+          this.connectionInfos.Add(new ConnectionInfo(shapeInfoFrom, param.Name, shapeInfoTo, OperatorShapeInfoFactory.PredecessorConnector));
+        }
+      } else
+        this.RegisterParameterEvents(param);
+    }
+
+    private void RemoveParameter(IOperator op, IParameter param) {
+      IValueParameter<IOperator> opParam = param as IValueParameter<IOperator>;
+      if (opParam != null) {
+        this.DeregisterOperatorParameterEvents(opParam);
+        IOperatorShapeInfo shapeInfo = this.operatorShapeInfoMapping.GetByFirst(op);
+        this.connectionInfos.RemoveWhere(c => c.From == shapeInfo && c.ConnectorFrom == param.Name);
+        this.connectionInfos.RemoveWhere(c => c.To == shapeInfo && c.ConnectorTo == param.Name);
+        shapeInfo.RemoveConnector(param.Name);
+      } else
+        this.DeregisterParameterEvents(param);
+
+      this.parameterOperatorMapping.Remove(param);
+    }
+
+    private void opParam_ValueChanged(object sender, EventArgs e) {
+      IValueParameter<IOperator> opParam = (IValueParameter<IOperator>)sender;
+      IOperator op = this.parameterOperatorMapping[opParam];
+      IOperatorShapeInfo shapeInfoFrom = this.operatorShapeInfoMapping.GetByFirst(op);
+      KeyValuePair<IOperatorShapeInfo, string> connectionFrom = new KeyValuePair<IOperatorShapeInfo, string>(shapeInfoFrom, opParam.Name);
+
+      this.connectionInfos.RemoveWhere(c => c.From == shapeInfoFrom && c.ConnectorFrom == opParam.Name);
+      if (opParam.Value != null) {
+        if (!this.operatorShapeInfoMapping.ContainsFirst(opParam.Value))
+          this.AddOperator(opParam.Value);
+        IShapeInfo shapeInfoTo = this.operatorShapeInfoMapping.GetByFirst(opParam.Value);
+        this.AddConnectionInfo(new ConnectionInfo(shapeInfoFrom, opParam.Name, shapeInfoTo, OperatorShapeInfoFactory.PredecessorConnector));
+      }
+    }
+
+    private void Parameters_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IParameter> e) {
+      IObservableKeyedCollection<string, IParameter> parameterCollection = sender as IObservableKeyedCollection<string, IParameter>;
+      IOperator op = this.operatorParameterCollectionMapping.GetBySecond(parameterCollection);
+      foreach (IParameter param in e.Items)
+        AddParameter(op, param);
+      this.UpdateParameterLabels(op);
+    }
+    private void Parameters_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IParameter> e) {
+      IObservableKeyedCollection<string, IParameter> parameterCollection = sender as IObservableKeyedCollection<string, IParameter>;
+      IOperator op = this.operatorParameterCollectionMapping.GetBySecond(parameterCollection);
+      foreach (IParameter param in e.Items)
+        RemoveParameter(op, param);
+      this.UpdateParameterLabels(op);
+    }
+    private void Parameters_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IParameter> e) {
+      IObservableKeyedCollection<string, IParameter> parameterCollection = sender as IObservableKeyedCollection<string, IParameter>;
+      IOperator op = this.operatorParameterCollectionMapping.GetBySecond(parameterCollection);
+      foreach (IParameter param in e.OldItems)
+        RemoveParameter(op, param);
+      foreach (IParameter param in e.Items)
+        AddParameter(op, param);
+      this.UpdateParameterLabels(op);
+    }
+    private void Parameters_CollectionReset(object sender, CollectionItemsChangedEventArgs<IParameter> e) {
+      IObservableKeyedCollection<string, IParameter> parameterCollection = sender as IObservableKeyedCollection<string, IParameter>;
+      IOperator op = this.operatorParameterCollectionMapping.GetBySecond(parameterCollection);
+      foreach (IParameter param in e.OldItems)
+        RemoveParameter(op, param);
+      foreach (IParameter param in e.Items)
+        AddParameter(op, param);
+      this.UpdateParameterLabels(op);
+    }
+
+    private void RegisterOperatorParameterEvents(IValueParameter<IOperator> opParam) {
+      opParam.ValueChanged += new EventHandler(opParam_ValueChanged);
+    }
+    private void DeregisterOperatorParameterEvents(IValueParameter<IOperator> opParam) {
+      opParam.ValueChanged -= new EventHandler(opParam_ValueChanged);
+    }
+    private void RegisterParameterEvents(IParameter param) {
+      param.ToStringChanged += new EventHandler(param_ToStringChanged);
+      param.NameChanged += new EventHandler(param_NameChanged);
+    }
+    private void DeregisterParameterEvents(IParameter param) {
+      param.ToStringChanged -= new EventHandler(param_ToStringChanged);
+      param.NameChanged -= new EventHandler(param_NameChanged);
+    }
+
+    private void param_NameChanged(object sender, EventArgs e) {
+      IParameter param = (IParameter)sender;
+      IOperator op = this.parameterOperatorMapping[param];
+      this.UpdateParameterLabels(op);
+    }
+    private void param_ToStringChanged(object sender, EventArgs e) {
+      IParameter param = (IParameter)sender;
+      IOperator op = this.parameterOperatorMapping[param];
+      this.UpdateParameterLabels(op);
+    }
+
+    private void UpdateParameterLabels(IOperator op) {
+      IEnumerable<IParameter> parameters = op.Parameters.Where(p => !(p is IValueParameter<IOperator>));
+      IOperatorShapeInfo operatorShapeInfo = this.operatorShapeInfoMapping.GetByFirst(op);
+      if (parameters.Count() > 0)
+        operatorShapeInfo.UpdateLabels(parameters.Select(p => p.ToString()));
+      else
+        operatorShapeInfo.UpdateLabels(new List<string>());
+    }
+    #endregion
+  }
+}
Index: /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/OperatorShape.cs
===================================================================
--- /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/OperatorShape.cs	(revision 3386)
+++ /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/OperatorShape.cs	(revision 3386)
@@ -0,0 +1,282 @@
+﻿#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.Linq;
+using System.Text;
+using Netron.Diagramming.Core;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using HeuristicLab.Netron;
+
+
+namespace HeuristicLab.Operators.Views.GraphVisualization {
+  public class OperatorShape : ComplexShapeBase {
+    private static int LABEL_HEIGHT = 16;
+    private static int LABEL_WIDTH = 180;
+    private static int LABEL_SPACING = 3;
+    private int headerHeight = 30;
+
+    private ExpandableIconMaterial expandIconMaterial;
+    public OperatorShape()
+      : base() {
+      this.Resizable = false;
+      this.additionalConnectors = new List<IConnector>();
+      this.labels = new List<string>();
+    }
+
+    public override string EntityName {
+      get { return "Operator Shape"; }
+    }
+
+    public bool Collapsed {
+      get { return this.expandIconMaterial.Collapsed; }
+      set {
+        if (this.expandIconMaterial.Collapsed != value)
+          this.expandIconMaterial.Collapsed = value;
+      }
+    }
+
+    private Color lineColor;
+    public Color LineColor {
+      get { return this.lineColor; }
+      set { this.lineColor = value; }
+    }
+
+    private float lineWidth;
+    public float LineWidth {
+      get { return this.lineWidth; }
+      set { this.lineWidth = value; }
+    }
+
+    private Color color;
+    public Color Color {
+      get { return this.color; }
+      set { this.color = value; }
+    }
+
+    private string title;
+    public string Title {
+      get { return title; }
+      set { title = value; }
+    }
+
+    private IconMaterial iconMaterial;
+    public Bitmap Icon {
+      get { return this.iconMaterial.Icon; }
+      set {
+        this.iconMaterial.Icon = value;
+        this.iconMaterial.Transform(new Rectangle(new Point(Rectangle.X + 5, Rectangle.Y + 5), this.iconMaterial.Icon.Size));
+      }
+    }
+
+    #region additional connectors
+    private List<IConnector> additionalConnectors;
+    public IEnumerable<string> AdditionalConnectorNames {
+      get { return this.additionalConnectors.Select(c => c.Name); }
+    }
+
+    private IConnector predecessor;
+    public IConnector Predecessor {
+      get { return this.predecessor; }
+    }
+
+    private IConnector successor;
+    public IConnector Successor {
+      get { return this.successor; }
+    }
+
+    private IConnector CreateConnector(string connectorName, Point location) {
+      Connector connector = new Connector(location, this.Model);
+      connector.ConnectorStyle = ConnectorStyle.Square;
+      connector.Parent = this;
+      connector.Name = connectorName;
+      return connector;
+    }
+
+    public void AddConnector(string connectorName) {
+      IConnector connector = this.CreateConnector(connectorName, this.BottomRightCorner);
+
+      this.additionalConnectors.Add(connector);
+      this.Connectors.Add(connector);
+      this.UpdateConnectorLocation();
+    }
+
+    public void RemoveConnector(string connectorName) {
+      IConnector connector = this.additionalConnectors.Where(c => c.Name == connectorName).FirstOrDefault();
+      if (connector != null) {
+        this.additionalConnectors.Remove(connector);
+        this.Connectors.Remove(connector);
+        this.UpdateConnectorLocation();
+      }
+    }
+
+    private void UpdateConnectorLocation() {
+      if (this.additionalConnectors.Count == 0)
+        return;
+
+      int spacing = this.Rectangle.Width / this.additionalConnectors.Count;
+      int margin = spacing / 2;
+      int posX = margin + this.Rectangle.X;
+      for (int i = 0; i < this.additionalConnectors.Count; i++) {
+        this.additionalConnectors[i].MoveBy(new Point(posX - this.additionalConnectors[i].Point.X, 0));
+        posX += spacing;
+      }
+    }
+    #endregion
+
+    #region label material
+    private List<string> labels;
+    public IEnumerable<string> Labels {
+      get { return this.labels; }
+    }
+
+    public void UpdateLabels(IEnumerable<string> labels) {
+      this.labels = new List<string>(labels);
+      this.expandIconMaterial.Visible = this.labels.Count != 0;
+      this.UpdateLabels();
+    }
+    #endregion
+
+    private void expandIconMaterial_OnExpand(object sender, EventArgs e) {
+      this.UpdateLabels();
+    }
+
+    private void expandIconMaterial_OnCollapse(object sender, EventArgs e) {
+      this.UpdateLabels();
+    }
+
+    private Size CalculateSize() {
+      int width = this.Rectangle.Width;
+      int height = headerHeight;
+      if (!Collapsed)
+        height += this.labels.Count * (LABEL_HEIGHT + LABEL_SPACING);
+      return new Size(width, height);
+    }
+
+    private void UpdateLabels() {
+      Size newSize = CalculateSize();
+      if (this.Rectangle.Size != newSize) {
+        foreach (IConnector connector in this.additionalConnectors)
+          connector.MoveBy(new Point(0, newSize.Height - this.Rectangle.Height));
+        this.mRectangle = new Rectangle(this.Rectangle.Location, newSize);
+        this.Invalidate();
+        this.RaiseOnChange(this, new EntityEventArgs(this));
+      }
+    }
+
+    protected override void Initialize() {
+      base.Initialize();
+
+      //the initial size
+      this.Transform(0, 0, 200, headerHeight);
+      this.color = Color.LightBlue;
+
+      this.iconMaterial = new IconMaterial();
+      this.iconMaterial.Gliding = false;
+      this.Children.Add(iconMaterial);
+
+      Bitmap expandBitmap = new Bitmap(HeuristicLab.Common.Resources.VS2008ImageLibrary.Expand);
+      Bitmap collapseBitmap = new Bitmap(HeuristicLab.Common.Resources.VS2008ImageLibrary.Collapse);
+      this.expandIconMaterial = new ExpandableIconMaterial(expandBitmap, collapseBitmap);
+      this.expandIconMaterial.Gliding = false;
+      this.expandIconMaterial.Transform(new Rectangle(new Point(Rectangle.Right - 20, Rectangle.Y + 7), expandIconMaterial.Icon.Size));
+      this.expandIconMaterial.Visible = false;
+      this.expandIconMaterial.OnExpand += new EventHandler(expandIconMaterial_OnExpand);
+      this.expandIconMaterial.OnCollapse += new EventHandler(expandIconMaterial_OnCollapse);
+      this.Children.Add(expandIconMaterial);
+
+      this.predecessor = this.CreateConnector("Predecessor", new Point(Rectangle.Left, Center.Y));
+      this.Connectors.Add(predecessor);
+
+      this.successor = this.CreateConnector("Successor", (new Point(Rectangle.Right, Center.Y)));
+      this.Connectors.Add(successor);
+    }
+
+    public override void Paint(Graphics g) {
+      base.Paint(g);
+
+      g.SmoothingMode = SmoothingMode.HighQuality;
+
+      Pen pen = new Pen(lineColor, lineWidth);
+
+      SizeF titleSize = g.MeasureString(this.Title, ArtPalette.DefaultBoldFont, Rectangle.Width - 45);
+      if (titleSize.Height + 10 > Rectangle.Height) {
+        headerHeight =  (int)titleSize.Height + 10;
+        this.UpdateLabels();
+      }
+
+      GraphicsPath path = new GraphicsPath();
+      path.AddArc(Rectangle.X, Rectangle.Y, 20, 20, -180, 90);
+      path.AddLine(Rectangle.X + 10, Rectangle.Y, Rectangle.X + Rectangle.Width - 10, Rectangle.Y);
+      path.AddArc(Rectangle.X + Rectangle.Width - 20, Rectangle.Y, 20, 20, -90, 90);
+      path.AddLine(Rectangle.X + Rectangle.Width, Rectangle.Y + 10, Rectangle.X + Rectangle.Width, Rectangle.Y + Rectangle.Height - 10);
+      path.AddArc(Rectangle.X + Rectangle.Width - 20, Rectangle.Y + Rectangle.Height - 20, 20, 20, 0, 90);
+      path.AddLine(Rectangle.X + Rectangle.Width - 10, Rectangle.Y + Rectangle.Height, Rectangle.X + 10, Rectangle.Y + Rectangle.Height);
+      path.AddArc(Rectangle.X, Rectangle.Y + Rectangle.Height - 20, 20, 20, 90, 90);
+      path.AddLine(Rectangle.X, Rectangle.Y + Rectangle.Height - 10, Rectangle.X, Rectangle.Y + 10);
+      //shadow
+      if (ArtPalette.EnableShadows) {
+        Region darkRegion = new Region(path);
+        darkRegion.Translate(5, 5);
+        g.FillRegion(ArtPalette.ShadowBrush, darkRegion);
+      }
+      //background
+      g.FillPath(Brush, path);
+
+      using (LinearGradientBrush gradientBrush = new LinearGradientBrush(Rectangle.Location, new Point(Rectangle.X + Rectangle.Width, Rectangle.Y), this.Color, Color.White)) {
+        Region gradientRegion = new Region(path);
+        g.FillRegion(gradientBrush, gradientRegion);
+      }
+
+      if (!this.Collapsed) {
+        TextStyle textStyle = new TextStyle(Color.Black, new Font("Arial", 7), StringAlignment.Near, StringAlignment.Near);
+        StringFormat stringFormat = textStyle.StringFormat;
+        stringFormat.Trimming = StringTrimming.EllipsisWord;
+        stringFormat.FormatFlags = StringFormatFlags.LineLimit;
+        Rectangle rect;
+
+        for (int i = 0; i < this.labels.Count; i++) {
+          rect = new Rectangle(Rectangle.X + 25, Rectangle.Y + headerHeight + i * (LABEL_HEIGHT + LABEL_SPACING), LABEL_WIDTH, LABEL_HEIGHT);
+          g.DrawString(textStyle.GetFormattedText(this.labels[i]), textStyle.Font, textStyle.GetBrush(), rect, stringFormat);
+        }
+      }
+
+      //the border
+      g.DrawPath(pen, path);
+
+      //the title
+      g.DrawString(this.Title, ArtPalette.DefaultBoldFont, Brushes.Black, new Rectangle(Rectangle.X + 25, Rectangle.Y + 5, Rectangle.Width - 45, Rectangle.Height - 5));
+
+
+      //the material
+      foreach (IPaintable material in Children)
+        material.Paint(g);
+
+      //the connectors
+      if (this.ShowConnectors) {
+        for (int k = 0; k < Connectors.Count; k++)
+          Connectors[k].Paint(g);
+      }
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/OperatorShapeInfo.cs
===================================================================
--- /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/OperatorShapeInfo.cs	(revision 3386)
+++ /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/OperatorShapeInfo.cs	(revision 3386)
@@ -0,0 +1,228 @@
+﻿#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.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using System.Drawing;
+using Netron.Diagramming.Core;
+using System.Windows.Forms;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Operators.Views.GraphVisualization {
+  [StorableClass]
+  internal class OperatorShapeInfo : ShapeInfo, IOperatorShapeInfo {
+    [Storable]
+    private List<string> labels;
+
+    public OperatorShapeInfo()
+      : base(typeof(OperatorShape)) {
+      this.connectorNames = new List<string>();
+      this.labels = new List<string>();
+    }
+
+    public OperatorShapeInfo(IEnumerable<string> connectorNames)
+      : this() {
+      foreach (string connectorName in connectorNames)
+        this.connectorNames.Add(connectorName);
+    }
+
+    public OperatorShapeInfo(IEnumerable<string> connectorNames, IEnumerable<string> labels)
+      : this(connectorNames) {
+      foreach (string label in labels)
+        this.labels.Add(label);
+    }
+
+    public void AddConnector(string connectorName) {
+      if (!this.connectorNames.Contains(connectorName)) {
+        this.connectorNames.Add(connectorName);
+        this.OnChanged();
+      }
+    }
+
+    public void RemoveConnector(string connectorName) {
+      if (this.connectorNames.Contains(connectorName)) {
+        this.connectorNames.Remove(connectorName);
+        this.OnChanged();
+      }
+    }
+
+    public void UpdateLabels(IEnumerable<string> labels) {
+      this.labels = new List<string>(labels);
+      this.OnChanged();
+    }
+
+    [Storable]
+    private List<string> connectorNames;
+    public override IEnumerable<string> Connectors {
+      get { return this.connectorNames; }
+    }
+
+    [Storable]
+    private bool collapsed;
+    public bool Collapsed {
+      get { return this.collapsed; }
+      set {
+        if (this.collapsed != value) {
+          this.collapsed = value;
+          this.OnChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private string title;
+    public string Title {
+      get { return this.title; }
+      set {
+        if (this.title != value) {
+          this.title = value;
+          this.OnChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private Color color;
+    public Color Color {
+      get { return this.color; }
+      set {
+        if (this.color != value) {
+          this.color = value;
+          this.OnChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private Color lineColor;
+    public Color LineColor {
+      get { return this.lineColor; }
+      set {
+        if (this.lineColor != value) {
+          this.lineColor = value;
+          this.OnChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private float lineWidth;
+    public float LineWidth {
+      get { return this.lineWidth; }
+      set {
+        if (this.lineWidth != value) {
+          this.lineWidth = value;
+          this.OnChanged();
+        }
+      }
+    }
+
+    private Bitmap icon;
+    public Bitmap Icon {
+      get { return this.icon; }
+      set {
+        if (this.icon != value) {
+          this.icon = value;
+          this.OnChanged();
+        }
+      }
+    }
+
+    public override IShape CreateShape() {
+      OperatorShape shape = (OperatorShape)base.CreateShape();
+      shape.Title = this.Title;
+      shape.Color = this.Color;
+      shape.LineColor = this.LineColor;
+      shape.LineWidth = this.LineWidth;
+      shape.Icon = this.Icon;
+      shape.Collapsed = this.Collapsed;
+      foreach (string connectorName in this.connectorNames)
+        shape.AddConnector(connectorName);
+
+      shape.UpdateLabels(this.labels);
+      return shape;
+    }
+
+    public override void UpdateShape(IShape shape) {
+      base.UpdateShape(shape);
+      OperatorShape operatorShape = (OperatorShape)shape;
+      operatorShape.Title = this.Title;
+      operatorShape.Color = this.Color;
+      operatorShape.LineColor = this.LineColor;
+      operatorShape.LineWidth = this.LineWidth;
+      operatorShape.Icon = this.Icon;
+      operatorShape.Collapsed = this.Collapsed;
+
+      int i = 0;
+      int j = 0;
+      //remove old connectors and skip correct connectors
+      List<string> oldConnectorNames = operatorShape.AdditionalConnectorNames.ToList();
+      while (i < this.connectorNames.Count && j < oldConnectorNames.Count) {
+        if (this.connectorNames[i] != oldConnectorNames[j]) {
+          operatorShape.RemoveConnector(oldConnectorNames[j]);
+        } else
+          i++;
+        j++;
+      }
+      //remove remaining old connectors
+      for (; j < oldConnectorNames.Count; j++)
+        operatorShape.RemoveConnector(oldConnectorNames[j]);
+
+      //add new connectors
+      for (; i < this.connectorNames.Count; i++)
+        operatorShape.AddConnector(this.connectorNames[i]);
+
+      operatorShape.UpdateLabels(this.labels);
+    }
+
+    public override void UpdateShapeInfo(IShape shape) {
+      base.UpdateShapeInfo(shape);
+      OperatorShape operatorShape = (OperatorShape)shape;
+      this.Title = operatorShape.Title;
+      this.Color = operatorShape.Color;
+      this.LineColor = operatorShape.LineColor;
+      this.LineWidth = operatorShape.LineWidth;
+      this.Icon = operatorShape.Icon;
+      this.Collapsed = operatorShape.Collapsed;
+
+      //TODO update Connector and labels;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      OperatorShapeInfo clone = (OperatorShapeInfo)base.Clone(cloner);
+      clone.collapsed = this.collapsed;
+      clone.color = this.color;
+      clone.lineColor = this.lineColor;
+      clone.lineWidth = this.lineWidth;
+      clone.title = this.title;
+      clone.icon = (Bitmap)this.icon.Clone();
+
+      clone.connectorNames = new List<string>(this.connectorNames);
+      clone.labels = new List<string>(this.labels);
+
+      return clone;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/OperatorShapeInfoFactory.cs
===================================================================
--- /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/OperatorShapeInfoFactory.cs	(revision 3386)
+++ /trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/OperatorShapeInfoFactory.cs	(revision 3386)
@@ -0,0 +1,50 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using Netron.Diagramming.Core;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+
+namespace HeuristicLab.Operators.Views.GraphVisualization {
+  internal static class OperatorShapeInfoFactory {
+    public const string PredecessorConnector = "Predecessor";
+    public static IOperatorShapeInfo CreateOperatorShapeInfo(IOperator op) {
+      IEnumerable<string> operatorParameterNames = op.Parameters.Where(p => p is IValueParameter<IOperator>).Select(p => p.Name);
+      IEnumerable<string> paramaterNameValues = op.Parameters.Where(p => !(p is IValueParameter<IOperator>)).Select(p => p.ToString());
+
+      OperatorShapeInfo operatorShapeInfo = new OperatorShapeInfo(operatorParameterNames, paramaterNameValues);
+      operatorShapeInfo.AddConnector(PredecessorConnector);
+      operatorShapeInfo.Collapsed = true;
+      operatorShapeInfo.Title = op.Name;
+      operatorShapeInfo.Color = Color.LightBlue;
+      operatorShapeInfo.LineWidth = 1;
+      operatorShapeInfo.LineColor = Color.Black;
+      operatorShapeInfo.Icon = new Bitmap(op.ItemImage);
+
+      return operatorShapeInfo;
+    }
+  }
+}
