Index: lemon/bits/graph_extender.h
===================================================================
--- lemon/bits/graph_extender.h	(revision 998)
+++ lemon/bits/graph_extender.h	(revision 1019)
@@ -747,4 +747,608 @@
   };
 
+  // \ingroup _graphbits
+  //
+  // \brief Extender for the BpGraphs
+  template <typename Base>
+  class BpGraphExtender : public Base {
+    typedef Base Parent;
+
+  public:
+
+    typedef BpGraphExtender BpGraph;
+
+    typedef True UndirectedTag;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+    typedef typename Parent::Edge Edge;
+
+    // BpGraph extension
+
+    class RedNode : public Node {
+    public:
+      RedNode() {}
+      RedNode(const RedNode& node) : Node(node) {}
+      RedNode(Invalid) : Node(INVALID){}
+      RedNode(const Node& node) : Node(node) {}
+    };
+    class BlueNode : public Node {
+    public:
+      BlueNode() {}
+      BlueNode(const BlueNode& node) : Node(node) {}
+      BlueNode(Invalid) : Node(INVALID){}
+      BlueNode(const Node& node) : Node(node) {}
+    };
+
+    using Parent::first;
+    using Parent::next;
+
+    void first(RedNode& node) const {
+      Parent::firstRed(node);
+    }
+    
+    void next(RedNode& node) const {
+      Parent::nextRed(node);
+    }
+
+    void first(BlueNode& node) const {
+      Parent::firstBlue(node);
+    }
+
+    void next(BlueNode& node) const {
+      Parent::nextBlue(node);
+    }
+
+    using Parent::id;
+
+    int id(const RedNode& node) const {
+      return Parent::redId(node);
+    }
+
+    int id(const BlueNode& node) const {
+      return Parent::blueId(node);
+    }
+
+    int maxId(Node) const {
+      return Parent::maxNodeId();
+    }
+
+    int maxId(RedNode) const {
+      return Parent::maxRedId();
+    }
+
+    int maxId(BlueNode) const {
+      return Parent::maxBlueId();
+    }
+
+    int maxId(Arc) const {
+      return Parent::maxArcId();
+    }
+
+    int maxId(Edge) const {
+      return Parent::maxEdgeId();
+    }
+
+    static Node fromId(int id, Node) {
+      return Parent::nodeFromId(id);
+    }
+
+    static Arc fromId(int id, Arc) {
+      return Parent::arcFromId(id);
+    }
+
+    static Edge fromId(int id, Edge) {
+      return Parent::edgeFromId(id);
+    }
+
+    Node oppositeNode(const Node &n, const Edge &e) const {
+      if( n == Parent::u(e))
+        return Parent::v(e);
+      else if( n == Parent::v(e))
+        return Parent::u(e);
+      else
+        return INVALID;
+    }
+
+    Arc oppositeArc(const Arc &arc) const {
+      return Parent::direct(arc, !Parent::direction(arc));
+    }
+
+    using Parent::direct;
+    Arc direct(const Edge &edge, const Node &node) const {
+      return Parent::direct(edge, Parent::u(edge) == node);
+    }
+
+    // Alterable extension
+
+    typedef AlterationNotifier<BpGraphExtender, Node> NodeNotifier;
+    typedef AlterationNotifier<BpGraphExtender, RedNode> RedNodeNotifier; 
+    typedef AlterationNotifier<BpGraphExtender, BlueNode> BlueNodeNotifier;
+    typedef AlterationNotifier<BpGraphExtender, Arc> ArcNotifier;
+    typedef AlterationNotifier<BpGraphExtender, Edge> EdgeNotifier;
+
+
+  protected:
+
+    mutable NodeNotifier node_notifier;
+    mutable RedNodeNotifier red_node_notifier;
+    mutable BlueNodeNotifier blue_node_notifier;
+    mutable ArcNotifier arc_notifier;
+    mutable EdgeNotifier edge_notifier;
+
+  public:
+
+    NodeNotifier& notifier(Node) const {
+      return node_notifier;
+    }
+
+    RedNodeNotifier& notifier(RedNode) const {
+      return red_node_notifier;
+    }
+
+    BlueNodeNotifier& notifier(BlueNode) const {
+      return blue_node_notifier;
+    }
+
+    ArcNotifier& notifier(Arc) const {
+      return arc_notifier;
+    }
+
+    EdgeNotifier& notifier(Edge) const {
+      return edge_notifier;
+    }
+
+
+
+    class NodeIt : public Node {
+      const BpGraph* _graph;
+    public:
+
+      NodeIt() {}
+
+      NodeIt(Invalid i) : Node(i) { }
+
+      explicit NodeIt(const BpGraph& graph) : _graph(&graph) {
+        _graph->first(static_cast<Node&>(*this));
+      }
+
+      NodeIt(const BpGraph& graph, const Node& node)
+        : Node(node), _graph(&graph) {}
+
+      NodeIt& operator++() {
+        _graph->next(*this);
+        return *this;
+      }
+
+    };
+
+    class RedIt : public Node {
+      const BpGraph* _graph;
+    public:
+
+      RedIt() {}
+
+      RedIt(Invalid i) : Node(i) { }
+
+      explicit RedIt(const BpGraph& graph) : _graph(&graph) {
+        _graph->firstRed(static_cast<Node&>(*this));
+      }
+
+      RedIt(const BpGraph& graph, const Node& node)
+        : Node(node), _graph(&graph) {
+        LEMON_DEBUG(_graph->red(node), "Node has to be red.");
+      }
+
+      RedIt& operator++() {
+        _graph->nextRed(*this);
+        return *this;
+      }
+
+    };
+
+    class BlueIt : public Node {
+      const BpGraph* _graph;
+    public:
+
+      BlueIt() {}
+
+      BlueIt(Invalid i) : Node(i) { }
+
+      explicit BlueIt(const BpGraph& graph) : _graph(&graph) {
+        _graph->firstBlue(static_cast<Node&>(*this));
+      }
+
+      BlueIt(const BpGraph& graph, const Node& node)
+        : Node(node), _graph(&graph) {
+        LEMON_DEBUG(_graph->blue(node), "Node has to be blue.");
+      }
+
+      BlueIt& operator++() {
+        _graph->nextBlue(*this);
+        return *this;
+      }
+
+    };
+
+
+    class ArcIt : public Arc {
+      const BpGraph* _graph;
+    public:
+
+      ArcIt() { }
+
+      ArcIt(Invalid i) : Arc(i) { }
+
+      explicit ArcIt(const BpGraph& graph) : _graph(&graph) {
+        _graph->first(static_cast<Arc&>(*this));
+      }
+
+      ArcIt(const BpGraph& graph, const Arc& arc) :
+        Arc(arc), _graph(&graph) { }
+
+      ArcIt& operator++() {
+        _graph->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class OutArcIt : public Arc {
+      const BpGraph* _graph;
+    public:
+
+      OutArcIt() { }
+
+      OutArcIt(Invalid i) : Arc(i) { }
+
+      OutArcIt(const BpGraph& graph, const Node& node)
+        : _graph(&graph) {
+        _graph->firstOut(*this, node);
+      }
+
+      OutArcIt(const BpGraph& graph, const Arc& arc)
+        : Arc(arc), _graph(&graph) {}
+
+      OutArcIt& operator++() {
+        _graph->nextOut(*this);
+        return *this;
+      }
+
+    };
+
+
+    class InArcIt : public Arc {
+      const BpGraph* _graph;
+    public:
+
+      InArcIt() { }
+
+      InArcIt(Invalid i) : Arc(i) { }
+
+      InArcIt(const BpGraph& graph, const Node& node)
+        : _graph(&graph) {
+        _graph->firstIn(*this, node);
+      }
+
+      InArcIt(const BpGraph& graph, const Arc& arc) :
+        Arc(arc), _graph(&graph) {}
+
+      InArcIt& operator++() {
+        _graph->nextIn(*this);
+        return *this;
+      }
+
+    };
+
+
+    class EdgeIt : public Parent::Edge {
+      const BpGraph* _graph;
+    public:
+
+      EdgeIt() { }
+
+      EdgeIt(Invalid i) : Edge(i) { }
+
+      explicit EdgeIt(const BpGraph& graph) : _graph(&graph) {
+        _graph->first(static_cast<Edge&>(*this));
+      }
+
+      EdgeIt(const BpGraph& graph, const Edge& edge) :
+        Edge(edge), _graph(&graph) { }
+
+      EdgeIt& operator++() {
+        _graph->next(*this);
+        return *this;
+      }
+
+    };
+
+    class IncEdgeIt : public Parent::Edge {
+      friend class BpGraphExtender;
+      const BpGraph* _graph;
+      bool _direction;
+    public:
+
+      IncEdgeIt() { }
+
+      IncEdgeIt(Invalid i) : Edge(i), _direction(false) { }
+
+      IncEdgeIt(const BpGraph& graph, const Node &node) : _graph(&graph) {
+        _graph->firstInc(*this, _direction, node);
+      }
+
+      IncEdgeIt(const BpGraph& graph, const Edge &edge, const Node &node)
+        : _graph(&graph), Edge(edge) {
+        _direction = (_graph->source(edge) == node);
+      }
+
+      IncEdgeIt& operator++() {
+        _graph->nextInc(*this, _direction);
+        return *this;
+      }
+    };
+
+    // \brief Base node of the iterator
+    //
+    // Returns the base node (ie. the source in this case) of the iterator
+    Node baseNode(const OutArcIt &arc) const {
+      return Parent::source(static_cast<const Arc&>(arc));
+    }
+    // \brief Running node of the iterator
+    //
+    // Returns the running node (ie. the target in this case) of the
+    // iterator
+    Node runningNode(const OutArcIt &arc) const {
+      return Parent::target(static_cast<const Arc&>(arc));
+    }
+
+    // \brief Base node of the iterator
+    //
+    // Returns the base node (ie. the target in this case) of the iterator
+    Node baseNode(const InArcIt &arc) const {
+      return Parent::target(static_cast<const Arc&>(arc));
+    }
+    // \brief Running node of the iterator
+    //
+    // Returns the running node (ie. the source in this case) of the
+    // iterator
+    Node runningNode(const InArcIt &arc) const {
+      return Parent::source(static_cast<const Arc&>(arc));
+    }
+
+    // Base node of the iterator
+    //
+    // Returns the base node of the iterator
+    Node baseNode(const IncEdgeIt &edge) const {
+      return edge._direction ? this->u(edge) : this->v(edge);
+    }
+    // Running node of the iterator
+    //
+    // Returns the running node of the iterator
+    Node runningNode(const IncEdgeIt &edge) const {
+      return edge._direction ? this->v(edge) : this->u(edge);
+    }
+
+    // Mappable extension
+
+    template <typename _Value>
+    class NodeMap
+      : public MapExtender<DefaultMap<BpGraph, Node, _Value> > {
+      typedef MapExtender<DefaultMap<BpGraph, Node, _Value> > Parent;
+
+    public:
+      explicit NodeMap(const BpGraph& bpgraph)
+        : Parent(bpgraph) {}
+      NodeMap(const BpGraph& bpgraph, const _Value& value)
+        : Parent(bpgraph, value) {}
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    template <typename _Value>
+    class RedMap
+      : public MapExtender<DefaultMap<BpGraph, RedNode, _Value> > {
+      typedef MapExtender<DefaultMap<BpGraph, RedNode, _Value> > Parent;
+
+    public:
+      explicit RedMap(const BpGraph& bpgraph)
+        : Parent(bpgraph) {}
+      RedMap(const BpGraph& bpgraph, const _Value& value)
+        : Parent(bpgraph, value) {}
+
+    private:
+      RedMap& operator=(const RedMap& cmap) {
+        return operator=<RedMap>(cmap);
+      }
+
+      template <typename CMap>
+      RedMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    template <typename _Value>
+    class BlueMap
+      : public MapExtender<DefaultMap<BpGraph, BlueNode, _Value> > {
+      typedef MapExtender<DefaultMap<BpGraph, BlueNode, _Value> > Parent;
+
+    public:
+      explicit BlueMap(const BpGraph& bpgraph)
+        : Parent(bpgraph) {}
+      BlueMap(const BpGraph& bpgraph, const _Value& value)
+        : Parent(bpgraph, value) {}
+
+    private:
+      BlueMap& operator=(const BlueMap& cmap) {
+        return operator=<BlueMap>(cmap);
+      }
+
+      template <typename CMap>
+      BlueMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    template <typename _Value>
+    class ArcMap
+      : public MapExtender<DefaultMap<BpGraph, Arc, _Value> > {
+      typedef MapExtender<DefaultMap<BpGraph, Arc, _Value> > Parent;
+
+    public:
+      explicit ArcMap(const BpGraph& graph)
+        : Parent(graph) {}
+      ArcMap(const BpGraph& graph, const _Value& value)
+        : Parent(graph, value) {}
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+
+    template <typename _Value>
+    class EdgeMap
+      : public MapExtender<DefaultMap<BpGraph, Edge, _Value> > {
+      typedef MapExtender<DefaultMap<BpGraph, Edge, _Value> > Parent;
+
+    public:
+      explicit EdgeMap(const BpGraph& graph)
+        : Parent(graph) {}
+
+      EdgeMap(const BpGraph& graph, const _Value& value)
+        : Parent(graph, value) {}
+
+    private:
+      EdgeMap& operator=(const EdgeMap& cmap) {
+        return operator=<EdgeMap>(cmap);
+      }
+
+      template <typename CMap>
+      EdgeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    // Alteration extension
+
+    Node addRedNode() {
+      Node node = Parent::addRedNode();
+      notifier(RedNode()).add(node);
+      notifier(Node()).add(node);
+      return node;
+    }
+
+    Node addBlueNode() {
+      Node node = Parent::addBlueNode();
+      notifier(BlueNode()).add(node);
+      notifier(Node()).add(node);
+      return node;
+    }
+
+    Edge addEdge(const Node& from, const Node& to) {
+      Edge edge = Parent::addEdge(from, to);
+      notifier(Edge()).add(edge);
+      std::vector<Arc> av;
+      av.push_back(Parent::direct(edge, true));
+      av.push_back(Parent::direct(edge, false));
+      notifier(Arc()).add(av);
+      return edge;
+    }
+
+    void clear() {
+      notifier(Arc()).clear();
+      notifier(Edge()).clear();
+      notifier(Node()).clear();
+      notifier(BlueNode()).clear();
+      notifier(RedNode()).clear();
+      Parent::clear();
+    }
+
+    template <typename BpGraph, typename NodeRefMap, typename EdgeRefMap>
+    void build(const BpGraph& graph, NodeRefMap& nodeRef,
+               EdgeRefMap& edgeRef) {
+      Parent::build(graph, nodeRef, edgeRef);
+      notifier(RedNode()).build();
+      notifier(BlueNode()).build();
+      notifier(Node()).build();
+      notifier(Edge()).build();
+      notifier(Arc()).build();
+    }
+
+    void erase(const Node& node) {
+      Arc arc;
+      Parent::firstOut(arc, node);
+      while (arc != INVALID ) {
+        erase(arc);
+        Parent::firstOut(arc, node);
+      }
+
+      Parent::firstIn(arc, node);
+      while (arc != INVALID ) {
+        erase(arc);
+        Parent::firstIn(arc, node);
+      }
+
+      if (Parent::red(node)) {
+        notifier(RedNode()).erase(node);
+      } else {
+        notifier(BlueNode()).erase(node);        
+      }
+
+      notifier(Node()).erase(node);
+      Parent::erase(node);
+    }
+
+    void erase(const Edge& edge) {
+      std::vector<Arc> av;
+      av.push_back(Parent::direct(edge, true));
+      av.push_back(Parent::direct(edge, false));
+      notifier(Arc()).erase(av);
+      notifier(Edge()).erase(edge);
+      Parent::erase(edge);
+    }
+
+    BpGraphExtender() {
+      red_node_notifier.setContainer(*this);
+      blue_node_notifier.setContainer(*this);
+      node_notifier.setContainer(*this);
+      arc_notifier.setContainer(*this);
+      edge_notifier.setContainer(*this);
+    }
+
+    ~BpGraphExtender() {
+      edge_notifier.clear();
+      arc_notifier.clear();
+      node_notifier.clear();
+      blue_node_notifier.clear();
+      red_node_notifier.clear();
+    }
+
+  };
+
 }
 
Index: lemon/bits/traits.h
===================================================================
--- lemon/bits/traits.h	(revision 616)
+++ lemon/bits/traits.h	(revision 1019)
@@ -149,4 +149,86 @@
         : Parent(_digraph, _value) {}
     };
+
+  };
+
+  template <typename GR, typename Enable = void>
+  struct RedNodeNotifierIndicator {
+    typedef InvalidType Type;
+  };
+  template <typename GR>
+  struct RedNodeNotifierIndicator<
+    GR,
+    typename enable_if<typename GR::RedNodeNotifier::Notifier, void>::type
+  > {
+    typedef typename GR::RedNodeNotifier Type;
+  };
+
+  template <typename GR>
+  class ItemSetTraits<GR, typename GR::RedNode> {
+  public:
+
+    typedef GR BpGraph;
+    typedef GR Graph;
+    typedef GR Digraph;
+
+    typedef typename GR::RedNode Item;
+    typedef typename GR::RedIt ItemIt;
+
+    typedef typename RedNodeNotifierIndicator<GR>::Type ItemNotifier;
+
+    template <typename V>
+    class Map : public GR::template RedMap<V> {
+      typedef typename GR::template RedMap<V> Parent;
+
+    public:
+      typedef typename GR::template RedMap<V> Type;
+      typedef typename Parent::Value Value;
+
+      Map(const GR& _bpgraph) : Parent(_bpgraph) {}
+      Map(const GR& _bpgraph, const Value& _value)
+        : Parent(_bpgraph, _value) {}
+
+     };
+
+  };
+
+  template <typename GR, typename Enable = void>
+  struct BlueNodeNotifierIndicator {
+    typedef InvalidType Type;
+  };
+  template <typename GR>
+  struct BlueNodeNotifierIndicator<
+    GR,
+    typename enable_if<typename GR::BlueNodeNotifier::Notifier, void>::type
+  > {
+    typedef typename GR::BlueNodeNotifier Type;
+  };
+
+  template <typename GR>
+  class ItemSetTraits<GR, typename GR::BlueNode> {
+  public:
+
+    typedef GR BpGraph;
+    typedef GR Graph;
+    typedef GR Digraph;
+
+    typedef typename GR::BlueNode Item;
+    typedef typename GR::BlueIt ItemIt;
+
+    typedef typename BlueNodeNotifierIndicator<GR>::Type ItemNotifier;
+
+    template <typename V>
+    class Map : public GR::template BlueMap<V> {
+      typedef typename GR::template BlueMap<V> Parent;
+
+    public:
+      typedef typename GR::template BlueMap<V> Type;
+      typedef typename Parent::Value Value;
+
+      Map(const GR& _bpgraph) : Parent(_bpgraph) {}
+      Map(const GR& _bpgraph, const Value& _value)
+        : Parent(_bpgraph, _value) {}
+
+     };
 
   };
Index: lemon/core.h
===================================================================
--- lemon/core.h	(revision 1000)
+++ lemon/core.h	(revision 1019)
@@ -149,4 +149,46 @@
   typedef typename Graph::template EdgeMap<double> DoubleEdgeMap
 
+  ///Create convenience typedefs for the bipartite graph types and iterators
+
+  ///This \c \#define creates the same convenient type definitions as defined
+  ///by \ref GRAPH_TYPEDEFS(BpGraph) and ten more, namely it creates
+  ///\c RedNode, \c RedIt, \c BoolRedMap, \c IntRedMap, \c DoubleRedMap,
+  ///\c BlueNode, \c BlueIt, \c BoolBlueMap, \c IntBlueMap, \c DoubleBlueMap.
+  ///
+  ///\note If the graph type is a dependent type, ie. the graph type depend
+  ///on a template parameter, then use \c TEMPLATE_BPGRAPH_TYPEDEFS()
+  ///macro.
+#define BPGRAPH_TYPEDEFS(BpGraph)                                       \
+  GRAPH_TYPEDEFS(BpGraph);                                              \
+  typedef BpGraph::RedNode RedNode;                                     \
+  typedef BpGraph::RedIt RedIt;                                         \
+  typedef BpGraph::RedMap<bool> BoolRedMap;                             \
+  typedef BpGraph::RedMap<int> IntRedMap;                               \
+  typedef BpGraph::RedMap<double> DoubleRedMap                          \
+  typedef BpGraph::BlueNode BlueNode;                                   \
+  typedef BpGraph::BlueIt BlueIt;                                       \
+  typedef BpGraph::BlueMap<bool> BoolBlueMap;                           \
+  typedef BpGraph::BlueMap<int> IntBlueMap;                             \
+  typedef BpGraph::BlueMap<double> DoubleBlueMap
+
+  ///Create convenience typedefs for the bipartite graph types and iterators
+
+  ///\see BPGRAPH_TYPEDEFS
+  ///
+  ///\note Use this macro, if the graph type is a dependent type,
+  ///ie. the graph type depend on a template parameter.
+#define TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph)                              \
+  TEMPLATE_GRAPH_TYPEDEFS(BpGraph);                                     \
+  typedef typename BpGraph::RedNode RedNode;                            \
+  typedef typename BpGraph::RedIt RedIt;                                \
+  typedef typename BpGraph::template RedMap<bool> BoolRedMap;           \
+  typedef typename BpGraph::template RedMap<int> IntRedMap;             \
+  typedef typename BpGraph::template RedMap<double> DoubleRedMap;       \
+  typedef typename BpGraph::BlueNode BlueNode;                          \
+  typedef typename BpGraph::BlueIt BlueIt;                              \
+  typedef typename BpGraph::template BlueMap<bool> BoolBlueMap;         \
+  typedef typename BpGraph::template BlueMap<int> IntBlueMap;           \
+  typedef typename BpGraph::template BlueMap<double> DoubleBlueMap
+
   /// \brief Function to count the items in a graph.
   ///
@@ -198,4 +240,72 @@
   inline int countNodes(const Graph& g) {
     return _core_bits::CountNodesSelector<Graph>::count(g);
+  }
+
+  namespace _graph_utils_bits {
+    
+    template <typename Graph, typename Enable = void>
+    struct CountRedNodesSelector {
+      static int count(const Graph &g) {
+        return countItems<Graph, typename Graph::RedNode>(g);
+      }
+    };
+
+    template <typename Graph>
+    struct CountRedNodesSelector<
+      Graph, typename 
+      enable_if<typename Graph::NodeNumTag, void>::type> 
+    {
+      static int count(const Graph &g) {
+        return g.redNum();
+      }
+    };    
+  }
+
+  /// \brief Function to count the red nodes in the graph.
+  ///
+  /// This function counts the red nodes in the graph.
+  /// The complexity of the function is O(n) but for some
+  /// graph structures it is specialized to run in O(1).
+  ///
+  /// If the graph contains a \e redNum() member function and a 
+  /// \e NodeNumTag tag then this function calls directly the member
+  /// function to query the cardinality of the node set.
+  template <typename Graph>
+  inline int countRedNodes(const Graph& g) {
+    return _graph_utils_bits::CountRedNodesSelector<Graph>::count(g);
+  }
+
+  namespace _graph_utils_bits {
+    
+    template <typename Graph, typename Enable = void>
+    struct CountBlueNodesSelector {
+      static int count(const Graph &g) {
+        return countItems<Graph, typename Graph::BlueNode>(g);
+      }
+    };
+
+    template <typename Graph>
+    struct CountBlueNodesSelector<
+      Graph, typename 
+      enable_if<typename Graph::NodeNumTag, void>::type> 
+    {
+      static int count(const Graph &g) {
+        return g.blueNum();
+      }
+    };    
+  }
+
+  /// \brief Function to count the blue nodes in the graph.
+  ///
+  /// This function counts the blue nodes in the graph.
+  /// The complexity of the function is O(n) but for some
+  /// graph structures it is specialized to run in O(1).
+  ///
+  /// If the graph contains a \e blueNum() member function and a 
+  /// \e NodeNumTag tag then this function calls directly the member
+  /// function to query the cardinality of the node set.
+  template <typename Graph>
+  inline int countBlueNodes(const Graph& g) {
+    return _graph_utils_bits::CountBlueNodesSelector<Graph>::count(g);
   }
 
@@ -1258,5 +1368,5 @@
     /// The Digraph type
     typedef GR Digraph;
-
+    
   protected:
 
Index: lemon/smart_graph.h
===================================================================
--- lemon/smart_graph.h	(revision 877)
+++ lemon/smart_graph.h	(revision 1019)
@@ -406,6 +406,4 @@
     std::vector<ArcT> arcs;
 
-    int first_free_arc;
-
   public:
 
@@ -812,4 +810,512 @@
   };
 
+  class SmartBpGraphBase {
+
+  protected:
+
+    struct NodeT {
+      int first_out;
+      int partition_next;
+      int partition_index;
+      bool red;
+    };
+
+    struct ArcT {
+      int target;
+      int next_out;
+    };
+
+    std::vector<NodeT> nodes;
+    std::vector<ArcT> arcs;
+
+    int first_red, first_blue;
+
+  public:
+
+    typedef SmartBpGraphBase Graph;
+
+    class Node;
+    class Arc;
+    class Edge;
+
+    class Node {
+      friend class SmartBpGraphBase;
+    protected:
+
+      int _id;
+      explicit Node(int id) { _id = id;}
+
+    public:
+      Node() {}
+      Node (Invalid) { _id = -1; }
+      bool operator==(const Node& node) const {return _id == node._id;}
+      bool operator!=(const Node& node) const {return _id != node._id;}
+      bool operator<(const Node& node) const {return _id < node._id;}
+    };
+
+    class Edge {
+      friend class SmartBpGraphBase;
+    protected:
+
+      int _id;
+      explicit Edge(int id) { _id = id;}
+
+    public:
+      Edge() {}
+      Edge (Invalid) { _id = -1; }
+      bool operator==(const Edge& arc) const {return _id == arc._id;}
+      bool operator!=(const Edge& arc) const {return _id != arc._id;}
+      bool operator<(const Edge& arc) const {return _id < arc._id;}
+    };
+
+    class Arc {
+      friend class SmartBpGraphBase;
+    protected:
+
+      int _id;
+      explicit Arc(int id) { _id = id;}
+
+    public:
+      operator Edge() const {
+        return _id != -1 ? edgeFromId(_id / 2) : INVALID;
+      }
+
+      Arc() {}
+      Arc (Invalid) { _id = -1; }
+      bool operator==(const Arc& arc) const {return _id == arc._id;}
+      bool operator!=(const Arc& arc) const {return _id != arc._id;}
+      bool operator<(const Arc& arc) const {return _id < arc._id;}
+    };
+
+
+
+    SmartBpGraphBase()
+      : nodes(), arcs(), first_red(-1), first_blue(-1) {}
+
+    typedef True NodeNumTag;
+    typedef True EdgeNumTag;
+    typedef True ArcNumTag;
+
+    int nodeNum() const { return nodes.size(); }
+    int redNum() const {
+      return first_red == -1 ? 0 : nodes[first_red].partition_index + 1;
+    }
+    int blueNum() const {
+      return first_blue == -1 ? 0 : nodes[first_blue].partition_index + 1;
+    }
+    int edgeNum() const { return arcs.size() / 2; }
+    int arcNum() const { return arcs.size(); }
+
+    int maxNodeId() const { return nodes.size()-1; }
+    int maxRedId() const {
+      return first_red == -1 ? -1 : nodes[first_red].partition_index;
+    }
+    int maxBlueId() const {
+      return first_blue == -1 ? -1 : nodes[first_blue].partition_index;
+    }
+    int maxEdgeId() const { return arcs.size() / 2 - 1; }
+    int maxArcId() const { return arcs.size()-1; }
+
+    bool red(Node n) const { return nodes[n._id].red; }
+    bool blue(Node n) const { return !nodes[n._id].red; }
+
+    Node source(Arc a) const { return Node(arcs[a._id ^ 1].target); }
+    Node target(Arc a) const { return Node(arcs[a._id].target); }
+
+    Node redNode(Edge e) const { return Node(arcs[2 * e._id].target); }
+    Node blueNode(Edge e) const { return Node(arcs[2 * e._id + 1].target); }
+
+    Node u(Edge e) const { return redNode(e); }
+    Node v(Edge e) const { return blueNode(e); }
+
+    static bool direction(Arc a) {
+      return (a._id & 1) == 1;
+    }
+
+    static Arc direct(Edge e, bool d) {
+      return Arc(e._id * 2 + (d ? 1 : 0));
+    }
+
+    void first(Node& node) const {
+      node._id = nodes.size() - 1;
+    }
+
+    static void next(Node& node) {
+      --node._id;
+    }
+
+    void firstRed(Node& node) const {
+      node._id = first_red;
+    }
+
+    void nextRed(Node& node) const {
+      node._id = nodes[node._id].partition_next;
+    }
+
+    void firstBlue(Node& node) const {
+      node._id = first_blue;
+    }
+
+    void nextBlue(Node& node) const {
+      node._id = nodes[node._id].partition_next;
+    }
+
+    void first(Arc& arc) const {
+      arc._id = arcs.size() - 1;
+    }
+
+    static void next(Arc& arc) {
+      --arc._id;
+    }
+
+    void first(Edge& arc) const {
+      arc._id = arcs.size() / 2 - 1;
+    }
+
+    static void next(Edge& arc) {
+      --arc._id;
+    }
+
+    void firstOut(Arc &arc, const Node& v) const {
+      arc._id = nodes[v._id].first_out;
+    }
+    void nextOut(Arc &arc) const {
+      arc._id = arcs[arc._id].next_out;
+    }
+
+    void firstIn(Arc &arc, const Node& v) const {
+      arc._id = ((nodes[v._id].first_out) ^ 1);
+      if (arc._id == -2) arc._id = -1;
+    }
+    void nextIn(Arc &arc) const {
+      arc._id = ((arcs[arc._id ^ 1].next_out) ^ 1);
+      if (arc._id == -2) arc._id = -1;
+    }
+
+    void firstInc(Edge &arc, bool& d, const Node& v) const {
+      int de = nodes[v._id].first_out;
+      if (de != -1) {
+        arc._id = de / 2;
+        d = ((de & 1) == 1);
+      } else {
+        arc._id = -1;
+        d = true;
+      }
+    }
+    void nextInc(Edge &arc, bool& d) const {
+      int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
+      if (de != -1) {
+        arc._id = de / 2;
+        d = ((de & 1) == 1);
+      } else {
+        arc._id = -1;
+        d = true;
+      }
+    }
+
+    static int id(Node v) { return v._id; }
+    int redId(Node v) const {
+      LEMON_DEBUG(nodes[v._id].red, "Node has to be red");
+      return nodes[v._id].partition_index;
+    }
+    int blueId(Node v) const {
+      LEMON_DEBUG(nodes[v._id].red, "Node has to be blue");
+      return nodes[v._id].partition_index;
+    }
+    static int id(Arc e) { return e._id; }
+    static int id(Edge e) { return e._id; }
+
+    static Node nodeFromId(int id) { return Node(id);}
+    static Arc arcFromId(int id) { return Arc(id);}
+    static Edge edgeFromId(int id) { return Edge(id);}
+
+    bool valid(Node n) const {
+      return n._id >= 0 && n._id < static_cast<int>(nodes.size());
+    }
+    bool valid(Arc a) const {
+      return a._id >= 0 && a._id < static_cast<int>(arcs.size());
+    }
+    bool valid(Edge e) const {
+      return e._id >= 0 && 2 * e._id < static_cast<int>(arcs.size());
+    }
+
+    Node addRedNode() {
+      int n = nodes.size();
+      nodes.push_back(NodeT());
+      nodes[n].first_out = -1;
+      nodes[n].red = true;
+      if (first_red == -1) {
+        nodes[n].partition_index = 0;
+      } else {
+        nodes[n].partition_index = nodes[first_red].partition_index + 1;
+      }
+      nodes[n].partition_next = first_red;
+      first_red = n;
+
+      return Node(n);
+    }
+
+    Node addBlueNode() {
+      int n = nodes.size();
+      nodes.push_back(NodeT());
+      nodes[n].first_out = -1;
+      nodes[n].red = false;
+      if (first_blue == -1) {
+        nodes[n].partition_index = 0;
+      } else {
+        nodes[n].partition_index = nodes[first_blue].partition_index + 1;
+      }
+      nodes[n].partition_next = first_blue;
+      first_blue = n;
+
+      return Node(n);
+    }
+
+    Edge addEdge(Node u, Node v) {
+      int n = arcs.size();
+      arcs.push_back(ArcT());
+      arcs.push_back(ArcT());
+
+      arcs[n].target = u._id;
+      arcs[n | 1].target = v._id;
+
+      arcs[n].next_out = nodes[v._id].first_out;
+      nodes[v._id].first_out = n;
+
+      arcs[n | 1].next_out = nodes[u._id].first_out;
+      nodes[u._id].first_out = (n | 1);
+
+      return Edge(n / 2);
+    }
+
+    void clear() {
+      arcs.clear();
+      nodes.clear();
+      first_red = -1;
+      first_blue = -1;
+    }
+
+  };
+
+  typedef BpGraphExtender<SmartBpGraphBase> ExtendedSmartBpGraphBase;
+
+  /// \ingroup graphs
+  ///
+  /// \brief A smart undirected graph class.
+  ///
+  /// \ref SmartBpGraph is a simple and fast graph implementation.
+  /// It is also quite memory efficient but at the price
+  /// that it does not support node and edge deletion
+  /// (except for the Snapshot feature).
+  ///
+  /// This type fully conforms to the \ref concepts::Graph "Graph concept"
+  /// and it also provides some additional functionalities.
+  /// Most of its member functions and nested classes are documented
+  /// only in the concept class.
+  ///
+  /// This class provides constant time counting for nodes, edges and arcs.
+  ///
+  /// \sa concepts::Graph
+  /// \sa SmartDigraph
+  class SmartBpGraph : public ExtendedSmartBpGraphBase {
+    typedef ExtendedSmartBpGraphBase Parent;
+
+  private:
+    /// Graphs are \e not copy constructible. Use GraphCopy instead.
+    SmartBpGraph(const SmartBpGraph &) : ExtendedSmartBpGraphBase() {};
+    /// \brief Assignment of a graph to another one is \e not allowed.
+    /// Use GraphCopy instead.
+    void operator=(const SmartBpGraph &) {}
+
+  public:
+
+    /// Constructor
+
+    /// Constructor.
+    ///
+    SmartBpGraph() {}
+
+    /// \brief Add a new red node to the graph.
+    ///
+    /// This function adds a red new node to the graph.
+    /// \return The new node.
+    Node addRedNode() { return Parent::addRedNode(); }
+
+    /// \brief Add a new blue node to the graph.
+    ///
+    /// This function adds a blue new node to the graph.
+    /// \return The new node.
+    Node addBlueNode() { return Parent::addBlueNode(); }
+
+    /// \brief Add a new edge to the graph.
+    ///
+    /// This function adds a new edge to the graph between nodes
+    /// \c u and \c v with inherent orientation from node \c u to
+    /// node \c v.
+    /// \return The new edge.
+    Edge addEdge(Node red, Node blue) {
+      LEMON_DEBUG(Parent::red(red) && Parent::blue(blue),
+                  "Edge has to be formed by a red and a blue nodes");
+      return Parent::addEdge(red, blue);
+    }
+
+    /// \brief Node validity check
+    ///
+    /// This function gives back \c true if the given node is valid,
+    /// i.e. it is a real node of the graph.
+    ///
+    /// \warning A removed node (using Snapshot) could become valid again
+    /// if new nodes are added to the graph.
+    bool valid(Node n) const { return Parent::valid(n); }
+
+    /// \brief Edge validity check
+    ///
+    /// This function gives back \c true if the given edge is valid,
+    /// i.e. it is a real edge of the graph.
+    ///
+    /// \warning A removed edge (using Snapshot) could become valid again
+    /// if new edges are added to the graph.
+    bool valid(Edge e) const { return Parent::valid(e); }
+
+    /// \brief Arc validity check
+    ///
+    /// This function gives back \c true if the given arc is valid,
+    /// i.e. it is a real arc of the graph.
+    ///
+    /// \warning A removed arc (using Snapshot) could become valid again
+    /// if new edges are added to the graph.
+    bool valid(Arc a) const { return Parent::valid(a); }
+
+    ///Clear the graph.
+
+    ///This function erases all nodes and arcs from the graph.
+    ///
+    void clear() {
+      Parent::clear();
+    }
+
+    /// Reserve memory for nodes.
+
+    /// Using this function, it is possible to avoid superfluous memory
+    /// allocation: if you know that the graph you want to build will
+    /// be large (e.g. it will contain millions of nodes and/or edges),
+    /// then it is worth reserving space for this amount before starting
+    /// to build the graph.
+    /// \sa reserveEdge()
+    void reserveNode(int n) { nodes.reserve(n); };
+
+    /// Reserve memory for edges.
+
+    /// Using this function, it is possible to avoid superfluous memory
+    /// allocation: if you know that the graph you want to build will
+    /// be large (e.g. it will contain millions of nodes and/or edges),
+    /// then it is worth reserving space for this amount before starting
+    /// to build the graph.
+    /// \sa reserveNode()
+    void reserveEdge(int m) { arcs.reserve(2 * m); };
+
+  public:
+
+    class Snapshot;
+
+  protected:
+
+    void saveSnapshot(Snapshot &s)
+    {
+      s._graph = this;
+      s.node_num = nodes.size();
+      s.arc_num = arcs.size();
+    }
+
+    void restoreSnapshot(const Snapshot &s)
+    {
+      while(s.arc_num<arcs.size()) {
+        int n=arcs.size()-1;
+        Edge arc=edgeFromId(n/2);
+        Parent::notifier(Edge()).erase(arc);
+        std::vector<Arc> dir;
+        dir.push_back(arcFromId(n));
+        dir.push_back(arcFromId(n-1));
+        Parent::notifier(Arc()).erase(dir);
+        nodes[arcs[n-1].target].first_out=arcs[n].next_out;
+        nodes[arcs[n].target].first_out=arcs[n-1].next_out;
+        arcs.pop_back();
+        arcs.pop_back();
+      }
+      while(s.node_num<nodes.size()) {
+        int n=nodes.size()-1;
+        Node node = nodeFromId(n);
+        if (Parent::red(node)) {
+          first_red = nodes[n].partition_next;
+          Parent::notifier(RedNode()).erase(node);          
+        } else {
+          first_blue = nodes[n].partition_next;
+          Parent::notifier(BlueNode()).erase(node);
+        }
+        Parent::notifier(Node()).erase(node);
+        nodes.pop_back();
+      }
+    }
+
+  public:
+
+    ///Class to make a snapshot of the graph and to restore it later.
+
+    ///Class to make a snapshot of the graph and to restore it later.
+    ///
+    ///The newly added nodes and edges can be removed using the
+    ///restore() function. This is the only way for deleting nodes and/or
+    ///edges from a SmartBpGraph structure.
+    ///
+    ///\note After a state is restored, you cannot restore a later state,
+    ///i.e. you cannot add the removed nodes and edges again using
+    ///another Snapshot instance.
+    ///
+    ///\warning The validity of the snapshot is not stored due to
+    ///performance reasons. If you do not use the snapshot correctly,
+    ///it can cause broken program, invalid or not restored state of
+    ///the graph or no change.
+    class Snapshot
+    {
+      SmartBpGraph *_graph;
+    protected:
+      friend class SmartBpGraph;
+      unsigned int node_num;
+      unsigned int arc_num;
+    public:
+      ///Default constructor.
+
+      ///Default constructor.
+      ///You have to call save() to actually make a snapshot.
+      Snapshot() : _graph(0) {}
+      ///Constructor that immediately makes a snapshot
+
+      /// This constructor immediately makes a snapshot of the given graph.
+      ///
+      Snapshot(SmartBpGraph &gr) {
+        gr.saveSnapshot(*this);
+      }
+
+      ///Make a snapshot.
+
+      ///This function makes a snapshot of the given graph.
+      ///It can be called more than once. In case of a repeated
+      ///call, the previous snapshot gets lost.
+      void save(SmartBpGraph &gr)
+      {
+        gr.saveSnapshot(*this);
+      }
+
+      ///Undo the changes until the last snapshot.
+
+      ///This function undos the changes until the last snapshot
+      ///created by save() or Snapshot(SmartBpGraph&).
+      void restore()
+      {
+        _graph->restoreSnapshot(*this);
+      }
+    };
+  };
+
 } //namespace lemon
 
Index: test/bpgraph_test.cc
===================================================================
--- test/bpgraph_test.cc	(revision 1018)
+++ test/bpgraph_test.cc	(revision 1019)
@@ -19,8 +19,6 @@
 #include <lemon/concepts/bpgraph.h>
 //#include <lemon/list_graph.h>
-//#include <lemon/smart_graph.h>
+#include <lemon/smart_graph.h>
 //#include <lemon/full_graph.h>
-//#include <lemon/grid_graph.h>
-//#include <lemon/hypercube_graph.h>
 
 #include "test_tools.h"
@@ -29,4 +27,190 @@
 using namespace lemon;
 using namespace lemon::concepts;
+
+template <class BpGraph>
+void checkBpGraphBuild() {
+  TEMPLATE_BPGRAPH_TYPEDEFS(BpGraph);
+
+  BpGraph G;
+  checkGraphNodeList(G, 0);
+  checkGraphRedNodeList(G, 0);
+  checkGraphBlueNodeList(G, 0);
+  checkGraphEdgeList(G, 0);
+  checkGraphArcList(G, 0);
+
+  G.reserveNode(3);
+  G.reserveEdge(3);
+
+  Node
+    rn1 = G.addRedNode();
+  checkGraphNodeList(G, 1);
+  checkGraphRedNodeList(G, 1);
+  checkGraphBlueNodeList(G, 0);
+  checkGraphEdgeList(G, 0);
+  checkGraphArcList(G, 0);
+
+  Node
+    bn1 = G.addBlueNode(),
+    bn2 = G.addBlueNode();
+  checkGraphNodeList(G, 3);
+  checkGraphRedNodeList(G, 1);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 0);
+  checkGraphArcList(G, 0);
+
+  Edge e1 = G.addEdge(rn1, bn2);
+  check(G.redNode(e1) == rn1 && G.blueNode(e1) == bn2, "Wrong edge");
+  check(G.u(e1) == rn1 && G.v(e1) == bn2, "Wrong edge");
+
+  checkGraphNodeList(G, 3);
+  checkGraphRedNodeList(G, 1);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 1);
+  checkGraphArcList(G, 2);
+
+  checkGraphIncEdgeArcLists(G, rn1, 1);
+  checkGraphIncEdgeArcLists(G, bn1, 0);
+  checkGraphIncEdgeArcLists(G, bn2, 1);
+
+  checkGraphConEdgeList(G, 1);
+  checkGraphConArcList(G, 2);
+
+  Edge
+    e2 = G.addEdge(rn1, bn1),
+    e3 = G.addEdge(rn1, bn2);
+
+  checkGraphNodeList(G, 3);
+  checkGraphRedNodeList(G, 1);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 3);
+  checkGraphArcList(G, 6);
+
+  checkGraphIncEdgeArcLists(G, rn1, 3);
+  checkGraphIncEdgeArcLists(G, bn1, 1);
+  checkGraphIncEdgeArcLists(G, bn2, 2);
+
+  checkGraphConEdgeList(G, 3);
+  checkGraphConArcList(G, 6);
+
+  checkArcDirections(G);
+
+  checkNodeIds(G);
+  checkRedNodeIds(G);
+  checkBlueNodeIds(G);
+  checkArcIds(G);
+  checkEdgeIds(G);
+
+  checkGraphNodeMap(G);
+  checkGraphRedMap(G);
+  checkGraphBlueMap(G);
+  checkGraphArcMap(G);
+  checkGraphEdgeMap(G);
+}
+
+template <class Graph>
+void checkBpGraphSnapshot() {
+  TEMPLATE_BPGRAPH_TYPEDEFS(Graph);
+
+  Graph G;
+  Node 
+    n1 = G.addRedNode(),
+    n2 = G.addBlueNode(),
+    n3 = G.addBlueNode();
+  Edge 
+    e1 = G.addEdge(n1, n2),
+    e2 = G.addEdge(n1, n3);
+
+  checkGraphNodeList(G, 3);
+  checkGraphRedNodeList(G, 1);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 2);
+  checkGraphArcList(G, 4);
+
+  typename Graph::Snapshot snapshot(G);
+
+  Node n4 = G.addRedNode();
+  G.addEdge(n4, n2);
+  G.addEdge(n4, n3);
+
+  checkGraphNodeList(G, 4);
+  checkGraphRedNodeList(G, 2);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 4);
+  checkGraphArcList(G, 8);
+
+  snapshot.restore();
+
+  checkGraphNodeList(G, 3);
+  checkGraphRedNodeList(G, 1);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 2);
+  checkGraphArcList(G, 4);
+
+  checkGraphIncEdgeArcLists(G, n1, 2);
+  checkGraphIncEdgeArcLists(G, n2, 1);
+  checkGraphIncEdgeArcLists(G, n3, 1);
+
+  checkGraphConEdgeList(G, 2);
+  checkGraphConArcList(G, 4);
+
+  checkNodeIds(G);
+  checkRedNodeIds(G);
+  checkBlueNodeIds(G);
+  checkArcIds(G);
+  checkEdgeIds(G);
+
+  checkGraphNodeMap(G);
+  checkGraphRedMap(G);
+  checkGraphBlueMap(G);
+  checkGraphArcMap(G);
+  checkGraphEdgeMap(G);
+
+  G.addRedNode();
+  snapshot.save(G);
+
+  G.addEdge(G.addRedNode(), G.addBlueNode());
+
+  snapshot.restore();
+  snapshot.save(G);
+
+  checkGraphNodeList(G, 4);
+  checkGraphRedNodeList(G, 2);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 2);
+  checkGraphArcList(G, 4);
+
+  G.addEdge(G.addRedNode(), G.addBlueNode());
+
+  snapshot.restore();
+
+  checkGraphNodeList(G, 4);
+  checkGraphRedNodeList(G, 2);
+  checkGraphBlueNodeList(G, 2);
+  checkGraphEdgeList(G, 2);
+  checkGraphArcList(G, 4);
+}
+
+template <typename Graph>
+void checkBpGraphValidity() {
+  TEMPLATE_GRAPH_TYPEDEFS(Graph);
+  Graph g;
+
+  Node
+    n1 = g.addRedNode(),
+    n2 = g.addBlueNode(),
+    n3 = g.addBlueNode();
+
+  Edge
+    e1 = g.addEdge(n1, n2),
+    e2 = g.addEdge(n1, n3);
+
+  check(g.valid(n1), "Wrong validity check");
+  check(g.valid(e1), "Wrong validity check");
+  check(g.valid(g.direct(e1, true)), "Wrong validity check");
+
+  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
+  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
+  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
+}
 
 void checkConcepts() {
@@ -52,6 +236,6 @@
       ErasableBpGraphComponent<> >();
 
-    checkConcept<ClearableGraphComponent<>,
-      ClearableGraphComponent<> >();
+    checkConcept<ClearableBpGraphComponent<>,
+      ClearableBpGraphComponent<> >();
 
   }
@@ -59,7 +243,18 @@
     checkConcept<BpGraph, BpGraph>();
   }
+  { // Checking SmartBpGraph
+    checkConcept<BpGraph, SmartBpGraph>();
+    checkConcept<AlterableBpGraphComponent<>, SmartBpGraph>();
+    checkConcept<ExtendableBpGraphComponent<>, SmartBpGraph>();
+    checkConcept<ClearableBpGraphComponent<>, SmartBpGraph>();
+  }
 }
 
 void checkGraphs() {
+  { // Checking SmartGraph
+    checkBpGraphBuild<SmartBpGraph>();
+    checkBpGraphSnapshot<SmartBpGraph>();
+    checkBpGraphValidity<SmartBpGraph>();
+  }
 }
 
Index: test/graph_test.h
===================================================================
--- test/graph_test.h	(revision 440)
+++ test/graph_test.h	(revision 1019)
@@ -42,4 +42,28 @@
 
   template<class Graph>
+  void checkGraphRedNodeList(const Graph &G, int cnt)
+  {
+    typename Graph::RedIt n(G);
+    for(int i=0;i<cnt;i++) {
+      check(n!=INVALID,"Wrong red Node list linking.");
+      ++n;
+    }
+    check(n==INVALID,"Wrong red Node list linking.");
+    check(countRedNodes(G)==cnt,"Wrong red Node number.");
+  }
+
+  template<class Graph>
+  void checkGraphBlueNodeList(const Graph &G, int cnt)
+  {
+    typename Graph::BlueIt n(G);
+    for(int i=0;i<cnt;i++) {
+      check(n!=INVALID,"Wrong blue Node list linking.");
+      ++n;
+    }
+    check(n==INVALID,"Wrong blue Node list linking.");
+    check(countBlueNodes(G)==cnt,"Wrong blue Node number.");
+  }
+
+  template<class Graph>
   void checkGraphArcList(const Graph &G, int cnt)
   {
@@ -167,4 +191,5 @@
   template <typename Graph>
   void checkNodeIds(const Graph& G) {
+    typedef typename Graph::Node Node;
     std::set<int> values;
     for (typename Graph::NodeIt n(G); n != INVALID; ++n) {
@@ -174,8 +199,38 @@
       values.insert(G.id(n));
     }
+    check(G.maxId(Node()) <= G.maxNodeId(), "Wrong maximum id");
+  }
+
+  template <typename Graph>
+  void checkRedNodeIds(const Graph& G) {
+    typedef typename Graph::RedNode RedNode;
+    std::set<int> values;
+    for (typename Graph::RedIt n(G); n != INVALID; ++n) {
+      check(G.red(n), "Wrong partition");
+      check(G.redId(n) == G.id(RedNode(n)), "Wrong id");
+      check(values.find(G.redId(n)) == values.end(), "Wrong id");
+      check(G.redId(n) <= G.maxRedId(), "Wrong maximum id");
+      values.insert(G.id(n));
+    }
+    check(G.maxId(RedNode()) == G.maxRedId(), "Wrong maximum id");
+  }
+
+  template <typename Graph>
+  void checkBlueNodeIds(const Graph& G) {
+    typedef typename Graph::BlueNode BlueNode;
+    std::set<int> values;
+    for (typename Graph::BlueIt n(G); n != INVALID; ++n) {
+      check(G.blue(n), "Wrong partition");
+      check(G.blueId(n) == G.id(BlueNode(n)), "Wrong id");
+      check(values.find(G.blueId(n)) == values.end(), "Wrong id");
+      check(G.blueId(n) <= G.maxBlueId(), "Wrong maximum id");
+      values.insert(G.id(n));
+    }
+    check(G.maxId(BlueNode()) == G.maxBlueId(), "Wrong maximum id");
   }
 
   template <typename Graph>
   void checkArcIds(const Graph& G) {
+    typedef typename Graph::Arc Arc;
     std::set<int> values;
     for (typename Graph::ArcIt a(G); a != INVALID; ++a) {
@@ -185,8 +240,10 @@
       values.insert(G.id(a));
     }
+    check(G.maxId(Arc()) <= G.maxArcId(), "Wrong maximum id");
   }
 
   template <typename Graph>
   void checkEdgeIds(const Graph& G) {
+    typedef typename Graph::Edge Edge;
     std::set<int> values;
     for (typename Graph::EdgeIt e(G); e != INVALID; ++e) {
@@ -196,4 +253,5 @@
       values.insert(G.id(e));
     }
+    check(G.maxId(Edge()) <= G.maxEdgeId(), "Wrong maximum id");
   }
 
@@ -229,4 +287,64 @@
 
   template <typename Graph>
+  void checkGraphRedMap(const Graph& G) {
+    typedef typename Graph::Node Node;
+    typedef typename Graph::RedIt RedIt;
+
+    typedef typename Graph::template RedMap<int> IntRedMap;
+    IntRedMap map(G, 42);
+    for (RedIt it(G); it != INVALID; ++it) {
+      check(map[it] == 42, "Wrong map constructor.");
+    }
+    int s = 0;
+    for (RedIt it(G); it != INVALID; ++it) {
+      map[it] = 0;
+      check(map[it] == 0, "Wrong operator[].");
+      map.set(it, s);
+      check(map[it] == s, "Wrong set.");
+      ++s;
+    }
+    s = s * (s - 1) / 2;
+    for (RedIt it(G); it != INVALID; ++it) {
+      s -= map[it];
+    }
+    check(s == 0, "Wrong sum.");
+
+    // map = constMap<Node>(12);
+    // for (NodeIt it(G); it != INVALID; ++it) {
+    //   check(map[it] == 12, "Wrong operator[].");
+    // }
+  }
+
+  template <typename Graph>
+  void checkGraphBlueMap(const Graph& G) {
+    typedef typename Graph::Node Node;
+    typedef typename Graph::BlueIt BlueIt;
+
+    typedef typename Graph::template BlueMap<int> IntBlueMap;
+    IntBlueMap map(G, 42);
+    for (BlueIt it(G); it != INVALID; ++it) {
+      check(map[it] == 42, "Wrong map constructor.");
+    }
+    int s = 0;
+    for (BlueIt it(G); it != INVALID; ++it) {
+      map[it] = 0;
+      check(map[it] == 0, "Wrong operator[].");
+      map.set(it, s);
+      check(map[it] == s, "Wrong set.");
+      ++s;
+    }
+    s = s * (s - 1) / 2;
+    for (BlueIt it(G); it != INVALID; ++it) {
+      s -= map[it];
+    }
+    check(s == 0, "Wrong sum.");
+
+    // map = constMap<Node>(12);
+    // for (NodeIt it(G); it != INVALID; ++it) {
+    //   check(map[it] == 12, "Wrong operator[].");
+    // }
+  }
+
+  template <typename Graph>
   void checkGraphArcMap(const Graph& G) {
     typedef typename Graph::Arc Arc;
