Index: /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/GenericPort.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/GenericPort.cs	(revision 11490)
+++ /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/GenericPort.cs	(revision 11490)
@@ -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;
+using System.Drawing;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace HeuristicLab.Optimization.Networks {
+  [Item("GenericPort", "A generic port of an optimization network node.")]
+  [StorableClass]
+  public class GenericPort : ParameterizedPort, IGenericPort, IConnectedPort {
+    public override Image ItemImage {
+      get {
+        if (PortConnectionValid) return base.ItemImage;
+        else return HeuristicLab.Common.Resources.VSImageLibrary.Error;
+      }
+    }
+
+    [Storable]
+    protected IConnectedPort connectedPort;
+    public IConnectedPort ConnectedPort {
+      get { return connectedPort; }
+      set {
+        if (connectedPort != value) {
+          DeregisterConnectedPortEvents();
+          connectedPort = value;
+          RegisterConnectedPortEvents();
+          OnConnectedPortChanged();
+          OnInterfaceChanged();
+        }
+      }
+    }
+    [Storable]
+    protected bool portConnectionValid;
+    public bool PortConnectionValid {
+      get { return portConnectionValid; }
+      protected set {
+        if (value != portConnectionValid) {
+          portConnectionValid = value;
+          OnItemImageChanged();
+        }
+      }
+    }
+
+    [StorableConstructor]
+    protected GenericPort(bool deserializing) : base(deserializing) { }
+    protected GenericPort(GenericPort original, Cloner cloner) : base(original, cloner) {
+      connectedPort = cloner.Clone(original.connectedPort);
+      portConnectionValid = original.portConnectionValid;
+      RegisterConnectedPortEvents();
+    }
+    public GenericPort() : base("GenericPort") { }
+    public GenericPort(string name) : base(name) { }
+    public GenericPort(string name, string description) : base(name, description) { }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterConnectedPortEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GenericPort(this, cloner);
+    }
+
+    public bool CanConnectToPort(IPort port) {
+      if (port == null) return true;
+
+      var cp = port as IConnectedPort;
+      if (cp == null) return false;
+
+      // check connected port input parameters
+      foreach (var input in cp.Parameters.Where(p => p.Type.HasFlag(PortParameterType.Input))) {
+        IPortParameter param;
+        Parameters.TryGetValue(input.Name, out param);
+        if ((param == null) && (input.DefaultValue == null)) return false;
+        if (!param.Type.HasFlag(PortParameterType.Output)) return false;
+        if (!input.DataType.IsAssignableFrom(param.DataType)) return false;
+      }
+      // check local port input parameters
+      foreach (var input in Parameters.Where(p => p.Type.HasFlag(PortParameterType.Input))) {
+        IPortParameter param;
+        cp.Parameters.TryGetValue(input.Name, out param);
+        if ((param == null) && (input.DefaultValue == null)) return false;
+        if (!param.Type.HasFlag(PortParameterType.Output)) return false;
+        if (!input.DataType.IsAssignableFrom(param.DataType)) return false;
+      }
+      return true;
+    }
+    public void CloneConnectedPortParameters() {
+      Parameters.Clear();
+      foreach (var p in connectedPort.Parameters) {
+        var param = (IPortParameter)p.Clone();
+        if (!(param.Type.HasFlag(PortParameterType.Input) && param.Type.HasFlag(PortParameterType.Output))) {
+          param.Type = ~param.Type;  // bitwise negation: input -> output, output -> input
+        }
+        Parameters.Add(param);
+      }
+    }
+
+    public IMessage PrepareMessage() {
+      if (!PortConnectionValid) throw new InvalidOperationException("Port connection is not valid");
+      var message = new Message();
+
+      // collect output parameters from local port
+      message.Values.AddRange(
+        Parameters.
+        Where(p => p.Type.HasFlag(PortParameterType.Output)).
+        Select(p => p.CreateMessageValue())
+      );
+
+      // collect remaining input parameters from connected port
+      if (ConnectedPort != null) {
+        message.Values.AddRange(
+          ConnectedPort.Parameters.
+          Where(p => p.Type.HasFlag(PortParameterType.Input) && !message.Values.ContainsKey(p.Name)).
+          Select(p => p.CreateMessageValue())
+        );
+      }
+
+      // collect output parameters from connected port
+      if (ConnectedPort != null) {
+        message.Values.AddRange(
+          ConnectedPort.Parameters.
+          Where(p => p.Type.HasFlag(PortParameterType.Output)).
+          Select(p => p.CreateMessageValue())
+        );
+      }
+
+      // collect remaining input parameters from local port
+      message.Values.AddRange(
+        Parameters.
+        Where(p => p.Type.HasFlag(PortParameterType.Input) && !message.Values.ContainsKey(p.Name)).
+        Select(p => p.CreateMessageValue())
+      );
+
+      return message;
+    }
+    public void SendMessage(IMessage message) {
+      SendMessage(message, CancellationToken.None);
+    }
+    public void SendMessage(IMessage message, CancellationToken token) {
+      if (!PortConnectionValid) throw new InvalidOperationException("Port connection is not valid");
+      if (ConnectedPort != null) ConnectedPort.ReceiveMessage(message, token);
+      OnMessageSent(message, token);
+    }
+    public async Task SendMessageAsync(IMessage message) {
+      await SendMessageAsync(message, CancellationToken.None);
+    }
+    public async Task SendMessageAsync(IMessage message, CancellationToken token) {
+      await Task.Run(() => { SendMessage(message, token); }, token);
+    }
+    public event EventHandler<EventArgs<IMessage, CancellationToken>> MessageSent;
+    protected virtual void OnMessageSent(IMessage message, CancellationToken token) {
+      var handler = MessageSent;
+      if (handler != null) handler(this, new EventArgs<IMessage, CancellationToken>(message, token));
+    }
+
+    public void ReceiveMessage(IMessage message, CancellationToken token) {
+      OnMessageReceived(message, token);
+    }
+    public event EventHandler<EventArgs<IMessage, CancellationToken>> MessageReceived;
+    protected virtual void OnMessageReceived(IMessage message, CancellationToken token) {
+      var handler = MessageReceived;
+      if (handler != null) handler(this, new EventArgs<IMessage, CancellationToken>(message, token));
+    }
+
+    public event EventHandler ConnectedPortChanged;
+    protected virtual void OnConnectedPortChanged() {
+      var handler = ConnectedPortChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    protected override void OnInterfaceChanged() {
+      PortConnectionValid = (connectedPort != null) && CanConnectToPort(connectedPort);
+      base.OnInterfaceChanged();
+    }
+
+    #region ConnectedPort Events
+    protected virtual void RegisterConnectedPortEvents() {
+      if (connectedPort != null) {
+        connectedPort.InterfaceChanged += ConnectedPort_InterfaceChanged;
+        connectedPort.MessageSent += ConnectedPort_MessageSent;
+      }
+    }
+    protected virtual void DeregisterConnectedPortEvents() {
+      if (connectedPort != null) {
+        connectedPort.InterfaceChanged -= ConnectedPort_InterfaceChanged;
+        connectedPort.MessageSent -= ConnectedPort_MessageSent;
+      }
+    }
+    protected virtual void ConnectedPort_InterfaceChanged(object sender, EventArgs e) {
+      OnInterfaceChanged();
+    }
+    protected virtual void ConnectedPort_MessageSent(object sender, EventArgs<IMessage, CancellationToken> e) {
+      ReceiveMessage(e.Value, e.Value2);
+    }
+    #endregion
+  }
+}
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 11489)
+++ /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/HeuristicLab.Optimization.Networks-3.3.csproj	(revision 11490)
@@ -92,7 +92,9 @@
     <Compile Include="ClientNode.cs" />
     <Compile Include="AlgorithmServiceNode.cs" />
+    <Compile Include="IConnectedPort.cs" />
     <Compile Include="IGenericPort.cs" />
     <Compile Include="IMessage.cs" />
     <Compile Include="IMessageValue.cs" />
+    <Compile Include="Message.cs" />
     <Compile Include="ParameterizedPort.cs" />
     <Compile Include="IClientNode.cs" />
@@ -119,4 +121,5 @@
     <Compile Include="ClientServicePort.cs" />
     <Compile Include="ClientPort.cs" />
+    <Compile Include="GenericPort.cs" />
     <Compile Include="ServicePort.cs" />
     <Compile Include="Port.cs" />
Index: /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/IConnectedPort.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/IConnectedPort.cs	(revision 11490)
+++ /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/IConnectedPort.cs	(revision 11490)
@@ -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.Common;
+using System;
+using System.Threading;
+
+namespace HeuristicLab.Optimization.Networks {
+  public interface IConnectedPort : IParameterizedPort {
+    void ReceiveMessage(IMessage message, CancellationToken token);
+    event EventHandler<EventArgs<IMessage, CancellationToken>> MessageSent;
+  }
+}
Index: /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/IGenericPort.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/IGenericPort.cs	(revision 11489)
+++ /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/IGenericPort.cs	(revision 11490)
@@ -27,5 +27,5 @@
 namespace HeuristicLab.Optimization.Networks {
   public interface IGenericPort : IParameterizedPort {
-    IGenericPort ConnectedPort { get; set; }
+    IConnectedPort ConnectedPort { get; set; }
     bool PortConnectionValid { get; }
 
@@ -40,10 +40,5 @@
     Task SendMessageAsync(IMessage message);
     Task SendMessageAsync(IMessage message, CancellationToken token);
-    event EventHandler<EventArgs<IMessage, CancellationToken>> MessageSent;
 
-    void ReceiveMessage(IMessage message);
-    void ReceiveMessage(IMessage message, CancellationToken token);
-    Task ReceiveMessageAsync(IMessage message);
-    Task ReceiveMessageAsync(IMessage message, CancellationToken token);
     event EventHandler<EventArgs<IMessage, CancellationToken>> MessageReceived;
   }
Index: /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/IMessage.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/IMessage.cs	(revision 11489)
+++ /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/IMessage.cs	(revision 11490)
@@ -20,8 +20,10 @@
 #endregion
 
+using HeuristicLab.Core;
 
 namespace HeuristicLab.Optimization.Networks {
-  public interface IMessage {
+  public interface IMessage : IItem {
     MessageValueCollection Values { get; }
+    IItem this[string valueName] { get; }
   }
 }
Index: /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/IPortParameter.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/IPortParameter.cs	(revision 11489)
+++ /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/IPortParameter.cs	(revision 11490)
@@ -28,12 +28,16 @@
     Type DataType { get; }
     PortParameterType Type { get; set; }
-    IItem Value { get; set; }
+    IItem DefaultValue { get; set; }
 
     event EventHandler TypeChanged;
     event EventHandler ValueChanged;
+
+    IMessageValue CreateMessageValue();
   }
 
   public interface IPortParameter<T> : IPortParameter where T : class, IItem {
-    new T Value { get; set; }
+    new T DefaultValue { get; set; }
+
+    new IMessageValue<T> CreateMessageValue();
   }
 }
Index: /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/Message.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/Message.cs	(revision 11490)
+++ /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/Message.cs	(revision 11490)
@@ -0,0 +1,58 @@
+#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.Drawing;
+
+namespace HeuristicLab.Optimization.Networks {
+  [Item("Message", "A message sent between ports.")]
+  [StorableClass]
+  public class Message : Item, IMessage {
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Field; }
+    }
+
+    [Storable]
+    protected MessageValueCollection values;
+    public MessageValueCollection Values {
+      get { return values; }
+    }
+    public IItem this[string valueName] {
+      get { return Values[valueName].Value; }
+    }
+
+    [StorableConstructor]
+    protected Message(bool deserializing) : base(deserializing) { }
+    protected Message(Message original, Cloner cloner)
+      : base(original, cloner) {
+      values = cloner.Clone(original.values);
+    }
+    public Message() {
+      values = new MessageValueCollection();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Message(this, cloner);
+    }
+  }
+}
Index: /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/PortParameter.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/PortParameter.cs	(revision 11489)
+++ /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/PortParameter.cs	(revision 11490)
@@ -63,18 +63,18 @@
     }
     [Storable]
-    protected T value;
-    public T Value {
-      get { return value; }
+    protected T defaultValue;
+    public T DefaultValue {
+      get { return defaultValue; }
       set {
-        if (value != this.value) {
-          DeregisterValueEvents();
-          this.value = value;
-          RegisterValueEvents();
+        if (value != this.defaultValue) {
+          DeregisterDefaultValueEvents();
+          this.defaultValue = value;
+          RegisterDefaultValueEvents();
           OnValueChanged();
         }
       }
     }
-    IItem IPortParameter.Value {
-      get { return Value; }
+    IItem IPortParameter.DefaultValue {
+      get { return DefaultValue; }
       set {
         T val = value as T;
@@ -84,5 +84,5 @@
                           typeof(T).GetPrettyName())
           );
-        Value = val;
+        DefaultValue = val;
       }
     }
@@ -93,6 +93,6 @@
       : base(original, cloner) {
       this.type = original.type;
-      this.value = cloner.Clone(original.value);
-      RegisterValueEvents();
+      this.defaultValue = cloner.Clone(original.defaultValue);
+      RegisterDefaultValueEvents();
     }
     public PortParameter() : base("PortParameter") { }
@@ -102,5 +102,5 @@
     [StorableHook(HookType.AfterDeserialization)]
     private void AfterDeserialization() {
-      RegisterValueEvents();
+      RegisterDefaultValueEvents();
     }
 
@@ -111,6 +111,6 @@
     public override string ToString() {
       var s = base.ToString();
-      if (Value != null)
-        s += ": " + Value.ToString();
+      if (DefaultValue != null)
+        s += ": " + DefaultValue.ToString();
       return s;
     }
@@ -129,17 +129,30 @@
       OnToStringChanged();
     }
-    protected virtual void RegisterValueEvents() {
-      if (value != null) {
-        value.ToStringChanged += new EventHandler(Value_ToStringChanged);
+
+    public IMessageValue<T> CreateMessageValue() {
+      if (DefaultValue == null)
+        return new MessageValue<T>(Name);
+      else
+        return new MessageValue<T>(Name, (T)DefaultValue.Clone());
+    }
+    IMessageValue IPortParameter.CreateMessageValue() {
+      return CreateMessageValue();
+    }
+
+    #region DefaultValue Events
+    protected virtual void RegisterDefaultValueEvents() {
+      if (defaultValue != null) {
+        defaultValue.ToStringChanged += new EventHandler(DefaultValue_ToStringChanged);
       }
     }
-    protected virtual void DeregisterValueEvents() {
-      if (value != null) {
-        value.ToStringChanged -= new EventHandler(Value_ToStringChanged);
+    protected virtual void DeregisterDefaultValueEvents() {
+      if (defaultValue != null) {
+        defaultValue.ToStringChanged -= new EventHandler(DefaultValue_ToStringChanged);
       }
     }
-    private void Value_ToStringChanged(object sender, EventArgs e) {
+    private void DefaultValue_ToStringChanged(object sender, EventArgs e) {
       OnToStringChanged();
     }
+    #endregion
   }
 }
Index: /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/PortParameterType.cs
===================================================================
--- /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/PortParameterType.cs	(revision 11489)
+++ /branches/OptimizationNetworks/HeuristicLab.Optimization.Networks/3.3/PortParameterType.cs	(revision 11490)
@@ -20,9 +20,11 @@
 #endregion
 
+using System;
 
 namespace HeuristicLab.Optimization.Networks {
+  [Flags]
   public enum PortParameterType {
-    Input,
-    Output
+    Input = 1,
+    Output = 2
   }
 }
