Index: trunk/sources/HeuristicLab.Core/3.3/Collections/DirectedGraph/Arc.cs
===================================================================
--- trunk/sources/HeuristicLab.Core/3.3/Collections/DirectedGraph/Arc.cs	(revision 11241)
+++ trunk/sources/HeuristicLab.Core/3.3/Collections/DirectedGraph/Arc.cs	(revision 11241)
@@ -0,0 +1,118 @@
+﻿#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 System;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Core {
+  /// <summary>
+  /// An arc that can have a weight, a label, and a data object for holding additional info
+  /// </summary>
+  [StorableClass]
+  public class Arc : Item, IArc {
+    [Storable]
+    public IVertex Source { get; private set; }
+
+    [Storable]
+    public IVertex Target { get; private set; }
+
+    [Storable]
+    protected string label;
+    public string Label {
+      get { return label; }
+      set {
+        if (label.Equals(value)) return;
+        label = value;
+        OnChanged(this, EventArgs.Empty);
+      }
+    }
+
+    [Storable]
+    protected double weight;
+    public double Weight {
+      get { return weight; }
+      set {
+        if (weight.Equals(value)) return;
+        weight = value;
+        OnChanged(this, EventArgs.Empty);
+      }
+    }
+
+    [Storable]
+    protected IDeepCloneable data;
+    public IDeepCloneable Data {
+      get { return data; }
+      set {
+        if (data == value) return;
+        data = value;
+        OnChanged(this, EventArgs.Empty);
+      }
+    }
+
+    [StorableConstructor]
+    public Arc(bool deserializing) : base(deserializing) { }
+
+    public Arc(IVertex source, IVertex target) {
+      Source = source;
+      Target = target;
+    }
+
+    protected Arc(Arc original, Cloner cloner)
+      : base(original, cloner) {
+      Source = cloner.Clone(original.Source);
+      Target = cloner.Clone(original.Target);
+      label = original.Label;
+      weight = original.Weight;
+      data = cloner.Clone(data);
+    }
+    public override IDeepCloneable Clone(Cloner cloner) { return new Arc(this, cloner); }
+
+    public event EventHandler Changed;
+    protected virtual void OnChanged(object sender, EventArgs args) {
+      var changed = Changed;
+      if (changed != null)
+        changed(sender, args);
+    }
+  }
+
+  [StorableClass]
+  public class Arc<T> : Arc, IArc<T> where T : class,IItem {
+    public Arc(bool deserializing)
+      : base(deserializing) {
+    }
+
+    public Arc(IVertex source, IVertex target)
+      : base(source, target) {
+    }
+
+    protected Arc(Arc original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    new public IVertex<T> Source {
+      get { return (IVertex<T>)base.Source; }
+    }
+    new public IVertex<T> Target {
+      get { return (IVertex<T>)base.Target; }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Core/3.3/Collections/DirectedGraph/DirectedGraph.cs
===================================================================
--- trunk/sources/HeuristicLab.Core/3.3/Collections/DirectedGraph/DirectedGraph.cs	(revision 11241)
+++ trunk/sources/HeuristicLab.Core/3.3/Collections/DirectedGraph/DirectedGraph.cs	(revision 11241)
@@ -0,0 +1,152 @@
+﻿#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 System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Common.Resources;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Core {
+  [Item("DirectedGraph", "Generic class representing a directed graph with custom vertices and content")]
+  [StorableClass]
+  public class DirectedGraph : Item, IDirectedGraph {
+    public override Image ItemImage { get { return VSImageLibrary.Graph; } }
+
+    private HashSet<IVertex> vertices;
+    [Storable]
+    public IEnumerable<IVertex> Vertices {
+      get { return vertices; }
+      private set { vertices = new HashSet<IVertex>(value); }
+    }
+
+    private HashSet<IArc> arcs;
+    [Storable]
+    public IEnumerable<IArc> Arcs {
+      get { return arcs; }
+      private set { arcs = new HashSet<IArc>(value); }
+    }
+
+    public DirectedGraph() {
+      vertices = new HashSet<IVertex>();
+      arcs = new HashSet<IArc>();
+    }
+
+    protected DirectedGraph(DirectedGraph original, Cloner cloner)
+      : base(original, cloner) {
+      vertices = new HashSet<IVertex>(original.vertices.Select(cloner.Clone));
+      arcs = new HashSet<IArc>(original.arcs.Select(cloner.Clone));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DirectedGraph(this, cloner);
+    }
+
+    [StorableConstructor]
+    protected DirectedGraph(bool serializing)
+      : base(serializing) {
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      foreach (var vertex in vertices) {
+        vertex.ArcAdded += OnArcAdded;
+        vertex.ArcRemoved += OnArcRemoved;
+      }
+
+      foreach (var arc in arcs) {
+        var source = arc.Source;
+        var target = arc.Target;
+        source.AddArc(arc);
+        target.AddArc(arc);
+      }
+    }
+
+    public virtual void Clear() {
+      vertices.Clear();
+      arcs.Clear();
+    }
+
+    public virtual void AddVertex(IVertex vertex) {
+      vertices.Add(vertex);
+      // register event handlers
+      vertex.ArcAdded += OnArcAdded;
+      vertex.ArcRemoved += OnArcRemoved;
+    }
+
+    public virtual void RemoveVertex(IVertex vertex) {
+      vertices.Remove(vertex);
+      // remove connections to/from the removed vertex
+      var arcList = vertex.InArcs.Concat(vertex.OutArcs).ToList(); // avoid invalid operation exception: "collection was modified" below
+      foreach (var arc in arcList)
+        RemoveArc(arc);
+      // deregister event handlers
+      vertex.ArcAdded -= OnArcAdded;
+      vertex.ArcRemoved -= OnArcRemoved;
+    }
+
+    public virtual IArc AddArc(IVertex source, IVertex target) {
+      var arc = new Arc(source, target);
+      AddArc(arc);
+      return arc;
+    }
+
+    public virtual void AddArc(IArc arc) {
+      var source = (Vertex)arc.Source;
+      var target = (Vertex)arc.Target;
+      source.AddArc(arc);
+      target.AddArc(arc);
+      arcs.Add(arc);
+    }
+
+    public virtual void RemoveArc(IArc arc) {
+      arcs.Remove(arc);
+      var source = (Vertex)arc.Source;
+      var target = (Vertex)arc.Target;
+      source.RemoveArc(arc);
+      target.RemoveArc(arc);
+    }
+
+    public event EventHandler ArcAdded;
+    protected virtual void OnArcAdded(object sender, EventArgs<IArc> args) {
+      var arc = args.Value;
+      // the ArcAdded event is fired by a vertex when an arc from or towards another vertex is added to his list of connections
+      // because the arc is added in both directions by both the source and the target, this event will get fired twice 
+      // here, we only want to add the arc once, so if its already contained, we return without complaining
+      if (arcs.Contains(arc)) return;
+      arcs.Add(arc);
+    }
+
+
+    public event EventHandler ArcRemoved;
+    protected virtual void OnArcRemoved(object sender, EventArgs<IArc> args) {
+      var arc = args.Value;
+      if (!arcs.Contains(arc)) return; // the same rationale as above 
+      arcs.Remove(arc);
+    }
+
+    // events
+    public event EventHandler VertexAdded;
+    public event EventHandler VertexRemoved;
+  }
+}
Index: trunk/sources/HeuristicLab.Core/3.3/Collections/DirectedGraph/Vertex.cs
===================================================================
--- trunk/sources/HeuristicLab.Core/3.3/Collections/DirectedGraph/Vertex.cs	(revision 11241)
+++ trunk/sources/HeuristicLab.Core/3.3/Collections/DirectedGraph/Vertex.cs	(revision 11241)
@@ -0,0 +1,173 @@
+﻿#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 System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Core {
+  [StorableClass]
+  public class Vertex : Item, IVertex {
+    [Storable]
+    private string label;
+    public string Label {
+      get { return label; }
+      set {
+        if (label.Equals(value)) return;
+        label = value;
+        OnChanged(this, EventArgs.Empty);
+      }
+    }
+
+    [Storable]
+    private double weight;
+    public double Weight {
+      get { return weight; }
+      set {
+        if (weight.Equals(value)) return;
+        weight = value;
+        OnChanged(this, EventArgs.Empty);
+      }
+    }
+
+    [Storable]
+    private IDeepCloneable data;
+    public IDeepCloneable Data {
+      get { return data; }
+      set {
+        if (data == value) return;
+        data = value;
+        OnChanged(this, EventArgs.Empty);
+      }
+    }
+
+    private readonly List<IArc> inArcs = new List<IArc>();
+    public IEnumerable<IArc> InArcs {
+      get { return inArcs; }
+    }
+
+    private readonly List<IArc> outArcs = new List<IArc>();
+    public IEnumerable<IArc> OutArcs {
+      get { return outArcs; }
+    }
+
+    public int InDegree { get { return InArcs.Count(); } }
+    public int OutDegree { get { return OutArcs.Count(); } }
+    public int Degree { get { return InDegree + OutDegree; } }
+
+    [StorableConstructor]
+    public Vertex(bool deserializing) : base(deserializing) { }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() { }
+
+    public Vertex(IDeepCloneable data) {
+      this.data = data;
+    }
+
+    protected Vertex(Vertex original, Cloner cloner)
+      : base(original, cloner) {
+      data = cloner.Clone(original.Data);
+      label = original.Label;
+      weight = original.Weight;
+
+      inArcs = original.InArcs.Select(cloner.Clone).ToList();
+      outArcs = original.OutArcs.Select(cloner.Clone).ToList();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Vertex(this, cloner);
+    }
+
+    public void AddArc(IArc arc) {
+      if (this != arc.Source && this != arc.Target)
+        throw new InvalidOperationException("The current vertex must be either the arc source or the arc target.");
+
+      if (this == arc.Source) {
+        if (outArcs.Contains(arc)) throw new InvalidOperationException("Arc already added.");
+        outArcs.Add(arc);
+      }
+      if (this == arc.Target) {
+        if (inArcs.Contains(arc)) throw new InvalidOperationException("Arc already added.");
+        inArcs.Add(arc);
+      }
+      OnArcAdded(this, new EventArgs<IArc>(arc));
+    }
+
+    public void RemoveArc(IArc arc) {
+      if (this != arc.Source && this != arc.Target)
+        throw new InvalidOperationException("The current vertex must be either the arc source or the arc target.");
+
+      if (this == arc.Source) {
+        if (!outArcs.Remove(arc)) throw new InvalidOperationException("Arc is not present in this vertex' outgoing arcs.");
+      }
+      if (this == arc.Target) {
+        if (!inArcs.Remove(arc)) throw new InvalidOperationException("Arc is not present in this vertex' incoming arcs.");
+      }
+      OnArcRemoved(this, new EventArgs<IArc>(arc));
+    }
+
+    #region events
+    // use the same event to signal a change in the content, weight or label
+    public event EventHandler Changed;
+    protected virtual void OnChanged(object sender, EventArgs args) {
+      var changed = Changed;
+      if (changed != null)
+        changed(sender, args);
+    }
+
+    public event EventHandler<EventArgs<IArc>> ArcAdded;
+    protected virtual void OnArcAdded(object sender, EventArgs<IArc> args) {
+      var added = ArcAdded;
+      if (added != null)
+        added(sender, args);
+    }
+
+    public event EventHandler<EventArgs<IArc>> ArcRemoved;
+    protected virtual void OnArcRemoved(object sender, EventArgs<IArc> args) {
+      var removed = ArcRemoved;
+      if (removed != null)
+        removed(sender, args);
+    }
+    #endregion
+  }
+
+  [StorableClass]
+  public class Vertex<T> : Vertex, IVertex<T> where T : class,IItem {
+    public new T Data {
+      get { return (T)base.Data; }
+      set { base.Data = value; }
+    }
+
+    [StorableConstructor]
+    protected Vertex(bool deserializing) : base(deserializing) { }
+
+    protected Vertex(Vertex<T> original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Vertex<T>(this, cloner);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Core/3.3/HeuristicLab.Core-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.Core/3.3/HeuristicLab.Core-3.3.csproj	(revision 11214)
+++ trunk/sources/HeuristicLab.Core/3.3/HeuristicLab.Core-3.3.csproj	(revision 11241)
@@ -116,4 +116,7 @@
     <Compile Include="Collections\CheckedItemCollection.cs" />
     <Compile Include="Collections\CheckedItemList.cs" />
+    <Compile Include="Collections\DirectedGraph\Arc.cs" />
+    <Compile Include="Collections\DirectedGraph\DirectedGraph.cs" />
+    <Compile Include="Collections\DirectedGraph\Vertex.cs" />
     <Compile Include="Collections\ReadOnlyCheckedItemCollection.cs" />
     <Compile Include="Collections\ReadOnlyCheckedItemList.cs">
@@ -148,4 +151,7 @@
     <Compile Include="Constraints\IConstraint.cs" />
     <Compile Include="Constraints\TypeCompatibilityConstraint.cs" />
+    <Compile Include="Interfaces\DirectedGraph\IArc.cs" />
+    <Compile Include="Interfaces\DirectedGraph\IDirectedGraph.cs" />
+    <Compile Include="Interfaces\DirectedGraph\IVertex.cs" />
     <Compile Include="Interfaces\ICheckedMultiOperator.cs" />
     <Compile Include="Interfaces\IConstrainedValueParameter.cs" />
Index: trunk/sources/HeuristicLab.Core/3.3/Interfaces/DirectedGraph/IArc.cs
===================================================================
--- trunk/sources/HeuristicLab.Core/3.3/Interfaces/DirectedGraph/IArc.cs	(revision 11241)
+++ trunk/sources/HeuristicLab.Core/3.3/Interfaces/DirectedGraph/IArc.cs	(revision 11241)
@@ -0,0 +1,40 @@
+﻿#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 System;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Core {
+  public interface IArc : IItem {
+    IVertex Source { get; }
+    IVertex Target { get; }
+    string Label { get; set; }
+    double Weight { get; set; }
+    IDeepCloneable Data { get; set; }
+
+    event EventHandler Changed; // generic event for when the label, weight or data were changed
+  }
+
+  public interface IArc<T> : IArc where T : class,IItem {
+    new IVertex<T> Source { get; }
+    new IVertex<T> Target { get; }
+  }
+}
Index: trunk/sources/HeuristicLab.Core/3.3/Interfaces/DirectedGraph/IDirectedGraph.cs
===================================================================
--- trunk/sources/HeuristicLab.Core/3.3/Interfaces/DirectedGraph/IDirectedGraph.cs	(revision 11241)
+++ trunk/sources/HeuristicLab.Core/3.3/Interfaces/DirectedGraph/IDirectedGraph.cs	(revision 11241)
@@ -0,0 +1,41 @@
+﻿#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 System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Core {
+  public interface IDirectedGraph : IItem {
+    void Clear();
+    void AddVertex(IVertex vertex);
+    IArc AddArc(IVertex source, IVertex target);
+    void AddArc(IArc arc);
+    void RemoveVertex(IVertex vertex);
+    void RemoveArc(IArc arc);
+    IEnumerable<IVertex> Vertices { get; }
+    IEnumerable<IArc> Arcs { get; }
+
+    event EventHandler VertexAdded;
+    event EventHandler VertexRemoved;
+    event EventHandler ArcAdded;
+    event EventHandler ArcRemoved;
+  }
+}
Index: trunk/sources/HeuristicLab.Core/3.3/Interfaces/DirectedGraph/IVertex.cs
===================================================================
--- trunk/sources/HeuristicLab.Core/3.3/Interfaces/DirectedGraph/IVertex.cs	(revision 11241)
+++ trunk/sources/HeuristicLab.Core/3.3/Interfaces/DirectedGraph/IVertex.cs	(revision 11241)
@@ -0,0 +1,52 @@
+﻿#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 System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Core {
+  public interface IVertex : IItem {
+    IEnumerable<IArc> InArcs { get; }
+    IEnumerable<IArc> OutArcs { get; }
+
+    int InDegree { get; }
+    int OutDegree { get; }
+    int Degree { get; }
+
+    string Label { get; set; }
+    double Weight { get; set; }
+
+    IDeepCloneable Data { get; set; }
+
+    void AddArc(IArc arc);
+    void RemoveArc(IArc arc);
+
+    event EventHandler Changed; // generic event for when the content, label or weight have changed
+    event EventHandler<EventArgs<IArc>> ArcAdded;
+    event EventHandler<EventArgs<IArc>> ArcRemoved;
+  }
+
+  public interface IVertex<T> : IVertex
+  where T : class {
+    new T Data { get; set; }
+  }
+}
