Index: branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/AlgorithmNodeView.cs
===================================================================
--- branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/AlgorithmNodeView.cs	(revision 11409)
+++ branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/AlgorithmNodeView.cs	(revision 11412)
@@ -27,5 +27,5 @@
 
 namespace HeuristicLab.Optimization.Networks.Views {
-  [View("Algorithm Node View")]
+  [View("AlgorithmNode View")]
   [Content(typeof(AlgorithmNode), true)]
   [Content(typeof(IAlgorithmNode), false)]
@@ -73,5 +73,5 @@
     protected override void SetEnabledStateOfControls() {
       base.SetEnabledStateOfControls();
-      portCollectionView.Enabled = Content != null;
+      portCollectionView.Enabled = Content != null && !ReadOnly;
       setAlgorithmButton.Enabled = Content != null && !ReadOnly;
       clearAlgorithmButton.Enabled = Content != null && Content.Algorithm != null && !ReadOnly;
@@ -116,5 +116,4 @@
         else if (e.AllowedEffect.HasFlag(DragDropEffects.Link)) e.Effect = DragDropEffects.Link;
       }
-
     }
     protected virtual void algorithmPanel_DragDrop(object sender, DragEventArgs e) {
Index: branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/HeuristicLab.Optimization.Networks.Views-3.3.csproj
===================================================================
--- branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/HeuristicLab.Optimization.Networks.Views-3.3.csproj	(revision 11409)
+++ branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/HeuristicLab.Optimization.Networks.Views-3.3.csproj	(revision 11412)
@@ -49,4 +49,10 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="VariablesNodeView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="VariablesNodeView.Designer.cs">
+      <DependentUpon>VariablesNodeView.cs</DependentUpon>
+    </Compile>
     <Compile Include="AlgorithmNodeView.cs">
       <SubType>UserControl</SubType>
@@ -54,4 +60,10 @@
     <Compile Include="AlgorithmNodeView.Designer.cs">
       <DependentUpon>AlgorithmNodeView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="InputPortView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="InputPortView.Designer.cs">
+      <DependentUpon>InputPortView.cs</DependentUpon>
     </Compile>
     <Compile Include="PortView.cs">
Index: branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/InputPortView.Designer.cs
===================================================================
--- branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/InputPortView.Designer.cs	(revision 11412)
+++ branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/InputPortView.Designer.cs	(revision 11412)
@@ -0,0 +1,128 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Networks.Views {
+  partial class InputPortView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.outputPortLabel = new System.Windows.Forms.Label();
+      this.outputPortTextBox = new System.Windows.Forms.TextBox();
+      this.valueGroupBox.SuspendLayout();
+      this.valuePanel.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // valueGroupBox
+      // 
+      this.valueGroupBox.Location = new System.Drawing.Point(0, 52);
+      this.valueGroupBox.Size = new System.Drawing.Size(645, 465);
+      this.valueGroupBox.TabIndex = 5;
+      // 
+      // valuePanel
+      // 
+      this.valuePanel.Size = new System.Drawing.Size(633, 440);
+      // 
+      // valueViewHost
+      // 
+      this.valueViewHost.Size = new System.Drawing.Size(633, 440);
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      this.nameTextBox.Location = new System.Drawing.Point(73, 0);
+      this.nameTextBox.Size = new System.Drawing.Size(547, 20);
+      // 
+      // outputPortLabel
+      // 
+      this.outputPortLabel.AutoSize = true;
+      this.outputPortLabel.Location = new System.Drawing.Point(3, 29);
+      this.outputPortLabel.Name = "outputPortLabel";
+      this.outputPortLabel.Size = new System.Drawing.Size(64, 13);
+      this.outputPortLabel.TabIndex = 3;
+      this.outputPortLabel.Text = "&Output Port:";
+      // 
+      // outputPortTextBox
+      // 
+      this.outputPortTextBox.AllowDrop = true;
+      this.outputPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.outputPortTextBox.Location = new System.Drawing.Point(73, 26);
+      this.outputPortTextBox.Name = "outputPortTextBox";
+      this.outputPortTextBox.ReadOnly = true;
+      this.outputPortTextBox.Size = new System.Drawing.Size(547, 20);
+      this.outputPortTextBox.TabIndex = 4;
+      this.outputPortTextBox.DragDrop += new System.Windows.Forms.DragEventHandler(this.outputPortTextBox_DragDrop);
+      this.outputPortTextBox.DragEnter += new System.Windows.Forms.DragEventHandler(this.outputPortTextBox_DragEnterOver);
+      this.outputPortTextBox.DragOver += new System.Windows.Forms.DragEventHandler(this.outputPortTextBox_DragEnterOver);
+      // 
+      // InputPortView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.outputPortTextBox);
+      this.Controls.Add(this.outputPortLabel);
+      this.Name = "InputPortView";
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      this.Controls.SetChildIndex(this.valueGroupBox, 0);
+      this.Controls.SetChildIndex(this.outputPortLabel, 0);
+      this.Controls.SetChildIndex(this.outputPortTextBox, 0);
+      this.valueGroupBox.ResumeLayout(false);
+      this.valuePanel.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    protected System.Windows.Forms.Label outputPortLabel;
+    protected System.Windows.Forms.TextBox outputPortTextBox;
+
+
+
+
+
+  }
+}
Index: branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/InputPortView.cs
===================================================================
--- branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/InputPortView.cs	(revision 11412)
+++ branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/InputPortView.cs	(revision 11412)
@@ -0,0 +1,81 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 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.MainForm;
+using System;
+using System.Windows.Forms;
+
+namespace HeuristicLab.Optimization.Networks.Views {
+  [View("InputPort View")]
+  [Content(typeof(InputPort<>), true)]
+  [Content(typeof(IInputPort<>), false)]
+  [Content(typeof(IInputPort), false)]
+  public partial class InputPortView : PortView {
+    public new IInputPort Content {
+      get { return (IInputPort)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public InputPortView() {
+      InitializeComponent();
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.OutputPortChanged -= Content_OutputPortChanged;
+      base.DeregisterContentEvents();
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.OutputPortChanged += Content_OutputPortChanged;
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      outputPortTextBox.Text = ((Content == null) || (Content.OutputPort == null)) ? string.Empty : Content.OutputPort.Name;
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      outputPortTextBox.Enabled = Content != null && !ReadOnly;
+    }
+    protected virtual void Content_OutputPortChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_OutputPortChanged), sender, e);
+      else {
+        outputPortTextBox.Text = Content.OutputPort == null ? string.Empty : Content.OutputPort.Name;
+      }
+    }
+
+    protected virtual void outputPortTextBox_DragEnterOver(object sender, DragEventArgs e) {
+      e.Effect = DragDropEffects.None;
+      if (!ReadOnly && (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) is IOutputPort)) {
+        e.Effect = DragDropEffects.Link;
+      }
+    }
+    protected virtual void outputPortTextBox_DragDrop(object sender, DragEventArgs e) {
+      if (e.Effect != DragDropEffects.None) {
+        IOutputPort port = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as IOutputPort;
+        Content.OutputPort = port;
+      }
+    }
+  }
+}
Index: branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/PortView.Designer.cs
===================================================================
--- branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/PortView.Designer.cs	(revision 11409)
+++ branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/PortView.Designer.cs	(revision 11412)
@@ -21,5 +21,5 @@
 
 namespace HeuristicLab.Optimization.Networks.Views {
-  partial class PortView<T> {
+  partial class PortView {
     /// <summary> 
     /// Required designer variable.
Index: branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/PortView.cs
===================================================================
--- branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/PortView.cs	(revision 11409)
+++ branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/PortView.cs	(revision 11412)
@@ -20,5 +20,5 @@
 #endregion
 
-using HeuristicLab.Core;
+using HeuristicLab.Common;
 using HeuristicLab.Core.Views;
 using HeuristicLab.MainForm;
@@ -30,7 +30,8 @@
   [Content(typeof(Port<>), true)]
   [Content(typeof(IPort<>), false)]
-  public partial class PortView<T> : NamedItemView where T : class, IItem {
-    public new IPort<T> Content {
-      get { return (IPort<T>)base.Content; }
+  [Content(typeof(IPort), false)]
+  public partial class PortView : NamedItemView {
+    public new IPort Content {
+      get { return (IPort)base.Content; }
       set { base.Content = value; }
     }
@@ -56,5 +57,5 @@
       } else {
         valueViewHost.ViewType = null;
-        valueViewHost.Content = Content.Value;
+        valueViewHost.Content = Content.Value as IContent;
       }
     }
@@ -62,5 +63,5 @@
     protected override void SetEnabledStateOfControls() {
       base.SetEnabledStateOfControls();
-      valueGroupBox.Enabled = Content != null;
+      valueGroupBox.Enabled = (Content as IContent) != null;
     }
     protected virtual void Content_ValueChanged(object sender, System.EventArgs e) {
@@ -69,5 +70,5 @@
       else {
         valueViewHost.ViewType = null;
-        valueViewHost.Content = Content.Value;
+        valueViewHost.Content = Content.Value as IContent;
 
       }
Index: branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/VariablesNodeView.Designer.cs
===================================================================
--- branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/VariablesNodeView.Designer.cs	(revision 11412)
+++ branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/VariablesNodeView.Designer.cs	(revision 11412)
@@ -0,0 +1,133 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Networks.Views {
+  partial class VariablesNodeView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.portCollectionView = new HeuristicLab.Optimization.Networks.Views.PortCollectionView();
+      this.splitContainer = new System.Windows.Forms.SplitContainer();
+      this.variableCollectionView = new HeuristicLab.Core.Views.VariableCollectionView();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      // 
+      // portCollectionView
+      // 
+      this.portCollectionView.Caption = "PortCollection View";
+      this.portCollectionView.Content = null;
+      this.portCollectionView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.portCollectionView.Location = new System.Drawing.Point(0, 0);
+      this.portCollectionView.Name = "portCollectionView";
+      this.portCollectionView.ReadOnly = false;
+      this.portCollectionView.ShowDetails = true;
+      this.portCollectionView.Size = new System.Drawing.Size(645, 238);
+      this.portCollectionView.TabIndex = 0;
+      // 
+      // splitContainer
+      // 
+      this.splitContainer.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.splitContainer.Location = new System.Drawing.Point(0, 26);
+      this.splitContainer.Name = "splitContainer";
+      this.splitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.portCollectionView);
+      // 
+      // splitContainer.Panel2
+      // 
+      this.splitContainer.Panel2.Controls.Add(this.variableCollectionView);
+      this.splitContainer.Size = new System.Drawing.Size(645, 491);
+      this.splitContainer.SplitterDistance = 238;
+      this.splitContainer.TabIndex = 3;
+      // 
+      // variableCollectionView
+      // 
+      this.variableCollectionView.Caption = "VariableCollection View";
+      this.variableCollectionView.Content = null;
+      this.variableCollectionView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.variableCollectionView.Location = new System.Drawing.Point(0, 0);
+      this.variableCollectionView.Name = "variableCollectionView";
+      this.variableCollectionView.ReadOnly = false;
+      this.variableCollectionView.ShowDetails = true;
+      this.variableCollectionView.Size = new System.Drawing.Size(645, 249);
+      this.variableCollectionView.TabIndex = 0;
+      // 
+      // VariablesNodeView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.splitContainer);
+      this.Name = "VariablesNodeView";
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      this.Controls.SetChildIndex(this.splitContainer, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    protected PortCollectionView portCollectionView;
+    protected System.Windows.Forms.SplitContainer splitContainer;
+    protected Core.Views.VariableCollectionView variableCollectionView;
+
+
+  }
+}
Index: branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/VariablesNodeView.cs
===================================================================
--- branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/VariablesNodeView.cs	(revision 11412)
+++ branches/OptimizationNetworks/HeuristicLab.Optimization.Networks.Views/3.3/VariablesNodeView.cs	(revision 11412)
@@ -0,0 +1,54 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.PluginInfrastructure;
+using System;
+using System.Windows.Forms;
+
+namespace HeuristicLab.Optimization.Networks.Views {
+  [View("VariablesNode View")]
+  [Content(typeof(VariablesNode), true)]
+  [Content(typeof(IVariablesNode), false)]
+  public partial class VariablesNodeView : NodeView {
+    public new IVariablesNode Content {
+      get { return (IVariablesNode)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public VariablesNodeView() {
+      InitializeComponent();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      portCollectionView.Content = Content == null ? null : Content.Ports;
+      variableCollectionView.Content = Content == null ? null : Content.Variables;
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      portCollectionView.Enabled = Content != null && !ReadOnly;
+      variableCollectionView.Enabled = Content != null && !ReadOnly;
+    }
+  }
+}
Index: branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/AlgorithmNode.cs
===================================================================
--- branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/AlgorithmNode.cs	(revision 11409)
+++ branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/AlgorithmNode.cs	(revision 11412)
@@ -83,5 +83,5 @@
         if (algorithm.Parameters.TryGetValue(port.Name, out param)) {
           IValueParameter p = param as IValueParameter;
-          if (p != null) {
+          if ((p != null) && (port.Value != null)) {
             p.Value = (IItem)port.Value;
           }
Index: branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/HeuristicLab.Optimization.Networks-3.3.csproj
===================================================================
--- branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/HeuristicLab.Optimization.Networks-3.3.csproj	(revision 11409)
+++ branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/HeuristicLab.Optimization.Networks-3.3.csproj	(revision 11412)
@@ -48,4 +48,6 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="IVariablesNode.cs" />
+    <Compile Include="VariablesNode.cs" />
     <Compile Include="EventArgs.cs" />
     <Compile Include="IInputOutputPort.cs" />
Index: branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/IInputOutputPort.cs
===================================================================
--- branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/IInputOutputPort.cs	(revision 11409)
+++ branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/IInputOutputPort.cs	(revision 11412)
@@ -26,4 +26,6 @@
   public interface IInputOutputPort : IPort {
     IOutputInputPort OutputInputPort { get; }
+
+    event EventHandler OutputInputPortChanged;
   }
 
Index: branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/IInputPort.cs
===================================================================
--- branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/IInputPort.cs	(revision 11409)
+++ branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/IInputPort.cs	(revision 11412)
@@ -20,10 +20,12 @@
 #endregion
 
+using HeuristicLab.Core;
 using System;
-using HeuristicLab.Core;
 
 namespace HeuristicLab.Optimization.Networks {
   public interface IInputPort : IPort {
-    IOutputPort OutputPort { get; }
+    IOutputPort OutputPort { get; set; }
+
+    event EventHandler OutputPortChanged;
   }
 
Index: branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/IVariablesNode.cs
===================================================================
--- branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/IVariablesNode.cs	(revision 11412)
+++ branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/IVariablesNode.cs	(revision 11412)
@@ -0,0 +1,31 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using System;
+
+namespace HeuristicLab.Optimization.Networks {
+  public interface IVariablesNode : INode {
+    new PortCollection Ports { get; }
+
+    VariableCollection Variables { get; }
+  }
+}
Index: branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/InputOutputPort.cs
===================================================================
--- branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/InputOutputPort.cs	(revision 11409)
+++ branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/InputOutputPort.cs	(revision 11412)
@@ -82,8 +82,12 @@
 
     protected void RegisterOutputInputPortEvents() {
-      outputInputPort.ValueSent += OutputInputPort_ValueSent;
+      if (outputInputPort != null) {
+        outputInputPort.ValueSent += OutputInputPort_ValueSent;
+      }
     }
     protected void DeregisterOutputInputPortEvents() {
-      outputInputPort.ValueSent -= OutputInputPort_ValueSent;
+      if (outputInputPort != null) {
+        outputInputPort.ValueSent -= OutputInputPort_ValueSent;
+      }
     }
     protected void OutputInputPort_ValueSent(object sender, OutputInputPortEventArgs<TIn, TOut> e) {
Index: branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/InputPort.cs
===================================================================
--- branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/InputPort.cs	(revision 11409)
+++ branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/InputPort.cs	(revision 11412)
@@ -49,4 +49,13 @@
     IOutputPort IInputPort.OutputPort {
       get { return outputPort; }
+      set {
+        var val = value as IOutputPort<T>;
+        if ((value != null) && (val == null))
+          throw new InvalidOperationException(
+            string.Format("Type mismatch. OutputPort is not a \"{0}\".",
+                          typeof(IOutputPort<T>).GetPrettyName())
+          );
+        OutputPort = val;
+      }
     }
 
@@ -77,9 +86,12 @@
 
     protected void RegisterOutputPortEvents() {
-      outputPort.ValueChanged += OutputPort_ValueChanged;
-      
+      if (outputPort != null) {
+        outputPort.ValueChanged += OutputPort_ValueChanged;
+      }
     }
     protected void DeregisterOutputPortEvents() {
-      outputPort.ValueChanged -= OutputPort_ValueChanged;
+      if (outputPort != null) {
+        outputPort.ValueChanged -= OutputPort_ValueChanged;
+      }
     }
     protected void OutputPort_ValueChanged(object sender, EventArgs e) {
Index: branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/VariablesNode.cs
===================================================================
--- branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/VariablesNode.cs	(revision 11412)
+++ branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/VariablesNode.cs	(revision 11412)
@@ -0,0 +1,222 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2014 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;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using System;
+
+namespace HeuristicLab.Optimization.Networks {
+  [Item("VariablesNode", "A node of an optimization network which contains variables.")]
+  [StorableClass]
+  public class VariablesNode : Node, IVariablesNode {
+    new public PortCollection Ports {
+      get { return base.Ports; }
+    }
+
+    [Storable]
+    private VariableCollection variables;
+    public VariableCollection Variables {
+      get { return variables; }
+    }
+
+    [StorableConstructor]
+    protected VariablesNode(bool deserializing) : base(deserializing) { }
+    protected VariablesNode(VariablesNode original, Cloner cloner)
+      : base(original, cloner) {
+      variables = cloner.Clone(original.variables);
+      RegisterPortsEvents();
+      RegisterVariablesEvents();
+    }
+    public VariablesNode()
+      : base("VariablesNode") {
+      variables = new VariableCollection();
+      RegisterPortsEvents();
+      RegisterVariablesEvents();
+    }
+    public VariablesNode(string name)
+      : base(name) {
+      variables = new VariableCollection();
+      RegisterPortsEvents();
+      RegisterVariablesEvents();
+    }
+    public VariablesNode(string name, string description)
+      : base(name, description) {
+      variables = new VariableCollection();
+      RegisterPortsEvents();
+      RegisterVariablesEvents();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterPortsEvents();
+      RegisterVariablesEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new VariablesNode(this, cloner);
+    }
+
+    private void UpdateVariable(IInputPort port) {
+      IVariable var = null;
+      if (variables.TryGetValue(port.Name, out var)) {
+        var.Value = (IItem)port.Value;
+      }
+    }
+    private void UpdateOutputPort(IVariable variable) {
+      IPort port = null;
+      if (Ports.TryGetValue(variable.Name, out port)) {
+        IOutputPort p = port as IOutputPort;
+        if (p != null) {
+          p.Value = variable.Value;
+        }
+      }
+    }
+    private void UpdateOutputPort(IOutputPort port) {
+      IVariable var = null;
+      if (variables.TryGetValue(port.Name, out var)) {
+        port.Value = var.Value;
+      } else {
+        port.Value = null;
+      }
+    }
+
+    #region Ports Events
+    private void RegisterPortsEvents() {
+      Ports.ItemsAdded += Ports_ItemsAdded;
+      Ports.ItemsRemoved += Ports_ItemsRemoved;
+      Ports.ItemsReplaced += Ports_ItemsReplaced;
+      Ports.CollectionReset += Ports_CollectionReset;
+      foreach (var p in Ports)
+        RegisterPortEvents(p);
+    }
+    void Ports_ItemsAdded(object sender, Collections.CollectionItemsChangedEventArgs<IPort> e) {
+      foreach (var p in e.Items)
+        RegisterPortEvents(p);
+    }
+    void Ports_ItemsRemoved(object sender, Collections.CollectionItemsChangedEventArgs<IPort> e) {
+      foreach (var p in e.Items)
+        DeregisterPortEvents(p);
+    }
+    void Ports_ItemsReplaced(object sender, Collections.CollectionItemsChangedEventArgs<IPort> e) {
+      foreach (var p in e.OldItems)
+        DeregisterPortEvents(p);
+      foreach (var p in e.Items)
+        RegisterPortEvents(p);
+    }
+    void Ports_CollectionReset(object sender, Collections.CollectionItemsChangedEventArgs<IPort> e) {
+      foreach (var p in e.OldItems)
+        DeregisterPortEvents(p);
+      foreach (var p in e.Items)
+        RegisterPortEvents(p);
+    }
+    #endregion
+
+    #region Port Events
+    private void RegisterPortEvents(IPort port) {
+      IInputPort i = port as IInputPort;
+      if (i != null) {
+        i.NameChanged += InputPort_NameChanged;
+        i.ValueChanged += InputPort_ValueChanged;
+        UpdateVariable(i);
+      }
+      IOutputPort o = port as IOutputPort;
+      if (o != null) {
+        o.NameChanged += OutputPort_NameChanged;
+        UpdateOutputPort(o);
+      }
+    }
+    private void DeregisterPortEvents(IPort port) {
+      IInputPort i = port as IInputPort;
+      if (i != null) {
+        i.NameChanged -= InputPort_NameChanged;
+        i.ValueChanged -= InputPort_ValueChanged;
+      }
+      IOutputPort o = port as IOutputPort;
+      if (o != null) {
+        o.NameChanged -= OutputPort_NameChanged;
+      }
+    }
+    private void InputPort_NameChanged(object sender, EventArgs e) {
+      UpdateVariable((IInputPort)sender);
+    }
+    private void InputPort_ValueChanged(object sender, EventArgs e) {
+      UpdateVariable((IInputPort)sender);
+    }
+    private void OutputPort_NameChanged(object sender, EventArgs e) {
+      UpdateOutputPort((IOutputPort)sender);
+    }
+    #endregion
+
+    #region Variables Events
+    private void RegisterVariablesEvents() {
+      variables.ItemsAdded += Variables_ItemsAdded;
+      variables.ItemsRemoved += Variables_ItemsRemoved;
+      variables.ItemsReplaced += Variables_ItemsReplaced;
+      variables.CollectionReset += Variables_CollectionReset;
+      foreach (var v in variables)
+        RegisterVariableEvents(v);
+    }
+    private void Variables_ItemsAdded(object sender, Collections.CollectionItemsChangedEventArgs<IVariable> e) {
+      foreach (var v in e.Items)
+        RegisterVariableEvents(v);
+    }
+    private void Variables_ItemsRemoved(object sender, Collections.CollectionItemsChangedEventArgs<IVariable> e) {
+      foreach (var v in e.Items)
+        DeregisterVariableEvents(v);
+    }
+    private void Variables_ItemsReplaced(object sender, Collections.CollectionItemsChangedEventArgs<IVariable> e) {
+      foreach (var v in e.OldItems)
+        DeregisterVariableEvents(v);
+      foreach (var v in e.Items)
+        RegisterVariableEvents(v);
+    }
+    private void Variables_CollectionReset(object sender, Collections.CollectionItemsChangedEventArgs<IVariable> e) {
+      foreach (var v in e.OldItems)
+        DeregisterVariableEvents(v);
+      foreach (var v in e.Items)
+        RegisterVariableEvents(v);
+    }
+    #endregion
+
+    #region Variable Events
+    private void RegisterVariableEvents(IVariable variable) {
+      if (variable != null) {
+        variable.ValueChanged += Variable_ValueChanged;
+        variable.ToStringChanged += Variable_ToStringChanged;
+        UpdateOutputPort(variable);
+      }
+    }
+    private void DeregisterVariableEvents(IVariable variable) {
+      if (variable != null) {
+        variable.ValueChanged -= Variable_ValueChanged;
+        variable.ToStringChanged += Variable_ToStringChanged;
+      }
+    }
+    private void Variable_ValueChanged(object sender, EventArgs e) {
+      UpdateOutputPort((IVariable)sender);
+    }
+    private void Variable_ToStringChanged(object sender, EventArgs e) {
+      UpdateOutputPort((IVariable)sender);
+    }
+    #endregion
+  }
+}
