Index: lemon/bits/static_map.h
===================================================================
--- lemon/bits/static_map.h	(revision 1810)
+++ lemon/bits/static_map.h	(revision 1828)
@@ -344,7 +344,271 @@
     };
 
-
   };
 
+  template <typename _Base>
+  class StaticMappableUndirBipartiteGraphExtender : public _Base {
+  public:
+
+    typedef _Base Parent;
+    typedef StaticMappableUndirBipartiteGraphExtender 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;
+    
+    template <typename _Value>
+    class UpperNodeMap 
+      : public IterableMapExtender<StaticMap<Graph, UpperNode, _Value> > {
+    public:
+      typedef StaticMappableUndirBipartiteGraphExtender Graph;
+      typedef IterableMapExtender<StaticMap<Graph, UpperNode, _Value> > 
+      Parent;
+    
+      UpperNodeMap(const Graph& _g) 
+	: Parent(_g) {}
+      UpperNodeMap(const Graph& _g, const _Value& _v) 
+	: Parent(_g, _v) {}
+    
+      UpperNodeMap& operator=(const UpperNodeMap& cmap) {
+	return operator=<UpperNodeMap>(cmap);
+      }
+    
+
+      /// \brief Template assign operator.
+      ///
+      /// The given parameter should be conform to the ReadMap
+      /// concept and could be indiced by the current item set of
+      /// the UpperNodeMap. In this case the value for each item
+      /// is assigned by the value of the given ReadMap. 
+      template <typename CMap>
+      UpperNodeMap& operator=(const CMap& cmap) {
+	checkConcept<concept::ReadMap<UpperNode, _Value>, CMap>();
+	const typename Parent::Graph* graph = Parent::getGraph();
+	UpperNode it;
+	for (graph->first(it); it != INVALID; graph->next(it)) {
+	  Parent::set(it, cmap[it]);
+	}
+	return *this;
+      }
+    
+    };
+
+    template <typename _Value>
+    class LowerNodeMap 
+      : public IterableMapExtender<StaticMap<Graph, LowerNode, _Value> > {
+    public:
+      typedef StaticMappableUndirBipartiteGraphExtender Graph;
+      typedef IterableMapExtender<StaticMap<Graph, LowerNode, _Value> > 
+      Parent;
+    
+      LowerNodeMap(const Graph& _g) 
+	: Parent(_g) {}
+      LowerNodeMap(const Graph& _g, const _Value& _v) 
+	: Parent(_g, _v) {}
+    
+      LowerNodeMap& operator=(const LowerNodeMap& cmap) {
+	return operator=<LowerNodeMap>(cmap);
+      }
+    
+
+      /// \brief Template assign operator.
+      ///
+      /// The given parameter should be conform to the ReadMap
+      /// concept and could be indiced by the current item set of
+      /// the LowerNodeMap. In this case the value for each item
+      /// is assigned by the value of the given ReadMap. 
+      template <typename CMap>
+      LowerNodeMap& operator=(const CMap& cmap) {
+	checkConcept<concept::ReadMap<LowerNode, _Value>, CMap>();
+	const typename Parent::Graph* graph = Parent::getGraph();
+	LowerNode it;
+	for (graph->first(it); it != INVALID; graph->next(it)) {
+	  Parent::set(it, cmap[it]);
+	}
+	return *this;
+      }
+    
+    };
+
+  protected:
+
+    template <typename _Value>
+    class NodeMapBase : public Parent::NodeNotifier::ObserverBase {
+    public:
+      typedef StaticMappableUndirBipartiteGraphExtender Graph;
+
+      typedef Node Key;
+      typedef _Value Value;
+
+      /// The reference type of the map;
+      typedef typename LowerNodeMap<_Value>::Reference Reference;
+      /// The pointer type of the map;
+      typedef typename LowerNodeMap<_Value>::Pointer Pointer;
+      
+      /// The const value type of the map.
+      typedef const Value ConstValue;
+      /// The const reference type of the map;
+      typedef typename LowerNodeMap<_Value>::ConstReference ConstReference;
+      /// The pointer type of the map;
+      typedef typename LowerNodeMap<_Value>::ConstPointer ConstPointer;
+
+      typedef True ReferenceMapTag;
+
+      NodeMapBase(const Graph& _g) 
+	: graph(&_g), lowerMap(_g), upperMap(_g) {
+	Parent::NodeNotifier::ObserverBase::attach(_g.getNotifier(Node()));
+      }
+      NodeMapBase(const Graph& _g, const _Value& _v) 
+	: graph(&_g), lowerMap(_g, _v), 
+	  upperMap(_g, _v) {
+	Parent::NodeNotifier::ObserverBase::attach(_g.getNotifier(Node()));
+      }
+
+      virtual ~NodeMapBase() {      
+	if (Parent::NodeNotifier::ObserverBase::attached()) {
+	  Parent::NodeNotifier::ObserverBase::detach();
+	}
+      }
+    
+      ConstReference operator[](const Key& node) const {
+	if (Parent::upper(node)) {
+	  return upperMap[node];
+	} else {
+	  return lowerMap[node];
+	}
+      } 
+
+      Reference operator[](const Key& node) {
+	if (Parent::upper(node)) {
+	  return upperMap[node];
+	} else {
+	  return lowerMap[node];
+	}
+      }
+
+      void set(const Key& node, const Value& value) {
+	if (Parent::upper(node)) {
+	  upperMap.set(node, value);
+	} else {
+	  lowerMap.set(node, value);
+	}
+      }
+
+    protected:
+      
+      virtual void add(const Node&) {}
+      virtual void erase(const Node&) {}
+      virtual void clear() {}
+      virtual void build() {}
+
+      const Graph* getGraph() const { return graph; }
+      
+    private:
+      const Graph* graph;
+      LowerNodeMap<_Value> lowerMap;
+      UpperNodeMap<_Value> upperMap;
+    };
+    
+  public:
+
+    template <typename _Value>
+    class NodeMap 
+      : public IterableMapExtender<NodeMapBase<_Value> > {
+    public:
+      typedef StaticMappableUndirBipartiteGraphExtender Graph;
+      typedef IterableMapExtender< NodeMapBase<_Value> > Parent;
+    
+      NodeMap(const Graph& _g) 
+	: Parent(_g) {}
+      NodeMap(const Graph& _g, const _Value& _v) 
+	: Parent(_g, _v) {}
+    
+      NodeMap& operator=(const NodeMap& cmap) {
+	return operator=<NodeMap>(cmap);
+      }
+    
+
+      /// \brief Template assign operator.
+      ///
+      /// The given parameter should be conform to the ReadMap
+      /// concept and could be indiced by the current item set of
+      /// the NodeMap. In this case the value for each item
+      /// is assigned by the value of the given ReadMap. 
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+	checkConcept<concept::ReadMap<Node, _Value>, CMap>();
+	const typename Parent::Graph* graph = Parent::getGraph();
+	Node it;
+	for (graph->first(it); it != INVALID; graph->next(it)) {
+	  Parent::set(it, cmap[it]);
+	}
+	return *this;
+      }
+    
+    };
+
+
+
+    template <typename _Value>
+    class EdgeMap 
+      : public IterableMapExtender<StaticMap<Graph, Edge, _Value> > {
+    public:
+      typedef StaticMappableUndirBipartiteGraphExtender Graph;
+      typedef IterableMapExtender<StaticMap<Graph, Edge, _Value> > Parent;
+    
+      EdgeMap(const Graph& _g) 
+	: Parent(_g) {}
+      EdgeMap(const Graph& _g, const _Value& _v) 
+	: Parent(_g, _v) {}
+    
+      EdgeMap& operator=(const EdgeMap& cmap) {
+	return operator=<EdgeMap>(cmap);
+      }
+    
+      template <typename CMap>
+      EdgeMap& operator=(const CMap& cmap) {
+	checkConcept<concept::ReadMap<Edge, _Value>, CMap>();
+	const typename Parent::Graph* graph = Parent::getGraph();
+	Edge it;
+	for (graph->first(it); it != INVALID; graph->next(it)) {
+	  Parent::set(it, cmap[it]);
+	}
+	return *this;
+      }
+    };
+
+    template <typename _Value>
+    class UndirEdgeMap 
+      : public IterableMapExtender<StaticMap<Graph, UndirEdge, _Value> > {
+    public:
+      typedef StaticMappableUndirBipartiteGraphExtender Graph;
+      typedef IterableMapExtender<StaticMap<Graph, UndirEdge, _Value> > 
+      Parent;
+    
+      UndirEdgeMap(const Graph& _g) 
+	: Parent(_g) {}
+      UndirEdgeMap(const Graph& _g, const _Value& _v) 
+	: Parent(_g, _v) {}
+    
+      UndirEdgeMap& operator=(const UndirEdgeMap& cmap) {
+	return operator=<UndirEdgeMap>(cmap);
+      }
+    
+      template <typename CMap>
+      UndirEdgeMap& operator=(const CMap& cmap) {
+	checkConcept<concept::ReadMap<UndirEdge, _Value>, CMap>();
+	const typename Parent::Graph* graph = Parent::getGraph();
+	UndirEdge it;
+	for (graph->first(it); it != INVALID; graph->next(it)) {
+	  Parent::set(it, cmap[it]);
+	}
+	return *this;
+      }
+    };
+  
+  };
+
 }
 
