Index: lemon/bits/iterable_graph_extender.h
===================================================================
--- lemon/bits/iterable_graph_extender.h	(revision 1704)
+++ lemon/bits/iterable_graph_extender.h	(revision 1820)
@@ -268,4 +268,248 @@
 
   };
+
+
+  template <typename _Base>
+  class IterableUndirBipartiteGraphExtender : public _Base {
+  public:
+    typedef _Base Parent;
+    typedef IterableUndirBipartiteGraphExtender Graph;
+   
+    typedef typename Parent::Node Node;
+    typedef typename Parent::UpperNode UpperNode;
+    typedef typename Parent::LowerNode LowerNode;
+    typedef typename Parent::Edge Edge;
+    typedef typename Parent::UndirEdge UndirEdge;
+  
+    class NodeIt : public Node { 
+      const Graph* graph;
+    public:
+    
+      NodeIt() { }
+    
+      NodeIt(Invalid i) : Node(INVALID) { }
+    
+      explicit NodeIt(const Graph& _graph) : graph(&_graph) {
+	graph->first(static_cast<Node&>(*this));
+      }
+
+      NodeIt(const Graph& _graph, const Node& node) 
+	: Node(node), graph(&_graph) { }
+    
+      NodeIt& operator++() { 
+	graph->next(*this);
+	return *this; 
+      }
+
+    };
+
+    class UpperNodeIt : public Node { 
+      friend class IterableUndirBipartiteGraphExtender;
+      const Graph* graph;
+    public:
+    
+      UpperNodeIt() { }
+    
+      UpperNodeIt(Invalid i) : Node(INVALID) { }
+    
+      explicit UpperNodeIt(const Graph& _graph) : graph(&_graph) {
+	graph->firstUpper(static_cast<Node&>(*this));
+      }
+
+      UpperNodeIt(const Graph& _graph, const Node& node) 
+	: Node(node), graph(&_graph) {}
+    
+      UpperNodeIt& operator++() { 
+	graph->nextUpper(*this);
+	return *this; 
+      }
+    };
+
+    class LowerNodeIt : public Node { 
+      friend class IterableUndirBipartiteGraphExtender;
+      const Graph* graph;
+    public:
+    
+      LowerNodeIt() { }
+    
+      LowerNodeIt(Invalid i) : Node(INVALID) { }
+    
+      explicit LowerNodeIt(const Graph& _graph) : graph(&_graph) {
+	graph->firstLower(static_cast<Node&>(*this));
+      }
+
+      LowerNodeIt(const Graph& _graph, const Node& node) 
+	: Node(node), graph(&_graph) {}
+    
+      LowerNodeIt& operator++() { 
+	graph->nextLower(*this);
+	return *this; 
+      }
+    };
+
+    class EdgeIt : public Edge { 
+      friend class IterableUndirBipartiteGraphExtender;
+      const Graph* graph;
+    public:
+    
+      EdgeIt() { }
+    
+      EdgeIt(Invalid i) : Edge(INVALID) { }
+    
+      explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
+	graph->first(static_cast<Edge&>(*this));
+      }
+
+      EdgeIt(const Graph& _graph, const Edge& edge) 
+	: Edge(edge), graph(&_graph) { }
+    
+      EdgeIt& operator++() { 
+	graph->next(*this);
+	return *this; 
+      }
+
+    };
+
+    class UndirEdgeIt : public UndirEdge { 
+      friend class IterableUndirBipartiteGraphExtender;
+      const Graph* graph;
+    public:
+    
+      UndirEdgeIt() { }
+    
+      UndirEdgeIt(Invalid i) : UndirEdge(INVALID) { }
+    
+      explicit UndirEdgeIt(const Graph& _graph) : graph(&_graph) {
+	graph->first(static_cast<UndirEdge&>(*this));
+      }
+
+      UndirEdgeIt(const Graph& _graph, const UndirEdge& edge) 
+	: UndirEdge(edge), graph(&_graph) { }
+    
+      UndirEdgeIt& operator++() { 
+	graph->next(*this);
+	return *this; 
+      }
+    };
+
+    class OutEdgeIt : public Edge { 
+      friend class IterableUndirBipartiteGraphExtender;
+      const Graph* graph;
+    public:
+    
+      OutEdgeIt() { }
+    
+      OutEdgeIt(Invalid i) : Edge(i) { }
+    
+      OutEdgeIt(const Graph& _graph, const Node& node) 
+	: graph(&_graph) {
+	graph->firstOut(*this, node);
+      }
+    
+      OutEdgeIt(const Graph& _graph, const Edge& edge) 
+	: Edge(edge), graph(&_graph) {}
+    
+      OutEdgeIt& operator++() { 
+	graph->nextOut(*this);
+	return *this; 
+      }
+
+    };
+
+
+    class InEdgeIt : public Edge { 
+      friend class IterableUndirBipartiteGraphExtender;
+      const Graph* graph;
+    public:
+    
+      InEdgeIt() { }
+    
+      InEdgeIt(Invalid i) : Edge(i) { }
+    
+      InEdgeIt(const Graph& _graph, const Node& node) 
+	: graph(&_graph) {
+	graph->firstIn(*this, node);
+      }
+    
+      InEdgeIt(const Graph& _graph, const Edge& edge) : 
+	Edge(edge), graph(&_graph) {}
+    
+      InEdgeIt& operator++() { 
+	graph->nextIn(*this);
+	return *this; 
+      }
+
+    };
+  
+    /// \brief Base node of the iterator
+    ///
+    /// Returns the base node (ie. the source in this case) of the iterator
+    Node baseNode(const OutEdgeIt &e) const {
+      return Parent::source((Edge&)e);
+    }
+    /// \brief Running node of the iterator
+    ///
+    /// Returns the running node (ie. the target in this case) of the
+    /// iterator
+    Node runningNode(const OutEdgeIt &e) const {
+      return Parent::target((Edge&)e);
+    }
+  
+    /// \brief Base node of the iterator
+    ///
+    /// Returns the base node (ie. the target in this case) of the iterator
+    Node baseNode(const InEdgeIt &e) const {
+      return Parent::target((Edge&)e);
+    }
+    /// \brief Running node of the iterator
+    ///
+    /// Returns the running node (ie. the source in this case) of the
+    /// iterator
+    Node runningNode(const InEdgeIt &e) const {
+      return Parent::source((Edge&)e);
+    }
+  
+    class IncEdgeIt : public Parent::UndirEdge { 
+      friend class IterableUndirBipartiteGraphExtender;
+      const Graph* graph;
+      bool direction;
+    public:
+    
+      IncEdgeIt() { }
+    
+      IncEdgeIt(Invalid i) : UndirEdge(i), direction(true) { }
+    
+      IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) {
+	graph->firstInc(*this, direction, n);
+      }
+
+      IncEdgeIt(const Graph& _graph, const UndirEdge &ue, const Node &n)
+	: graph(&_graph), UndirEdge(ue) {
+	direction = (graph->source(ue) == n);
+      }
+
+      IncEdgeIt& operator++() {
+	graph->nextInc(*this, direction);
+	return *this; 
+      }
+    };
+  
+
+    /// Base node of the iterator
+    ///
+    /// Returns the base node of the iterator
+    Node baseNode(const IncEdgeIt &e) const {
+      return e.direction ? source(e) : target(e);
+    }
+
+    /// Running node of the iterator
+    ///
+    /// Returns the running node of the iterator
+    Node runningNode(const IncEdgeIt &e) const {
+      return e.direction ? target(e) : source(e);
+    }
+  
+  };
+
 }
 
