Index: src/work/marci/merge_node_graph_wrapper.h
===================================================================
--- src/work/marci/merge_node_graph_wrapper.h	(revision 1013)
+++ src/work/marci/merge_node_graph_wrapper.h	(revision 1016)
@@ -271,6 +271,5 @@
     into the node-set of one graph. 
     Specialization for the case when 
-    _Graph1::Node are base and derived _Graph2::Node.
-    NOT YET IMPLEMENTED
+    _Graph1::Node is a base class and _Graph2::Node is derived from it.
    */
   template <typename _Graph1, typename _Graph2>
@@ -290,11 +289,107 @@
     MergeNodeGraphWrapperBase() { }
   public:
-    class Node { };
+    template <typename _Value> class NodeMap;
+
+    class Node : public Graph2Node {
+      friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
+      template <typename _Value> friend class NodeMap;
+    protected:
+      bool backward; //true, iff backward
+    public:
+      Node() { }
+      /// \todo =false is needed, or causes problems?
+      /// If \c _backward is false, then we get an edge corresponding to the 
+      /// original one, otherwise its oppositely directed pair is obtained.
+      Node(const Graph1Node& n1, 
+	   const Graph2Node& n2, bool _backward) : 
+	Graph2Node(n2), backward(_backward) { 
+	if (!backward) *this=n1;
+      }
+      Node(Invalid i) : Graph2Node(i), backward(true) { }
+      bool operator==(const Node& v) const { 
+	if (backward) 
+	  return (v.backward && 
+		  static_cast<Graph2Node>(*this)==static_cast<Graph2Node>(v)); 
+	else 
+	  return (!v.backward && 
+		  static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v)); 
+      } 
+      bool operator!=(const Node& v) const { 
+	return !(*this==v);
+      }
+    };
+
+    //typedef void Edge;
     class Edge { };
-    void first() const;
-    void next() const;
+    
+    void first(Node& i) const {
+      Parent1::graph->first(*static_cast<Graph1Node*>(&i));
+      i.backward=false;
+      if (*static_cast<Graph1Node*>(&i)==INVALID) {
+	Parent2::graph->first(*static_cast<Graph2Node*>(&i));
+	i.backward=true;
+      }
+    }
+    void next(Node& i) const {
+      if (!(i.backward)) {
+	Parent1::graph->next(*static_cast<Graph1Node*>(&i));
+	if (*static_cast<Graph1Node*>(&i)==INVALID) {
+	  Parent2::graph->first(*static_cast<Graph2Node*>(&i));
+	  i.backward=true;
+	}
+      } else {
+	Parent2::graph->next(*static_cast<Graph2Node*>(&i));
+      }
+    }
+
+    int id(const Node& n) const { 
+      if (!n.backward) 
+	return this->Parent1::graph->id(n);
+      else
+	return this->Parent2::graph->id(n);
+    }
+
+    template <typename _Value> 
+    class NodeMap { 
+    protected:
+      typedef typename _Graph1::template NodeMap<_Value> ParentMap1;
+      typedef typename _Graph2::template NodeMap<_Value> ParentMap2;
+      ParentMap1 forward_map;
+      ParentMap2 backward_map;
+    public:
+      typedef _Value Value;
+      typedef Node Key;
+      NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
+	forward_map(*(gw.Parent1::graph)), 
+	backward_map(*(gw.Parent2::graph)) { }
+      NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw, 
+	      const _Value& value) : 
+	forward_map(*(gw.Parent1::graph), value), 
+	backward_map(*(gw.Parent2::graph), value) { }
+      _Value operator[](const Node& n) const {
+	if (!n.backward) 
+	  return forward_map[n];
+	else 
+	  return backward_map[n];
+      }
+      void set(const Node& n, const _Value& value) {
+	if (!n.backward) 
+	  forward_map.set(n, value);
+	else 
+	  backward_map.set(n, value);
+      }
+//       using ParentMap1::operator[];
+//       using ParentMap2::operator[];
+    };
+
   };
 
-  //not yet working
+
+  /*! A graph wrapper base class 
+    for merging the node-set of two node-disjoint graphs 
+    into the node-set of one graph. 
+    Specialized implementaton for the case when _Graph1::Node is derived 
+    from _Graph2::Node.
+   */
   template <typename _Graph1, typename _Graph2>
   class MergeNodeGraphWrapperBase<
@@ -313,8 +408,98 @@
     MergeNodeGraphWrapperBase() { }
   public:
-    class Node { };
+    template <typename _Value> class NodeMap;
+
+    class Node : public Graph1Node {
+      friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
+      template <typename _Value> friend class NodeMap;
+    protected:
+      bool backward; //true, iff backward
+    public:
+      Node() { }
+      /// \todo =false is needed, or causes problems?
+      /// If \c _backward is false, then we get an edge corresponding to the 
+      /// original one, otherwise its oppositely directed pair is obtained.
+      Node(const Graph1Node& n1, 
+	   const Graph2Node& n2, bool _backward) : 
+	Graph1Node(n1), backward(_backward) { 
+	if (backward) *this=n2;
+      }
+      Node(Invalid i) : Graph1Node(i), backward(true) { }
+      bool operator==(const Node& v) const { 
+	if (backward) 
+	  return (v.backward && 
+		  static_cast<Graph2Node>(*this)==static_cast<Graph2Node>(v)); 
+	else 
+	  return (!v.backward && 
+		  static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v)); 
+      } 
+      bool operator!=(const Node& v) const { 
+	return !(*this==v);
+      }
+    };
+
+    //typedef void Edge;
     class Edge { };
-    void first() const;
-    void next() const;
+    
+    void first(Node& i) const {
+      Parent1::graph->first(*static_cast<Graph1Node*>(&i));
+      i.backward=false;
+      if (*static_cast<Graph1Node*>(&i)==INVALID) {
+	Parent2::graph->first(*static_cast<Graph2Node*>(&i));
+	i.backward=true;
+      }
+    }
+    void next(Node& i) const {
+      if (!(i.backward)) {
+	Parent1::graph->next(*static_cast<Graph1Node*>(&i));
+	if (*static_cast<Graph1Node*>(&i)==INVALID) {
+	  Parent2::graph->first(*static_cast<Graph2Node*>(&i));
+	  i.backward=true;
+	}
+      } else {
+	Parent2::graph->next(*static_cast<Graph2Node*>(&i));
+      }
+    }
+
+    int id(const Node& n) const { 
+      if (!n.backward) 
+	return this->Parent1::graph->id(n);
+      else
+	return this->Parent2::graph->id(n);
+    }
+
+    template <typename _Value> 
+    class NodeMap { 
+    protected:
+      typedef typename _Graph1::template NodeMap<_Value> ParentMap1;
+      typedef typename _Graph2::template NodeMap<_Value> ParentMap2;
+      ParentMap1 forward_map;
+      ParentMap2 backward_map;
+    public:
+      typedef _Value Value;
+      typedef Node Key;
+      NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
+	forward_map(*(gw.Parent1::graph)), 
+	backward_map(*(gw.Parent2::graph)) { }
+      NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw, 
+	      const _Value& value) : 
+	forward_map(*(gw.Parent1::graph), value), 
+	backward_map(*(gw.Parent2::graph), value) { }
+      _Value operator[](const Node& n) const {
+	if (!n.backward) 
+	  return forward_map[n];
+	else 
+	  return backward_map[n];
+      }
+      void set(const Node& n, const _Value& value) {
+	if (!n.backward) 
+	  forward_map.set(n, value);
+	else 
+	  backward_map.set(n, value);
+      }
+//       using ParentMap1::operator[];
+//       using ParentMap2::operator[];
+    };
+
   };
 
@@ -533,5 +718,5 @@
   class MergeEdgeGraphWrapperBase<
     _Graph1, _Graph2, typename boost::enable_if<
-    boost::is_same<typename _Graph1::Node, typename _Graph2::Node> >::type> : 
+    boost::is_same<typename _Graph1::Edge, typename _Graph2::Edge> >::type> : 
     public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
   public:
@@ -701,4 +886,373 @@
 
 
+  /*! A grah wrapper base class 
+    for merging the node-sets and edge-sets of 
+    two node-disjoint graphs 
+    into one graph. 
+    Specialized implementation for the case 
+    when _Graph1::Edge is a base class and _Graph2::Edge
+    is derived from it.
+   */
+  template <typename _Graph1, typename _Graph2>
+  class MergeEdgeGraphWrapperBase<
+    _Graph1, _Graph2, typename boost::enable_if<
+    boost::is_base_and_derived<typename _Graph1::Edge, typename _Graph2::Edge> >::type> : 
+    public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
+  public:
+    static void printEdge() { std::cout << "edge: 2nd is derived" << std::endl; }
+    typedef _Graph1 Graph1;
+    typedef _Graph2 Graph2;
+    typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
+    typedef typename Parent::Parent1 Parent1;
+    typedef typename Parent::Parent2 Parent2;
+//     typedef P1<_Graph1> Parent1;
+//     typedef P2<_Graph2> Parent2;
+    typedef typename Parent1::Edge Graph1Edge;
+    typedef typename Parent2::Edge Graph2Edge;
+  protected:
+    MergeEdgeGraphWrapperBase() { }
+  public:
+    template <typename _Value> class EdgeMap;
+
+    typedef typename Parent::Node Node;
+
+    class Edge : public Graph2Edge {
+      friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
+      template <typename _Value> friend class EdgeMap;
+    protected:
+      bool backward; //true, iff backward
+    public:
+      Edge() { }
+      /// \todo =false is needed, or causes problems?
+      /// If \c _backward is false, then we get an edge corresponding to the 
+      /// original one, otherwise its oppositely directed pair is obtained.
+      Edge(const Graph1Edge& n1, 
+	   const Graph2Edge& n2, bool _backward) : 
+	Graph2Edge(n2), backward(_backward) { 
+	if (!backward) *this=n1;
+      }
+      Edge(Invalid i) : Graph2Edge(i), backward(true) { }
+      bool operator==(const Edge& v) const { 
+	if (backward) 
+	  return (v.backward && 
+		  static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v)); 
+	else 
+	  return (!v.backward && 
+		  static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v)); 
+      } 
+      bool operator!=(const Edge& v) const { 
+	return !(*this==v);
+      }
+    };
+
+    using Parent::first;
+    void first(Edge& i) const {
+      Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
+      i.backward=false;
+      if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+	Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
+	i.backward=true;
+      }
+    }
+    void firstIn(Edge& i, const Node& n) const {
+      Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
+      i.backward=false;
+      if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+	Parent2::graph->firstIn(*static_cast<Graph2Edge*>(&i), n);
+	i.backward=true;
+      }
+    }
+    void firstOut(Edge& i, const Node& n) const {
+      Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
+      i.backward=false;
+      if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+	Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
+	i.backward=true;
+      }
+    }
+
+    using Parent::next;
+    void next(Edge& i) const {
+      if (!(i.backward)) {
+	Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
+	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
+	  i.backward=true;
+	}
+      } else {
+	Parent2::graph->next(*static_cast<Graph2Edge*>(&i));
+      }
+    }
+    void nextIn(Edge& i) const {
+      if (!(i.backward)) {
+	Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
+	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
+	  i.backward=true;
+	}
+      } else {
+	Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
+      }
+    }
+    void nextOut(Edge& i) const {
+      if (!(i.backward)) {
+	Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
+	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
+	  i.backward=true;
+	}
+      } else {
+	Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&i));
+      }
+    }
+
+    Node source(const Edge& i) const {
+      if (!(i.backward)) {
+	return 
+	  Node(Parent1::graph->source(i), INVALID, false);
+      } else {
+	return 
+	  Node(INVALID, Parent2::graph->source(i), true);
+      }
+    }
+
+    Node target(const Edge& i) const {
+      if (!(i.backward)) {
+	return 
+	  Node(Parent1::graph->target(i), INVALID, false);
+      } else {
+	return 
+	  Node(INVALID, Parent2::graph->target(i), true);
+      }
+    }
+
+    using Parent::id;
+    int id(const Edge& n) const { 
+      if (!n.backward) 
+	return this->Parent1::graph->id(n);
+      else
+	return this->Parent2::graph->id(n);
+    }
+
+    template <typename _Value> 
+    class EdgeMap { 
+    protected:
+      typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1;
+      typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2;
+      ParentMap1 forward_map;
+      ParentMap2 backward_map;
+    public:
+      typedef _Value Value;
+      typedef Edge Key;
+      EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
+	forward_map(*(gw.Parent1::graph)), 
+	backward_map(*(gw.Parent2::graph)) { }
+      EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw, 
+	      const _Value& value) : 
+	forward_map(*(gw.Parent1::graph), value), 
+	backward_map(*(gw.Parent2::graph), value) { }
+      _Value operator[](const Edge& n) const {
+	if (!n.backward) 
+	  return forward_map[n];
+	else 
+	  return backward_map[n];
+      }
+      void set(const Edge& n, const _Value& value) {
+	if (!n.backward) 
+	  forward_map.set(n, value);
+	else 
+	  backward_map.set(n, value);
+      }
+//       using ParentMap1::operator[];
+//       using ParentMap2::operator[];
+    };
+
+  };
+
+
+  /*! A grah wrapper base class 
+    for merging the node-sets and edge-sets of 
+    two node-disjoint graphs 
+    into one graph. 
+    Specialized implementation for the case 
+    when _Graph1::Edge is derived from _Graph2::Edge.
+   */
+  template <typename _Graph1, typename _Graph2>
+  class MergeEdgeGraphWrapperBase<
+    _Graph1, _Graph2, typename boost::enable_if<
+    boost::is_base_and_derived<typename _Graph2::Edge, typename _Graph1::Edge> >::type> : 
+    public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
+  public:
+    static void printEdge() { std::cout << "edge: 1st is derived" << std::endl; }
+    typedef _Graph1 Graph1;
+    typedef _Graph2 Graph2;
+    typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
+    typedef typename Parent::Parent1 Parent1;
+    typedef typename Parent::Parent2 Parent2;
+//     typedef P1<_Graph1> Parent1;
+//     typedef P2<_Graph2> Parent2;
+    typedef typename Parent1::Edge Graph1Edge;
+    typedef typename Parent2::Edge Graph2Edge;
+  protected:
+    MergeEdgeGraphWrapperBase() { }
+  public:
+    template <typename _Value> class EdgeMap;
+
+    typedef typename Parent::Node Node;
+
+    class Edge : public Graph1Edge {
+      friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
+      template <typename _Value> friend class EdgeMap;
+    protected:
+      bool backward; //true, iff backward
+    public:
+      Edge() { }
+      /// \todo =false is needed, or causes problems?
+      /// If \c _backward is false, then we get an edge corresponding to the 
+      /// original one, otherwise its oppositely directed pair is obtained.
+      Edge(const Graph1Edge& n1, 
+	   const Graph2Edge& n2, bool _backward) : 
+	Graph1Edge(n1), backward(_backward) { 
+	if (backward) *this=n2;
+      }
+      Edge(Invalid i) : Graph1Edge(i), backward(true) { }
+      bool operator==(const Edge& v) const { 
+	if (backward) 
+	  return (v.backward && 
+		  static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v)); 
+	else 
+	  return (!v.backward && 
+		  static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v)); 
+      } 
+      bool operator!=(const Edge& v) const { 
+	return !(*this==v);
+      }
+    };
+
+    using Parent::first;
+    void first(Edge& i) const {
+      Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
+      i.backward=false;
+      if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+	Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
+	i.backward=true;
+      }
+    }
+    void firstIn(Edge& i, const Node& n) const {
+      Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
+      i.backward=false;
+      if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+	Parent2::graph->firstIn(*static_cast<Graph2Edge*>(&i), n);
+	i.backward=true;
+      }
+    }
+    void firstOut(Edge& i, const Node& n) const {
+      Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
+      i.backward=false;
+      if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+	Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
+	i.backward=true;
+      }
+    }
+
+    using Parent::next;
+    void next(Edge& i) const {
+      if (!(i.backward)) {
+	Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
+	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
+	  i.backward=true;
+	}
+      } else {
+	Parent2::graph->next(*static_cast<Graph2Edge*>(&i));
+      }
+    }
+    void nextIn(Edge& i) const {
+      if (!(i.backward)) {
+	Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
+	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
+	  i.backward=true;
+	}
+      } else {
+	Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
+      }
+    }
+    void nextOut(Edge& i) const {
+      if (!(i.backward)) {
+	Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
+	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
+	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
+	  i.backward=true;
+	}
+      } else {
+	Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&i));
+      }
+    }
+
+    Node source(const Edge& i) const {
+      if (!(i.backward)) {
+	return 
+	  Node(Parent1::graph->source(i), INVALID, false);
+      } else {
+	return 
+	  Node(INVALID, Parent2::graph->source(i), true);
+      }
+    }
+
+    Node target(const Edge& i) const {
+      if (!(i.backward)) {
+	return 
+	  Node(Parent1::graph->target(i), INVALID, false);
+      } else {
+	return 
+	  Node(INVALID, Parent2::graph->target(i), true);
+      }
+    }
+
+    using Parent::id;
+    int id(const Edge& n) const { 
+      if (!n.backward) 
+	return this->Parent1::graph->id(n);
+      else
+	return this->Parent2::graph->id(n);
+    }
+
+    template <typename _Value> 
+    class EdgeMap { 
+    protected:
+      typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1;
+      typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2;
+      ParentMap1 forward_map;
+      ParentMap2 backward_map;
+    public:
+      typedef _Value Value;
+      typedef Edge Key;
+      EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
+	forward_map(*(gw.Parent1::graph)), 
+	backward_map(*(gw.Parent2::graph)) { }
+      EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw, 
+	      const _Value& value) : 
+	forward_map(*(gw.Parent1::graph), value), 
+	backward_map(*(gw.Parent2::graph), value) { }
+      _Value operator[](const Edge& n) const {
+	if (!n.backward) 
+	  return forward_map[n];
+	else 
+	  return backward_map[n];
+      }
+      void set(const Edge& n, const _Value& value) {
+	if (!n.backward) 
+	  forward_map.set(n, value);
+	else 
+	  backward_map.set(n, value);
+      }
+//       using ParentMap1::operator[];
+//       using ParentMap2::operator[];
+    };
+
+  };
+
+
   /*! A graph wrapper class 
     for merging the node-sets and edge-sets of 
