Index: lemon/graph_utils.h
===================================================================
--- lemon/graph_utils.h	(revision 2287)
+++ lemon/graph_utils.h	(revision 2290)
@@ -616,4 +616,19 @@
     };
 
+    template <typename Graph, typename Item, typename RefMap, typename It>
+    class ItemCopy : public MapCopyBase<Graph, Item, RefMap> {
+    public:
+
+      ItemCopy(It& it, const Item& item) : _it(it), _item(item) {}
+      
+      virtual void copy(const Graph&, const RefMap& refMap) {
+        _it = refMap[_item];
+      }
+
+    private:
+      It& _it;
+      Item _item;
+    };
+
     template <typename Graph, typename Item, typename RefMap, typename Ref>
     class RefCopy : public MapCopyBase<Graph, Item, RefMap> {
@@ -651,4 +666,93 @@
     };
 
+    template <typename Graph, typename Enable = void>
+    struct GraphCopySelector {
+      template <typename Source, typename NodeRefMap, typename EdgeRefMap>
+      static void copy(Graph &target, const Source& source,
+                       NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) {
+        for (typename Source::NodeIt it(source); it != INVALID; ++it) {
+          nodeRefMap[it] = target.addNode();
+        }
+        for (typename Source::EdgeIt it(source); it != INVALID; ++it) {
+          edgeRefMap[it] = target.addEdge(nodeRefMap[source.source(it)], 
+                                          nodeRefMap[source.target(it)]);
+        }
+      }
+    };
+
+    template <typename Graph>
+    struct GraphCopySelector<
+      Graph, 
+      typename enable_if<typename Graph::CloneableTag, void>::type> 
+    {
+      template <typename Source, typename NodeRefMap, typename EdgeRefMap>
+      static void copy(Graph &target, const Source& source,
+                       NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) {
+        target.clone(source, nodeRefMap, edgeRefMap);
+      }
+    };
+
+    template <typename UGraph, typename Enable = void>
+    struct UGraphCopySelector {
+      template <typename Source, typename NodeRefMap, typename UEdgeRefMap>
+      static void copy(UGraph &target, const Source& source,
+                       NodeRefMap& nodeRefMap, UEdgeRefMap& uEdgeRefMap) {
+        for (typename Source::NodeIt it(source); it != INVALID; ++it) {
+          nodeRefMap[it] = target.addNode();
+        }
+        for (typename Source::UEdgeIt it(source); it != INVALID; ++it) {
+          uEdgeRefMap[it] = target.addEdge(nodeRefMap[source.source(it)], 
+                                          nodeRefMap[source.target(it)]);
+        }
+      }
+    };
+
+    template <typename UGraph>
+    struct UGraphCopySelector<
+      UGraph, 
+      typename enable_if<typename UGraph::CloneableTag, void>::type> 
+    {
+      template <typename Source, typename NodeRefMap, typename UEdgeRefMap>
+      static void copy(UGraph &target, const Source& source,
+                       NodeRefMap& nodeRefMap, UEdgeRefMap& uEdgeRefMap) {
+        target.clone(source, nodeRefMap, uEdgeRefMap);
+      }
+    };
+
+    template <typename BpUGraph, typename Enable = void>
+    struct BpUGraphCopySelector {
+      template <typename Source, typename ANodeRefMap, 
+                typename BNodeRefMap, typename UEdgeRefMap>
+      static void copy(BpUGraph &target, const Source& source,
+                       ANodeRefMap& aNodeRefMap, BNodeRefMap& bNodeRefMap,
+                       UEdgeRefMap& uEdgeRefMap) {
+        for (typename Source::ANodeIt it(source); it != INVALID; ++it) {
+          aNodeRefMap[it] = target.addANode();
+        }
+        for (typename Source::BNodeIt it(source); it != INVALID; ++it) {
+          bNodeRefMap[it] = target.addBNode();
+        }
+        for (typename Source::UEdgeIt it(source); it != INVALID; ++it) {
+          uEdgeRefMap[it] = target.addEdge(aNodeRefMap[source.aNode(it)], 
+                                           bNodeRefMap[source.bNode(it)]);
+        }
+      }
+    };
+
+    template <typename BpUGraph>
+    struct BpUGraphCopySelector<
+      BpUGraph, 
+      typename enable_if<typename BpUGraph::CloneableTag, void>::type> 
+    {
+      template <typename Source, typename ANodeRefMap, 
+                typename BNodeRefMap, typename UEdgeRefMap>
+      static void copy(BpUGraph &target, const Source& source,
+                       ANodeRefMap& aNodeRefMap, BNodeRefMap& bNodeRefMap,
+                       UEdgeRefMap& uEdgeRefMap) {
+        target.clone(source, aNodeRefMap, bNodeRefMap, uEdgeRefMap);
+      }
+    };
+    
+
   }
 
@@ -706,7 +810,8 @@
     }
 
-    /// \brief Reverse and copies the node references into the given map.
-    ///
-    /// Reverse and copies the node references into the given map.
+    /// \brief Copies the node cross references into the given map.
+    ///
+    ///  Copies the node cross references (reverse references) into
+    ///  the given map.
     template <typename NodeCrossRef>
     GraphCopy& nodeCrossRef(NodeCrossRef& map) {
@@ -729,4 +834,13 @@
     }
 
+    /// \brief Make a copy of the given node.
+    ///
+    /// Make a copy of the given node.
+    GraphCopy& node(TNode& tnode, const Node& node) {
+      nodeMapCopies.push_back(new _graph_utils_bits::ItemCopy<Source, Node, 
+                              NodeRefMap, TNode>(tnode, node));
+      return *this;
+    }
+
     /// \brief Copies the edge references into the given map.
     ///
@@ -739,7 +853,8 @@
     }
 
-    /// \brief Reverse and copies the edge references into the given map.
-    ///
-    /// Reverse and copies the edge references into the given map.
+    /// \brief Copies the edge cross references into the given map.
+    ///
+    ///  Copies the edge cross references (reverse references) into
+    ///  the given map.
     template <typename EdgeCrossRef>
     GraphCopy& edgeCrossRef(EdgeCrossRef& map) {
@@ -762,4 +877,13 @@
     }
 
+    /// \brief Make a copy of the given edge.
+    ///
+    /// Make a copy of the given edge.
+    GraphCopy& edge(TEdge& tedge, const Edge& edge) {
+      edgeMapCopies.push_back(new _graph_utils_bits::ItemCopy<Source, Edge, 
+                              EdgeRefMap, TEdge>(tedge, edge));
+      return *this;
+    }
+
     /// \brief Executes the copies.
     ///
@@ -767,22 +891,18 @@
     void run() {
       NodeRefMap nodeRefMap(source);
-      for (NodeIt it(source); it != INVALID; ++it) {
-	nodeRefMap[it] = target.addNode();
-      }
+      EdgeRefMap edgeRefMap(source);
+      _graph_utils_bits::GraphCopySelector<Target>::
+        copy(target, source, nodeRefMap, edgeRefMap);
       for (int i = 0; i < (int)nodeMapCopies.size(); ++i) {
         nodeMapCopies[i]->copy(source, nodeRefMap);
       }
-      EdgeRefMap edgeRefMap(source);
-      for (EdgeIt it(source); it != INVALID; ++it) {
-	edgeRefMap[it] = target.addEdge(nodeRefMap[source.source(it)], 
-					nodeRefMap[source.target(it)]);
-      }
       for (int i = 0; i < (int)edgeMapCopies.size(); ++i) {
         edgeMapCopies[i]->copy(source, edgeRefMap);
-      }
-    }
-
-  private:
-    
+      }      
+    }
+
+  protected:
+
+
     const Source& source;
     Target& target;
@@ -809,4 +929,6 @@
   /// contain the mapping from the target graph's edges to the source's
   /// edges.
+  ///
+  /// \see GraphCopy 
   template <typename Target, typename Source>
   GraphCopy<Target, Source> copyGraph(Target& target, const Source& source) {
@@ -895,7 +1017,8 @@
     }
 
-    /// \brief Reverse and copies the node references into the given map.
-    ///
-    /// Reverse and copies the node references into the given map.
+    /// \brief Copies the node cross references into the given map.
+    ///
+    ///  Copies the node cross references (reverse references) into
+    ///  the given map.
     template <typename NodeCrossRef>
     UGraphCopy& nodeCrossRef(NodeCrossRef& map) {
@@ -918,4 +1041,13 @@
     }
 
+    /// \brief Make a copy of the given node.
+    ///
+    /// Make a copy of the given node.
+    UGraphCopy& node(TNode& tnode, const Node& node) {
+      nodeMapCopies.push_back(new _graph_utils_bits::ItemCopy<Source, Node, 
+                              NodeRefMap, TNode>(tnode, node));
+      return *this;
+    }
+
     /// \brief Copies the edge references into the given map.
     ///
@@ -928,7 +1060,8 @@
     }
 
-    /// \brief Reverse and copies the edge references into the given map.
-    ///
-    /// Reverse and copies the edge references into the given map.
+    /// \brief Copies the edge cross references into the given map.
+    ///
+    ///  Copies the edge cross references (reverse references) into
+    ///  the given map.
     template <typename EdgeCrossRef>
     UGraphCopy& edgeCrossRef(EdgeCrossRef& map) {
@@ -951,7 +1084,16 @@
     }
 
-    /// \brief Copies the uEdge references into the given map.
-    ///
-    /// Copies the uEdge references into the given map.
+    /// \brief Make a copy of the given edge.
+    ///
+    /// Make a copy of the given edge.
+    UGraphCopy& edge(TEdge& tedge, const Edge& edge) {
+      edgeMapCopies.push_back(new _graph_utils_bits::ItemCopy<Source, Edge, 
+                              EdgeRefMap, TEdge>(tedge, edge));
+      return *this;
+    }
+
+    /// \brief Copies the undirected edge references into the given map.
+    ///
+    /// Copies the undirected edge references into the given map.
     template <typename UEdgeRef>
     UGraphCopy& uEdgeRef(UEdgeRef& map) {
@@ -961,7 +1103,8 @@
     }
 
-    /// \brief Reverse and copies the uEdge references into the given map.
-    ///
-    /// Reverse and copies the uEdge references into the given map.
+    /// \brief Copies the undirected edge cross references into the given map.
+    ///
+    /// Copies the undirected edge cross references (reverse
+    /// references) into the given map.
     template <typename UEdgeCrossRef>
     UGraphCopy& uEdgeCrossRef(UEdgeCrossRef& map) {
@@ -974,6 +1117,6 @@
     ///
     /// Makes copy of the given map for the newly created graph. 
-    /// The new map's key type is the target graph's uEdge type,
-    /// and the copied map's key type is the source graph's uEdge
+    /// The new map's key type is the target graph's undirected edge type,
+    /// and the copied map's key type is the source graph's undirected edge
     /// type.  
     template <typename TargetMap, typename SourceMap>
@@ -984,4 +1127,13 @@
     }
 
+    /// \brief Make a copy of the given undirected edge.
+    ///
+    /// Make a copy of the given undirected edge.
+    UGraphCopy& uEdge(TUEdge& tuedge, const UEdge& uedge) {
+      uEdgeMapCopies.push_back(new _graph_utils_bits::ItemCopy<Source, UEdge, 
+                               UEdgeRefMap, TUEdge>(tuedge, uedge));
+      return *this;
+    }
+
     /// \brief Executes the copies.
     ///
@@ -989,16 +1141,11 @@
     void run() {
       NodeRefMap nodeRefMap(source);
-      for (NodeIt it(source); it != INVALID; ++it) {
-	nodeRefMap[it] = target.addNode();
-      }
+      UEdgeRefMap uEdgeRefMap(source);
+      EdgeRefMap edgeRefMap(target, source, uEdgeRefMap, nodeRefMap);
+      _graph_utils_bits::UGraphCopySelector<Target>::
+        copy(target, source, nodeRefMap, uEdgeRefMap);
       for (int i = 0; i < (int)nodeMapCopies.size(); ++i) {
         nodeMapCopies[i]->copy(source, nodeRefMap);
       }
-      UEdgeRefMap uEdgeRefMap(source);
-      EdgeRefMap edgeRefMap(target, source, uEdgeRefMap, nodeRefMap);
-      for (UEdgeIt it(source); it != INVALID; ++it) {
-	uEdgeRefMap[it] = target.addEdge(nodeRefMap[source.source(it)], 
-                                         nodeRefMap[source.target(it)]);
-      }
       for (int i = 0; i < (int)uEdgeMapCopies.size(); ++i) {
         uEdgeMapCopies[i]->copy(source, uEdgeRefMap);
@@ -1025,7 +1172,7 @@
   };
 
-  /// \brief Copy a graph to another graph.
-  ///
-  /// Copy a graph to another graph.
+  /// \brief Copy an undirected graph to another graph.
+  ///
+  /// Copy an undirected graph to another graph.
   /// The usage of the function:
   /// 
@@ -1038,8 +1185,374 @@
   /// contain the mapping from the target graph's edges to the source's
   /// edges.
+  ///
+  /// \see UGraphCopy 
   template <typename Target, typename Source>
   UGraphCopy<Target, Source> 
   copyUGraph(Target& target, const Source& source) {
     return UGraphCopy<Target, Source>(target, source);
+  }
+
+  /// \brief Class to copy a bipartite undirected graph.
+  ///
+  /// Class to copy a bipartite undirected graph to another graph
+  /// (duplicate a graph).  The simplest way of using it is through
+  /// the \c copyBpUGraph() function.
+  template <typename Target, typename Source>
+  class BpUGraphCopy {
+  private:
+
+    typedef typename Source::Node Node;
+    typedef typename Source::ANode ANode;
+    typedef typename Source::BNode BNode;
+    typedef typename Source::NodeIt NodeIt;
+    typedef typename Source::Edge Edge;
+    typedef typename Source::EdgeIt EdgeIt;
+    typedef typename Source::UEdge UEdge;
+    typedef typename Source::UEdgeIt UEdgeIt;
+
+    typedef typename Target::Node TNode;
+    typedef typename Target::Edge TEdge;
+    typedef typename Target::UEdge TUEdge;
+
+    typedef typename Source::template ANodeMap<TNode> ANodeRefMap;
+    typedef typename Source::template BNodeMap<TNode> BNodeRefMap;
+    typedef typename Source::template UEdgeMap<TUEdge> UEdgeRefMap;
+
+    struct NodeRefMap {
+      NodeRefMap(const Source& _source, const ANodeRefMap& _anode_ref,
+                 const BNodeRefMap& _bnode_ref)
+        : source(_source), anode_ref(_anode_ref), bnode_ref(_bnode_ref) {}
+
+      typedef typename Source::Node Key;
+      typedef typename Target::Node Value;
+
+      Value operator[](const Key& key) const {
+	return source.aNode(key) ? anode_ref[key] : bnode_ref[key]; 
+      }
+      
+      const Source& source;
+      const ANodeRefMap& anode_ref;
+      const BNodeRefMap& bnode_ref;
+    };
+
+    struct EdgeRefMap {
+      EdgeRefMap(const Target& _target, const Source& _source,
+                 const UEdgeRefMap& _uedge_ref, const NodeRefMap& _node_ref) 
+        : target(_target), source(_source), 
+          uedge_ref(_uedge_ref), node_ref(_node_ref) {}
+
+      typedef typename Source::Edge Key;
+      typedef typename Target::Edge Value;
+
+      Value operator[](const Key& key) const {
+        bool forward = (source.direction(key) == 
+                        (node_ref[source.source((UEdge)key)] == 
+                         target.source(uedge_ref[(UEdge)key])));
+	return target.direct(uedge_ref[key], forward); 
+      }
+      
+      const Target& target;
+      const Source& source;
+      const UEdgeRefMap& uedge_ref;
+      const NodeRefMap& node_ref;
+    };
+    
+  public: 
+
+
+    /// \brief Constructor for the GraphCopy.
+    ///
+    /// It copies the content of the \c _source graph into the
+    /// \c _target graph.
+    BpUGraphCopy(Target& _target, const Source& _source) 
+      : source(_source), target(_target) {}
+
+    /// \brief Destructor of the GraphCopy
+    ///
+    /// Destructor of the GraphCopy
+    ~BpUGraphCopy() {
+      for (int i = 0; i < (int)aNodeMapCopies.size(); ++i) {
+        delete aNodeMapCopies[i];
+      }
+      for (int i = 0; i < (int)bNodeMapCopies.size(); ++i) {
+        delete bNodeMapCopies[i];
+      }
+      for (int i = 0; i < (int)nodeMapCopies.size(); ++i) {
+        delete nodeMapCopies[i];
+      }
+      for (int i = 0; i < (int)edgeMapCopies.size(); ++i) {
+        delete edgeMapCopies[i];
+      }
+      for (int i = 0; i < (int)uEdgeMapCopies.size(); ++i) {
+        delete uEdgeMapCopies[i];
+      }
+
+    }
+
+    /// \brief Copies the A-node references into the given map.
+    ///
+    /// Copies the A-node references into the given map.
+    template <typename ANodeRef>
+    BpUGraphCopy& aNodeRef(ANodeRef& map) {
+      aNodeMapCopies.push_back(new _graph_utils_bits::RefCopy<Source, ANode, 
+                               ANodeRefMap, ANodeRef>(map));
+      return *this;
+    }
+
+    /// \brief Copies the A-node cross references into the given map.
+    ///
+    /// Copies the A-node cross references (reverse references) into
+    /// the given map.
+    template <typename ANodeCrossRef>
+    BpUGraphCopy& aNodeCrossRef(ANodeCrossRef& map) {
+      aNodeMapCopies.push_back(new _graph_utils_bits::CrossRefCopy<Source, 
+                               ANode, ANodeRefMap, ANodeCrossRef>(map));
+      return *this;
+    }
+
+    /// \brief Make copy of the given A-node map.
+    ///
+    /// Makes copy of the given map for the newly created graph. 
+    /// The new map's key type is the target graph's node type,
+    /// and the copied map's key type is the source graph's node
+    /// type.  
+    template <typename TargetMap, typename SourceMap>
+    BpUGraphCopy& aNodeMap(TargetMap& tmap, const SourceMap& map) {
+      aNodeMapCopies.push_back(new _graph_utils_bits::MapCopy<Source, ANode, 
+                               ANodeRefMap, TargetMap, SourceMap>(tmap, map));
+      return *this;
+    }
+
+    /// \brief Copies the B-node references into the given map.
+    ///
+    /// Copies the B-node references into the given map.
+    template <typename BNodeRef>
+    BpUGraphCopy& bNodeRef(BNodeRef& map) {
+      bNodeMapCopies.push_back(new _graph_utils_bits::RefCopy<Source, BNode, 
+                               BNodeRefMap, BNodeRef>(map));
+      return *this;
+    }
+
+    /// \brief Copies the B-node cross references into the given map.
+    ///
+    ///  Copies the B-node cross references (reverse references) into
+    ///  the given map.
+    template <typename BNodeCrossRef>
+    BpUGraphCopy& bNodeCrossRef(BNodeCrossRef& map) {
+      bNodeMapCopies.push_back(new _graph_utils_bits::CrossRefCopy<Source, 
+                              BNode, BNodeRefMap, BNodeCrossRef>(map));
+      return *this;
+    }
+
+    /// \brief Make copy of the given B-node map.
+    ///
+    /// Makes copy of the given map for the newly created graph. 
+    /// The new map's key type is the target graph's node type,
+    /// and the copied map's key type is the source graph's node
+    /// type.  
+    template <typename TargetMap, typename SourceMap>
+    BpUGraphCopy& bNodeMap(TargetMap& tmap, const SourceMap& map) {
+      bNodeMapCopies.push_back(new _graph_utils_bits::MapCopy<Source, BNode, 
+                               BNodeRefMap, TargetMap, SourceMap>(tmap, map));
+      return *this;
+    }
+    /// \brief Copies the node references into the given map.
+    ///
+    /// Copies the node references into the given map.
+    template <typename NodeRef>
+    BpUGraphCopy& nodeRef(NodeRef& map) {
+      nodeMapCopies.push_back(new _graph_utils_bits::RefCopy<Source, Node, 
+                              NodeRefMap, NodeRef>(map));
+      return *this;
+    }
+
+    /// \brief Copies the node cross references into the given map.
+    ///
+    ///  Copies the node cross references (reverse references) into
+    ///  the given map.
+    template <typename NodeCrossRef>
+    BpUGraphCopy& nodeCrossRef(NodeCrossRef& map) {
+      nodeMapCopies.push_back(new _graph_utils_bits::CrossRefCopy<Source, Node,
+                              NodeRefMap, NodeCrossRef>(map));
+      return *this;
+    }
+
+    /// \brief Make copy of the given map.
+    ///
+    /// Makes copy of the given map for the newly created graph. 
+    /// The new map's key type is the target graph's node type,
+    /// and the copied map's key type is the source graph's node
+    /// type.  
+    template <typename TargetMap, typename SourceMap>
+    BpUGraphCopy& nodeMap(TargetMap& tmap, const SourceMap& map) {
+      nodeMapCopies.push_back(new _graph_utils_bits::MapCopy<Source, Node, 
+                              NodeRefMap, TargetMap, SourceMap>(tmap, map));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given node.
+    ///
+    /// Make a copy of the given node.
+    BpUGraphCopy& node(TNode& tnode, const Node& node) {
+      nodeMapCopies.push_back(new _graph_utils_bits::ItemCopy<Source, Node, 
+                              NodeRefMap, TNode>(tnode, node));
+      return *this;
+    }
+
+    /// \brief Copies the edge references into the given map.
+    ///
+    /// Copies the edge references into the given map.
+    template <typename EdgeRef>
+    BpUGraphCopy& edgeRef(EdgeRef& map) {
+      edgeMapCopies.push_back(new _graph_utils_bits::RefCopy<Source, Edge, 
+                              EdgeRefMap, EdgeRef>(map));
+      return *this;
+    }
+
+    /// \brief Copies the edge cross references into the given map.
+    ///
+    ///  Copies the edge cross references (reverse references) into
+    ///  the given map.
+    template <typename EdgeCrossRef>
+    BpUGraphCopy& edgeCrossRef(EdgeCrossRef& map) {
+      edgeMapCopies.push_back(new _graph_utils_bits::CrossRefCopy<Source, Edge,
+                              EdgeRefMap, EdgeCrossRef>(map));
+      return *this;
+    }
+
+    /// \brief Make copy of the given map.
+    ///
+    /// Makes copy of the given map for the newly created graph. 
+    /// The new map's key type is the target graph's edge type,
+    /// and the copied map's key type is the source graph's edge
+    /// type.  
+    template <typename TargetMap, typename SourceMap>
+    BpUGraphCopy& edgeMap(TargetMap& tmap, const SourceMap& map) {
+      edgeMapCopies.push_back(new _graph_utils_bits::MapCopy<Source, Edge, 
+                              EdgeRefMap, TargetMap, SourceMap>(tmap, map));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given edge.
+    ///
+    /// Make a copy of the given edge.
+    BpUGraphCopy& edge(TEdge& tedge, const Edge& edge) {
+      edgeMapCopies.push_back(new _graph_utils_bits::ItemCopy<Source, Edge, 
+                              EdgeRefMap, TEdge>(tedge, edge));
+      return *this;
+    }
+
+    /// \brief Copies the undirected edge references into the given map.
+    ///
+    /// Copies the undirected edge references into the given map.
+    template <typename UEdgeRef>
+    BpUGraphCopy& uEdgeRef(UEdgeRef& map) {
+      uEdgeMapCopies.push_back(new _graph_utils_bits::RefCopy<Source, UEdge, 
+                               UEdgeRefMap, UEdgeRef>(map));
+      return *this;
+    }
+
+    /// \brief Copies the undirected edge cross references into the given map.
+    ///
+    /// Copies the undirected edge cross references (reverse
+    /// references) into the given map.
+    template <typename UEdgeCrossRef>
+    BpUGraphCopy& uEdgeCrossRef(UEdgeCrossRef& map) {
+      uEdgeMapCopies.push_back(new _graph_utils_bits::CrossRefCopy<Source, 
+                               UEdge, UEdgeRefMap, UEdgeCrossRef>(map));
+      return *this;
+    }
+
+    /// \brief Make copy of the given map.
+    ///
+    /// Makes copy of the given map for the newly created graph. 
+    /// The new map's key type is the target graph's undirected edge type,
+    /// and the copied map's key type is the source graph's undirected edge
+    /// type.  
+    template <typename TargetMap, typename SourceMap>
+    BpUGraphCopy& uEdgeMap(TargetMap& tmap, const SourceMap& map) {
+      uEdgeMapCopies.push_back(new _graph_utils_bits::MapCopy<Source, UEdge, 
+                               UEdgeRefMap, TargetMap, SourceMap>(tmap, map));
+      return *this;
+    }
+
+    /// \brief Make a copy of the given undirected edge.
+    ///
+    /// Make a copy of the given undirected edge.
+    BpUGraphCopy& uEdge(TUEdge& tuedge, const UEdge& uedge) {
+      uEdgeMapCopies.push_back(new _graph_utils_bits::ItemCopy<Source, UEdge, 
+                               UEdgeRefMap, TUEdge>(tuedge, uedge));
+      return *this;
+    }
+
+    /// \brief Executes the copies.
+    ///
+    /// Executes the copies.
+    void run() {
+      ANodeRefMap aNodeRefMap(source);
+      BNodeRefMap bNodeRefMap(source);
+      NodeRefMap nodeRefMap(source, aNodeRefMap, bNodeRefMap);
+      UEdgeRefMap uEdgeRefMap(source);
+      EdgeRefMap edgeRefMap(target, source, uEdgeRefMap, nodeRefMap);
+      _graph_utils_bits::BpUGraphCopySelector<Target>::
+        copy(target, source, aNodeRefMap, bNodeRefMap, uEdgeRefMap);
+      for (int i = 0; i < (int)aNodeMapCopies.size(); ++i) {
+        aNodeMapCopies[i]->copy(source, aNodeRefMap);
+      }
+      for (int i = 0; i < (int)bNodeMapCopies.size(); ++i) {
+        bNodeMapCopies[i]->copy(source, bNodeRefMap);
+      }
+      for (int i = 0; i < (int)nodeMapCopies.size(); ++i) {
+        nodeMapCopies[i]->copy(source, nodeRefMap);
+      }
+      for (int i = 0; i < (int)uEdgeMapCopies.size(); ++i) {
+        uEdgeMapCopies[i]->copy(source, uEdgeRefMap);
+      }
+      for (int i = 0; i < (int)edgeMapCopies.size(); ++i) {
+        edgeMapCopies[i]->copy(source, edgeRefMap);
+      }
+    }
+
+  private:
+    
+    const Source& source;
+    Target& target;
+
+    std::vector<_graph_utils_bits::MapCopyBase<Source, ANode, ANodeRefMap>* > 
+    aNodeMapCopies;
+
+    std::vector<_graph_utils_bits::MapCopyBase<Source, BNode, BNodeRefMap>* > 
+    bNodeMapCopies;
+
+    std::vector<_graph_utils_bits::MapCopyBase<Source, Node, NodeRefMap>* > 
+    nodeMapCopies;
+
+    std::vector<_graph_utils_bits::MapCopyBase<Source, Edge, EdgeRefMap>* > 
+    edgeMapCopies;
+
+    std::vector<_graph_utils_bits::MapCopyBase<Source, UEdge, UEdgeRefMap>* > 
+    uEdgeMapCopies;
+
+  };
+
+  /// \brief Copy a bipartite undirected graph to another graph.
+  ///
+  /// Copy a bipartite undirected graph to another graph.
+  /// The usage of the function:
+  /// 
+  ///\code
+  /// copyBpUGraph(trg, src).aNodeRef(anr).edgeCrossRef(ecr).run();
+  ///\endcode
+  /// 
+  /// After the copy the \c nr map will contain the mapping from the
+  /// source graph's nodes to the target graph's nodes and the \c ecr will
+  /// contain the mapping from the target graph's edges to the source's
+  /// edges.
+  ///
+  /// \see BpUGraphCopy
+  template <typename Target, typename Source>
+  BpUGraphCopy<Target, Source> 
+  copyBpUGraph(Target& target, const Source& source) {
+    return BpUGraphCopy<Target, Source>(target, source);
   }
 
