Index: /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization.Views/3.3/ChartModes/AddNodesChartMode.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization.Views/3.3/ChartModes/AddNodesChartMode.cs	(revision 13134)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization.Views/3.3/ChartModes/AddNodesChartMode.cs	(revision 13135)
@@ -24,4 +24,5 @@
 using System.Drawing.Drawing2D;
 using System.Windows.Forms;
+using HeuristicLab.Common;
 using HeuristicLab.Common.Resources;
 using HeuristicLab.Core.Networks;
@@ -36,18 +37,18 @@
 
     public override Image Image { get { return VSImageLibrary.RadialChart; } }
-    public override string ToolTip { get { return "Add Nodes"; } }
+    public override string Text { get { return "Add &Nodes"; } }
+    public override string ToolTipText { get { return "Add Nodes"; } }
 
     public AddNodesChartMode(ChartControl control) : base(control) { }
 
     public override void HandleOnMouseMove(object sender, MouseEventArgs e) {
-      base.HandleOnMouseMove(sender, e);
+      try {
+        if (!(chartControl.Tag is IUserDefinedNetwork)) return;
 
-      if (!(chartControl.Tag is IUserDefinedNetwork)) return;
-
-      try {
-        chartControl.PictureBox.Refresh();
+        chartControl.RefreshPicture();
 
         var size = new Size(200, 100);
-        using (var graphics = chartControl.PictureBox.CreateGraphics())
+
+        using (var graphics = chartControl.CreatePictureGraphics())
         using (var pen = new Pen(Color.Gray) { DashStyle = DashStyle.Dash }) {
           graphics.DrawRectangle(pen,
@@ -57,32 +58,38 @@
             size.Height);
         }
+
       } finally {
-        chartControl.PictureBox.Update();
+        chartControl.UpdatePicture();
+        base.HandleOnMouseMove(sender, e);
       }
     }
 
-    public override void HandleOnMouseUp(object sender, MouseEventArgs e) {
-      base.HandleOnMouseUp(sender, e);
+    public override void HandleOnMouseDown(object sender, MouseEventArgs e) {
+      try {
+        switch (e.Button) {
+          case MouseButtons.Left:
+            var network = chartControl.Tag as IUserDefinedNetwork;
+            if (network == null) return;
 
-      switch (e.Button) {
-        case MouseButtons.Left:
-          var network = chartControl.Tag as IUserDefinedNetwork;
-          if (network == null) return;
+            var node = CreateNode(network);
+            if (node == null) return;
 
-          var node = CreateNode(network);
-          var visualizableNode = node as IVisualizableNode;
-          if (visualizableNode == null) return;
+            var center = chartControl.Chart.TransformPixelToWorld(e.Location);
+            var size = chartControl.Chart.TransformPixelToWorld(new Size(100, 50));
+            var lowerLeft = center - new Offset(size);
+            var upperRight = center + new Offset(size);
+            node.VisualProperties = new NodeVisualProperties(new Point2D<double>(lowerLeft.X, lowerLeft.Y),
+                                                             new Point2D<double>(upperRight.X, upperRight.Y));
+            network.Nodes.Add(node);
+            break;
+        }
+      } finally {
+        base.HandleOnMouseDown(sender, e);
+      }
+    }
 
-          var center = chartControl.Chart.TransformPixelToWorld(e.Location);
-          var size = chartControl.Chart.TransformPixelToWorld(new Size(200, 100));
-
-          visualizableNode.VisualProperties.X = center.X;
-          visualizableNode.VisualProperties.Y = center.Y;
-          visualizableNode.VisualProperties.Width = size.Width;
-          visualizableNode.VisualProperties.Height = size.Height;
-
-          network.Nodes.Add(node);
-          break;
-      }
+    public override void HandleOnMouseLeave(object sender, EventArgs e) {
+      chartControl.RefreshPicture();
+      base.HandleOnMouseLeave(sender, e);
     }
 
Index: /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization.Views/3.3/ChartModes/AddPortsChartMode.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization.Views/3.3/ChartModes/AddPortsChartMode.cs	(revision 13134)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization.Views/3.3/ChartModes/AddPortsChartMode.cs	(revision 13135)
@@ -36,15 +36,14 @@
 
     public override Image Image { get { return VSImageLibrary.Interface; } }
-    public override string ToolTip { get { return "Add Ports"; } }
+    public override string Text { get { return "Add Por&ts"; } }
+    public override string ToolTipText { get { return "Add Ports"; } }
 
     public AddPortsChartMode(ChartControl control) : base(control) { }
 
     public override void HandleOnMouseMove(object sender, MouseEventArgs e) {
-      base.HandleOnMouseMove(sender, e);
+      try {
+        if (!(chartControl.Tag is IUserDefinedNetwork)) return;
 
-      if (!(chartControl.Tag is IUserDefinedNetwork)) return;
-
-      try {
-        chartControl.PictureBox.Refresh();
+        chartControl.RefreshPicture();
 
         var nodeRectangles = chartControl.Chart.GetAllPrimitives(e.Location).OfType<NodeRectangle>();
@@ -56,6 +55,9 @@
         var ur = chartControl.Chart.TransformWorldToPixel(nodeRectangle.UpperRight);
 
-        using (var graphics = chartControl.PictureBox.CreateGraphics())
-        using (var pen = new Pen(Color.Green) { Width = 2f }) {
+        var node = nodeRectangle.NetworkItem;
+        bool nodeValid = node is IAlgorithmNode || node is IUserDefinedNode;
+
+        using (var graphics = chartControl.CreatePictureGraphics())
+        using (var pen = new Pen(nodeValid ? Color.Green : Color.Red) { Width = 2f }) {
           graphics.DrawRectangle(pen,
             ll.X,
@@ -65,35 +67,38 @@
         }
       } finally {
-        chartControl.PictureBox.Update();
+        chartControl.UpdatePicture();
+        base.HandleOnMouseMove(sender, e);
       }
     }
 
-    public override void HandleOnMouseUp(object sender, MouseEventArgs e) {
-      base.HandleOnMouseUp(sender, e);
+    public override void HandleOnMouseDown(object sender, MouseEventArgs e) {
+      try {
+        switch (e.Button) {
+          case MouseButtons.Left:
+            if (!(chartControl.Tag is IUserDefinedNetwork)) return;
 
-      switch (e.Button) {
-        case MouseButtons.Left:
-          var network = chartControl.Tag as IUserDefinedNetwork;
-          if (network == null) return;
+            var nodeRectangles = chartControl.Chart.GetAllPrimitives(e.Location).OfType<NodeRectangle>();
+            var nodeRectangle = nodeRectangles.FirstOrDefault();
+            if (nodeRectangle == null) return;
 
-          var nodeRectangles = chartControl.Chart.GetAllPrimitives(e.Location).OfType<NodeRectangle>();
-          var nodeRectangle = nodeRectangles.FirstOrDefault();
-          if (nodeRectangle == null) return;
+            var node = nodeRectangle.NetworkItem;
+            bool nodeValid = node is IAlgorithmNode || node is IUserDefinedNode;
+            if (!nodeValid) return;
 
-          var node = nodeRectangle.NetworkItem;
-          var port = CreatePort(node);
+            var port = CreatePort(node);
+            if (port == null) return;
 
-          var algNode = node as IAlgorithmNode;
-          if (algNode != null) {
-            algNode.Ports.Add(port);
-            return;
-          }
+            var algNode = node as IAlgorithmNode;
+            if (algNode != null) {
+              algNode.Ports.Add(port);
+              return;
+            }
 
-          var userDefNode = node as IUserDefinedNode;
-          if (userDefNode != null) {
+            var userDefNode = (IUserDefinedNode)node;
             userDefNode.Ports.Add(port);
-            return;
-          }
-          break;
+            break;
+        }
+      } finally {
+        base.HandleOnMouseDown(sender, e);
       }
     }
Index: /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization.Views/3.3/ChartModes/ConnectPortsChartMode.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization.Views/3.3/ChartModes/ConnectPortsChartMode.cs	(revision 13134)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization.Views/3.3/ChartModes/ConnectPortsChartMode.cs	(revision 13135)
@@ -35,95 +35,106 @@
 
     public override Image Image { get { return VSImageLibrary.OrgChart; } }
-    public override string ToolTip { get { return "Connect Ports"; } }
+    public override string Text { get { return "&Connect Ports"; } }
+    public override string ToolTipText { get { return "Connect Ports"; } }
 
     public ConnectPortsChartMode(ChartControl control) : base(control) { }
 
-    public override void HandleOnMouseDown(object sender, MouseEventArgs e) {
-      base.HandleOnMouseDown(sender, e);
+    public override void HandleOnMouseMove(object sender, MouseEventArgs e) {
+      try {
+        if (!(chartControl.Tag is IUserDefinedNetwork)) return;
 
-      if (!(chartControl.Tag is IUserDefinedNetwork)) return;
+        chartControl.RefreshPicture();
 
-      switch (e.Button) {
-        case MouseButtons.Left:
-          var worldLocation = chartControl.Chart.TransformPixelToWorld(e.Location);
-          var nodeRectangles = chartControl.Chart.Group.Primitives.OfType<NodeRectangle>();
-          var portRectangles = nodeRectangles.SelectMany(x => x.NetworkItem.Ports.Select(x.GetPortRectangle));
-          startPortRectangle = portRectangles.FirstOrDefault(x => x.ContainsPoint(worldLocation));
-          break;
+        var worldLocation = chartControl.Chart.TransformPixelToWorld(e.Location);
+        var nodeRectangles = chartControl.Chart.Group.Primitives.OfType<NodeRectangle>();
+        var portRectangles = nodeRectangles.SelectMany(x => x.NetworkItem.Ports.Select(x.GetPortPrimitive));
+        var currentPortRectangle = (PortRectangle)portRectangles.FirstOrDefault(x => x.ContainsPoint(worldLocation));
+
+        // TODO: highlight allowed port connections only
+
+        using (var graphics = chartControl.CreatePictureGraphics()) {
+          Point startLocation = Point.Empty;
+          if (startPortRectangle != null) {
+            DrawCircleAroundPortRectangle(graphics, startPortRectangle, startPortRectangle.NetworkItem is IConnectablePort);
+            startLocation = chartControl.Chart.TransformWorldToPixel(startPortRectangle.Point);
+          }
+
+          Point endLocation = e.Location;
+          if (currentPortRectangle != null && (startPortRectangle != null || e.Button == MouseButtons.None)) {
+            DrawCircleAroundPortRectangle(graphics, currentPortRectangle, currentPortRectangle.NetworkItem is IConnectablePort);
+            endLocation = chartControl.Chart.TransformWorldToPixel(currentPortRectangle.Point);
+          }
+
+          bool connectionValid = startPortRectangle != null && startPortRectangle.NetworkItem is IConnectablePort;
+          connectionValid &= currentPortRectangle == null || currentPortRectangle.NetworkItem is IConnectablePort;
+
+          if (startPortRectangle != null)
+            DrawLineBetweenLocations(graphics, startLocation, endLocation, connectionValid);
+        }
+      } finally {
+        chartControl.UpdatePicture();
+        base.HandleOnMouseMove(sender, e);
       }
     }
 
-    public override void HandleOnMouseMove(object sender, MouseEventArgs e) {
-      base.HandleOnMouseMove(sender, e);
+    public override void HandleOnMouseDown(object sender, MouseEventArgs e) {
+      try {
+        var network = chartControl.Tag as IUserDefinedNetwork;
+        if (network == null) return;
 
-      if (!(chartControl.Tag is IUserDefinedNetwork)) return;
-
-      try {
-        chartControl.PictureBox.Refresh();
-
-        var worldLocation = chartControl.Chart.TransformPixelToWorld(e.Location);
-        var nodeRectangles = chartControl.Chart.Group.Primitives.OfType<NodeRectangle>();
-        var portRectangles = nodeRectangles.SelectMany(x => x.NetworkItem.Ports.Select(x.GetPortRectangle)).ToList();
-        var currentPortRectangle = portRectangles.FirstOrDefault(x => x.ContainsPoint(worldLocation));
-
-        // TODO: highlight allowed port connections only
-
-        Point startLocation = Point.Empty;
-        if (startPortRectangle != null) {
-          DrawCircleAroundPortRectangle(startPortRectangle);
-          startLocation = chartControl.Chart.TransformWorldToPixel(startPortRectangle.Point);
+        switch (e.Button) {
+          case MouseButtons.Left:
+            var worldLocation = chartControl.Chart.TransformPixelToWorld(e.Location);
+            var nodeRectangles = chartControl.Chart.Group.Primitives.OfType<NodeRectangle>();
+            var portRectangles = nodeRectangles.SelectMany(x => x.NetworkItem.Ports.Select(x.GetPortPrimitive));
+            startPortRectangle = (PortRectangle)portRectangles.FirstOrDefault(x => x.ContainsPoint(worldLocation));
+            break;
         }
-
-        Point endLocation = e.Location;
-        if (currentPortRectangle != null) {
-          DrawCircleAroundPortRectangle(currentPortRectangle);
-          endLocation = chartControl.Chart.TransformWorldToPixel(currentPortRectangle.Point);
-        }
-
-        if (startPortRectangle != null)
-          DrawLineBetweenLocations(startLocation, endLocation);
       } finally {
-        chartControl.PictureBox.Update();
+        base.HandleOnMouseDown(sender, e);
       }
     }
 
     public override void HandleOnMouseUp(object sender, MouseEventArgs e) {
-      base.HandleOnMouseUp(sender, e);
+      try {
+        var network = chartControl.Tag as IUserDefinedNetwork;
+        if (network == null) return;
 
-      if (!(chartControl.Tag is IUserDefinedNetwork)) return;
+        switch (e.Button) {
+          case MouseButtons.Left:
+            var worldLocation = chartControl.Chart.TransformPixelToWorld(e.Location);
+            var nodeRectangles = chartControl.Chart.Group.Primitives.OfType<NodeRectangle>();
+            var portRectangles = nodeRectangles.SelectMany(x => x.NetworkItem.Ports.Select(x.GetPortPrimitive));
+            endPortRectangle = (PortRectangle)portRectangles.FirstOrDefault(x => x.ContainsPoint(worldLocation));
 
-      switch (e.Button) {
-        case MouseButtons.Left:
-          var worldLocation = chartControl.Chart.TransformPixelToWorld(e.Location);
-          var nodeRectangles = chartControl.Chart.Group.Primitives.OfType<NodeRectangle>();
-          var portRectangles = nodeRectangles.SelectMany(x => x.NetworkItem.Ports.Select(x.GetPortRectangle)).ToList();
-          endPortRectangle = portRectangles.FirstOrDefault(x => x.ContainsPoint(worldLocation));
+            if (startPortRectangle == endPortRectangle || startPortRectangle == null || endPortRectangle == null) {
+              startPortRectangle = null;
+              endPortRectangle = null;
+              return;
+            }
 
-          if (startPortRectangle == endPortRectangle && startPortRectangle == null || endPortRectangle == null) {
+            var startPort = (IConnectablePort)startPortRectangle.NetworkItem;
+            var endPort = (IConnectablePort)endPortRectangle.NetworkItem;
+
+            // TODO: check if port connection is allowed
+
+            startPort.ConnectedPort = endPort;
+
             startPortRectangle = null;
             endPortRectangle = null;
-            return;
-          }
-
-          var startPort = (IConnectablePort)startPortRectangle.NetworkItem;
-          var endPort = (IConnectablePort)endPortRectangle.NetworkItem;
-
-          // TODO: check if port connection is allowed
-
-          startPort.ConnectedPort = endPort;
-
-          startPortRectangle = null;
-          endPortRectangle = null;
-          break;
+            break;
+        }
+      } finally {
+        base.HandleOnMouseUp(sender, e);
       }
     }
 
-    protected virtual void DrawCircleAroundPortRectangle(PortRectangle portRectangle) {
+    #region Helpers
+    protected virtual void DrawCircleAroundPortRectangle(Graphics graphics, PortRectangle portRectangle, bool valid) {
       var centerP = chartControl.Chart.TransformWorldToPixel(portRectangle.Point);
       int a = (int)Math.Round(portRectangle.Size.Width / 2.0 * Math.Sqrt(2));
       int b = (int)Math.Round(portRectangle.Size.Height / 2.0 * Math.Sqrt(2));
 
-      using (var graphics = chartControl.PictureBox.CreateGraphics())
-      using (var pen = new Pen(Color.Green) { Width = 2f }) {
+      using (var pen = new Pen(valid ? Color.Green : Color.Red) { Width = 2f }) {
         graphics.DrawEllipse(pen,
           centerP.X - a,
@@ -134,9 +145,9 @@
     }
 
-    protected virtual void DrawLineBetweenLocations(Point startLocation, Point endLocation) {
-      using (var graphics = chartControl.PictureBox.CreateGraphics())
-      using (var pen = new Pen(Color.Green) { DashStyle = DashStyle.Dash, Width = 2f })
+    protected virtual void DrawLineBetweenLocations(Graphics graphics, Point startLocation, Point endLocation, bool valid) {
+      using (var pen = new Pen(valid ? Color.Green : Color.Red) { DashStyle = DashStyle.Dash, Width = 2f })
         graphics.DrawLine(pen, startLocation.X, startLocation.Y, endLocation.X, endLocation.Y);
     }
+    #endregion
   }
 }
Index: anches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization.Views/3.3/ChartModes/NetworkSelectChartMode.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization.Views/3.3/ChartModes/NetworkSelectChartMode.cs	(revision 13134)
+++ 	(revision )
@@ -1,90 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Linq;
-using System.Windows.Forms;
-using HeuristicLab.Core.Networks;
-using HeuristicLab.Visualization;
-
-namespace HeuristicLab.Networks.Views.NetworkVisualization.Views {
-  public class NetworkSelectChartMode : SelectChartMode {
-    public NetworkSelectChartMode(ChartControl control) : base(control) { }
-
-    public override void HandleOnKeyDown(object sender, KeyEventArgs e) {
-      switch (e.KeyCode) {
-        case Keys.Delete:
-          if (e.KeyCode == Keys.Delete) {
-            try {
-              chartControl.SuspendRendering();
-              var primitives = chartControl.Chart.Group.SelectedPrimitives.ToList();
-              foreach (var connectionLine in primitives.OfType<ConnectionLine>()) {
-                chartControl.Chart.Group.Remove(connectionLine);
-                var startPortRectangle = connectionLine.StartPortRectangle;
-                if (startPortRectangle != null) {
-                  var startPort = (IMessagePort)startPortRectangle.NetworkItem;
-                  if (startPort != null) startPort.ConnectedPort = null;
-                }
-              }
-
-              foreach (var nodeRectangle in primitives.OfType<NodeRectangle>()) {
-                chartControl.Chart.Group.Remove(nodeRectangle);
-                var node = nodeRectangle.NetworkItem;
-                if (node != null) {
-                  var deletedPorts = node.Ports.OfType<IMessagePort>().ToList();
-                  foreach (var port in deletedPorts)
-                    port.ConnectedPort = null;
-
-                  var connectionLines = chartControl.Chart.Group.Primitives.OfType<ConnectionLine>();
-                  foreach (var connectionLine in connectionLines) {
-                    var startPortRectangle = connectionLine.StartPortRectangle;
-                    var endPortRectangle = connectionLine.EndPortRectangle;
-                    if (startPortRectangle != null && endPortRectangle != null) {
-                      var startPort = (IMessagePort)startPortRectangle.NetworkItem;
-                      var endPort = (IMessagePort)endPortRectangle.NetworkItem;
-                      if (startPort != null && endPort != null && deletedPorts.Contains(endPort))
-                        startPort.ConnectedPort = null;
-                    }
-                  }
-
-                  var parent = node.Parent;
-                  if (parent != null)
-                    parent.Nodes.Remove(node);
-                }
-              }
-            } finally { chartControl.ResumeRendering(); }
-          }
-          break;
-      }
-    }
-
-    public override void HandleOnMouseDoubleClick(object sender, MouseEventArgs e) {
-      base.HandleOnMouseDoubleClick(sender, e);
-
-      switch (e.Button) {
-        case MouseButtons.Left:
-          var p = chartControl.Chart.GetPrimitive(e.Location) as NodeRectangle;
-          if (p != null)
-            MainForm.MainFormManager.MainForm.ShowContent(p.NetworkItem);
-          break;
-      }
-    }
-  }
-}
Index: /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization.Views/3.3/ChartModes/SelectChartMode.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization.Views/3.3/ChartModes/SelectChartMode.cs	(revision 13135)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization.Views/3.3/ChartModes/SelectChartMode.cs	(revision 13135)
@@ -0,0 +1,199 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Core.Networks;
+using HeuristicLab.Networks.Programmable;
+using HeuristicLab.Visualization;
+
+namespace HeuristicLab.Networks.Views.NetworkVisualization.Views {
+  public class SelectChartMode : Visualization.SelectChartMode {
+    protected PortRectangle selectedPortRectangle;
+    protected NodeRectangle constrainingNodeRectangle;
+
+    public SelectChartMode(ChartControl control) : base(control) { }
+
+    protected override void OnDeselected() {
+      try {
+        chartControl.SuspendRendering();
+        if (selectedPortRectangle != null) {
+          selectedPortRectangle.Selected = false;
+          selectedPortRectangle = null;
+          constrainingNodeRectangle = null;
+        }
+      } finally {
+        chartControl.ResumeRendering();
+        base.OnDeselected();
+      }
+    }
+
+    public override void HandleOnKeyDown(object sender, KeyEventArgs e) {
+      try {
+        if (!(chartControl.Tag is IUserDefinedNetwork)) return;
+
+        switch (e.KeyCode) {
+          case Keys.Delete:
+            chartControl.SuspendRendering();
+
+            var connectionLines = chartControl.Chart.Group.Primitives.OfType<ConnectionLine>().ToList();
+            var nodeRectangles = chartControl.Chart.Group.Primitives.OfType<NodeRectangle>().ToList();
+            var portRectangles = nodeRectangles.SelectMany(x => x.NetworkItem.Ports.Select(x.GetPortPrimitive)).OfType<PortRectangle>().ToList();
+
+            var deletedNodes = new HashSet<INode>();
+            var deletedPorts = new HashSet<IMessagePort>();
+
+            foreach (var nodeRectangle in nodeRectangles) {
+              if (nodeRectangle.Selected) {
+                var node = nodeRectangle.NetworkItem;
+                if (node == null) continue;
+                deletedNodes.Add(node);
+                foreach (var port in node.Ports.OfType<IMessagePort>())
+                  deletedPorts.Add(port);
+              }
+            }
+
+            foreach (var portRectangle in portRectangles) {
+              if (portRectangle.Selected) {
+                var port = portRectangle.NetworkItem as IMessagePort;
+                if (port == null) continue;
+                port.Parent.Ports.Remove(port);
+                deletedPorts.Add(port);
+              }
+            }
+
+            selectedPortRectangle = null;
+
+            foreach (var connectionLine in connectionLines) {
+              var startPortRectangle = connectionLine.StartPortRectangle;
+              var endPortRectangle = connectionLine.EndPortRectangle;
+              if (startPortRectangle == null || endPortRectangle == null) continue;
+
+              var startPort = startPortRectangle.NetworkItem as IMessagePort;
+              var endPort = endPortRectangle.NetworkItem as IMessagePort;
+              if (startPort == null || endPort == null) continue;
+
+              if (connectionLine.Selected || deletedPorts.Contains(startPort) || deletedPorts.Contains(endPort))
+                startPort.ConnectedPort = null;
+            }
+
+            foreach (var node in deletedNodes)
+              node.Parent.Nodes.Remove(node);
+            break;
+        }
+      } finally {
+        chartControl.ResumeRendering();
+      }
+    }
+
+    public override void HandleOnMouseDown(object sender, MouseEventArgs e) {
+      try {
+        switch (e.Button) {
+          case MouseButtons.Left:
+            chartControl.SuspendRendering();
+
+            if (selectedPortRectangle != null) {
+              selectedPortRectangle.Selected = false;
+              selectedPortRectangle = null;
+              constrainingNodeRectangle = null;
+            }
+
+            var worldLocation = chartControl.Chart.TransformPixelToWorld(e.Location);
+            var nodeRectangles = chartControl.Chart.Group.Primitives.OfType<NodeRectangle>();
+            foreach (var nodeRectangle in nodeRectangles) {
+              var node = nodeRectangle.NetworkItem;
+              var portRectangles = node.Ports.Select(nodeRectangle.GetPortPrimitive).OfType<PortRectangle>();
+              foreach (var portRectangle in portRectangles) {
+                portRectangle.Selected = selectedPortRectangle == null && portRectangle.ContainsPoint(worldLocation);
+                if (portRectangle.Selected) {
+                  selectedPortRectangle = portRectangle;
+                  constrainingNodeRectangle = nodeRectangle;
+                }
+              }
+            }
+
+            if (selectedPortRectangle != null)
+              foreach (var sp in chartControl.Chart.Group.SelectedPrimitives)
+                sp.Selected = false;
+            else
+              base.HandleOnMouseDown(sender, e);
+            break;
+        }
+      } finally {
+        chartControl.ResumeRendering();
+      }
+    }
+
+    public override void HandleOnMouseMove(object sender, MouseEventArgs e) {
+      if (selectedPortRectangle != null) {
+        switch (e.Button) {
+          case MouseButtons.Left:
+            var point = chartControl.Chart.TransformPixelToWorld(e.Location);
+            var lowerLeft = constrainingNodeRectangle.LowerLeft;
+            var upperRight = constrainingNodeRectangle.UpperRight;
+
+            if (point.X < lowerLeft.X) point.X = lowerLeft.X;
+            else if (point.X > upperRight.X) point.X = upperRight.X;
+            if (point.Y < lowerLeft.Y) point.Y = lowerLeft.Y;
+            else if (point.Y > upperRight.Y) point.Y = upperRight.Y;
+
+            double dS = lowerLeft.Y - point.Y;
+            double dW = lowerLeft.X - point.X;
+
+            double dX = upperRight.X - point.X; // dE
+            if (Math.Abs(dX) > Math.Abs(dW)) dX = dW;
+            double dY = upperRight.Y - point.Y; // dN
+            if (Math.Abs(dY) > Math.Abs(dS)) dY = dS;
+
+            var offset = Offset.Empty;
+            if (Math.Abs(dX) < Math.Abs(dY)) offset.DX = dX;
+            else offset.DY = dY;
+
+            point = point + offset;
+            offset = point - selectedPortRectangle.Point;
+            try {
+              chartControl.SuspendRendering();
+              selectedPortRectangle.Move(offset);
+            } finally { chartControl.ResumeRendering(); }
+            break;
+        }
+      } else
+        base.HandleOnMouseMove(sender, e);
+      previousLocation = e.Location;
+    }
+
+    public override void HandleOnMouseDoubleClick(object sender, MouseEventArgs e) {
+      try {
+        switch (e.Button) {
+          case MouseButtons.Left:
+            var nodeRectangle = chartControl.Chart.GetPrimitive(e.Location) as NodeRectangle;
+            if (nodeRectangle != null)
+              MainForm.MainFormManager.MainForm.ShowContent(nodeRectangle.NetworkItem);
+            break;
+        }
+      } finally {
+        base.HandleOnMouseDoubleClick(sender, e);
+      }
+    }
+  }
+}
Index: /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization.Views/3.3/HeuristicLab.Networks.Views.NetworkVisualization.Views-3.3.csproj
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization.Views/3.3/HeuristicLab.Networks.Views.NetworkVisualization.Views-3.3.csproj	(revision 13134)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization.Views/3.3/HeuristicLab.Networks.Views.NetworkVisualization.Views-3.3.csproj	(revision 13135)
@@ -120,5 +120,5 @@
     <Compile Include="ChartModes\AddNodesChartMode.cs" />
     <Compile Include="ChartModes\AddPortsChartMode.cs" />
-    <Compile Include="ChartModes\NetworkSelectChartMode.cs" />
+    <Compile Include="ChartModes\SelectChartMode.cs" />
     <Compile Include="ChartModes\ConnectPortsChartMode.cs" />
     <Compile Include="NetworkVisualizationView.cs">
Index: /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization.Views/3.3/NetworkVisualizationView.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization.Views/3.3/NetworkVisualizationView.cs	(revision 13134)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization.Views/3.3/NetworkVisualizationView.cs	(revision 13135)
@@ -20,4 +20,5 @@
 #endregion
 
+using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Collections;
@@ -28,4 +29,5 @@
 using HeuristicLab.Networks.Views.NetworkVisualization.Views.ChartModes;
 using HeuristicLab.Visualization;
+using HeuristicLab.Visualization.ChartModes;
 
 namespace HeuristicLab.Networks.Views.NetworkVisualization.Views {
@@ -34,4 +36,6 @@
   [Content(typeof(INetwork), false)]
   public partial class NetworkVisualizationView : NetworkItemView {
+    private Dictionary<string, IPrimitive> primitiveDict = new Dictionary<string, IPrimitive>();
+
     public new INetwork Content {
       get { return (INetwork)base.Content; }
@@ -42,8 +46,9 @@
       InitializeComponent();
 
-      var initialMode = new NetworkSelectChartMode(chartControl);
+      var initialMode = new SelectChartMode(chartControl);
       chartControl.AddChartModes(
         initialMode,
-        new MoveChartMode(chartControl),
+        new PanChartMode(chartControl),
+        new RulerChartMode(chartControl),
         new ZoomInChartMode(chartControl),
         new ZoomOutChartMode(chartControl),
@@ -81,46 +86,4 @@
     }
 
-    private void UpdateContent() {
-      if (Content == null) return;
-
-      chartControl.Chart.Group.Clear();
-      DrawNodes(Content.Nodes);
-      ConnectNodes(Content.Nodes);
-    }
-
-    private void DrawNodes(IKeyedItemCollection<string, INode> nodes) {
-      var chart = chartControl.Chart;
-
-      foreach (var node in nodes.OfType<IVisualizableNode>()) {
-        var nodeShape = new NodeRectangle(chart, node);
-        chart.Group.Add(nodeShape);
-      }
-    }
-
-    private void ConnectNodes(IKeyedItemCollection<string, INode> nodes) {
-      var chart = chartControl.Chart;
-      var nodeRectangles = chart.Group.Primitives.OfType<NodeRectangle>();
-      var node2NodeShape = nodeRectangles.ToDictionary(k => k.NetworkItem.Name, v => v);
-
-      foreach (var node in nodes) {
-        var nodeShape = node2NodeShape[node.Name];
-        foreach (var port in node.Ports.OfType<IConnectablePort>()) {
-          var connectedPort = port.ConnectedPort as IConnectablePort;
-          if (connectedPort == null) continue;
-
-          var connectedNode = connectedPort.Parent;
-          if (connectedNode == null) continue;
-
-          var connectedShape = node2NodeShape[connectedNode.Name];
-          var leftPortRectangle = nodeShape.GetPortRectangle(port);
-          var rightPortRectangle = connectedShape.GetPortRectangle(connectedPort);
-
-          var connectionShape = new ConnectionLine(chart, leftPortRectangle, rightPortRectangle);
-
-          chart.Group.Add(connectionShape);
-        }
-      }
-    }
-
     #region Event Handlers
     #region Nodes Event Handlers
@@ -149,4 +112,54 @@
     #endregion
     #endregion
+
+    #region Helpers
+    private void UpdateContent() {
+      if (Content == null) return;
+
+      chartControl.SuspendRendering();
+      try {
+        chartControl.Chart.Group.Clear();
+        DrawNodes(Content.Nodes);
+        ConnectNodes(Content.Nodes);
+      } finally {
+        chartControl.ResumeRendering();
+      }
+    }
+
+    private void DrawNodes(IKeyedItemCollection<string, INode> nodes) {
+      foreach (var node in nodes) {
+        var defaultPrimitive = PrimitiveAttribute.CreateDefaultPrimitive(node.GetType(), chartControl.Chart, node);
+        if (defaultPrimitive == null) continue;
+        chartControl.Chart.Group.Add(defaultPrimitive);
+        primitiveDict[node.Name] = defaultPrimitive;
+      }
+    }
+
+    private void ConnectNodes(IKeyedItemCollection<string, INode> nodes) {
+      var chart = chartControl.Chart;
+      foreach (var node in nodes) {
+        var nodeRectangle = primitiveDict[node.Name] as NodeRectangle;
+        if (nodeRectangle == null) continue;
+
+        foreach (var port in node.Ports.OfType<IConnectablePort>()) {
+          var connectedPort = port.ConnectedPort as IConnectablePort;
+          if (connectedPort == null) continue;
+
+          var connectedNode = connectedPort.Parent;
+          if (connectedNode == null) continue;
+
+          var connectedRectangle = primitiveDict[connectedNode.Name] as NodeRectangle;
+          if (connectedRectangle == null) continue;
+
+          var leftPortRectangle = (PortRectangle)nodeRectangle.GetPortPrimitive(port);
+          var rightPortRectangle = (PortRectangle)connectedRectangle.GetPortPrimitive(connectedPort);
+
+          var connectionShape = new ConnectionLine(chart, leftPortRectangle, rightPortRectangle);
+
+          chart.Group.Add(connectionShape);
+        }
+      }
+    }
+    #endregion
   }
 }
Index: /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/HeuristicLab.Networks.Views.NetworkVisualization-3.3.csproj
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/HeuristicLab.Networks.Views.NetworkVisualization-3.3.csproj	(revision 13134)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/HeuristicLab.Networks.Views.NetworkVisualization-3.3.csproj	(revision 13135)
@@ -86,4 +86,7 @@
       <Private>False</Private>
     </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
     <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -98,13 +101,12 @@
     <Reference Include="System.Core" />
     <Reference Include="System.Drawing" />
-    <Reference Include="System.Windows.Forms" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Net.Http" />
-    <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Interfaces\INetworkItemPrimitive.cs" />
+    <Compile Include="INodeVisualProperties.cs" />
+    <Compile Include="IPortVisualProperties.cs" />
+    <Compile Include="NodeVisualProperties.cs" />
+    <Compile Include="Orientation.cs" />
+    <Compile Include="PortVisualProperties.cs" />
     <Compile Include="Primitives\ConnectionLine.cs" />
     <Compile Include="Plugin.cs" />
@@ -123,4 +125,5 @@
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>
Index: /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/INodeVisualProperties.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/INodeVisualProperties.cs	(revision 13135)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/INodeVisualProperties.cs	(revision 13135)
@@ -0,0 +1,30 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core.Networks;
+
+namespace HeuristicLab.Networks.Views.NetworkVisualization {
+  public interface INodeVisualProperties : IVisualProperties {
+    Point2D<double> LowerLeft { get; set; }
+    Point2D<double> UpperRight { get; set; }
+  }
+}
Index: /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/IPortVisualProperties.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/IPortVisualProperties.cs	(revision 13135)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/IPortVisualProperties.cs	(revision 13135)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core.Networks;
+
+namespace HeuristicLab.Networks.Views.NetworkVisualization {
+  public interface IPortVisualProperties : IVisualProperties {
+    Orientation Orientation { get; set; }
+    double Offset { get; set; }
+  }
+}
Index: /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/NodeVisualProperties.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/NodeVisualProperties.cs	(revision 13135)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/NodeVisualProperties.cs	(revision 13135)
@@ -0,0 +1,70 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core.Networks;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Networks.Views.NetworkVisualization {
+  [StorableClass]
+  public sealed class NodeVisualProperties : VisualProperties, INodeVisualProperties {
+    [Storable]
+    private Point2D<double> lowerLeft;
+    public Point2D<double> LowerLeft {
+      get { return lowerLeft; }
+      set {
+        if (lowerLeft == value) return;
+        lowerLeft = value;
+        OnChanged();
+      }
+    }
+
+    [Storable]
+    private Point2D<double> upperRight;
+    public Point2D<double> UpperRight {
+      get { return upperRight; }
+      set {
+        if (upperRight == value) return;
+        upperRight = value;
+        OnChanged();
+      }
+    }
+
+    #region Constructors & Cloning
+    [StorableConstructor]
+    private NodeVisualProperties(bool deserializing) : base(deserializing) { }
+    private NodeVisualProperties(NodeVisualProperties original, Cloner cloner)
+      : base(original, cloner) {
+      lowerLeft = original.lowerLeft;
+      upperRight = original.upperRight;
+    }
+
+    public NodeVisualProperties(Point2D<double> lowerLeft, Point2D<double> upperRight) {
+      this.lowerLeft = lowerLeft;
+      this.upperRight = upperRight;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new NodeVisualProperties(this, cloner);
+    }
+    #endregion
+  }
+}
Index: /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/Orientation.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/Orientation.cs	(revision 13135)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/Orientation.cs	(revision 13135)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Networks.Views.NetworkVisualization {
+  public enum Orientation {
+    North,
+    East,
+    South,
+    West
+  }
+}
Index: /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/PortVisualProperties.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/PortVisualProperties.cs	(revision 13135)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/PortVisualProperties.cs	(revision 13135)
@@ -0,0 +1,70 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core.Networks;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Networks.Views.NetworkVisualization {
+  [StorableClass]
+  public sealed class PortVisualProperties : VisualProperties, IPortVisualProperties {
+    [Storable]
+    private Orientation orientation;
+    public Orientation Orientation {
+      get { return orientation; }
+      set {
+        if (orientation == value) return;
+        orientation = value;
+        OnChanged();
+      }
+    }
+
+    [Storable]
+    private double offset;
+    public double Offset {
+      get { return offset; }
+      set {
+        if (offset == value) return;
+        offset = value;
+        OnChanged();
+      }
+    }
+
+    #region Constructors & Cloning
+    [StorableConstructor]
+    private PortVisualProperties(bool deserializing) : base(deserializing) { }
+    private PortVisualProperties(PortVisualProperties original, Cloner cloner)
+      : base(original, cloner) {
+      orientation = original.orientation;
+      offset = original.offset;
+    }
+
+    public PortVisualProperties(Orientation orientation, double offset) {
+      this.orientation = orientation;
+      this.offset = offset;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PortVisualProperties(this, cloner);
+    }
+    #endregion
+  }
+}
Index: /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/Primitives/ConnectionLine.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/Primitives/ConnectionLine.cs	(revision 13134)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/Primitives/ConnectionLine.cs	(revision 13135)
@@ -59,18 +59,8 @@
     protected virtual void RegisterPortRectangleEvents(PortRectangle portRectangle) {
       portRectangle.RedrawRequired += PortRectangle_RedrawRequired;
-      portRectangle.NetworkItemChanged += PortRectangleNetworkItemChanged;
-      if (portRectangle.NetworkItem != null) {
-        var port = portRectangle.NetworkItem;
-        port.NameChanged += Port_NameChanged;
-      }
     }
 
     protected virtual void DeregisterPortRectangleEvents(PortRectangle portRectangle) {
       portRectangle.RedrawRequired -= PortRectangle_RedrawRequired;
-      portRectangle.NetworkItemChanged -= PortRectangleNetworkItemChanged;
-      if (portRectangle.NetworkItem != null) {
-        var port = portRectangle.NetworkItem;
-        port.NameChanged -= Port_NameChanged;
-      }
     }
 
@@ -105,5 +95,4 @@
       }
     }
-
     #endregion
 
@@ -111,5 +100,4 @@
     public event EventHandler StartPortRectangleChanged;
     protected virtual void OnStartPortRectangleChanged() {
-      UpdateToolTip();
       var handler = StartPortRectangleChanged;
       if (handler != null) handler(this, EventArgs.Empty);
@@ -118,5 +106,4 @@
     public event EventHandler EndPortRectangleChanged;
     protected virtual void OnEndPortRectangleChanged() {
-      UpdateToolTip();
       var handler = EndPortRectangleChanged;
       if (handler != null) handler(this, EventArgs.Empty);
@@ -128,38 +115,4 @@
       SetPosition(startPortRectangle.Point, endPortRectangle.Point);
     }
-
-    private void PortRectangleNetworkItemChanged(object sender, EventArgs e) {
-      UpdateToolTip();
-    }
-
-    private void Port_NameChanged(object sender, EventArgs e) {
-      UpdateToolTip();
-    }
-    #endregion
-
-    #region Helpers
-    private void UpdateToolTip() {
-      string startText = "null", endText = "null";
-
-      if (startPortRectangle != null) {
-        var startPort = startPortRectangle.NetworkItem;
-        if (startPort != null) {
-          startText = startPort.Name;
-          var startNode = startPort.Parent;
-          startText = (startNode != null ? startNode.Name : "null") + "." + startText;
-        }
-      }
-
-      if (endPortRectangle != null) {
-        var endPort = endPortRectangle.NetworkItem;
-        if (endPort != null) {
-          endText = endPort.Name;
-          var endNode = endPort.Parent;
-          endText = (endNode != null ? endNode.Name : "null") + "." + endText;
-        }
-      }
-
-      ToolTipText = string.Format("[{0}] --> [{1}]", startText, endText);
-    }
     #endregion
   }
Index: /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/Primitives/NodeRectangle.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/Primitives/NodeRectangle.cs	(revision 13134)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/Primitives/NodeRectangle.cs	(revision 13135)
@@ -23,18 +23,18 @@
 using System.Collections.Generic;
 using System.Drawing;
-using System.Linq;
+using HeuristicLab.Common;
 using HeuristicLab.Core.Networks;
 using HeuristicLab.Visualization;
 
 namespace HeuristicLab.Networks.Views.NetworkVisualization {
-  public class NodeRectangle : Visualization.Rectangle, INetworkItemPrimitive<IVisualizableNode> {
-    private readonly Dictionary<IPort, PortRectangle> port2PortRectangle = new Dictionary<IPort, PortRectangle>();
-
-    protected IGroup portRectangles;
+  [Primitive(typeof(INode), true)]
+  public class NodeRectangle : Visualization.Rectangle, INetworkItemPrimitive<INode> {
+    protected readonly Dictionary<IPort, IPrimitive> port2primitive = new Dictionary<IPort, IPrimitive>();
+    protected readonly IGroup portRectangles;
 
     protected bool IgnoreVisualPropertiesChanges { get; set; }
 
-    protected IVisualizableNode networkItem;
-    public IVisualizableNode NetworkItem {
+    protected INode networkItem;
+    public INode NetworkItem {
       get { return networkItem; }
       set {
@@ -43,5 +43,4 @@
         networkItem = value;
         if (networkItem != null) RegisterNetworkItemEvents();
-        UpdateToolTip();
         LoadVisualProperties();
         OnNetworkItemChanged();
@@ -49,20 +48,19 @@
     }
 
-    public NodeRectangle(IChart chart, IVisualizableNode node)
-      : base(chart, Point.Empty, Point.Empty) {
+    public NodeRectangle(IChart chart, INode node)
+      : base(chart, PointD.Empty, PointD.Empty) {
       NetworkItem = node;
 
       portRectangles = new Group(chart);
       foreach (var port in node.Ports) {
-        var portRectangle = new PortRectangle(this, port);
-        port2PortRectangle.Add(port, portRectangle);
-        portRectangles.Add(portRectangle);
+        var portPrimitive = PrimitiveAttribute.CreateDefaultPrimitive(port.GetType(), chart, port, node); // TODO: port.Parent != node
+        port2primitive.Add(port, portPrimitive);
+        portRectangles.Add(portPrimitive);
       }
-      UpdatePortRectangles();
       portRectangles.RedrawRequired += (sender, args) => OnRedrawRequired();
     }
 
     protected virtual void RegisterNetworkItemEvents() {
-      networkItem.NameChanged += NetworkItemNameChanged;
+      networkItem.NameChanged += NetworkItem_NameChanged;
       if (networkItem.VisualProperties != null) {
         networkItem.VisualProperties.Changed += VisualProperties_Changed;
@@ -75,5 +73,5 @@
 
     protected virtual void DeregisterNetworkItemEvents() {
-      networkItem.NameChanged -= NetworkItemNameChanged;
+      networkItem.NameChanged -= NetworkItem_NameChanged;
       if (networkItem.VisualProperties != null) {
         networkItem.VisualProperties.Changed -= VisualProperties_Changed;
@@ -87,13 +85,6 @@
     #region Overrides
     public override void SetPosition(PointD lowerLeft, PointD upperRight) {
-      SuppressEvents = true;
-      try {
-        base.SetPosition(lowerLeft, upperRight);
-        SaveVisualProperties();
-        UpdatePortRectangles();
-      } finally {
-        SuppressEvents = false;
-        OnRedrawRequired();
-      }
+      base.SetPosition(lowerLeft, upperRight);
+      SaveVisualProperties();
     }
 
@@ -103,6 +94,8 @@
       var p = Chart.TransformWorldToPixel(new PointD(LowerLeft.X, LowerLeft.Y + Size.Height));
 
-      using (var font = new Font(FontFamily.GenericSansSerif, (float)Math.Round(8.25 * Chart.WorldToPixelRatio.Width))) {
-        graphics.DrawString(ToolTipText, font, Brushes.Black, p.X + 5, p.Y + 5);
+      if (networkItem != null) {
+        using (var font = new Font(FontFamily.GenericSansSerif, (float)Math.Round(8.25 * Chart.WorldToPixelRatio.Width))) {
+          graphics.DrawString(networkItem.Name, font, Brushes.Black, p.X + 5, p.Y + 5);
+        }
       }
 
@@ -111,8 +104,8 @@
     #endregion
 
-    public PortRectangle GetPortRectangle(IPort name) {
-      PortRectangle portRectangle;
-      port2PortRectangle.TryGetValue(name, out portRectangle);
-      return portRectangle;
+    public IPrimitive GetPortPrimitive(IPort name) {
+      IPrimitive portPrimitive;
+      port2primitive.TryGetValue(name, out portPrimitive);
+      return portPrimitive;
     }
 
@@ -126,37 +119,29 @@
 
     #region Event Handlers
-    private void NetworkItemNameChanged(object sender, EventArgs e) {
-      UpdateToolTip();
-    }
-
     private void VisualProperties_Changed(object sender, EventArgs e) {
       if (IgnoreVisualPropertiesChanges) return;
+
       LoadVisualProperties();
     }
 
+    private void NetworkItem_NameChanged(object sender, EventArgs e) { OnRedrawRequired(); }
+
     private void Ports_ItemsAdded(object sender, Collections.CollectionItemsChangedEventArgs<IPort> e) {
       foreach (var port in e.Items) {
-        var portRectangle = new PortRectangle(this, port);
-        port2PortRectangle.Add(port, portRectangle);
+        var portRectangle = PrimitiveAttribute.CreateDefaultPrimitive(port.GetType(), Chart, port, networkItem);
+        port2primitive.Add(port, portRectangle);
         portRectangles.Add(portRectangle);
       }
 
-      SuppressEvents = true;
-      try {
-        UpdatePortRectangles();
-      } finally {
-        SuppressEvents = false;
-        OnRedrawRequired();
-      }
+      OnRedrawRequired();
     }
 
     private void Ports_ItemsRemoved(object sender, Collections.CollectionItemsChangedEventArgs<IPort> e) {
       foreach (var port in e.Items) {
-        var portRectangle = port2PortRectangle[port];
-        port2PortRectangle.Remove(port);
+        var portRectangle = port2primitive[port];
+        port2primitive.Remove(port);
         portRectangles.Remove(portRectangle);
       }
 
-      UpdatePortRectangles();
       OnRedrawRequired();
     }
@@ -164,31 +149,19 @@
 
     #region Helpers
-    private void UpdateToolTip() {
-      ToolTipText = networkItem.Name;
+    private INodeVisualProperties CreateDefaultVisualProperties() {
+      var offset = Chart.UpperRight - Chart.LowerLeft;
+      var center = new PointD(Chart.LowerLeft.X + offset.DX * 0.5, Chart.LowerLeft.Y + offset.DY * 0.5);
+      var size = Chart.TransformPixelToWorld(new Size(200, 100));
+      var lowerLeft = center - new Offset(size.Width * 0.5, size.Height * 0.5);
+      var upperRight = center + new Offset(size.Width * 0.5, size.Height * 0.5);
+      return new NodeVisualProperties(new Point2D<double>(lowerLeft.X, lowerLeft.Y), new Point2D<double>(upperRight.X, upperRight.Y));
     }
 
     private void LoadVisualProperties() {
-      var offset = Chart.UpperRight - Chart.LowerLeft;
-      var center = new PointD(Chart.LowerLeft.X + offset.DX * 0.5, Chart.LowerLeft.Y + offset.DY * 0.5);
-      var size = Chart.TransformPixelToWorld(new Size(200, 100));
+      if (networkItem.VisualProperties == null)
+        networkItem.VisualProperties = CreateDefaultVisualProperties();
 
-      bool vpAvailable = networkItem != null && networkItem.VisualProperties != null;
-      bool useDefaultLocation = !vpAvailable || double.IsNaN(networkItem.VisualProperties.X);
-      bool useDefaultSize = !vpAvailable || double.IsNaN(networkItem.VisualProperties.Width);
-
-      if (!useDefaultLocation) {
-        center.X = networkItem.VisualProperties.X;
-        center.Y = networkItem.VisualProperties.Y;
-      }
-
-      if (!useDefaultSize) {
-        size.Width = networkItem.VisualProperties.Width;
-        size.Height = networkItem.VisualProperties.Height;
-      }
-
-      var ll = new PointD(center.X - size.Width * 0.5, center.Y - size.Height * 0.5);
-      var ur = ll + new Offset(size.Width, size.Height);
-
-      SetPosition(ll, ur);
+      var vp = (INodeVisualProperties)networkItem.VisualProperties;
+      SetPosition(new PointD(vp.LowerLeft.X, vp.LowerLeft.Y), new PointD(vp.UpperRight.X, vp.UpperRight.Y));
     }
 
@@ -196,28 +169,11 @@
       if (networkItem == null) return;
 
-      var visualProperties = networkItem.VisualProperties;
-      var centerW = new PointD(LowerLeft.X + Size.Width * 0.5, UpperRight.Y - Size.Height * 0.5);
+      var vp = (INodeVisualProperties)networkItem.VisualProperties;
 
       IgnoreVisualPropertiesChanges = true;
       try {
-        visualProperties.X = centerW.X;
-        visualProperties.Y = centerW.Y;
-        visualProperties.Width = Size.Width;
-        visualProperties.Height = Size.Height;
+        vp.LowerLeft = new Point2D<double>(LowerLeft.X, LowerLeft.Y);
+        vp.UpperRight = new Point2D<double>(UpperRight.X, UpperRight.Y);
       } finally { IgnoreVisualPropertiesChanges = false; }
-
-      OnRedrawRequired();
-    }
-
-    private void UpdatePortRectangles() {
-      if (portRectangles == null) return;
-
-      var rectangles = portRectangles.OfType<PortRectangle>().ToArray();
-      double space = Size.Width / (rectangles.Length + 1);
-      for (int i = 0; i < rectangles.Length; i++) {
-        double dx = Math.Round(space * (i + 1));
-        var point = LowerLeft + new Offset(dx, 0);
-        rectangles[i].SetPosition(point);
-      }
     }
     #endregion
Index: /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/Primitives/PortRectangle.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/Primitives/PortRectangle.cs	(revision 13134)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks.Views.NetworkVisualization/3.3/Primitives/PortRectangle.cs	(revision 13135)
@@ -22,11 +22,18 @@
 using System;
 using System.Drawing;
+using System.Drawing.Drawing2D;
 using System.Linq;
+using HeuristicLab.Common;
 using HeuristicLab.Core.Networks;
 using HeuristicLab.Visualization;
 
 namespace HeuristicLab.Networks.Views.NetworkVisualization {
+  [Primitive(typeof(IPort), true)]
   public class PortRectangle : FixedSizeRectangle, INetworkItemPrimitive<IPort> {
     private const int size = 10;
+
+    protected readonly INodeVisualProperties nodeVisualProperties;
+
+    protected bool IgnoreVisualPropertiesChanges { get; set; }
 
     public override Size Size {
@@ -45,15 +52,21 @@
         networkItem = value;
         if (networkItem != null) RegisterNetworkItemEvents();
+        LoadVisualProperties();
         OnNetworkItemChanged();
       }
     }
 
-    public PortRectangle(NodeRectangle nodeRectangle, IPort port)
-      : base(nodeRectangle.Chart, PointD.Empty, Size.Empty, Pens.Black, Brushes.Red) {
+    public PortRectangle(IChart chart, IPort port, INode node)
+      : base(chart, PointD.Empty, Size.Empty, Pens.Black, Brushes.Red) {
+      nodeVisualProperties = (INodeVisualProperties)node.VisualProperties;
+      nodeVisualProperties.Changed += NodeVisualProperties_Changed;
       NetworkItem = port;
     }
 
     protected virtual void RegisterNetworkItemEvents() {
-      networkItem.NameChanged += NetworkItemNameChanged;
+      networkItem.NameChanged += NetworkItem_NameChanged;
+      if (networkItem.VisualProperties != null) {
+        networkItem.VisualProperties.Changed += VisualProperties_Changed;
+      }
       var connectablePort = networkItem as IConnectablePort;
       if (connectablePort != null) {
@@ -63,5 +76,8 @@
 
     protected virtual void DeregisterNetworkItemEvents() {
-      networkItem.NameChanged -= NetworkItemNameChanged;
+      networkItem.NameChanged -= NetworkItem_NameChanged;
+      if (networkItem.VisualProperties != null) {
+        networkItem.VisualProperties.Changed -= VisualProperties_Changed;
+      }
       var connectablePort = networkItem as IConnectablePort;
       if (connectablePort != null) {
@@ -70,43 +86,85 @@
     }
 
+    #region Overrides
+    public override void SetPosition(PointD point) {
+      base.SetPosition(point);
+      SaveVisualProperties();
+    }
+
+    public override void Draw(Graphics graphics) {
+      base.Draw(graphics);
+
+      var p = Chart.TransformWorldToPixel(Point);
+
+      if (networkItem != null && networkItem.VisualProperties != null) {
+        using (var font = new Font(FontFamily.GenericSansSerif, (float)Math.Round(8.25 * Chart.WorldToPixelRatio.Width))) {
+          var textSize = graphics.MeasureString(networkItem.Name, font);
+          var vp = (IPortVisualProperties)networkItem.VisualProperties;
+          switch (vp.Orientation) {
+            case Orientation.North: p = new Point((int)(p.X - textSize.Width / 2), (int)(p.Y - Size.Height - textSize.Height)); break;
+            case Orientation.East: p = new Point(p.X + Size.Width, (int)(p.Y - textSize.Height / 2)); break;
+            case Orientation.South: p = new Point((int)(p.X - textSize.Width / 2), p.Y + Size.Height); break;
+            case Orientation.West: p = new Point((int)(p.X - Size.Width - textSize.Width), (int)(p.Y - textSize.Height / 2)); break;
+          }
+
+          graphics.DrawString(networkItem.Name, font, Brushes.Black, p);
+        }
+      }
+    }
+
+    public override void PostDraw(Graphics graphics) {
+      base.PostDraw(graphics);
+
+      if (Selected) {
+        var p = Chart.TransformWorldToPixel(Point);
+        using (var pen = new Pen(Color.LightGray, 3) { DashStyle = DashStyle.Dash })
+          graphics.DrawRectangle(pen, p.X - Size.Width / 2, p.Y - Size.Height / 2, Size.Width, Size.Height);
+      }
+    }
+
+    #endregion
+
     #region Events
+
     public event EventHandler NetworkItemChanged;
+
     protected virtual void OnNetworkItemChanged() {
-      UpdateToolTip();
       var handler = NetworkItemChanged;
       if (handler != null) handler(this, EventArgs.Empty);
     }
 
-    public event EventHandler NodeRectangleChanged;
-    protected virtual void OnNodeRectangleChanged() {
-      var handler = NodeRectangleChanged;
-      if (handler != null) handler(this, EventArgs.Empty);
-    }
     #endregion
 
     #region Event Handlers
-    private void NetworkItemNameChanged(object sender, EventArgs e) {
-      UpdateToolTip();
+
+    private void NodeVisualProperties_Changed(object sender, EventArgs e) {
+      if (IgnoreVisualPropertiesChanges) return;
+
+      LoadVisualProperties();
+    }
+
+    private void VisualProperties_Changed(object sender, EventArgs e) {
+      if (IgnoreVisualPropertiesChanges) return;
+
+      LoadVisualProperties();
+    }
+
+    private void NetworkItem_NameChanged(object sender, EventArgs e) {
+      OnRedrawRequired();
     }
 
     private void Port_ConnectedPortChanged(object sender, EventArgs e) {
-      var connectablePort = (IConnectablePort)networkItem;
-
       var connectionLines = Chart.Group.GetAllPrimitives(Point).OfType<ConnectionLine>();
       var outgoingLines = connectionLines.Where(x => x.StartPortRectangle == this);
-
-      foreach (var l in outgoingLines)
-        Chart.Group.Remove(l);
-
+      foreach (var l in outgoingLines) Chart.Group.Remove(l);
+
+      var connectablePort = (IConnectablePort)networkItem;
       var connectedPort = connectablePort.ConnectedPort as IConnectablePort;
       if (connectedPort == null) return;
-
-      var connectedNode = connectedPort.Parent;
-      if (connectedNode == null) return;
 
       var nodeRectangles = Chart.Group.Primitives.OfType<NodeRectangle>();
       PortRectangle endPortRectangle = null;
       foreach (var nodeRectangle in nodeRectangles) {
-        endPortRectangle = nodeRectangle.GetPortRectangle(connectedPort);
+        endPortRectangle = (PortRectangle)nodeRectangle.GetPortPrimitive(connectedPort);
         if (endPortRectangle != null) break;
       }
@@ -116,12 +174,80 @@
       var connectionShape = new ConnectionLine(Chart, this, endPortRectangle);
       Chart.Group.Add(connectionShape);
-
-    }
+    }
+
     #endregion
 
     #region Helpers
-    private void UpdateToolTip() {
-      ToolTipText = networkItem.Name;
-    }
+
+    private IPortVisualProperties CreateDefaultVisualProperties() {
+      return new PortVisualProperties(Orientation.South, 0.5);
+    }
+
+    private void LoadVisualProperties() {
+      if (networkItem.VisualProperties == null)
+        networkItem.VisualProperties = CreateDefaultVisualProperties();
+
+      var vp = (IPortVisualProperties)networkItem.VisualProperties;
+      var p = PointD.Empty;
+      double nodeWidth = nodeVisualProperties.UpperRight.X - nodeVisualProperties.LowerLeft.X;
+      double nodeHeight = nodeVisualProperties.UpperRight.Y - nodeVisualProperties.LowerLeft.Y;
+
+      switch (vp.Orientation) {
+        case Orientation.North:
+          p.X = nodeVisualProperties.LowerLeft.X + vp.Offset * nodeWidth;
+          p.Y = nodeVisualProperties.UpperRight.Y;
+          break;
+        case Orientation.East:
+          p.X = nodeVisualProperties.UpperRight.X;
+          p.Y = nodeVisualProperties.UpperRight.Y - vp.Offset * nodeHeight;
+          break;
+        case Orientation.South:
+          p.X = nodeVisualProperties.UpperRight.X - vp.Offset * nodeWidth;
+          p.Y = nodeVisualProperties.LowerLeft.Y;
+          break;
+        case Orientation.West:
+          p.X = nodeVisualProperties.LowerLeft.X;
+          p.Y = nodeVisualProperties.LowerLeft.Y + vp.Offset * nodeHeight;
+          break;
+      }
+
+      SetPosition(p);
+    }
+
+    private void SaveVisualProperties() {
+      if (networkItem == null) return;
+
+      var vp = (IPortVisualProperties)networkItem.VisualProperties;
+
+      IgnoreVisualPropertiesChanges = true;
+      try {
+        var lowerLeft = nodeVisualProperties.LowerLeft;
+        var upperRight = nodeVisualProperties.UpperRight;
+
+        if (lowerLeft.X <= Point.X && Point.X <= upperRight.X) {
+          // check N/S
+          if (Point.Y.IsAlmost(upperRight.Y)) {
+            vp.Orientation = Orientation.North;
+            vp.Offset = (Point.X - lowerLeft.X) / (upperRight.X - lowerLeft.X);
+          } else if (Point.Y.IsAlmost(lowerLeft.Y)) {
+            vp.Orientation = Orientation.South;
+            vp.Offset = (upperRight.X - Point.X) / (upperRight.X - lowerLeft.X);
+          }
+        }
+        if (lowerLeft.Y <= Point.Y && Point.Y <= upperRight.Y) {
+          // check E/W
+          if (Point.X.IsAlmost(upperRight.X)) {
+            vp.Orientation = Orientation.East;
+            vp.Offset = (upperRight.Y - Point.Y) / (upperRight.Y - lowerLeft.Y);
+          } else if (Point.X.IsAlmost(lowerLeft.X)) {
+            vp.Orientation = Orientation.West;
+            vp.Offset = (Point.Y - lowerLeft.Y) / (upperRight.Y - lowerLeft.Y);
+          }
+        }
+      } finally {
+        IgnoreVisualPropertiesChanges = false;
+      }
+    }
+
     #endregion
   }
Index: /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/INetworkItem.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/INetworkItem.cs	(revision 13134)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/INetworkItem.cs	(revision 13135)
@@ -23,5 +23,5 @@
 
 namespace HeuristicLab.Core.Networks {
-  public interface INetworkItem : INamedItem {
+  public interface INetworkItem : INamedItem, IVisualizable {
     INetworkItem Parent { get; }
     IEnumerable<INetworkItem> Children { get; }
Index: anches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/INodeVisualProperties.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/INodeVisualProperties.cs	(revision 13134)
+++ 	(revision )
@@ -1,32 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Drawing;
-
-namespace HeuristicLab.Core.Networks {
-  public interface INodeVisualProperties : IVisualProperties {
-    double X { get; set; }
-    double Y { get; set; }
-    double Width { get; set; }
-    double Height { get; set; }
-    Color Color { get; set; }
-  }
-}
Index: anches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/IPortVisualProperties.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/IPortVisualProperties.cs	(revision 13134)
+++ 	(revision )
@@ -1,32 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Drawing;
-
-namespace HeuristicLab.Core.Networks {
-  public interface IPortVisualProperties : IVisualProperties {
-    double X { get; set; }
-    double Y { get; set; }
-    double Width { get; set; }
-    double Height { get; }
-    Color Color { get; set; }
-  }
-}
Index: /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/IVisualProperties.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/IVisualProperties.cs	(revision 13134)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/IVisualProperties.cs	(revision 13135)
@@ -21,7 +21,8 @@
 
 using System;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Core.Networks {
-  public interface IVisualProperties {
+  public interface IVisualProperties : IDeepCloneable {
     event EventHandler Changed;
   }
Index: /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/IVisualizable.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/IVisualizable.cs	(revision 13135)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/IVisualizable.cs	(revision 13135)
@@ -0,0 +1,26 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Core.Networks {
+  public interface IVisualizable {
+    IVisualProperties VisualProperties { get; set; }
+  }
+}
Index: anches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/IVisualizableNode.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/IVisualizableNode.cs	(revision 13134)
+++ 	(revision )
@@ -1,26 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * 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.Core.Networks {
-  public interface IVisualizableNode : INode {
-    INodeVisualProperties VisualProperties { get; }
-  }
-}
Index: anches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/IVisualizablePort.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/IVisualizablePort.cs	(revision 13134)
+++ 	(revision )
@@ -1,26 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * 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.Core.Networks {
-  public interface IVisualizablePort {
-    IPortVisualProperties VisualProperties { get; }
-  }
-}
Index: /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/NetworkItem.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/NetworkItem.cs	(revision 13134)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/NetworkItem.cs	(revision 13135)
@@ -47,7 +47,12 @@
     }
 
+    [Storable]
+    public IVisualProperties VisualProperties { get; set; }
+
     [StorableConstructor]
     protected NetworkItem(bool deserializing) : base(deserializing) { }
-    protected NetworkItem(NetworkItem original, Cloner cloner) : base(original, cloner) { }
+    protected NetworkItem(NetworkItem original, Cloner cloner) : base(original, cloner) {
+      VisualProperties = cloner.Clone(original.VisualProperties);
+    }
     protected NetworkItem() : base("NetworkItem") { }
     protected NetworkItem(string name) : base(name) { }
Index: /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/Node.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/Node.cs	(revision 13134)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/Node.cs	(revision 13135)
@@ -29,5 +29,5 @@
   [Item("Node", "Abstract base class for nodes of a network.")]
   [StorableClass]
-  public abstract class Node : NetworkItem, IVisualizableNode {
+  public abstract class Node : NetworkItem, INode {
     public static new Image StaticItemImage {
       get { return HeuristicLab.Common.Resources.VSImageLibrary.RadialChart; }
@@ -55,16 +55,4 @@
         if (readOnlyPorts == null) readOnlyPorts = ports.AsReadOnly();
         return readOnlyPorts;
-      }
-    }
-
-    public string VisualName { get { return Name; } }
-
-    [Storable]
-    private INodeVisualProperties visualProperties;
-    public INodeVisualProperties VisualProperties {
-      get {
-        if (visualProperties == null)
-          visualProperties = new NodeVisualProperties();
-        return visualProperties;
       }
     }
Index: anches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/NodeVisualProperties.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/NodeVisualProperties.cs	(revision 13134)
+++ 	(revision )
@@ -1,108 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Drawing;
-using HeuristicLab.Common;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Core.Networks {
-  [StorableClass]
-  public sealed class NodeVisualProperties : VisualProperties, INodeVisualProperties {
-    [Storable]
-    private double x;
-    public double X {
-      get { return x; }
-      set {
-        if (x == value) return;
-        x = value;
-        OnChanged();
-      }
-    }
-
-    [Storable]
-    private double y;
-    public double Y {
-      get { return y; }
-      set {
-        if (y == value) return;
-        y = value;
-        OnChanged();
-      }
-    }
-
-    [Storable]
-    private double width;
-    public double Width {
-      get { return width; }
-      set {
-        if (width == value) return;
-        width = value;
-        OnChanged();
-      }
-    }
-
-    [Storable]
-    private double height;
-    public double Height {
-      get { return height; }
-      set {
-        if (height == value) return;
-        height = value;
-        OnChanged();
-      }
-    }
-
-    [Storable]
-    private Color color;
-    public Color Color {
-      get { return color; }
-      set {
-        if (color == value) return;
-        color = value;
-        OnChanged();
-      }
-    }
-
-    #region Constructors & Cloning
-    [StorableConstructor]
-    private NodeVisualProperties(bool deserializing) : base(deserializing) { }
-    private NodeVisualProperties(NodeVisualProperties original, Cloner cloner)
-      : base(original, cloner) {
-      x = original.x;
-      y = original.y;
-      width = original.width;
-      height = original.height;
-      color = original.color;
-    }
-
-    public NodeVisualProperties() {
-      x = double.NaN;
-      y = double.NaN;
-      width = double.NaN;
-      height = double.NaN;
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new NodeVisualProperties(this, cloner);
-    }
-    #endregion
-  }
-}
Index: /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/Port.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/Port.cs	(revision 13134)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/Port.cs	(revision 13135)
@@ -27,5 +27,5 @@
   [Item("Port", "Abstract base class for ports of network nodes.")]
   [StorableClass]
-  public abstract class Port : NetworkItem, IVisualizablePort {
+  public abstract class Port : NetworkItem, IPort {
     public static new Image StaticItemImage {
       get { return HeuristicLab.Common.Resources.VSImageLibrary.Interface; }
@@ -40,14 +40,4 @@
     }
 
-    [Storable]
-    private IPortVisualProperties visualProperties;
-    public IPortVisualProperties VisualProperties {
-      get {
-        if (visualProperties == null)
-          visualProperties = new PortVisualProperties();
-        return visualProperties;
-      }
-    }
-
     [StorableConstructor]
     protected Port(bool deserializing) : base(deserializing) { }
Index: anches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/PortVisualProperties.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/PortVisualProperties.cs	(revision 13134)
+++ 	(revision )
@@ -1,108 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Drawing;
-using HeuristicLab.Common;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Core.Networks {
-  [StorableClass]
-  public sealed class PortVisualProperties : VisualProperties, IPortVisualProperties {
-    [Storable]
-    private double x;
-    public double X {
-      get { return x; }
-      set {
-        if (x == value) return;
-        x = value;
-        OnChanged();
-      }
-    }
-
-    [Storable]
-    private double y;
-    public double Y {
-      get { return y; }
-      set {
-        if (y == value) return;
-        y = value;
-        OnChanged();
-      }
-    }
-
-    [Storable]
-    private double width;
-    public double Width {
-      get { return width; }
-      set {
-        if (width == value) return;
-        width = value;
-        OnChanged();
-      }
-    }
-
-    [Storable]
-    private double height;
-    public double Height {
-      get { return height; }
-      set {
-        if (height == value) return;
-        height = value;
-        OnChanged();
-      }
-    }
-
-    [Storable]
-    private Color color;
-    public Color Color {
-      get { return color; }
-      set {
-        if (color == value) return;
-        color = value;
-        OnChanged();
-      }
-    }
-
-    #region Constructors & Cloning
-    [StorableConstructor]
-    private PortVisualProperties(bool deserializing) : base(deserializing) { }
-    private PortVisualProperties(PortVisualProperties original, Cloner cloner)
-      : base(original, cloner) {
-      x = original.x;
-      y = original.y;
-      width = original.width;
-      height = original.height;
-      color = original.color;
-    }
-
-    public PortVisualProperties() {
-      x = double.NaN;
-      y = double.NaN;
-      width = double.NaN;
-      height = double.NaN;
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new PortVisualProperties(this, cloner);
-    }
-    #endregion
-  }
-}
Index: /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/VisualProperties.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/VisualProperties.cs	(revision 13134)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Core/VisualProperties.cs	(revision 13135)
@@ -1,3 +1,24 @@
-﻿using System;
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
 using HeuristicLab.Common;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
@@ -5,16 +26,11 @@
 namespace HeuristicLab.Core.Networks {
   [StorableClass]
-  public class VisualProperties : DeepCloneable, IVisualProperties {
+  public abstract class VisualProperties : DeepCloneable, IVisualProperties {
     #region Constructors & Cloning
     [StorableConstructor]
     protected VisualProperties(bool deserializing) : base() { }
-    protected VisualProperties(VisualProperties original, Cloner cloner)
-      : base(original, cloner) { }
+    protected VisualProperties(VisualProperties original, Cloner cloner) : base(original, cloner) { }
 
-    public VisualProperties() { }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new VisualProperties(this, cloner);
-    }
+    protected VisualProperties() { }
     #endregion
 
Index: /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/HeuristicLab.Networks-3.3.csproj
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/HeuristicLab.Networks-3.3.csproj	(revision 13134)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/HeuristicLab.Networks-3.3.csproj	(revision 13135)
@@ -203,11 +203,6 @@
     </Compile>
     <Compile Include="ConfigurationPort.cs" />
-    <Compile Include="Core\INodeVisualProperties.cs" />
-    <Compile Include="Core\IPortVisualProperties.cs" />
-    <Compile Include="Core\IVisualizableNode.cs" />
-    <Compile Include="Core\IVisualizablePort.cs" />
+    <Compile Include="Core\IVisualizable.cs" />
     <Compile Include="Core\IVisualProperties.cs" />
-    <Compile Include="Core\NodeVisualProperties.cs" />
-    <Compile Include="Core\PortVisualProperties.cs" />
     <Compile Include="Core\VisualProperties.cs" />
     <Compile Include="ExecutionPort.cs" />
Index: /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Programmable/ProgrammableNetworkItem.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Programmable/ProgrammableNetworkItem.cs	(revision 13134)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Programmable/ProgrammableNetworkItem.cs	(revision 13135)
@@ -98,4 +98,7 @@
       get { return CompiledNetworkItem.Children; }
     }
+
+    [Storable]
+    public IVisualProperties VisualProperties { get; set; }
     #endregion
 
@@ -169,4 +172,5 @@
       variableStore = cloner.Clone(original.variableStore);
       CompiledNetworkItem = cloner.Clone(original.compiledNetworkItem);
+      VisualProperties = cloner.Clone(original.VisualProperties);
     }
     protected ProgrammableNetworkItem()
@@ -358,4 +362,10 @@
         get { return Enumerable.Empty<INetworkItem>(); }
       }
+
+      // TODO: no visual properties needed here
+      public IVisualProperties VisualProperties {
+        get { return Context.VisualProperties; }
+        set { Context.VisualProperties = value; }
+      }
       #endregion
 
Index: /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Programmable/ProgrammableNode.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Programmable/ProgrammableNode.cs	(revision 13134)
+++ /branches/OptimizationNetworks/HeuristicLab.Networks/3.3/Programmable/ProgrammableNode.cs	(revision 13135)
@@ -32,5 +32,5 @@
   [Item("ProgrammableNode", "Abstract base class for programmable nodes of a network.")]
   [StorableClass]
-  public abstract class ProgrammableNode : ProgrammableNetworkItem, IProgrammableNode, IVisualizableNode {
+  public abstract class ProgrammableNode : ProgrammableNetworkItem, IProgrammableNode {
     public static new Image StaticItemImage {
       get { return HeuristicLab.Common.Resources.VSImageLibrary.RadialChart; }
@@ -58,16 +58,4 @@
       }
     }
-
-    public string VisualName { get { return Name; } }
-
-    [Storable]
-    private INodeVisualProperties visualProperties;
-    public INodeVisualProperties VisualProperties {
-      get {
-        if (visualProperties == null)
-          visualProperties = new NodeVisualProperties();
-        return visualProperties;
-      }
-    }
     #endregion
 
@@ -127,10 +115,4 @@
       IKeyedItemCollection<string, IPort> INode.Ports {
         get { return Ports; }
-      }
-
-      public string VisualName { get { return Context.VisualName; } }
-
-      public INodeVisualProperties VisualProperties {
-        get { return Context.VisualProperties; }
       }
       #endregion
