Index: gtags
===================================================================
--- .hgtags	(revision 1321)
+++ 	(revision )
@@ -1,2 +1,0 @@
-57ab090b6109902536ee34b1e8d4d123474311e3 r1.3
-bdabbf66b2ad131199059736178664f44c69adaf r1.3.1
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt	(revision 1416)
+++ CMakeLists.txt	(revision 1417)
@@ -4,4 +4,8 @@
   CMAKE_POLICY(SET CMP0048 OLD) 
 ENDIF(POLICY CMP0048)
+
+IF(POLICY CMP0043) 
+  CMAKE_POLICY(SET CMP0043 OLD) 
+ENDIF(POLICY CMP0043)
 
 IF(POLICY CMP0026)
@@ -247,4 +251,8 @@
     FORCE )
 
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+  COMPILE_DEFINITIONS_DEBUG "LEMON_ENABLE_DEBUG"
+  COMPILE_DEFINITIONS_MAINTAINER "LEMON_ENABLE_DEBUG"
+)
 
 INCLUDE(CheckTypeSize)
@@ -275,4 +283,12 @@
 
 ENABLE_TESTING()
+
+
+INCLUDE(CheckCXXCompilerFlag)
+CHECK_CXX_COMPILER_FLAG("-std=c++11" LEMON_CXX11)
+IF(LEMON_CXX11)
+  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+ENDIF()
+
 
 IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
Index: NEWS
===================================================================
--- NEWS	(revision 1320)
+++ NEWS	(revision 1281)
@@ -1,17 +1,2 @@
-2014-07-07 Version 1.3.1 released
-
-        Bugfix release.
-
-        #484: Require CMAKE 2.8
-        #471, #472, #480: Various clang compatibility fixes
-        #481, #482: Fix shared lib build and versioning
-        #476: Fix invalid map query in NearestNeighborTsp
-        #478: Bugfix in debug checking and lower bound handling
-              in min cost flow algorithms
-        #479, #465: Bugfix in default LP/MIP backend settings
-        #476: Bugfix in tsp_test
-        #487: Add missing include header and std:: namespace spec.
-        #474: Fix division by zero error in NetworkSimplex
-
 2013-08-10 Version 1.3 released
 
Index: doc/Doxyfile.in
===================================================================
--- doc/Doxyfile.in	(revision 1251)
+++ doc/Doxyfile.in	(revision 1354)
@@ -20,5 +20,5 @@
 STRIP_FROM_PATH        = "@abs_top_srcdir@"
 STRIP_FROM_INC_PATH    = "@abs_top_srcdir@"
-SHORT_NAMES            = YES
+SHORT_NAMES            = NO
 JAVADOC_AUTOBRIEF      = NO
 QT_AUTOBRIEF           = NO
@@ -40,5 +40,4 @@
 SUBGROUPING            = YES
 TYPEDEF_HIDES_STRUCT   = NO
-SYMBOL_CACHE_SIZE      = 0
 #---------------------------------------------------------------------------
 # Build related configuration options
@@ -73,5 +72,4 @@
 MAX_INITIALIZER_LINES  = 5
 SHOW_USED_FILES        = NO
-SHOW_DIRECTORIES       = YES
 SHOW_FILES             = YES
 SHOW_NAMESPACES        = YES
@@ -151,5 +149,4 @@
 HTML_COLORSTYLE_GAMMA  = 80
 HTML_TIMESTAMP         = YES
-HTML_ALIGN_MEMBERS     = YES
 HTML_DYNAMIC_SECTIONS  = YES
 GENERATE_DOCSET        = NO
@@ -178,5 +175,4 @@
 ENUM_VALUES_PER_LINE   = 4
 GENERATE_TREEVIEW      = NO
-USE_INLINE_TREES       = NO
 TREEVIEW_WIDTH         = 250
 EXT_LINKS_IN_WINDOW    = NO
@@ -225,6 +221,4 @@
 GENERATE_XML           = NO
 XML_OUTPUT             = xml
-XML_SCHEMA             = 
-XML_DTD                = 
 XML_PROGRAMLISTING     = YES
 #---------------------------------------------------------------------------
@@ -267,5 +261,5 @@
 HAVE_DOT               = YES
 DOT_NUM_THREADS        = 0
-DOT_FONTNAME           = FreeSans
+DOT_FONTNAME           = 
 DOT_FONTSIZE           = 10
 DOT_FONTPATH           = 
Index: doc/groups.dox
===================================================================
--- doc/groups.dox	(revision 1280)
+++ doc/groups.dox	(revision 1366)
@@ -295,4 +295,12 @@
 
 /**
+@defgroup matrices Matrices
+@ingroup auxdat
+\brief Two dimensional data storages implemented in LEMON.
+
+This group contains two dimensional data storages implemented in LEMON.
+*/
+
+/**
 @defgroup algs Algorithms
 \brief This group contains the several algorithms
@@ -327,4 +335,8 @@
    but the digraph should not contain directed cycles with negative total
    length.
+ - \ref FloydWarshall "Floyd-Warshall" and \ref Johnson "Johnson" algorithms
+   for solving the \e all-pairs \e shortest \e paths \e problem when arc
+   lenghts can be either positive or negative, but the digraph should
+   not contain directed cycles with negative total length.
  - \ref Suurballe A successive shortest path algorithm for finding
    arc-disjoint paths between two nodes having minimum total length.
@@ -360,8 +372,18 @@
 \f[ 0 \leq f(uv) \leq cap(uv) \quad \forall uv\in A \f]
 
-\ref Preflow is an efficient implementation of Goldberg-Tarjan's
-preflow push-relabel algorithm \cite goldberg88newapproach for finding
-maximum flows. It also provides functions to query the minimum cut,
-which is the dual problem of maximum flow.
+LEMON contains several algorithms for solving maximum flow problems:
+- \ref EdmondsKarp Edmonds-Karp algorithm
+  \cite edmondskarp72theoretical.
+- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm
+  \cite goldberg88newapproach.
+- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees
+  \cite dinic70algorithm, \cite sleator83dynamic.
+- \ref GoldbergTarjan !Preflow push-relabel algorithm with dynamic trees
+  \cite goldberg88newapproach, \cite sleator83dynamic.
+
+In most cases the \ref Preflow algorithm provides the
+fastest method for computing a maximum flow. All implementations
+also provide functions to query the minimum cut, which is the dual
+problem of maximum flow.
 
 \ref Circulation is a preflow push-relabel algorithm implemented directly
@@ -498,4 +520,14 @@
 
 The matching algorithms implemented in LEMON:
+- \ref MaxBipartiteMatching Hopcroft-Karp augmenting path algorithm
+  for calculating maximum cardinality matching in bipartite graphs.
+- \ref PrBipartiteMatching Push-relabel algorithm
+  for calculating maximum cardinality matching in bipartite graphs.
+- \ref MaxWeightedBipartiteMatching
+  Successive shortest path algorithm for calculating maximum weighted
+  matching and maximum weighted bipartite matching in bipartite graphs.
+- \ref MinCostMaxBipartiteMatching
+  Successive shortest path algorithm for calculating minimum cost maximum
+  matching in bipartite graphs.
 - \ref MaxMatching Edmond's blossom shrinking algorithm for calculating
   maximum cardinality matching in general graphs.
@@ -530,4 +562,33 @@
 
 /**
+@defgroup graph_isomorphism Graph Isomorphism
+@ingroup algs
+\brief Algorithms for testing (sub)graph isomorphism
+
+This group contains algorithms for finding isomorph copies of a
+given graph in another one, or simply check whether two graphs are isomorphic.
+
+The formal definition of subgraph isomorphism is as follows.
+
+We are given two graphs, \f$G_1=(V_1,E_1)\f$ and \f$G_2=(V_2,E_2)\f$. A
+function \f$f:V_1\longrightarrow V_2\f$ is called \e mapping or \e
+embedding if \f$f(u)\neq f(v)\f$ whenever \f$u\neq v\f$.
+
+The standard <em>Subgraph Isomorphism Problem (SIP)</em> looks for a
+mapping with the property that whenever \f$(u,v)\in E_1\f$, then
+\f$(f(u),f(v))\in E_2\f$.
+
+In case of <em>Induced Subgraph Isomorphism Problem (ISIP)</em> one
+also requires that if \f$(u,v)\not\in E_1\f$, then \f$(f(u),f(v))\not\in
+E_2\f$
+
+In addition, the graph nodes may be \e labeled, i.e. we are given two
+node labelings \f$l_1:V_1\longrightarrow L\f$ and \f$l_2:V_2\longrightarrow
+L\f$ and we require that \f$l_1(u)=l_2(f(u))\f$ holds for all nodes \f$u \in
+G_1\f$.
+
+*/
+
+/**
 @defgroup planar Planar Embedding and Drawing
 @ingroup algs
@@ -619,4 +680,21 @@
 The currently supported solvers are \cite glpk, \cite clp, \cite cbc,
 \cite cplex, \cite soplex.
+*/
+
+/**
+@defgroup lp_utils Tools for Lp and Mip Solvers
+@ingroup lp_group
+\brief Helper tools to the Lp and Mip solvers.
+
+This group adds some helper tools to general optimization framework
+implemented in LEMON.
+*/
+
+/**
+@defgroup metah Metaheuristics
+@ingroup gen_opt_group
+\brief Metaheuristics for LEMON library.
+
+This group contains some metaheuristic optimization tools.
 */
 
Index: doc/named-param.dox
===================================================================
--- doc/named-param.dox	(revision 463)
+++ doc/named-param.dox	(revision 1351)
@@ -26,5 +26,5 @@
 function parameters by name also when you call the function. It is
 especially comfortable in case of a function having tons of parameters
-with natural default values. Sadly, C++ lack this amenity.
+with natural default values. Sadly, C++ lacks this amenity.
 
 However, with a crafty trick and with some little
Index: doc/references.bib
===================================================================
--- doc/references.bib	(revision 1219)
+++ doc/references.bib	(revision 1414)
@@ -43,4 +43,15 @@
   pages =        {67--118}
 }
+
+@article{VF2PP,
+  author =       {Alp\'ar J\"uttner and  P\'eter Madarasi},
+  title =        {{VF2++} â An improved subgraph isomorphism algorithm},
+  journal =      {Discrete Applied Mathematics},
+  year =         {2018},
+  volume =       {242},
+  pages =        {69--81},
+  url =          {https://doi.org/10.1016/j.dam.2018.02.018}
+}
+
 
 
@@ -355,2 +366,15 @@
   pages =        {587--612}
 }
+
+@article{cordella2004sub,
+  author =       {Cordella, Luigi P. and Foggia, Pasquale and Sansone,
+                  Carlo and Vento, Mario},
+  title =        {A (sub)graph isomorphism algorithm for matching
+                  large graphs},
+  journal =      {IEEE Transactions on Pattern Analysis and Machine
+                  Intelligence},
+  volume =       26,
+  number =       10,
+  pages =        {1367--1372},
+  year =         2004
+}
Index: lemon/bellman_ford.h
===================================================================
--- lemon/bellman_ford.h	(revision 1270)
+++ lemon/bellman_ford.h	(revision 1337)
@@ -30,4 +30,5 @@
 #include <lemon/maps.h>
 #include <lemon/path.h>
+#include <lemon/bits/stl_iterators.h>
 
 #include <limits>
@@ -690,4 +691,19 @@
       int _index;
     };
+
+    /// \brief Gets the collection of the active nodes.
+    ///
+    /// This function can be used for iterating on the active nodes of the
+    /// Bellman-Ford algorithm after the last phase.
+    /// These nodes should be checked in the next phase to
+    /// find augmenting arcs outgoing from them.
+    /// It returns a wrapped ActiveIt, which looks
+    /// like an STL container (by having begin() and end())
+    /// which you can use in range-based for loops, STL algorithms, etc.
+    LemonRangeWrapper1<ActiveIt, BellmanFord>
+    activeNodes() const {
+      return LemonRangeWrapper1<ActiveIt, BellmanFord>(*this);
+    }
+
 
     /// \name Query Functions
Index: lemon/bits/edge_set_extender.h
===================================================================
--- lemon/bits/edge_set_extender.h	(revision 1270)
+++ lemon/bits/edge_set_extender.h	(revision 1337)
@@ -114,4 +114,7 @@
     };
 
+    LemonRangeWrapper1<NodeIt, Digraph> nodes() const {
+      return LemonRangeWrapper1<NodeIt, Digraph>(*this);
+    }
 
     class ArcIt : public Arc {
@@ -137,4 +140,7 @@
     };
 
+    LemonRangeWrapper1<ArcIt, Digraph> arcs() const {
+      return LemonRangeWrapper1<ArcIt, Digraph>(*this);
+    }
 
     class OutArcIt : public Arc {
@@ -161,4 +167,7 @@
     };
 
+    LemonRangeWrapper2<OutArcIt, Digraph, Node> outArcs(const Node& u) const {
+      return LemonRangeWrapper2<OutArcIt, Digraph, Node>(*this, u);
+    }
 
     class InArcIt : public Arc {
@@ -184,4 +193,8 @@
 
     };
+
+    LemonRangeWrapper2<InArcIt, Digraph, Node> inArcs(const Node& u) const {
+      return LemonRangeWrapper2<InArcIt, Digraph, Node>(*this, u);
+    }
 
     // \brief Base node of the iterator
@@ -373,4 +386,7 @@
     };
 
+    LemonRangeWrapper1<NodeIt, Graph> nodes() const {
+      return LemonRangeWrapper1<NodeIt, Graph>(*this);
+    }
 
     class ArcIt : public Arc {
@@ -396,4 +412,7 @@
     };
 
+    LemonRangeWrapper1<ArcIt, Graph> arcs() const {
+      return LemonRangeWrapper1<ArcIt, Graph>(*this);
+    }
 
     class OutArcIt : public Arc {
@@ -420,4 +439,7 @@
     };
 
+    LemonRangeWrapper2<OutArcIt, Graph, Node> outArcs(const Node& u) const {
+      return LemonRangeWrapper2<OutArcIt, Graph, Node>(*this, u);
+    }
 
     class InArcIt : public Arc {
@@ -444,4 +466,7 @@
     };
 
+    LemonRangeWrapper2<InArcIt, Graph, Node> inArcs(const Node& u) const {
+      return LemonRangeWrapper2<InArcIt, Graph, Node>(*this, u);
+    }
 
     class EdgeIt : public Parent::Edge {
@@ -466,4 +491,8 @@
 
     };
+
+    LemonRangeWrapper1<EdgeIt, Graph> edges() const {
+      return LemonRangeWrapper1<EdgeIt, Graph>(*this);
+    }
 
     class IncEdgeIt : public Parent::Edge {
@@ -491,4 +520,8 @@
       }
     };
+
+    LemonRangeWrapper2<IncEdgeIt, Graph, Node> incEdges(const Node& u) const {
+      return LemonRangeWrapper2<IncEdgeIt, Graph, Node>(*this, u);
+    }
 
     // \brief Base node of the iterator
Index: lemon/bits/graph_adaptor_extender.h
===================================================================
--- lemon/bits/graph_adaptor_extender.h	(revision 1270)
+++ lemon/bits/graph_adaptor_extender.h	(revision 1337)
@@ -86,4 +86,7 @@
     };
 
+    LemonRangeWrapper1<NodeIt, Adaptor> nodes() const {
+      return LemonRangeWrapper1<NodeIt, Adaptor>(*this);
+    }
 
     class ArcIt : public Arc {
@@ -108,4 +111,8 @@
 
     };
+
+    LemonRangeWrapper1<ArcIt, Adaptor> arcs() const {
+      return LemonRangeWrapper1<ArcIt, Adaptor>(*this);
+    }
 
 
@@ -133,4 +140,8 @@
     };
 
+    LemonRangeWrapper2<OutArcIt, Adaptor, Node> outArcs(const Node& u) const {
+      return LemonRangeWrapper2<OutArcIt, Adaptor, Node>(*this, u);
+    }
+
 
     class InArcIt : public Arc {
@@ -156,4 +167,8 @@
 
     };
+
+    LemonRangeWrapper2<InArcIt, Adaptor, Node> inArcs(const Node& u) const {
+      return LemonRangeWrapper2<InArcIt, Adaptor, Node>(*this, u);
+    }
 
     Node baseNode(const OutArcIt &e) const {
@@ -255,4 +270,8 @@
     };
 
+    LemonRangeWrapper1<NodeIt, Adaptor> nodes() const {
+      return LemonRangeWrapper1<NodeIt, Adaptor>(*this);
+    }
+
 
     class ArcIt : public Arc {
@@ -277,4 +296,8 @@
 
     };
+
+    LemonRangeWrapper1<ArcIt, Adaptor> arcs() const {
+      return LemonRangeWrapper1<ArcIt, Adaptor>(*this);
+    }
 
 
@@ -302,4 +325,8 @@
     };
 
+    LemonRangeWrapper2<OutArcIt, Adaptor, Node> outArcs(const Node& u) const {
+      return LemonRangeWrapper2<OutArcIt, Adaptor, Node>(*this, u);
+    }
+
 
     class InArcIt : public Arc {
@@ -326,4 +353,8 @@
     };
 
+    LemonRangeWrapper2<InArcIt, Adaptor, Node> inArcs(const Node& u) const {
+      return LemonRangeWrapper2<InArcIt, Adaptor, Node>(*this, u);
+    }
+
     class EdgeIt : public Parent::Edge {
       const Adaptor* _adaptor;
@@ -347,4 +378,9 @@
 
     };
+
+    LemonRangeWrapper1<EdgeIt, Adaptor> edges() const {
+      return LemonRangeWrapper1<EdgeIt, Adaptor>(*this);
+    }
+
 
     class IncEdgeIt : public Edge {
@@ -373,4 +409,9 @@
     };
 
+    LemonRangeWrapper2<IncEdgeIt, Adaptor, Node> incEdges(const Node& u) const {
+      return LemonRangeWrapper2<IncEdgeIt, Adaptor, Node>(*this, u);
+    }
+
+
     Node baseNode(const OutArcIt &a) const {
       return Parent::source(a);
Index: lemon/bits/graph_extender.h
===================================================================
--- lemon/bits/graph_extender.h	(revision 1270)
+++ lemon/bits/graph_extender.h	(revision 1336)
@@ -28,4 +28,6 @@
 #include <lemon/concepts/maps.h>
 
+#include <lemon/bits/stl_iterators.h>
+
 //\ingroup graphbits
 //\file
@@ -117,4 +119,8 @@
     };
 
+    LemonRangeWrapper1<NodeIt, Digraph> nodes() const {
+      return LemonRangeWrapper1<NodeIt, Digraph>(*this);
+    }
+
 
     class ArcIt : public Arc {
@@ -139,4 +145,8 @@
 
     };
+
+    LemonRangeWrapper1<ArcIt, Digraph> arcs() const {
+      return LemonRangeWrapper1<ArcIt, Digraph>(*this);
+    }
 
 
@@ -164,4 +174,8 @@
     };
 
+    LemonRangeWrapper2<OutArcIt, Digraph, Node> outArcs(const Node& u) const {
+      return LemonRangeWrapper2<OutArcIt, Digraph, Node>(*this, u);
+    }
+
 
     class InArcIt : public Arc {
@@ -187,4 +201,8 @@
 
     };
+
+    LemonRangeWrapper2<InArcIt, Digraph, Node> inArcs(const Node& u) const {
+      return LemonRangeWrapper2<InArcIt, Digraph, Node>(*this, u);
+    }
 
     // \brief Base node of the iterator
@@ -437,4 +455,8 @@
     };
 
+    LemonRangeWrapper1<NodeIt, Graph> nodes() const {
+      return LemonRangeWrapper1<NodeIt, Graph>(*this);
+    }
+
 
     class ArcIt : public Arc {
@@ -459,4 +481,8 @@
 
     };
+
+    LemonRangeWrapper1<ArcIt, Graph> arcs() const {
+      return LemonRangeWrapper1<ArcIt, Graph>(*this);
+    }
 
 
@@ -484,4 +510,8 @@
     };
 
+    LemonRangeWrapper2<OutArcIt, Graph, Node> outArcs(const Node& u) const {
+      return LemonRangeWrapper2<OutArcIt, Graph, Node>(*this, u);
+    }
+
 
     class InArcIt : public Arc {
@@ -508,4 +538,8 @@
     };
 
+    LemonRangeWrapper2<InArcIt, Graph, Node> inArcs(const Node& u) const {
+      return LemonRangeWrapper2<InArcIt, Graph, Node>(*this, u);
+    }
+
 
     class EdgeIt : public Parent::Edge {
@@ -530,4 +564,9 @@
 
     };
+
+    LemonRangeWrapper1<EdgeIt, Graph> edges() const {
+      return LemonRangeWrapper1<EdgeIt, Graph>(*this);
+    }
+
 
     class IncEdgeIt : public Parent::Edge {
@@ -555,4 +594,9 @@
       }
     };
+
+    LemonRangeWrapper2<IncEdgeIt, Graph, Node> incEdges(const Node& u) const {
+      return LemonRangeWrapper2<IncEdgeIt, Graph, Node>(*this, u);
+    }
+
 
     // \brief Base node of the iterator
@@ -904,4 +948,9 @@
     };
 
+    LemonRangeWrapper1<NodeIt, BpGraph> nodes() const {
+      return LemonRangeWrapper1<NodeIt, BpGraph>(*this);
+    }
+
+
     class RedNodeIt : public RedNode {
       const BpGraph* _graph;
@@ -926,4 +975,9 @@
     };
 
+    LemonRangeWrapper1<RedNodeIt, BpGraph> redNodes() const {
+      return LemonRangeWrapper1<RedNodeIt, BpGraph>(*this);
+    }
+
+
     class BlueNodeIt : public BlueNode {
       const BpGraph* _graph;
@@ -948,4 +1002,9 @@
     };
 
+    LemonRangeWrapper1<BlueNodeIt, BpGraph> blueNodes() const {
+      return LemonRangeWrapper1<BlueNodeIt, BpGraph>(*this);
+    }
+
+
 
     class ArcIt : public Arc {
@@ -970,4 +1029,8 @@
 
     };
+
+    LemonRangeWrapper1<ArcIt, BpGraph> arcs() const {
+      return LemonRangeWrapper1<ArcIt, BpGraph>(*this);
+    }
 
 
@@ -995,4 +1058,8 @@
     };
 
+    LemonRangeWrapper2<OutArcIt, BpGraph, Node> outArcs(const Node& u) const {
+      return LemonRangeWrapper2<OutArcIt, BpGraph, Node>(*this, u);
+    }
+
 
     class InArcIt : public Arc {
@@ -1019,4 +1086,8 @@
     };
 
+    LemonRangeWrapper2<InArcIt, BpGraph, Node> inArcs(const Node& u) const {
+      return LemonRangeWrapper2<InArcIt, BpGraph, Node>(*this, u);
+    }
+
 
     class EdgeIt : public Parent::Edge {
@@ -1041,4 +1112,9 @@
 
     };
+
+    LemonRangeWrapper1<EdgeIt, BpGraph> edges() const {
+      return LemonRangeWrapper1<EdgeIt, BpGraph>(*this);
+    }
+
 
     class IncEdgeIt : public Parent::Edge {
@@ -1066,4 +1142,9 @@
       }
     };
+
+    LemonRangeWrapper2<IncEdgeIt, BpGraph, Node> incEdges(const Node& u) const {
+      return LemonRangeWrapper2<IncEdgeIt, BpGraph, Node>(*this, u);
+    }
+
 
     // \brief Base node of the iterator
Index: lemon/bits/path_dump.h
===================================================================
--- lemon/bits/path_dump.h	(revision 1270)
+++ lemon/bits/path_dump.h	(revision 1338)
@@ -62,5 +62,5 @@
       }
 
-      operator const typename Digraph::Arc() const {
+      operator typename Digraph::Arc() const {
         return path->predMap[current];
       }
Index: lemon/bits/stl_iterators.h
===================================================================
--- lemon/bits/stl_iterators.h	(revision 1339)
+++ lemon/bits/stl_iterators.h	(revision 1339)
@@ -0,0 +1,99 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ */
+
+#ifndef STL_ITERATORS_H_
+#define STL_ITERATORS_H_
+
+#include <lemon/core.h>
+
+namespace lemon {
+
+  /// \brief Template to make STL iterators from Lemon iterators.
+  ///
+  /// This template makes an STL iterator from a Lemon iterator
+  /// by adding the missing features.
+  /// It inherits from \c std::iterator to make \c iterator_concept work
+  /// (so that STL algorithms work).
+  /// \c T should be the lemon iterator to be decorated.
+  template<class T>
+  struct LemonItWrapper
+      : public T, public std::iterator<std::input_iterator_tag, T> {
+
+    LemonItWrapper(const T &x) : T(x) {}
+
+    //Lemon iterators don't have operator*, (because they rather
+    //inherit from their "value_type"),
+    //so we add one that just returns the object.
+    const T& operator*() const {
+      return static_cast<const T&>(*this);
+    }
+
+    //I can't think of any use case for this with Lemon iterators,
+    //but maybe it should be included for completeness.
+    const T* operator->() {
+      return static_cast<const T*>(this);
+    }
+
+    //Lemon iterators don't have postincrement.
+    void operator++(int) {
+      T::operator++();
+    }
+
+    using T::operator++;
+
+  };
+
+
+  /// \brief A generic wrapper for Lemon iterators for range-based for loops.
+  ///
+  /// This template can be used to create a class
+  /// that has begin() and end() from a Lemon iterator
+  /// (with a 1-parameter constructor)
+  /// to make range-based for loops and STL algorithms work.
+  ///
+  /// \c LIT is the Lemon iterator that will be wrapped
+  /// \c P is the type of the parameter of the constructor of \c LIT.
+  template<class LIT, class P>
+  class LemonRangeWrapper1 {
+    typedef LemonItWrapper<LIT> It;
+    It _begin;
+    
+  public:
+    LemonRangeWrapper1(const P &p) : _begin(LIT(p)) {}
+    It begin() const {
+      return _begin;
+    }
+    It end() const {
+      return It(lemon::INVALID);
+    }
+  };
+
+
+  /// \brief A generic wrapper for Lemon iterators for range-based for loops.
+  ///
+  /// This template can be used to create a class
+  /// that has begin() and end() from a Lemon iterator
+  /// (with a 2-parameter constructor)
+  /// to make range-based for loops and STL algorithms work.
+  ///
+  /// \c LIT is the Lemon iterator that will be wrapped
+  /// \c P1 and \c P2 are the types of the parameters
+  /// of the constructor of \c LIT.
+  template<class LIT, class P1, class P2>
+  class LemonRangeWrapper2 {
+    typedef LemonItWrapper<LIT> It; 
+    It _begin;
+ public:
+    LemonRangeWrapper2(const P1 &p1, const P2 &p2) : _begin(LIT(p1, p2)) {}
+    It begin() const {
+      return _begin;
+    }
+    It end() const {
+      return It(lemon::INVALID);
+    }
+  };
+
+
+}
+
+#endif /* STL_ITERATORS_H_ */
Index: lemon/bits/vf2_internals.h
===================================================================
--- lemon/bits/vf2_internals.h	(revision 1407)
+++ lemon/bits/vf2_internals.h	(revision 1407)
@@ -0,0 +1,47 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2015-2017
+ * EMAXA Kutato-fejleszto Kft. (EMAXA Research Ltd.)
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef VF2_INTERNALS_H
+#define VF2_INTERNALS_H
+
+
+///\ingroup graph_properties
+///\file
+///\brief Mapping types for graph matching algorithms.
+
+namespace lemon {
+  ///\ingroup graph_isomorphism
+  ///The \ref Vf2 "VF2" algorithm is capable of finding different kind of
+  ///graph embeddings, this enum specifies their types.
+  ///
+  ///See \ref graph_isomorphism for a more detailed description.
+  enum MappingType {
+    /// Subgraph isomorphism
+    SUBGRAPH = 0,
+    /// Induced subgraph isomorphism
+    INDUCED = 1,
+    /// Graph isomorphism
+    ///
+    /// If the two graphs have the same number of nodes, than it is
+    /// equivalent to \ref INDUCED, and if they also have the same
+    /// number of edges, then it is also equivalent to \ref SUBGRAPH.
+    ///
+    /// However, using this setting is faster than the other two options.
+    ISOMORPH = 2
+  };
+}
+#endif
Index: lemon/cbc.cc
===================================================================
--- lemon/cbc.cc	(revision 1270)
+++ lemon/cbc.cc	(revision 1336)
@@ -112,9 +112,9 @@
 
   void CbcMip::_eraseColId(int i) {
-    cols.eraseIndex(i);
+    _cols.eraseIndex(i);
   }
 
   void CbcMip::_eraseRowId(int i) {
-    rows.eraseIndex(i);
+    _rows.eraseIndex(i);
   }
 
Index: lemon/clp.cc
===================================================================
--- lemon/clp.cc	(revision 1270)
+++ lemon/clp.cc	(revision 1336)
@@ -30,6 +30,6 @@
   ClpLp::ClpLp(const ClpLp& other) {
     _prob = new ClpSimplex(*other._prob);
-    rows = other.rows;
-    cols = other.cols;
+    _rows = other._rows;
+    _cols = other._cols;
     _init_temporals();
     messageLevel(MESSAGE_NOTHING);
@@ -104,11 +104,11 @@
 
   void ClpLp::_eraseColId(int i) {
-    cols.eraseIndex(i);
-    cols.shiftIndices(i);
+    _cols.eraseIndex(i);
+    _cols.shiftIndices(i);
   }
 
   void ClpLp::_eraseRowId(int i) {
-    rows.eraseIndex(i);
-    rows.shiftIndices(i);
+    _rows.eraseIndex(i);
+    _rows.shiftIndices(i);
   }
 
Index: lemon/clp.h
===================================================================
--- lemon/clp.h	(revision 1270)
+++ lemon/clp.h	(revision 1336)
@@ -152,8 +152,8 @@
 
     ///Returns the constraint identifier understood by CLP.
-    int clpRow(Row r) const { return rows(id(r)); }
+    int clpRow(Row r) const { return _rows(id(r)); }
 
     ///Returns the variable identifier understood by CLP.
-    int clpCol(Col c) const { return cols(id(c)); }
+    int clpCol(Col c) const { return _cols(id(c)); }
 
   };
Index: lemon/compact_graph.h
===================================================================
--- lemon/compact_graph.h	(revision 1419)
+++ lemon/compact_graph.h	(revision 1419)
@@ -0,0 +1,430 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2017
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_COMPACT_GRAPH_H
+#define LEMON_COMPACT_GRAPH_H
+
+///\ingroup graphs
+///\file
+///\brief CompactDigraph class.
+
+#include <lemon/core.h>
+#include <lemon/bits/graph_extender.h>
+
+#include <algorithm>
+
+namespace lemon {
+
+  class CompactDigraphBase {
+
+  public:
+
+    CompactDigraphBase()
+      : built(false), node_num(0), arc_num(0),
+        node_first_out(NULL),
+        arc_target(NULL) {}
+
+    ~CompactDigraphBase() {
+      if (built) {
+        delete[] node_first_out;
+        delete[] arc_target;
+      }
+    }
+
+    class Node {
+      friend class CompactDigraphBase;
+    protected:
+      int id;
+      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 Arc {
+      friend class CompactDigraphBase;
+    protected:
+      int id;
+      int source;
+      Arc(int _id, int _source) : id(_id), source(_source) {}
+    public:
+      Arc() { }
+      Arc (Invalid) : id(-1), source(-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; }
+    };
+
+    Node source(const Arc& e) const { return Node(e.source); }
+    Node target(const Arc& e) const { return Node(arc_target[e.id]); }
+
+    void first(Node& n) const { n.id = node_num - 1; }
+    static void next(Node& n) { --n.id; }
+
+  private:
+
+    void nextSource(Arc& e) const {
+      if (e.id == -1) return;
+      int last = node_first_out[e.source] - 1;
+      while (e.id == last) {
+        --e.source;
+        last = node_first_out[e.source] - 1;
+      }
+    }
+
+  public:
+
+    void first(Arc& e) const {
+      e.id = arc_num - 1;
+      e.source = node_num - 1;
+      nextSource(e);
+    }
+    void next(Arc& e) const {
+      --e.id;
+      nextSource(e);
+    }
+
+    void firstOut(Arc& e, const Node& n) const {
+      e.source = n.id;
+      e.id = node_first_out[n.id];
+      if (e.id == node_first_out[n.id + 1]) e = INVALID;
+    }
+    void nextOut(Arc& e) const {
+      ++e.id;
+      if (e.id == node_first_out[e.source + 1]) e = INVALID;
+    }
+
+    void firstIn(Arc& e, const Node& n) const {
+      first(e);
+      while(e != INVALID && target(e) != n) {
+        next(e);
+      }
+    }
+    void nextIn(Arc& e) const {
+      Node arcTarget = target(e);
+      do {
+        next(e);
+      } while(e != INVALID && target(e) != arcTarget);
+    }
+
+    static int id(const Node& n) { return n.id; }
+    static Node nodeFromId(int id) { return Node(id); }
+    int maxNodeId() const { return node_num - 1; }
+
+    static int id(const Arc& e) { return e.id; }
+    Arc arcFromId(int id) const {
+      int *l = std::upper_bound(node_first_out, node_first_out + node_num, id) - 1;
+      int src = l - node_first_out;
+      return Arc(id, src);
+    }
+    int maxArcId() const { return arc_num - 1; }
+
+    typedef True NodeNumTag;
+    typedef True ArcNumTag;
+
+    int nodeNum() const { return node_num; }
+    int arcNum() const { return arc_num; }
+
+  private:
+
+    template <typename Digraph, typename NodeRefMap>
+    class ArcLess {
+    public:
+      typedef typename Digraph::Arc Arc;
+
+      ArcLess(const Digraph &_graph, const NodeRefMap& _nodeRef)
+        : digraph(_graph), nodeRef(_nodeRef) {}
+
+      bool operator()(const Arc& left, const Arc& right) const {
+        return nodeRef[digraph.target(left)] < nodeRef[digraph.target(right)];
+      }
+    private:
+      const Digraph& digraph;
+      const NodeRefMap& nodeRef;
+    };
+
+  public:
+
+    typedef True BuildTag;
+
+    void clear() {
+      if (built) {
+        delete[] node_first_out;
+        delete[] arc_target;
+      }
+      built = false;
+      node_num = 0;
+      arc_num = 0;
+    }
+
+    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
+    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
+      typedef typename Digraph::Node GNode;
+      typedef typename Digraph::Arc GArc;
+
+      built = true;
+
+      node_num = countNodes(digraph);
+      arc_num = countArcs(digraph);
+
+      node_first_out = new int[node_num + 1];
+
+      arc_target = new int[arc_num];
+
+      int node_index = 0;
+      for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
+        nodeRef[n] = Node(node_index);
+        ++node_index;
+      }
+
+      ArcLess<Digraph, NodeRefMap> arcLess(digraph, nodeRef);
+
+      int arc_index = 0;
+      for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
+        int source = nodeRef[n].id;
+        std::vector<GArc> arcs;
+        for (typename Digraph::OutArcIt e(digraph, n); e != INVALID; ++e) {
+          arcs.push_back(e);
+        }
+        if (!arcs.empty()) {
+          node_first_out[source] = arc_index;
+          std::sort(arcs.begin(), arcs.end(), arcLess);
+          for (typename std::vector<GArc>::iterator it = arcs.begin();
+               it != arcs.end(); ++it) {
+            int target = nodeRef[digraph.target(*it)].id;
+            arcRef[*it] = Arc(arc_index, source);
+            arc_target[arc_index] = target;
+            ++arc_index;
+          }
+        } else {
+          node_first_out[source] = arc_index;
+        }
+      }
+      node_first_out[node_num] = arc_num;
+    }
+
+    template <typename ArcListIterator>
+    void build(int n, ArcListIterator first, ArcListIterator last) {
+      built = true;
+
+      node_num = n;
+      arc_num = static_cast<int>(std::distance(first, last));
+
+      node_first_out = new int[node_num + 1];
+
+      arc_target = new int[arc_num];
+
+      int arc_index = 0;
+      for (int i = 0; i != node_num; ++i) {
+        node_first_out[i] = arc_index;
+        for ( ; first != last && (*first).first == i; ++first) {
+          int j = (*first).second;
+          LEMON_ASSERT(j >= 0 && j < node_num,
+            "Wrong arc list for CompactDigraph::build()");
+          arc_target[arc_index] = j;
+          ++arc_index;
+        }
+      }
+      LEMON_ASSERT(first == last,
+        "Wrong arc list for CompactDigraph::build()");
+      node_first_out[node_num] = arc_num;
+    }
+
+  protected:
+    bool built;
+    int node_num;
+    int arc_num;
+    int *node_first_out;
+    int *arc_target;
+  };
+
+  typedef DigraphExtender<CompactDigraphBase> ExtendedCompactDigraphBase;
+
+
+  /// \ingroup graphs
+  ///
+  /// \brief A static directed graph class.
+  ///
+  /// \ref CompactDigraph is a highly efficient digraph implementation
+  /// similar to \ref StaticDigraph. It is more memory efficient but does
+  /// not provide efficient iteration over incoming arcs.
+  ///
+  /// It stores only one \c int values for each node and one \c int value
+  /// for each arc. Its \ref InArcIt implementation is inefficient and
+  /// provided only for compatibility with the \ref concepts::Digraph "Digraph concept".
+  ///
+  /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
+  /// Most of its member functions and nested classes are documented
+  /// only in the concept class.
+  ///
+  /// \sa concepts::Digraph
+  class CompactDigraph : public ExtendedCompactDigraphBase {
+
+  private:
+    /// Graphs are \e not copy constructible. Use DigraphCopy instead.
+    CompactDigraph(const CompactDigraph &) : ExtendedCompactDigraphBase() {};
+    /// \brief Assignment of a graph to another one is \e not allowed.
+    /// Use DigraphCopy instead.
+    void operator=(const CompactDigraph&) {}
+
+  public:
+
+    typedef ExtendedCompactDigraphBase Parent;
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Default constructor.
+    CompactDigraph() : Parent() {}
+
+    /// \brief The node with the given index.
+    ///
+    /// This function returns the node with the given index.
+    /// \sa index()
+    static Node node(int ix) { return Parent::nodeFromId(ix); }
+
+    /// \brief The arc with the given index.
+    ///
+    /// This function returns the arc with the given index.
+    /// \sa index()
+    Arc arc(int ix) { return arcFromId(ix); }
+
+    /// \brief The index of the given node.
+    ///
+    /// This function returns the index of the the given node.
+    /// \sa node()
+    static int index(Node node) { return Parent::id(node); }
+
+    /// \brief The index of the given arc.
+    ///
+    /// This function returns the index of the the given arc.
+    /// \sa arc()
+    static int index(Arc arc) { return Parent::id(arc); }
+
+    /// \brief Number of nodes.
+    ///
+    /// This function returns the number of nodes.
+    int nodeNum() const { return node_num; }
+
+    /// \brief Number of arcs.
+    ///
+    /// This function returns the number of arcs.
+    int arcNum() const { return arc_num; }
+
+    /// \brief Build the digraph copying another digraph.
+    ///
+    /// This function builds the digraph copying another digraph of any
+    /// kind. It can be called more than once, but in such case, the whole
+    /// structure and all maps will be cleared and rebuilt.
+    ///
+    /// This method also makes possible to copy a digraph to a CompactDigraph
+    /// structure using \ref DigraphCopy.
+    ///
+    /// \param digraph An existing digraph to be copied.
+    /// \param nodeRef The node references will be copied into this map.
+    /// Its key type must be \c Digraph::Node and its value type must be
+    /// \c CompactDigraph::Node.
+    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
+    /// concept.
+    /// \param arcRef The arc references will be copied into this map.
+    /// Its key type must be \c Digraph::Arc and its value type must be
+    /// \c CompactDigraph::Arc.
+    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    ///
+    /// \note If you do not need the arc references, then you could use
+    /// \ref NullMap for the last parameter. However the node references
+    /// are required by the function itself, thus they must be readable
+    /// from the map.
+    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
+    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
+      if (built) Parent::clear();
+      Parent::build(digraph, nodeRef, arcRef);
+    }
+
+    /// \brief Build the digraph from an arc list.
+    ///
+    /// This function builds the digraph from the given arc list.
+    /// It can be called more than once, but in such case, the whole
+    /// structure and all maps will be cleared and rebuilt.
+    ///
+    /// The list of the arcs must be given in the range <tt>[begin, end)</tt>
+    /// specified by STL compatible itartors whose \c value_type must be
+    /// <tt>std::pair<int,int></tt>.
+    /// Each arc must be specified by a pair of integer indices
+    /// from the range <tt>[0..n-1]</tt>. <i>The pairs must be in a
+    /// non-decreasing order with respect to their first values.</i>
+    /// If the k-th pair in the list is <tt>(i,j)</tt>, then
+    /// <tt>arc(k-1)</tt> will connect <tt>node(i)</tt> to <tt>node(j)</tt>.
+    ///
+    /// \param n The number of nodes.
+    /// \param begin An iterator pointing to the beginning of the arc list.
+    /// \param end An iterator pointing to the end of the arc list.
+    ///
+    /// For example, a simple digraph can be constructed like this.
+    /// \code
+    ///   std::vector<std::pair<int,int> > arcs;
+    ///   arcs.push_back(std::make_pair(0,1));
+    ///   arcs.push_back(std::make_pair(0,2));
+    ///   arcs.push_back(std::make_pair(1,3));
+    ///   arcs.push_back(std::make_pair(1,2));
+    ///   arcs.push_back(std::make_pair(3,0));
+    ///   CompactDigraph gr;
+    ///   gr.build(4, arcs.begin(), arcs.end());
+    /// \endcode
+    template <typename ArcListIterator>
+    void build(int n, ArcListIterator begin, ArcListIterator end) {
+      if (built) Parent::clear();
+      CompactDigraphBase::build(n, begin, end);
+      notifier(Node()).build();
+      notifier(Arc()).build();
+    }
+
+    /// \brief Clear the digraph.
+    ///
+    /// This function erases all nodes and arcs from the digraph.
+    void clear() {
+      Parent::clear();
+    }
+
+  public:
+
+    Node baseNode(const OutArcIt &arc) const {
+      return Parent::source(static_cast<const Arc&>(arc));
+    }
+
+    Node runningNode(const OutArcIt &arc) const {
+      return Parent::target(static_cast<const Arc&>(arc));
+    }
+
+    Node baseNode(const InArcIt &arc) const {
+      return Parent::target(static_cast<const Arc&>(arc));
+    }
+
+    Node runningNode(const InArcIt &arc) const {
+      return Parent::source(static_cast<const Arc&>(arc));
+    }
+
+  };
+
+}
+
+#endif
Index: lemon/concepts/bpgraph.h
===================================================================
--- lemon/concepts/bpgraph.h	(revision 1270)
+++ lemon/concepts/bpgraph.h	(revision 1336)
@@ -28,4 +28,5 @@
 #include <lemon/concept_check.h>
 #include <lemon/core.h>
+#include <lemon/bits/stl_iterators.h>
 
 namespace lemon {
@@ -222,4 +223,20 @@
       };
 
+      /// \brief Gets the collection of the red nodes of the graph.
+      ///
+      /// This function can be used for iterating on
+      /// the red nodes of the graph. It returns a wrapped RedNodeIt,
+      /// which looks like an STL container (by having begin() and end())
+      /// which you can use in range-based for loops, stl algorithms, etc.
+      /// For example if g is a BpGraph, you can write:
+      ///\code
+      /// for(auto v: g.redNodes())
+      ///   doSomething(v);
+      ///\endcode
+      LemonRangeWrapper1<RedNodeIt, BpGraph> redNodes() const {
+        return LemonRangeWrapper1<RedNodeIt, BpGraph>(*this);
+      }
+
+
       /// Iterator class for the blue nodes.
 
@@ -265,4 +282,20 @@
       };
 
+      /// \brief Gets the collection of the blue nodes of the graph.
+      ///
+      /// This function can be used for iterating on
+      /// the blue nodes of the graph. It returns a wrapped BlueNodeIt,
+      /// which looks like an STL container (by having begin() and end())
+      /// which you can use in range-based for loops, stl algorithms, etc.
+      /// For example if g is a BpGraph, you can write:
+      ///\code
+      /// for(auto v: g.blueNodes())
+      ///   doSomething(v);
+      ///\endcode
+      LemonRangeWrapper1<BlueNodeIt, BpGraph> blueNodes() const {
+        return LemonRangeWrapper1<BlueNodeIt, BpGraph>(*this);
+      }
+
+
       /// Iterator class for the nodes.
 
@@ -307,4 +340,20 @@
         NodeIt& operator++() { return *this; }
       };
+
+      /// \brief Gets the collection of the nodes of the graph.
+      ///
+      /// This function can be used for iterating on
+      /// the nodes of the graph. It returns a wrapped NodeIt,
+      /// which looks like an STL container (by having begin() and end())
+      /// which you can use in range-based for loops, stl algorithms, etc.
+      /// For example if g is a BpGraph, you can write:
+      ///\code
+      /// for(auto v: g.nodes())
+      ///   doSomething(v);
+      ///\endcode
+      LemonRangeWrapper1<NodeIt, BpGraph> nodes() const {
+        return LemonRangeWrapper1<NodeIt, BpGraph>(*this);
+      }
+
 
 
@@ -395,4 +444,21 @@
         EdgeIt& operator++() { return *this; }
       };
+
+      /// \brief Gets the collection of the edges of the graph.
+      ///
+      /// This function can be used for iterating on the
+      /// edges of the graph. It returns a wrapped
+      /// EdgeIt, which looks like an STL container
+      /// (by having begin() and end()) which you can use in range-based
+      /// for loops, stl algorithms, etc.
+      /// For example if g is a BpGraph, you can write:
+      ///\code
+      /// for(auto e: g.edges())
+      ///   doSomething(e);
+      ///\endcode
+      LemonRangeWrapper1<EdgeIt, BpGraph> edges() const {
+        return LemonRangeWrapper1<EdgeIt, BpGraph>(*this);
+      }
+
 
       /// Iterator class for the incident edges of a node.
@@ -444,4 +510,23 @@
       };
 
+      /// \brief Gets the collection of the incident edges
+      ///  of a certain node of the graph.
+      ///
+      /// This function can be used for iterating on the
+      /// incident undirected edges of a certain node of the graph.
+      /// It returns a wrapped
+      /// IncEdgeIt, which looks like an STL container
+      /// (by having begin() and end()) which you can use in range-based
+      /// for loops, stl algorithms, etc.
+      /// For example if g is a BpGraph and u is a Node, you can write:
+      ///\code
+      /// for(auto e: g.incEdges(u))
+      ///   doSomething(e);
+      ///\endcode
+      LemonRangeWrapper2<IncEdgeIt, BpGraph, Node> incEdges(const Node& u) const {
+        return LemonRangeWrapper2<IncEdgeIt, BpGraph, Node>(*this, u);
+      }
+
+
       /// The arc type of the graph
 
@@ -540,4 +625,21 @@
       };
 
+      /// \brief Gets the collection of the directed arcs of the graph.
+      ///
+      /// This function can be used for iterating on the
+      /// arcs of the graph. It returns a wrapped
+      /// ArcIt, which looks like an STL container
+      /// (by having begin() and end()) which you can use in range-based
+      /// for loops, stl algorithms, etc.
+      /// For example if g is a BpGraph you can write:
+      ///\code
+      /// for(auto a: g.arcs())
+      ///   doSomething(a);
+      ///\endcode
+      LemonRangeWrapper1<ArcIt, BpGraph> arcs() const {
+        return LemonRangeWrapper1<ArcIt, BpGraph>(*this);
+      }
+
+
       /// Iterator class for the outgoing arcs of a node.
 
@@ -588,4 +690,22 @@
       };
 
+      /// \brief Gets the collection of the outgoing directed arcs of a
+      /// certain node of the graph.
+      ///
+      /// This function can be used for iterating on the
+      /// outgoing arcs of a certain node of the graph. It returns a wrapped
+      /// OutArcIt, which looks like an STL container
+      /// (by having begin() and end()) which you can use in range-based
+      /// for loops, stl algorithms, etc.
+      /// For example if g is a BpGraph and u is a Node, you can write:
+      ///\code
+      /// for(auto a: g.outArcs(u))
+      ///   doSomething(a);
+      ///\endcode
+      LemonRangeWrapper2<OutArcIt, BpGraph, Node> outArcs(const Node& u) const {
+        return LemonRangeWrapper2<OutArcIt, BpGraph, Node>(*this, u);
+      }
+
+
       /// Iterator class for the incoming arcs of a node.
 
@@ -635,4 +755,22 @@
         InArcIt& operator++() { return *this; }
       };
+
+      /// \brief Gets the collection of the incoming directed arcs of a
+      /// certain node of the graph.
+      ///
+      /// This function can be used for iterating on the
+      /// incoming arcs of a certain node of the graph. It returns a wrapped
+      /// InArcIt, which looks like an STL container
+      /// (by having begin() and end()) which you can use in range-based
+      /// for loops, stl algorithms, etc.
+      /// For example if g is a BpGraph and u is a Node, you can write:
+      ///\code
+      /// for(auto a: g.inArcs(u))
+      ///   doSomething(a);
+      ///\endcode
+      LemonRangeWrapper2<InArcIt, BpGraph, Node> inArcs(const Node& u) const {
+        return LemonRangeWrapper2<InArcIt, BpGraph, Node>(*this, u);
+      }
+
 
       /// \brief Standard graph map type for the nodes.
Index: lemon/concepts/digraph.h
===================================================================
--- lemon/concepts/digraph.h	(revision 1271)
+++ lemon/concepts/digraph.h	(revision 1336)
@@ -28,4 +28,5 @@
 #include <lemon/concept_check.h>
 #include <lemon/concepts/graph_components.h>
+#include <lemon/bits/stl_iterators.h>
 
 namespace lemon {
@@ -148,4 +149,23 @@
       };
 
+      /// \brief Gets the collection of the nodes of the digraph.
+      ///
+      /// This function can be used for iterating on
+      /// the nodes of the digraph. It returns a wrapped NodeIt, which looks
+      /// like an STL container (by having begin() and end())
+      /// which you can use in range-based for loops, STL algorithms, etc.
+      /// For example you can write:
+      ///\code
+      /// ListDigraph g;
+      /// for(auto v: g.nodes())
+      ///   doSomething(v);
+      ///
+      /// //Using an STL algorithm:
+      /// copy(g.nodes().begin(), g.nodes().end(), vect.begin());
+      ///\endcode
+      LemonRangeWrapper1<NodeIt, Digraph> nodes() const {
+        return LemonRangeWrapper1<NodeIt, Digraph>(*this);
+      }
+
 
       /// The arc type of the digraph
@@ -238,4 +258,25 @@
       };
 
+      /// \brief Gets the collection of the outgoing arcs of a certain node
+      /// of the digraph.
+      ///
+      /// This function can be used for iterating on the
+      /// outgoing arcs of a certain node of the digraph. It returns a wrapped
+      /// OutArcIt, which looks like an STL container
+      /// (by having begin() and end()) which you can use in range-based
+      /// for loops, STL algorithms, etc.
+      /// For example if g is a Digraph and u is a node, you can write:
+      ///\code
+      /// for(auto a: g.outArcs(u))
+      ///   doSomething(a);
+      ///
+      /// //Using an STL algorithm:
+      /// copy(g.outArcs(u).begin(), g.outArcs(u).end(), vect.begin());
+      ///\endcode
+      LemonRangeWrapper2<OutArcIt, Digraph, Node> outArcs(const Node& u) const {
+        return LemonRangeWrapper2<OutArcIt, Digraph, Node>(*this, u);
+      }
+
+
       /// Iterator class for the incoming arcs of a node.
 
@@ -283,4 +324,25 @@
       };
 
+      /// \brief Gets the collection of the incoming arcs of a certain node
+      /// of the digraph.
+      ///
+      /// This function can be used for iterating on the
+      /// incoming arcs of a certain node of the digraph. It returns a wrapped
+      /// InArcIt, which looks like an STL container
+      /// (by having begin() and end()) which you can use in range-based
+      /// for loops, STL algorithms, etc.
+      /// For example if g is a Digraph and u is a node, you can write:
+      ///\code
+      /// for(auto a: g.inArcs(u))
+      ///   doSomething(a);
+      ///
+      /// //Using an STL algorithm:
+      /// copy(g.inArcs(u).begin(), g.inArcs(u).end(), vect.begin());
+      ///\endcode
+      LemonRangeWrapper2<InArcIt, Digraph, Node> inArcs(const Node& u) const {
+        return LemonRangeWrapper2<InArcIt, Digraph, Node>(*this, u);
+      }
+
+
       /// Iterator class for the arcs.
 
@@ -327,4 +389,25 @@
         ArcIt& operator++() { return *this; }
       };
+
+      /// \brief Gets the collection of the arcs of the digraph.
+      ///
+      /// This function can be used for iterating on the
+      /// arcs of the digraph. It returns a wrapped
+      /// ArcIt, which looks like an STL container
+      /// (by having begin() and end()) which you can use in range-based
+      /// for loops, STL algorithms, etc.
+      /// For example you can write:
+      ///\code
+      /// ListDigraph g;
+      /// for(auto a: g.arcs())
+      ///   doSomething(a);
+      ///
+      /// //Using an STL algorithm:
+      /// copy(g.arcs().begin(), g.arcs().end(), vect.begin());
+      ///\endcode
+      LemonRangeWrapper1<ArcIt, Digraph> arcs() const {
+        return LemonRangeWrapper1<ArcIt, Digraph>(*this);
+      }
+
 
       /// \brief The source node of the arc.
Index: lemon/concepts/graph.h
===================================================================
--- lemon/concepts/graph.h	(revision 1271)
+++ lemon/concepts/graph.h	(revision 1336)
@@ -28,4 +28,5 @@
 #include <lemon/concept_check.h>
 #include <lemon/core.h>
+#include <lemon/bits/stl_iterators.h>
 
 namespace lemon {
@@ -181,4 +182,23 @@
       };
 
+      /// \brief Gets the collection of the nodes of the graph.
+      ///
+      /// This function can be used for iterating on
+      /// the nodes of the graph. It returns a wrapped NodeIt, which looks
+      /// like an STL container (by having begin() and end())
+      /// which you can use in range-based for loops, STL algorithms, etc.
+      /// For example you can write:
+      ///\code
+      /// ListGraph g;
+      /// for(auto v: g.nodes())
+      ///   doSomething(v);
+      ///
+      /// //Using an STL algorithm:
+      /// copy(g.nodes().begin(), g.nodes().end(), vect.begin());
+      ///\endcode
+      LemonRangeWrapper1<NodeIt, Graph> nodes() const {
+        return LemonRangeWrapper1<NodeIt, Graph>(*this);
+      }
+
 
       /// The edge type of the graph
@@ -268,4 +288,25 @@
         EdgeIt& operator++() { return *this; }
       };
+
+      /// \brief Gets the collection of the edges of the graph.
+      ///
+      /// This function can be used for iterating on the
+      /// edges of the graph. It returns a wrapped
+      /// EdgeIt, which looks like an STL container
+      /// (by having begin() and end()) which you can use in range-based
+      /// for loops, STL algorithms, etc.
+      /// For example you can write:
+      ///\code
+      /// ListGraph g;
+      /// for(auto e: g.edges())
+      ///   doSomething(e);
+      ///
+      /// //Using an STL algorithm:
+      /// copy(g.edges().begin(), g.edges().end(), vect.begin());
+      ///\endcode
+      LemonRangeWrapper1<EdgeIt, Graph> edges() const {
+        return LemonRangeWrapper1<EdgeIt, Graph>(*this);
+      }
+
 
       /// Iterator class for the incident edges of a node.
@@ -317,4 +358,26 @@
       };
 
+      /// \brief Gets the collection of the incident undirected edges
+      ///  of a certain node of the graph.
+      ///
+      /// This function can be used for iterating on the
+      /// incident undirected edges of a certain node of the graph.
+      /// It returns a wrapped
+      /// IncEdgeIt, which looks like an STL container
+      /// (by having begin() and end()) which you can use in range-based
+      /// for loops, STL algorithms, etc.
+      /// For example if g is a Graph and u is a Node, you can write:
+      ///\code
+      /// for(auto e: g.incEdges(u))
+      ///   doSomething(e);
+      ///
+      /// //Using an STL algorithm:
+      /// copy(g.incEdges(u).begin(), g.incEdges(u).end(), vect.begin());
+      ///\endcode
+      LemonRangeWrapper2<IncEdgeIt, Graph, Node> incEdges(const Node& u) const {
+        return LemonRangeWrapper2<IncEdgeIt, Graph, Node>(*this, u);
+      }
+
+
       /// The arc type of the graph
 
@@ -411,4 +474,25 @@
         ArcIt& operator++() { return *this; }
       };
+
+      /// \brief Gets the collection of the directed arcs of the graph.
+      ///
+      /// This function can be used for iterating on the
+      /// arcs of the graph. It returns a wrapped
+      /// ArcIt, which looks like an STL container
+      /// (by having begin() and end()) which you can use in range-based
+      /// for loops, STL algorithms, etc.
+      /// For example you can write:
+      ///\code
+      /// ListGraph g;
+      /// for(auto a: g.arcs())
+      ///   doSomething(a);
+      ///
+      /// //Using an STL algorithm:
+      /// copy(g.arcs().begin(), g.arcs().end(), vect.begin());
+      ///\endcode
+      LemonRangeWrapper1<ArcIt, Graph> arcs() const {
+        return LemonRangeWrapper1<ArcIt, Graph>(*this);
+      }
+
 
       /// Iterator class for the outgoing arcs of a node.
@@ -460,4 +544,25 @@
       };
 
+      /// \brief Gets the collection of the outgoing directed arcs of a
+      /// certain node of the graph.
+      ///
+      /// This function can be used for iterating on the
+      /// outgoing arcs of a certain node of the graph. It returns a wrapped
+      /// OutArcIt, which looks like an STL container
+      /// (by having begin() and end()) which you can use in range-based
+      /// for loops, STL algorithms, etc.
+      /// For example if g is a Graph and u is a Node, you can write:
+      ///\code
+      /// for(auto a: g.outArcs(u))
+      ///   doSomething(a);
+      ///
+      /// //Using an STL algorithm:
+      /// copy(g.outArcs(u).begin(), g.outArcs(u).end(), vect.begin());
+      ///\endcode
+      LemonRangeWrapper2<OutArcIt, Graph, Node> outArcs(const Node& u) const {
+        return LemonRangeWrapper2<OutArcIt, Graph, Node>(*this, u);
+      }
+
+
       /// Iterator class for the incoming arcs of a node.
 
@@ -507,4 +612,24 @@
         InArcIt& operator++() { return *this; }
       };
+
+      /// \brief Gets the collection of the incoming directed arcs of
+      /// a certain node of the graph.
+      ///
+      /// This function can be used for iterating on the
+      /// incoming directed arcs of a certain node of the graph. It returns
+      /// a wrapped InArcIt, which looks like an STL container
+      /// (by having begin() and end()) which you can use in range-based
+      /// for loops, STL algorithms, etc.
+      /// For example if g is a Graph and u is a Node, you can write:
+      ///\code
+      /// for(auto a: g.inArcs(u))
+      ///   doSomething(a);
+      ///
+      /// //Using an STL algorithm:
+      /// copy(g.inArcs(u).begin(), g.inArcs(u).end(), vect.begin());
+      ///\endcode
+      LemonRangeWrapper2<InArcIt, Graph, Node> inArcs(const Node& u) const {
+        return LemonRangeWrapper2<InArcIt, Graph, Node>(*this, u);
+      }
 
       /// \brief Standard graph map type for the nodes.
Index: lemon/concepts/path.h
===================================================================
--- lemon/concepts/path.h	(revision 1416)
+++ lemon/concepts/path.h	(revision 1417)
@@ -27,4 +27,5 @@
 #include <lemon/core.h>
 #include <lemon/concept_check.h>
+#include <lemon/bits/stl_iterators.h>
 
 namespace lemon {
@@ -118,4 +119,21 @@
       };
 
+      /// \brief Gets the collection of the arcs of the path.
+      ///
+      /// This function can be used for iterating on the
+      /// arcs of the path. It returns a wrapped
+      /// ArcIt, which looks like an STL container
+      /// (by having begin() and end()) which you can use in range-based
+      /// for loops, STL algorithms, etc.
+      /// For example you can write:
+      ///\code
+      /// for(auto a: p.arcs())
+      ///   doSomething(a);
+      ///\endcode
+      LemonRangeWrapper1<ArcIt, Path> arcs() const {
+        return LemonRangeWrapper1<ArcIt, Path>(*this);
+      }
+
+
       template <typename _Path>
       struct Constraints {
@@ -266,4 +284,21 @@
 
       };
+
+      /// \brief Gets the collection of the arcs of the path.
+      ///
+      /// This function can be used for iterating on the
+      /// arcs of the path. It returns a wrapped
+      /// ArcIt, which looks like an STL container
+      /// (by having begin() and end()) which you can use in range-based
+      /// for loops, STL algorithms, etc.
+      /// For example you can write:
+      ///\code
+      /// for(auto a: p.arcs())
+      ///   doSomething(a);
+      ///\endcode
+      LemonRangeWrapper1<ArcIt, PathDumper> arcs() const {
+        return LemonRangeWrapper1<ArcIt, PathDumper>(*this);
+      }
+
 
       /// \brief LEMON style iterator for enumerating the arcs of a path
@@ -296,4 +331,22 @@
       };
 
+      /// \brief Gets the collection of the arcs of the path
+      /// in reverse direction.
+      ///
+      /// This function can be used for iterating on the
+      /// arcs of the path in reverse direction. It returns a wrapped
+      /// RevArcIt, which looks like an STL container
+      /// (by having begin() and end()) which you can use in range-based
+      /// for loops, STL algorithms, etc.
+      /// For example you can write:
+      ///\code
+      /// for(auto a: p.revArcs())
+      ///   doSomething(a);
+      ///\endcode
+      LemonRangeWrapper1<RevArcIt, PathDumper> revArcs() const {
+        return LemonRangeWrapper1<RevArcIt, PathDumper>(*this);
+      }
+
+
       template <typename _Path>
       struct Constraints {
Index: lemon/config.h.in
===================================================================
--- lemon/config.h.in	(revision 1416)
+++ lemon/config.h.in	(revision 1417)
@@ -5,4 +5,6 @@
 
 #cmakedefine LEMON_HAVE_LONG_LONG 1
+
+#cmakedefine LEMON_CXX11 1
 
 #cmakedefine LEMON_WIN32 1
Index: lemon/cplex.cc
===================================================================
--- lemon/cplex.cc	(revision 1347)
+++ lemon/cplex.cc	(revision 1349)
@@ -105,6 +105,6 @@
     int status;
     _prob = CPXcloneprob(cplexEnv(), cplex._prob, &status);
-    rows = cplex.rows;
-    cols = cplex.cols;
+    _rows = cplex._rows;
+    _cols = cplex._cols;
     messageLevel(MESSAGE_NOTHING);
   }
@@ -133,32 +133,35 @@
                          ExprIterator e, Value ub) {
     int i = CPXgetnumrows(cplexEnv(), _prob);
+
+    int rmatbeg = 0;
+    
+    std::vector<int> indices;
+    std::vector<Value> values;
+
+    for(ExprIterator it=b; it!=e; ++it) {
+      indices.push_back(it->first);
+      values.push_back(it->second);
+    }
+
     if (lb == -INF) {
       const char s = 'L';
-      CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
+      CPXaddrows(cplexEnv(), _prob, 0, 1, values.size(), &ub, &s,
+                 &rmatbeg, &indices.front(), &values.front(), 0, 0);
     } else if (ub == INF) {
       const char s = 'G';
-      CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
+      CPXaddrows(cplexEnv(), _prob, 0, 1, values.size(), &lb, &s,
+                 &rmatbeg, &indices.front(), &values.front(), 0, 0);
     } else if (lb == ub){
       const char s = 'E';
-      CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
+      CPXaddrows(cplexEnv(), _prob, 0, 1, values.size(), &lb, &s,
+                 &rmatbeg, &indices.front(), &values.front(), 0, 0);
     } else {
       const char s = 'R';
       double len = ub - lb;
-      CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, &len, 0);
-    }
-
-    std::vector<int> indices;
-    std::vector<int> rowlist;
-    std::vector<Value> values;
-
-    for(ExprIterator it=b; it!=e; ++it) {
-      indices.push_back(it->first);
-      values.push_back(it->second);
-      rowlist.push_back(i);
-    }
-
-    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
-                   &rowlist.front(), &indices.front(), &values.front());
-
+      CPXaddrows(cplexEnv(), _prob, 0, 1, values.size(), &ub, &s,
+                 &rmatbeg, &indices.front(), &values.front(), 0, 0);
+      CPXchgrngval(cplexEnv(), _prob, 1, &i, &len);
+    }
+    
     return i;
   }
@@ -173,10 +176,10 @@
 
   void CplexBase::_eraseColId(int i) {
-    cols.eraseIndex(i);
-    cols.shiftIndices(i);
+    _cols.eraseIndex(i);
+    _cols.shiftIndices(i);
   }
   void CplexBase::_eraseRowId(int i) {
-    rows.eraseIndex(i);
-    rows.shiftIndices(i);
+    _rows.eraseIndex(i);
+    _rows.shiftIndices(i);
   }
 
Index: lemon/dfs.h
===================================================================
--- lemon/dfs.h	(revision 1416)
+++ lemon/dfs.h	(revision 1418)
@@ -182,5 +182,5 @@
     bool local_processed;
 
-    std::vector<typename Digraph::OutArcIt> _stack;
+    std::vector<typename Digraph::Arc> _stack;
     int _stack_head;
 
@@ -458,5 +458,6 @@
           _reached->set(s,true);
           _pred->set(s,INVALID);
-          OutArcIt e(*G,s);
+          Arc e;
+          G->firstOut(e,s);
           if(e!=INVALID) {
             _stack[++_stack_head]=e;
@@ -485,10 +486,10 @@
         _reached->set(m,true);
         ++_stack_head;
-        _stack[_stack_head] = OutArcIt(*G, m);
+        G->firstOut(_stack[_stack_head],m);
         _dist->set(m,_stack_head);
       }
       else {
         m=G->source(e);
-        ++_stack[_stack_head];
+        G->nextOut(_stack[_stack_head]);
       }
       while(_stack_head>=0 && _stack[_stack_head]==INVALID) {
@@ -497,5 +498,5 @@
         if(_stack_head>=0) {
           m=G->source(_stack[_stack_head]);
-          ++_stack[_stack_head];
+          G->nextOut(_stack[_stack_head]);
         }
       }
@@ -511,5 +512,5 @@
     OutArcIt nextArc() const
     {
-      return _stack_head>=0?_stack[_stack_head]:INVALID;
+      return OutArcIt(*G,_stack_head>=0?_stack[_stack_head]:INVALID);
     }
 
Index: lemon/glpk.cc
===================================================================
--- lemon/glpk.cc	(revision 1270)
+++ lemon/glpk.cc	(revision 1336)
@@ -39,6 +39,6 @@
     glp_copy_prob(lp, other.lp, GLP_ON);
     glp_create_index(lp);
-    rows = other.rows;
-    cols = other.cols;
+    _rows = other._rows;
+    _cols = other._cols;
     messageLevel(MESSAGE_NOTHING);
   }
@@ -109,11 +109,11 @@
 
   void GlpkBase::_eraseColId(int i) {
-    cols.eraseIndex(i);
-    cols.shiftIndices(i);
+    _cols.eraseIndex(i);
+    _cols.shiftIndices(i);
   }
 
   void GlpkBase::_eraseRowId(int i) {
-    rows.eraseIndex(i);
-    rows.shiftIndices(i);
+    _rows.eraseIndex(i);
+    _rows.shiftIndices(i);
   }
 
Index: lemon/glpk.h
===================================================================
--- lemon/glpk.h	(revision 1270)
+++ lemon/glpk.h	(revision 1336)
@@ -142,8 +142,8 @@
 
     ///Returns the constraint identifier understood by GLPK.
-    int lpxRow(Row r) const { return rows(id(r)); }
+    int lpxRow(Row r) const { return _rows(id(r)); }
 
     ///Returns the variable identifier understood by GLPK.
-    int lpxCol(Col c) const { return cols(id(c)); }
+    int lpxCol(Col c) const { return _cols(id(c)); }
 
 #ifdef DOXYGEN
Index: lemon/lgf_reader.h
===================================================================
--- lemon/lgf_reader.h	(revision 1270)
+++ lemon/lgf_reader.h	(revision 1377)
@@ -452,11 +452,11 @@
   ///
   ///\code
-  /// DigraphReader<DGR>(digraph, std::cin).
-  ///   nodeMap("coordinates", coord_map).
-  ///   arcMap("capacity", cap_map).
-  ///   node("source", src).
-  ///   node("target", trg).
-  ///   attribute("caption", caption).
-  ///   run();
+  /// DigraphReader<DGR>(digraph, std::cin)
+  ///   .nodeMap("coordinates", coord_map)
+  ///   .arcMap("capacity", cap_map)
+  ///   .node("source", src)
+  ///   .node("target", trg)
+  ///   .attribute("caption", caption)
+  ///   .run();
   ///\endcode
   ///
@@ -1245,11 +1245,11 @@
   ///\code
   ///ListDigraph digraph;
-  ///ListDigraph::ArcMap<int> cm(digraph);
+  ///ListDigraph::ArcMap<int> cap(digraph);
   ///ListDigraph::Node src, trg;
-  ///digraphReader(digraph, std::cin).
-  ///  arcMap("capacity", cap).
-  ///  node("source", src).
-  ///  node("target", trg).
-  ///  run();
+  ///digraphReader(digraph, std::cin)
+  ///  .arcMap("capacity", cap)
+  ///  .node("source", src)
+  ///  .node("target", trg)
+  ///  .run();
   ///\endcode
   ///
@@ -2124,7 +2124,7 @@
   ///ListGraph graph;
   ///ListGraph::EdgeMap<int> weight(graph);
-  ///graphReader(graph, std::cin).
-  ///  edgeMap("weight", weight).
-  ///  run();
+  ///graphReader(graph, std::cin)
+  ///  .edgeMap("weight", weight)
+  ///  .run();
   ///\endcode
   ///
@@ -3192,7 +3192,7 @@
   ///ListBpGraph graph;
   ///ListBpGraph::EdgeMap<int> weight(graph);
-  ///bpGraphReader(graph, std::cin).
-  ///  edgeMap("weight", weight).
-  ///  run();
+  ///bpGraphReader(graph, std::cin)
+  ///  .edgeMap("weight", weight)
+  ///  .run();
   ///\endcode
   ///
Index: lemon/lgf_writer.h
===================================================================
--- lemon/lgf_writer.h	(revision 1270)
+++ lemon/lgf_writer.h	(revision 1377)
@@ -409,13 +409,13 @@
   ///
   ///\code
-  /// DigraphWriter<DGR>(digraph, std::cout).
-  ///   nodeMap("coordinates", coord_map).
-  ///   nodeMap("size", size).
-  ///   nodeMap("title", title).
-  ///   arcMap("capacity", cap_map).
-  ///   node("source", src).
-  ///   node("target", trg).
-  ///   attribute("caption", caption).
-  ///   run();
+  /// DigraphWriter<DGR>(digraph, std::cout)
+  ///   .nodeMap("coordinates", coord_map)
+  ///   .nodeMap("size", size)
+  ///   .nodeMap("title", title)
+  ///   .arcMap("capacity", cap_map)
+  ///   .node("source", src)
+  ///   .node("target", trg)
+  ///   .attribute("caption", caption)
+  ///   .run();
   ///\endcode
   ///
@@ -962,9 +962,9 @@
   ///ListDigraph::Node src, trg;
   ///  // Setting the capacity map and source and target nodes
-  ///digraphWriter(digraph, std::cout).
-  ///  arcMap("capacity", cap).
-  ///  node("source", src).
-  ///  node("target", trg).
-  ///  run();
+  ///digraphWriter(digraph, std::cout)
+  ///  .arcMap("capacity", cap)
+  ///  .node("source", src)
+  ///  .node("target", trg)
+  ///  .run();
   ///\endcode
   ///
@@ -1600,7 +1600,7 @@
   ///ListGraph::EdgeMap<int> weight(graph);
   ///  // Setting the weight map
-  ///graphWriter(graph, std::cout).
-  ///  edgeMap("weight", weight).
-  ///  run();
+  ///graphWriter(graph, std::cout)
+  ///  .edgeMap("weight", weight)
+  ///  .run();
   ///\endcode
   ///
@@ -2420,7 +2420,7 @@
   ///ListBpGraph::EdgeMap<int> weight(graph);
   ///  // Setting the weight map
-  ///bpGraphWriter(graph, std::cout).
-  ///  edgeMap("weight", weight).
-  ///  run();
+  ///bpGraphWriter(graph, std::cout)
+  ///  .edgeMap("weight", weight)
+  ///  .run();
   ///\endcode
   ///
Index: lemon/list_graph.h
===================================================================
--- lemon/list_graph.h	(revision 1357)
+++ lemon/list_graph.h	(revision 1359)
@@ -49,5 +49,5 @@
     };
 
-    std::vector<NodeT> nodes;
+    std::vector<NodeT> _nodes;
 
     int first_node;
@@ -55,5 +55,5 @@
     int first_free_node;
 
-    std::vector<ArcT> arcs;
+    std::vector<ArcT> _arcs;
 
     int first_free_arc;
@@ -98,13 +98,13 @@
 
     ListDigraphBase()
-      : nodes(), first_node(-1),
-        first_free_node(-1), arcs(), first_free_arc(-1) {}
-
-
-    int maxNodeId() const { return nodes.size()-1; }
-    int maxArcId() const { return arcs.size()-1; }
-
-    Node source(Arc e) const { return Node(arcs[e.id].source); }
-    Node target(Arc e) const { return Node(arcs[e.id].target); }
+      : _nodes(), first_node(-1),
+        first_free_node(-1), _arcs(), first_free_arc(-1) {}
+
+
+    int maxNodeId() const { return _nodes.size()-1; }
+    int maxArcId() const { return _arcs.size()-1; }
+
+    Node source(Arc e) const { return Node(_arcs[e.id].source); }
+    Node target(Arc e) const { return Node(_arcs[e.id].target); }
 
 
@@ -114,5 +114,5 @@
 
     void next(Node& node) const {
-      node.id = nodes[node.id].next;
+      node.id = _nodes[node.id].next;
     }
 
@@ -121,33 +121,33 @@
       int n;
       for(n = first_node;
-          n != -1 && nodes[n].first_out == -1;
-          n = nodes[n].next) {}
-      arc.id = (n == -1) ? -1 : nodes[n].first_out;
+          n != -1 && _nodes[n].first_out == -1;
+          n = _nodes[n].next) {}
+      arc.id = (n == -1) ? -1 : _nodes[n].first_out;
     }
 
     void next(Arc& arc) const {
-      if (arcs[arc.id].next_out != -1) {
-        arc.id = arcs[arc.id].next_out;
+      if (_arcs[arc.id].next_out != -1) {
+        arc.id = _arcs[arc.id].next_out;
       } else {
         int n;
-        for(n = nodes[arcs[arc.id].source].next;
-            n != -1 && nodes[n].first_out == -1;
-            n = nodes[n].next) {}
-        arc.id = (n == -1) ? -1 : nodes[n].first_out;
+        for(n = _nodes[_arcs[arc.id].source].next;
+            n != -1 && _nodes[n].first_out == -1;
+            n = _nodes[n].next) {}
+        arc.id = (n == -1) ? -1 : _nodes[n].first_out;
       }
     }
 
     void firstOut(Arc &e, const Node& v) const {
-      e.id = nodes[v.id].first_out;
+      e.id = _nodes[v.id].first_out;
     }
     void nextOut(Arc &e) const {
-      e.id=arcs[e.id].next_out;
+      e.id=_arcs[e.id].next_out;
     }
 
     void firstIn(Arc &e, const Node& v) const {
-      e.id = nodes[v.id].first_in;
+      e.id = _nodes[v.id].first_in;
     }
     void nextIn(Arc &e) const {
-      e.id=arcs[e.id].next_in;
+      e.id=_arcs[e.id].next_in;
     }
 
@@ -160,11 +160,11 @@
 
     bool valid(Node n) const {
-      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
-        nodes[n.id].prev != -2;
+      return n.id >= 0 && n.id < static_cast<int>(_nodes.size()) &&
+        _nodes[n.id].prev != -2;
     }
 
     bool valid(Arc a) const {
-      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
-        arcs[a.id].prev_in != -2;
+      return a.id >= 0 && a.id < static_cast<int>(_arcs.size()) &&
+        _arcs[a.id].prev_in != -2;
     }
 
@@ -173,17 +173,17 @@
 
       if(first_free_node==-1) {
-        n = nodes.size();
-        nodes.push_back(NodeT());
+        n = _nodes.size();
+        _nodes.push_back(NodeT());
       } else {
         n = first_free_node;
-        first_free_node = nodes[n].next;
-      }
-
-      nodes[n].next = first_node;
-      if(first_node != -1) nodes[first_node].prev = n;
+        first_free_node = _nodes[n].next;
+      }
+
+      _nodes[n].next = first_node;
+      if(first_node != -1) _nodes[first_node].prev = n;
       first_node = n;
-      nodes[n].prev = -1;
-
-      nodes[n].first_in = nodes[n].first_out = -1;
+      _nodes[n].prev = -1;
+
+      _nodes[n].first_in = _nodes[n].first_out = -1;
 
       return Node(n);
@@ -194,27 +194,27 @@
 
       if (first_free_arc == -1) {
-        n = arcs.size();
-        arcs.push_back(ArcT());
+        n = _arcs.size();
+        _arcs.push_back(ArcT());
       } else {
         n = first_free_arc;
-        first_free_arc = arcs[n].next_in;
-      }
-
-      arcs[n].source = u.id;
-      arcs[n].target = v.id;
-
-      arcs[n].next_out = nodes[u.id].first_out;
-      if(nodes[u.id].first_out != -1) {
-        arcs[nodes[u.id].first_out].prev_out = n;
-      }
-
-      arcs[n].next_in = nodes[v.id].first_in;
-      if(nodes[v.id].first_in != -1) {
-        arcs[nodes[v.id].first_in].prev_in = n;
-      }
-
-      arcs[n].prev_in = arcs[n].prev_out = -1;
-
-      nodes[u.id].first_out = nodes[v.id].first_in = n;
+        first_free_arc = _arcs[n].next_in;
+      }
+
+      _arcs[n].source = u.id;
+      _arcs[n].target = v.id;
+
+      _arcs[n].next_out = _nodes[u.id].first_out;
+      if(_nodes[u.id].first_out != -1) {
+        _arcs[_nodes[u.id].first_out].prev_out = n;
+      }
+
+      _arcs[n].next_in = _nodes[v.id].first_in;
+      if(_nodes[v.id].first_in != -1) {
+        _arcs[_nodes[v.id].first_in].prev_in = n;
+      }
+
+      _arcs[n].prev_in = _arcs[n].prev_out = -1;
+
+      _nodes[u.id].first_out = _nodes[v.id].first_in = n;
 
       return Arc(n);
@@ -224,17 +224,17 @@
       int n = node.id;
 
-      if(nodes[n].next != -1) {
-        nodes[nodes[n].next].prev = nodes[n].prev;
-      }
-
-      if(nodes[n].prev != -1) {
-        nodes[nodes[n].prev].next = nodes[n].next;
-      } else {
-        first_node = nodes[n].next;
-      }
-
-      nodes[n].next = first_free_node;
+      if(_nodes[n].next != -1) {
+        _nodes[_nodes[n].next].prev = _nodes[n].prev;
+      }
+
+      if(_nodes[n].prev != -1) {
+        _nodes[_nodes[n].prev].next = _nodes[n].next;
+      } else {
+        first_node = _nodes[n].next;
+      }
+
+      _nodes[n].next = first_free_node;
       first_free_node = n;
-      nodes[n].prev = -2;
+      _nodes[n].prev = -2;
 
     }
@@ -243,33 +243,33 @@
       int n = arc.id;
 
-      if(arcs[n].next_in!=-1) {
-        arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
-      }
-
-      if(arcs[n].prev_in!=-1) {
-        arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
-      } else {
-        nodes[arcs[n].target].first_in = arcs[n].next_in;
-      }
-
-
-      if(arcs[n].next_out!=-1) {
-        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
-      }
-
-      if(arcs[n].prev_out!=-1) {
-        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
-      } else {
-        nodes[arcs[n].source].first_out = arcs[n].next_out;
-      }
-
-      arcs[n].next_in = first_free_arc;
+      if(_arcs[n].next_in!=-1) {
+        _arcs[_arcs[n].next_in].prev_in = _arcs[n].prev_in;
+      }
+
+      if(_arcs[n].prev_in!=-1) {
+        _arcs[_arcs[n].prev_in].next_in = _arcs[n].next_in;
+      } else {
+        _nodes[_arcs[n].target].first_in = _arcs[n].next_in;
+      }
+
+
+      if(_arcs[n].next_out!=-1) {
+        _arcs[_arcs[n].next_out].prev_out = _arcs[n].prev_out;
+      }
+
+      if(_arcs[n].prev_out!=-1) {
+        _arcs[_arcs[n].prev_out].next_out = _arcs[n].next_out;
+      } else {
+        _nodes[_arcs[n].source].first_out = _arcs[n].next_out;
+      }
+
+      _arcs[n].next_in = first_free_arc;
       first_free_arc = n;
-      arcs[n].prev_in = -2;
+      _arcs[n].prev_in = -2;
     }
 
     void clear() {
-      arcs.clear();
-      nodes.clear();
+      _arcs.clear();
+      _nodes.clear();
       first_node = first_free_node = first_free_arc = -1;
     }
@@ -278,31 +278,31 @@
     void changeTarget(Arc e, Node n)
     {
-      if(arcs[e.id].next_in != -1)
-        arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in;
-      if(arcs[e.id].prev_in != -1)
-        arcs[arcs[e.id].prev_in].next_in = arcs[e.id].next_in;
-      else nodes[arcs[e.id].target].first_in = arcs[e.id].next_in;
-      if (nodes[n.id].first_in != -1) {
-        arcs[nodes[n.id].first_in].prev_in = e.id;
-      }
-      arcs[e.id].target = n.id;
-      arcs[e.id].prev_in = -1;
-      arcs[e.id].next_in = nodes[n.id].first_in;
-      nodes[n.id].first_in = e.id;
+      if(_arcs[e.id].next_in != -1)
+        _arcs[_arcs[e.id].next_in].prev_in = _arcs[e.id].prev_in;
+      if(_arcs[e.id].prev_in != -1)
+        _arcs[_arcs[e.id].prev_in].next_in = _arcs[e.id].next_in;
+      else _nodes[_arcs[e.id].target].first_in = _arcs[e.id].next_in;
+      if (_nodes[n.id].first_in != -1) {
+        _arcs[_nodes[n.id].first_in].prev_in = e.id;
+      }
+      _arcs[e.id].target = n.id;
+      _arcs[e.id].prev_in = -1;
+      _arcs[e.id].next_in = _nodes[n.id].first_in;
+      _nodes[n.id].first_in = e.id;
     }
     void changeSource(Arc e, Node n)
     {
-      if(arcs[e.id].next_out != -1)
-        arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out;
-      if(arcs[e.id].prev_out != -1)
-        arcs[arcs[e.id].prev_out].next_out = arcs[e.id].next_out;
-      else nodes[arcs[e.id].source].first_out = arcs[e.id].next_out;
-      if (nodes[n.id].first_out != -1) {
-        arcs[nodes[n.id].first_out].prev_out = e.id;
-      }
-      arcs[e.id].source = n.id;
-      arcs[e.id].prev_out = -1;
-      arcs[e.id].next_out = nodes[n.id].first_out;
-      nodes[n.id].first_out = e.id;
+      if(_arcs[e.id].next_out != -1)
+        _arcs[_arcs[e.id].next_out].prev_out = _arcs[e.id].prev_out;
+      if(_arcs[e.id].prev_out != -1)
+        _arcs[_arcs[e.id].prev_out].next_out = _arcs[e.id].next_out;
+      else _nodes[_arcs[e.id].source].first_out = _arcs[e.id].next_out;
+      if (_nodes[n.id].first_out != -1) {
+        _arcs[_nodes[n.id].first_out].prev_out = e.id;
+      }
+      _arcs[e.id].source = n.id;
+      _arcs[e.id].prev_out = -1;
+      _arcs[e.id].next_out = _nodes[n.id].first_out;
+      _nodes[n.id].first_out = e.id;
     }
 
@@ -487,8 +487,8 @@
     Node split(Node n, bool connect = true) {
       Node b = addNode();
-      nodes[b.id].first_out=nodes[n.id].first_out;
-      nodes[n.id].first_out=-1;
-      for(int i=nodes[b.id].first_out; i!=-1; i=arcs[i].next_out) {
-        arcs[i].source=b.id;
+      _nodes[b.id].first_out=_nodes[n.id].first_out;
+      _nodes[n.id].first_out=-1;
+      for(int i=_nodes[b.id].first_out; i!=-1; i=_arcs[i].next_out) {
+        _arcs[i].source=b.id;
       }
       if (connect) addArc(n,b);
@@ -533,5 +533,5 @@
     /// to build the digraph.
     /// \sa reserveArc()
-    void reserveNode(int n) { nodes.reserve(n); };
+    void reserveNode(int n) { _nodes.reserve(n); };
 
     /// Reserve memory for arcs.
@@ -543,5 +543,5 @@
     /// to build the digraph.
     /// \sa reserveNode()
-    void reserveArc(int m) { arcs.reserve(m); };
+    void reserveArc(int m) { _arcs.reserve(m); };
 
     /// \brief Class to make a snapshot of the digraph and restore
@@ -804,5 +804,5 @@
     };
 
-    std::vector<NodeT> nodes;
+    std::vector<NodeT> _nodes;
 
     int first_node;
@@ -810,5 +810,5 @@
     int first_free_node;
 
-    std::vector<ArcT> arcs;
+    std::vector<ArcT> _arcs;
 
     int first_free_arc;
@@ -868,17 +868,17 @@
 
     ListGraphBase()
-      : nodes(), first_node(-1),
-        first_free_node(-1), arcs(), first_free_arc(-1) {}
-
-
-    int maxNodeId() const { return nodes.size()-1; }
-    int maxEdgeId() const { return arcs.size() / 2 - 1; }
-    int maxArcId() const { return arcs.size()-1; }
-
-    Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
-    Node target(Arc e) const { return Node(arcs[e.id].target); }
-
-    Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
-    Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
+      : _nodes(), first_node(-1),
+        first_free_node(-1), _arcs(), first_free_arc(-1) {}
+
+
+    int maxNodeId() const { return _nodes.size()-1; }
+    int maxEdgeId() const { return _arcs.size() / 2 - 1; }
+    int maxArcId() const { return _arcs.size()-1; }
+
+    Node source(Arc e) const { return Node(_arcs[e.id ^ 1].target); }
+    Node target(Arc e) const { return Node(_arcs[e.id].target); }
+
+    Node u(Edge e) const { return Node(_arcs[2 * e.id].target); }
+    Node v(Edge e) const { return Node(_arcs[2 * e.id + 1].target); }
 
     static bool direction(Arc e) {
@@ -895,24 +895,24 @@
 
     void next(Node& node) const {
-      node.id = nodes[node.id].next;
+      node.id = _nodes[node.id].next;
     }
 
     void first(Arc& e) const {
       int n = first_node;
-      while (n != -1 && nodes[n].first_out == -1) {
-        n = nodes[n].next;
-      }
-      e.id = (n == -1) ? -1 : nodes[n].first_out;
+      while (n != -1 && _nodes[n].first_out == -1) {
+        n = _nodes[n].next;
+      }
+      e.id = (n == -1) ? -1 : _nodes[n].first_out;
     }
 
     void next(Arc& e) const {
-      if (arcs[e.id].next_out != -1) {
-        e.id = arcs[e.id].next_out;
-      } else {
-        int n = nodes[arcs[e.id ^ 1].target].next;
-        while(n != -1 && nodes[n].first_out == -1) {
-          n = nodes[n].next;
-        }
-        e.id = (n == -1) ? -1 : nodes[n].first_out;
+      if (_arcs[e.id].next_out != -1) {
+        e.id = _arcs[e.id].next_out;
+      } else {
+        int n = _nodes[_arcs[e.id ^ 1].target].next;
+        while(n != -1 && _nodes[n].first_out == -1) {
+          n = _nodes[n].next;
+        }
+        e.id = (n == -1) ? -1 : _nodes[n].first_out;
       }
     }
@@ -921,7 +921,7 @@
       int n = first_node;
       while (n != -1) {
-        e.id = nodes[n].first_out;
+        e.id = _nodes[n].first_out;
         while ((e.id & 1) != 1) {
-          e.id = arcs[e.id].next_out;
+          e.id = _arcs[e.id].next_out;
         }
         if (e.id != -1) {
@@ -929,5 +929,5 @@
           return;
         }
-        n = nodes[n].next;
+        n = _nodes[n].next;
       }
       e.id = -1;
@@ -935,8 +935,8 @@
 
     void next(Edge& e) const {
-      int n = arcs[e.id * 2].target;
-      e.id = arcs[(e.id * 2) | 1].next_out;
+      int n = _arcs[e.id * 2].target;
+      e.id = _arcs[(e.id * 2) | 1].next_out;
       while ((e.id & 1) != 1) {
-        e.id = arcs[e.id].next_out;
+        e.id = _arcs[e.id].next_out;
       }
       if (e.id != -1) {
@@ -944,9 +944,9 @@
         return;
       }
-      n = nodes[n].next;
+      n = _nodes[n].next;
       while (n != -1) {
-        e.id = nodes[n].first_out;
+        e.id = _nodes[n].first_out;
         while ((e.id & 1) != 1) {
-          e.id = arcs[e.id].next_out;
+          e.id = _arcs[e.id].next_out;
         }
         if (e.id != -1) {
@@ -954,5 +954,5 @@
           return;
         }
-        n = nodes[n].next;
+        n = _nodes[n].next;
       }
       e.id = -1;
@@ -960,21 +960,21 @@
 
     void firstOut(Arc &e, const Node& v) const {
-      e.id = nodes[v.id].first_out;
+      e.id = _nodes[v.id].first_out;
     }
     void nextOut(Arc &e) const {
-      e.id = arcs[e.id].next_out;
+      e.id = _arcs[e.id].next_out;
     }
 
     void firstIn(Arc &e, const Node& v) const {
-      e.id = ((nodes[v.id].first_out) ^ 1);
+      e.id = ((_nodes[v.id].first_out) ^ 1);
       if (e.id == -2) e.id = -1;
     }
     void nextIn(Arc &e) const {
-      e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
+      e.id = ((_arcs[e.id ^ 1].next_out) ^ 1);
       if (e.id == -2) e.id = -1;
     }
 
     void firstInc(Edge &e, bool& d, const Node& v) const {
-      int a = nodes[v.id].first_out;
+      int a = _nodes[v.id].first_out;
       if (a != -1 ) {
         e.id = a / 2;
@@ -986,5 +986,5 @@
     }
     void nextInc(Edge &e, bool& d) const {
-      int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
+      int a = (_arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
       if (a != -1 ) {
         e.id = a / 2;
@@ -1005,16 +1005,16 @@
 
     bool valid(Node n) const {
-      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
-        nodes[n.id].prev != -2;
+      return n.id >= 0 && n.id < static_cast<int>(_nodes.size()) &&
+        _nodes[n.id].prev != -2;
     }
 
     bool valid(Arc a) const {
-      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
-        arcs[a.id].prev_out != -2;
+      return a.id >= 0 && a.id < static_cast<int>(_arcs.size()) &&
+        _arcs[a.id].prev_out != -2;
     }
 
     bool valid(Edge e) const {
-      return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
-        arcs[2 * e.id].prev_out != -2;
+      return e.id >= 0 && 2 * e.id < static_cast<int>(_arcs.size()) &&
+        _arcs[2 * e.id].prev_out != -2;
     }
 
@@ -1023,17 +1023,17 @@
 
       if(first_free_node==-1) {
-        n = nodes.size();
-        nodes.push_back(NodeT());
+        n = _nodes.size();
+        _nodes.push_back(NodeT());
       } else {
         n = first_free_node;
-        first_free_node = nodes[n].next;
-      }
-
-      nodes[n].next = first_node;
-      if (first_node != -1) nodes[first_node].prev = n;
+        first_free_node = _nodes[n].next;
+      }
+
+      _nodes[n].next = first_node;
+      if (first_node != -1) _nodes[first_node].prev = n;
       first_node = n;
-      nodes[n].prev = -1;
-
-      nodes[n].first_out = -1;
+      _nodes[n].prev = -1;
+
+      _nodes[n].first_out = -1;
 
       return Node(n);
@@ -1044,28 +1044,28 @@
 
       if (first_free_arc == -1) {
-        n = arcs.size();
-        arcs.push_back(ArcT());
-        arcs.push_back(ArcT());
+        n = _arcs.size();
+        _arcs.push_back(ArcT());
+        _arcs.push_back(ArcT());
       } else {
         n = first_free_arc;
-        first_free_arc = arcs[n].next_out;
-      }
-
-      arcs[n].target = u.id;
-      arcs[n | 1].target = v.id;
-
-      arcs[n].next_out = nodes[v.id].first_out;
-      if (nodes[v.id].first_out != -1) {
-        arcs[nodes[v.id].first_out].prev_out = n;
-      }
-      arcs[n].prev_out = -1;
-      nodes[v.id].first_out = n;
-
-      arcs[n | 1].next_out = nodes[u.id].first_out;
-      if (nodes[u.id].first_out != -1) {
-        arcs[nodes[u.id].first_out].prev_out = (n | 1);
-      }
-      arcs[n | 1].prev_out = -1;
-      nodes[u.id].first_out = (n | 1);
+        first_free_arc = _arcs[n].next_out;
+      }
+
+      _arcs[n].target = u.id;
+      _arcs[n | 1].target = v.id;
+
+      _arcs[n].next_out = _nodes[v.id].first_out;
+      if (_nodes[v.id].first_out != -1) {
+        _arcs[_nodes[v.id].first_out].prev_out = n;
+      }
+      _arcs[n].prev_out = -1;
+      _nodes[v.id].first_out = n;
+
+      _arcs[n | 1].next_out = _nodes[u.id].first_out;
+      if (_nodes[u.id].first_out != -1) {
+        _arcs[_nodes[u.id].first_out].prev_out = (n | 1);
+      }
+      _arcs[n | 1].prev_out = -1;
+      _nodes[u.id].first_out = (n | 1);
 
       return Edge(n / 2);
@@ -1075,17 +1075,17 @@
       int n = node.id;
 
-      if(nodes[n].next != -1) {
-        nodes[nodes[n].next].prev = nodes[n].prev;
-      }
-
-      if(nodes[n].prev != -1) {
-        nodes[nodes[n].prev].next = nodes[n].next;
-      } else {
-        first_node = nodes[n].next;
-      }
-
-      nodes[n].next = first_free_node;
+      if(_nodes[n].next != -1) {
+        _nodes[_nodes[n].next].prev = _nodes[n].prev;
+      }
+
+      if(_nodes[n].prev != -1) {
+        _nodes[_nodes[n].prev].next = _nodes[n].next;
+      } else {
+        first_node = _nodes[n].next;
+      }
+
+      _nodes[n].next = first_free_node;
       first_free_node = n;
-      nodes[n].prev = -2;
+      _nodes[n].prev = -2;
     }
 
@@ -1093,34 +1093,34 @@
       int n = edge.id * 2;
 
-      if (arcs[n].next_out != -1) {
-        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
-      }
-
-      if (arcs[n].prev_out != -1) {
-        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
-      } else {
-        nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
-      }
-
-      if (arcs[n | 1].next_out != -1) {
-        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
-      }
-
-      if (arcs[n | 1].prev_out != -1) {
-        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
-      } else {
-        nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
-      }
-
-      arcs[n].next_out = first_free_arc;
+      if (_arcs[n].next_out != -1) {
+        _arcs[_arcs[n].next_out].prev_out = _arcs[n].prev_out;
+      }
+
+      if (_arcs[n].prev_out != -1) {
+        _arcs[_arcs[n].prev_out].next_out = _arcs[n].next_out;
+      } else {
+        _nodes[_arcs[n | 1].target].first_out = _arcs[n].next_out;
+      }
+
+      if (_arcs[n | 1].next_out != -1) {
+        _arcs[_arcs[n | 1].next_out].prev_out = _arcs[n | 1].prev_out;
+      }
+
+      if (_arcs[n | 1].prev_out != -1) {
+        _arcs[_arcs[n | 1].prev_out].next_out = _arcs[n | 1].next_out;
+      } else {
+        _nodes[_arcs[n].target].first_out = _arcs[n | 1].next_out;
+      }
+
+      _arcs[n].next_out = first_free_arc;
       first_free_arc = n;
-      arcs[n].prev_out = -2;
-      arcs[n | 1].prev_out = -2;
+      _arcs[n].prev_out = -2;
+      _arcs[n | 1].prev_out = -2;
 
     }
 
     void clear() {
-      arcs.clear();
-      nodes.clear();
+      _arcs.clear();
+      _nodes.clear();
       first_node = first_free_node = first_free_arc = -1;
     }
@@ -1129,44 +1129,44 @@
 
     void changeV(Edge e, Node n) {
-      if(arcs[2 * e.id].next_out != -1) {
-        arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
-      }
-      if(arcs[2 * e.id].prev_out != -1) {
-        arcs[arcs[2 * e.id].prev_out].next_out =
-          arcs[2 * e.id].next_out;
-      } else {
-        nodes[arcs[(2 * e.id) | 1].target].first_out =
-          arcs[2 * e.id].next_out;
-      }
-
-      if (nodes[n.id].first_out != -1) {
-        arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
-      }
-      arcs[(2 * e.id) | 1].target = n.id;
-      arcs[2 * e.id].prev_out = -1;
-      arcs[2 * e.id].next_out = nodes[n.id].first_out;
-      nodes[n.id].first_out = 2 * e.id;
+      if(_arcs[2 * e.id].next_out != -1) {
+        _arcs[_arcs[2 * e.id].next_out].prev_out = _arcs[2 * e.id].prev_out;
+      }
+      if(_arcs[2 * e.id].prev_out != -1) {
+        _arcs[_arcs[2 * e.id].prev_out].next_out =
+          _arcs[2 * e.id].next_out;
+      } else {
+        _nodes[_arcs[(2 * e.id) | 1].target].first_out =
+          _arcs[2 * e.id].next_out;
+      }
+
+      if (_nodes[n.id].first_out != -1) {
+        _arcs[_nodes[n.id].first_out].prev_out = 2 * e.id;
+      }
+      _arcs[(2 * e.id) | 1].target = n.id;
+      _arcs[2 * e.id].prev_out = -1;
+      _arcs[2 * e.id].next_out = _nodes[n.id].first_out;
+      _nodes[n.id].first_out = 2 * e.id;
     }
 
     void changeU(Edge e, Node n) {
-      if(arcs[(2 * e.id) | 1].next_out != -1) {
-        arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
-          arcs[(2 * e.id) | 1].prev_out;
-      }
-      if(arcs[(2 * e.id) | 1].prev_out != -1) {
-        arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
-          arcs[(2 * e.id) | 1].next_out;
-      } else {
-        nodes[arcs[2 * e.id].target].first_out =
-          arcs[(2 * e.id) | 1].next_out;
-      }
-
-      if (nodes[n.id].first_out != -1) {
-        arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
-      }
-      arcs[2 * e.id].target = n.id;
-      arcs[(2 * e.id) | 1].prev_out = -1;
-      arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
-      nodes[n.id].first_out = ((2 * e.id) | 1);
+      if(_arcs[(2 * e.id) | 1].next_out != -1) {
+        _arcs[_arcs[(2 * e.id) | 1].next_out].prev_out =
+          _arcs[(2 * e.id) | 1].prev_out;
+      }
+      if(_arcs[(2 * e.id) | 1].prev_out != -1) {
+        _arcs[_arcs[(2 * e.id) | 1].prev_out].next_out =
+          _arcs[(2 * e.id) | 1].next_out;
+      } else {
+        _nodes[_arcs[2 * e.id].target].first_out =
+          _arcs[(2 * e.id) | 1].next_out;
+      }
+
+      if (_nodes[n.id].first_out != -1) {
+        _arcs[_nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
+      }
+      _arcs[2 * e.id].target = n.id;
+      _arcs[(2 * e.id) | 1].prev_out = -1;
+      _arcs[(2 * e.id) | 1].next_out = _nodes[n.id].first_out;
+      _nodes[n.id].first_out = ((2 * e.id) | 1);
     }
 
@@ -1210,5 +1210,5 @@
     ListGraph() {}
 
-    typedef Parent::OutArcIt IncEdgeIt;
+    typedef Parent::IncEdgeIt IncEdgeIt;
 
     /// \brief Add a new node to the graph.
@@ -1345,5 +1345,5 @@
     /// to build the graph.
     /// \sa reserveEdge()
-    void reserveNode(int n) { nodes.reserve(n); };
+    void reserveNode(int n) { _nodes.reserve(n); };
 
     /// Reserve memory for edges.
@@ -1355,5 +1355,5 @@
     /// to build the graph.
     /// \sa reserveNode()
-    void reserveEdge(int m) { arcs.reserve(2 * m); };
+    void reserveEdge(int m) { _arcs.reserve(2 * m); };
 
     /// \brief Class to make a snapshot of the graph and restore
@@ -1618,5 +1618,5 @@
     };
 
-    std::vector<NodeT> nodes;
+    std::vector<NodeT> _nodes;
 
     int first_node, first_red, first_blue;
@@ -1625,5 +1625,5 @@
     int first_free_red, first_free_blue;
 
-    std::vector<ArcT> arcs;
+    std::vector<ArcT> _arcs;
 
     int first_free_arc;
@@ -1707,31 +1707,31 @@
 
     ListBpGraphBase()
-      : nodes(), first_node(-1),
+      : _nodes(), first_node(-1),
         first_red(-1), first_blue(-1),
         max_red(-1), max_blue(-1),
         first_free_red(-1), first_free_blue(-1),
-        arcs(), first_free_arc(-1) {}
-
-
-    bool red(Node n) const { return nodes[n.id].red; }
-    bool blue(Node n) const { return !nodes[n.id].red; }
+        _arcs(), first_free_arc(-1) {}
+
+
+    bool red(Node n) const { return _nodes[n.id].red; }
+    bool blue(Node n) const { return !_nodes[n.id].red; }
 
     static RedNode asRedNodeUnsafe(Node n) { return RedNode(n.id); }
     static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n.id); }
 
-    int maxNodeId() const { return nodes.size()-1; }
+    int maxNodeId() const { return _nodes.size()-1; }
     int maxRedId() const { return max_red; }
     int maxBlueId() const { return max_blue; }
-    int maxEdgeId() const { return arcs.size() / 2 - 1; }
-    int maxArcId() const { return arcs.size()-1; }
-
-    Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
-    Node target(Arc e) const { return Node(arcs[e.id].target); }
+    int maxEdgeId() const { return _arcs.size() / 2 - 1; }
+    int maxArcId() const { return _arcs.size()-1; }
+
+    Node source(Arc e) const { return Node(_arcs[e.id ^ 1].target); }
+    Node target(Arc e) const { return Node(_arcs[e.id].target); }
 
     RedNode redNode(Edge e) const {
-      return RedNode(arcs[2 * e.id].target);
+      return RedNode(_arcs[2 * e.id].target);
     }
     BlueNode blueNode(Edge e) const {
-      return BlueNode(arcs[2 * e.id + 1].target);
+      return BlueNode(_arcs[2 * e.id + 1].target);
     }
 
@@ -1749,5 +1749,5 @@
 
     void next(Node& node) const {
-      node.id = nodes[node.id].next;
+      node.id = _nodes[node.id].next;
     }
 
@@ -1757,5 +1757,5 @@
 
     void next(RedNode& node) const {
-      node.id = nodes[node.id].partition_next;
+      node.id = _nodes[node.id].partition_next;
     }
 
@@ -1765,24 +1765,24 @@
 
     void next(BlueNode& node) const {
-      node.id = nodes[node.id].partition_next;
+      node.id = _nodes[node.id].partition_next;
     }
 
     void first(Arc& e) const {
       int n = first_node;
-      while (n != -1 && nodes[n].first_out == -1) {
-        n = nodes[n].next;
-      }
-      e.id = (n == -1) ? -1 : nodes[n].first_out;
+      while (n != -1 && _nodes[n].first_out == -1) {
+        n = _nodes[n].next;
+      }
+      e.id = (n == -1) ? -1 : _nodes[n].first_out;
     }
 
     void next(Arc& e) const {
-      if (arcs[e.id].next_out != -1) {
-        e.id = arcs[e.id].next_out;
-      } else {
-        int n = nodes[arcs[e.id ^ 1].target].next;
-        while(n != -1 && nodes[n].first_out == -1) {
-          n = nodes[n].next;
-        }
-        e.id = (n == -1) ? -1 : nodes[n].first_out;
+      if (_arcs[e.id].next_out != -1) {
+        e.id = _arcs[e.id].next_out;
+      } else {
+        int n = _nodes[_arcs[e.id ^ 1].target].next;
+        while(n != -1 && _nodes[n].first_out == -1) {
+          n = _nodes[n].next;
+        }
+        e.id = (n == -1) ? -1 : _nodes[n].first_out;
       }
     }
@@ -1791,7 +1791,7 @@
       int n = first_node;
       while (n != -1) {
-        e.id = nodes[n].first_out;
+        e.id = _nodes[n].first_out;
         while ((e.id & 1) != 1) {
-          e.id = arcs[e.id].next_out;
+          e.id = _arcs[e.id].next_out;
         }
         if (e.id != -1) {
@@ -1799,5 +1799,5 @@
           return;
         }
-        n = nodes[n].next;
+        n = _nodes[n].next;
       }
       e.id = -1;
@@ -1805,8 +1805,8 @@
 
     void next(Edge& e) const {
-      int n = arcs[e.id * 2].target;
-      e.id = arcs[(e.id * 2) | 1].next_out;
+      int n = _arcs[e.id * 2].target;
+      e.id = _arcs[(e.id * 2) | 1].next_out;
       while ((e.id & 1) != 1) {
-        e.id = arcs[e.id].next_out;
+        e.id = _arcs[e.id].next_out;
       }
       if (e.id != -1) {
@@ -1814,9 +1814,9 @@
         return;
       }
-      n = nodes[n].next;
+      n = _nodes[n].next;
       while (n != -1) {
-        e.id = nodes[n].first_out;
+        e.id = _nodes[n].first_out;
         while ((e.id & 1) != 1) {
-          e.id = arcs[e.id].next_out;
+          e.id = _arcs[e.id].next_out;
         }
         if (e.id != -1) {
@@ -1824,5 +1824,5 @@
           return;
         }
-        n = nodes[n].next;
+        n = _nodes[n].next;
       }
       e.id = -1;
@@ -1830,21 +1830,21 @@
 
     void firstOut(Arc &e, const Node& v) const {
-      e.id = nodes[v.id].first_out;
+      e.id = _nodes[v.id].first_out;
     }
     void nextOut(Arc &e) const {
-      e.id = arcs[e.id].next_out;
+      e.id = _arcs[e.id].next_out;
     }
 
     void firstIn(Arc &e, const Node& v) const {
-      e.id = ((nodes[v.id].first_out) ^ 1);
+      e.id = ((_nodes[v.id].first_out) ^ 1);
       if (e.id == -2) e.id = -1;
     }
     void nextIn(Arc &e) const {
-      e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
+      e.id = ((_arcs[e.id ^ 1].next_out) ^ 1);
       if (e.id == -2) e.id = -1;
     }
 
     void firstInc(Edge &e, bool& d, const Node& v) const {
-      int a = nodes[v.id].first_out;
+      int a = _nodes[v.id].first_out;
       if (a != -1 ) {
         e.id = a / 2;
@@ -1856,5 +1856,5 @@
     }
     void nextInc(Edge &e, bool& d) const {
-      int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
+      int a = (_arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
       if (a != -1 ) {
         e.id = a / 2;
@@ -1867,6 +1867,6 @@
 
     static int id(Node v) { return v.id; }
-    int id(RedNode v) const { return nodes[v.id].partition_index; }
-    int id(BlueNode v) const { return nodes[v.id].partition_index; }
+    int id(RedNode v) const { return _nodes[v.id].partition_index; }
+    int id(BlueNode v) const { return _nodes[v.id].partition_index; }
     static int id(Arc e) { return e.id; }
     static int id(Edge e) { return e.id; }
@@ -1877,16 +1877,16 @@
 
     bool valid(Node n) const {
-      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
-        nodes[n.id].prev != -2;
+      return n.id >= 0 && n.id < static_cast<int>(_nodes.size()) &&
+        _nodes[n.id].prev != -2;
     }
 
     bool valid(Arc a) const {
-      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
-        arcs[a.id].prev_out != -2;
+      return a.id >= 0 && a.id < static_cast<int>(_arcs.size()) &&
+        _arcs[a.id].prev_out != -2;
     }
 
     bool valid(Edge e) const {
-      return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
-        arcs[2 * e.id].prev_out != -2;
+      return e.id >= 0 && 2 * e.id < static_cast<int>(_arcs.size()) &&
+        _arcs[2 * e.id].prev_out != -2;
     }
 
@@ -1895,24 +1895,24 @@
 
       if(first_free_red==-1) {
-        n = nodes.size();
-        nodes.push_back(NodeT());
-        nodes[n].partition_index = ++max_red;
-        nodes[n].red = true;
+        n = _nodes.size();
+        _nodes.push_back(NodeT());
+        _nodes[n].partition_index = ++max_red;
+        _nodes[n].red = true;
       } else {
         n = first_free_red;
-        first_free_red = nodes[n].next;
-      }
-
-      nodes[n].next = first_node;
-      if (first_node != -1) nodes[first_node].prev = n;
+        first_free_red = _nodes[n].next;
+      }
+
+      _nodes[n].next = first_node;
+      if (first_node != -1) _nodes[first_node].prev = n;
       first_node = n;
-      nodes[n].prev = -1;
-
-      nodes[n].partition_next = first_red;
-      if (first_red != -1) nodes[first_red].partition_prev = n;
+      _nodes[n].prev = -1;
+
+      _nodes[n].partition_next = first_red;
+      if (first_red != -1) _nodes[first_red].partition_prev = n;
       first_red = n;
-      nodes[n].partition_prev = -1;
-
-      nodes[n].first_out = -1;
+      _nodes[n].partition_prev = -1;
+
+      _nodes[n].first_out = -1;
 
       return RedNode(n);
@@ -1923,24 +1923,24 @@
 
       if(first_free_blue==-1) {
-        n = nodes.size();
-        nodes.push_back(NodeT());
-        nodes[n].partition_index = ++max_blue;
-        nodes[n].red = false;
+        n = _nodes.size();
+        _nodes.push_back(NodeT());
+        _nodes[n].partition_index = ++max_blue;
+        _nodes[n].red = false;
       } else {
         n = first_free_blue;
-        first_free_blue = nodes[n].next;
-      }
-
-      nodes[n].next = first_node;
-      if (first_node != -1) nodes[first_node].prev = n;
+        first_free_blue = _nodes[n].next;
+      }
+
+      _nodes[n].next = first_node;
+      if (first_node != -1) _nodes[first_node].prev = n;
       first_node = n;
-      nodes[n].prev = -1;
-
-      nodes[n].partition_next = first_blue;
-      if (first_blue != -1) nodes[first_blue].partition_prev = n;
+      _nodes[n].prev = -1;
+
+      _nodes[n].partition_next = first_blue;
+      if (first_blue != -1) _nodes[first_blue].partition_prev = n;
       first_blue = n;
-      nodes[n].partition_prev = -1;
-
-      nodes[n].first_out = -1;
+      _nodes[n].partition_prev = -1;
+
+      _nodes[n].first_out = -1;
 
       return BlueNode(n);
@@ -1951,28 +1951,28 @@
 
       if (first_free_arc == -1) {
-        n = arcs.size();
-        arcs.push_back(ArcT());
-        arcs.push_back(ArcT());
+        n = _arcs.size();
+        _arcs.push_back(ArcT());
+        _arcs.push_back(ArcT());
       } else {
         n = first_free_arc;
-        first_free_arc = arcs[n].next_out;
-      }
-
-      arcs[n].target = u.id;
-      arcs[n | 1].target = v.id;
-
-      arcs[n].next_out = nodes[v.id].first_out;
-      if (nodes[v.id].first_out != -1) {
-        arcs[nodes[v.id].first_out].prev_out = n;
-      }
-      arcs[n].prev_out = -1;
-      nodes[v.id].first_out = n;
-
-      arcs[n | 1].next_out = nodes[u.id].first_out;
-      if (nodes[u.id].first_out != -1) {
-        arcs[nodes[u.id].first_out].prev_out = (n | 1);
-      }
-      arcs[n | 1].prev_out = -1;
-      nodes[u.id].first_out = (n | 1);
+        first_free_arc = _arcs[n].next_out;
+      }
+
+      _arcs[n].target = u.id;
+      _arcs[n | 1].target = v.id;
+
+      _arcs[n].next_out = _nodes[v.id].first_out;
+      if (_nodes[v.id].first_out != -1) {
+        _arcs[_nodes[v.id].first_out].prev_out = n;
+      }
+      _arcs[n].prev_out = -1;
+      _nodes[v.id].first_out = n;
+
+      _arcs[n | 1].next_out = _nodes[u.id].first_out;
+      if (_nodes[u.id].first_out != -1) {
+        _arcs[_nodes[u.id].first_out].prev_out = (n | 1);
+      }
+      _arcs[n | 1].prev_out = -1;
+      _nodes[u.id].first_out = (n | 1);
 
       return Edge(n / 2);
@@ -1982,36 +1982,36 @@
       int n = node.id;
 
-      if(nodes[n].next != -1) {
-        nodes[nodes[n].next].prev = nodes[n].prev;
-      }
-
-      if(nodes[n].prev != -1) {
-        nodes[nodes[n].prev].next = nodes[n].next;
-      } else {
-        first_node = nodes[n].next;
-      }
-
-      if (nodes[n].partition_next != -1) {
-        nodes[nodes[n].partition_next].partition_prev = nodes[n].partition_prev;
-      }
-
-      if (nodes[n].partition_prev != -1) {
-        nodes[nodes[n].partition_prev].partition_next = nodes[n].partition_next;
-      } else {
-        if (nodes[n].red) {
-          first_red = nodes[n].partition_next;
+      if(_nodes[n].next != -1) {
+        _nodes[_nodes[n].next].prev = _nodes[n].prev;
+      }
+
+      if(_nodes[n].prev != -1) {
+        _nodes[_nodes[n].prev].next = _nodes[n].next;
+      } else {
+        first_node = _nodes[n].next;
+      }
+
+      if (_nodes[n].partition_next != -1) {
+        _nodes[_nodes[n].partition_next].partition_prev = _nodes[n].partition_prev;
+      }
+
+      if (_nodes[n].partition_prev != -1) {
+        _nodes[_nodes[n].partition_prev].partition_next = _nodes[n].partition_next;
+      } else {
+        if (_nodes[n].red) {
+          first_red = _nodes[n].partition_next;
         } else {
-          first_blue = nodes[n].partition_next;
-        }
-      }
-
-      if (nodes[n].red) {
-        nodes[n].next = first_free_red;
+          first_blue = _nodes[n].partition_next;
+        }
+      }
+
+      if (_nodes[n].red) {
+        _nodes[n].next = first_free_red;
         first_free_red = n;
       } else {
-        nodes[n].next = first_free_blue;
+        _nodes[n].next = first_free_blue;
         first_free_blue = n;
       }
-      nodes[n].prev = -2;
+      _nodes[n].prev = -2;
     }
 
@@ -2019,34 +2019,34 @@
       int n = edge.id * 2;
 
-      if (arcs[n].next_out != -1) {
-        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
-      }
-
-      if (arcs[n].prev_out != -1) {
-        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
-      } else {
-        nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
-      }
-
-      if (arcs[n | 1].next_out != -1) {
-        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
-      }
-
-      if (arcs[n | 1].prev_out != -1) {
-        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
-      } else {
-        nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
-      }
-
-      arcs[n].next_out = first_free_arc;
+      if (_arcs[n].next_out != -1) {
+        _arcs[_arcs[n].next_out].prev_out = _arcs[n].prev_out;
+      }
+
+      if (_arcs[n].prev_out != -1) {
+        _arcs[_arcs[n].prev_out].next_out = _arcs[n].next_out;
+      } else {
+        _nodes[_arcs[n | 1].target].first_out = _arcs[n].next_out;
+      }
+
+      if (_arcs[n | 1].next_out != -1) {
+        _arcs[_arcs[n | 1].next_out].prev_out = _arcs[n | 1].prev_out;
+      }
+
+      if (_arcs[n | 1].prev_out != -1) {
+        _arcs[_arcs[n | 1].prev_out].next_out = _arcs[n | 1].next_out;
+      } else {
+        _nodes[_arcs[n].target].first_out = _arcs[n | 1].next_out;
+      }
+
+      _arcs[n].next_out = first_free_arc;
       first_free_arc = n;
-      arcs[n].prev_out = -2;
-      arcs[n | 1].prev_out = -2;
+      _arcs[n].prev_out = -2;
+      _arcs[n | 1].prev_out = -2;
 
     }
 
     void clear() {
-      arcs.clear();
-      nodes.clear();
+      _arcs.clear();
+      _nodes.clear();
       first_node = first_free_arc = first_red = first_blue =
         max_red = max_blue = first_free_red = first_free_blue = -1;
@@ -2056,44 +2056,44 @@
 
     void changeRed(Edge e, RedNode n) {
-      if(arcs[(2 * e.id) | 1].next_out != -1) {
-        arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
-          arcs[(2 * e.id) | 1].prev_out;
-      }
-      if(arcs[(2 * e.id) | 1].prev_out != -1) {
-        arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
-          arcs[(2 * e.id) | 1].next_out;
-      } else {
-        nodes[arcs[2 * e.id].target].first_out =
-          arcs[(2 * e.id) | 1].next_out;
-      }
-
-      if (nodes[n.id].first_out != -1) {
-        arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
-      }
-      arcs[2 * e.id].target = n.id;
-      arcs[(2 * e.id) | 1].prev_out = -1;
-      arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
-      nodes[n.id].first_out = ((2 * e.id) | 1);
+      if(_arcs[(2 * e.id) | 1].next_out != -1) {
+        _arcs[_arcs[(2 * e.id) | 1].next_out].prev_out =
+          _arcs[(2 * e.id) | 1].prev_out;
+      }
+      if(_arcs[(2 * e.id) | 1].prev_out != -1) {
+        _arcs[_arcs[(2 * e.id) | 1].prev_out].next_out =
+          _arcs[(2 * e.id) | 1].next_out;
+      } else {
+        _nodes[_arcs[2 * e.id].target].first_out =
+          _arcs[(2 * e.id) | 1].next_out;
+      }
+
+      if (_nodes[n.id].first_out != -1) {
+        _arcs[_nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
+      }
+      _arcs[2 * e.id].target = n.id;
+      _arcs[(2 * e.id) | 1].prev_out = -1;
+      _arcs[(2 * e.id) | 1].next_out = _nodes[n.id].first_out;
+      _nodes[n.id].first_out = ((2 * e.id) | 1);
     }
 
     void changeBlue(Edge e, BlueNode n) {
-       if(arcs[2 * e.id].next_out != -1) {
-        arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
-      }
-      if(arcs[2 * e.id].prev_out != -1) {
-        arcs[arcs[2 * e.id].prev_out].next_out =
-          arcs[2 * e.id].next_out;
-      } else {
-        nodes[arcs[(2 * e.id) | 1].target].first_out =
-          arcs[2 * e.id].next_out;
-      }
-
-      if (nodes[n.id].first_out != -1) {
-        arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
-      }
-      arcs[(2 * e.id) | 1].target = n.id;
-      arcs[2 * e.id].prev_out = -1;
-      arcs[2 * e.id].next_out = nodes[n.id].first_out;
-      nodes[n.id].first_out = 2 * e.id;
+       if(_arcs[2 * e.id].next_out != -1) {
+        _arcs[_arcs[2 * e.id].next_out].prev_out = _arcs[2 * e.id].prev_out;
+      }
+      if(_arcs[2 * e.id].prev_out != -1) {
+        _arcs[_arcs[2 * e.id].prev_out].next_out =
+          _arcs[2 * e.id].next_out;
+      } else {
+        _nodes[_arcs[(2 * e.id) | 1].target].first_out =
+          _arcs[2 * e.id].next_out;
+      }
+
+      if (_nodes[n.id].first_out != -1) {
+        _arcs[_nodes[n.id].first_out].prev_out = 2 * e.id;
+      }
+      _arcs[(2 * e.id) | 1].target = n.id;
+      _arcs[2 * e.id].prev_out = -1;
+      _arcs[2 * e.id].next_out = _nodes[n.id].first_out;
+      _nodes[n.id].first_out = 2 * e.id;
     }
 
@@ -2137,5 +2137,5 @@
     ListBpGraph() {}
 
-    typedef Parent::OutArcIt IncEdgeIt;
+    typedef Parent::IncEdgeIt IncEdgeIt;
 
     /// \brief Add a new red node to the graph.
@@ -2250,5 +2250,5 @@
     /// to build the graph.
     /// \sa reserveEdge()
-    void reserveNode(int n) { nodes.reserve(n); };
+    void reserveNode(int n) { _nodes.reserve(n); };
 
     /// Reserve memory for edges.
@@ -2260,5 +2260,5 @@
     /// to build the graph.
     /// \sa reserveNode()
-    void reserveEdge(int m) { arcs.reserve(2 * m); };
+    void reserveEdge(int m) { _arcs.reserve(2 * m); };
 
     /// \brief Class to make a snapshot of the graph and restore
Index: lemon/lp_base.h
===================================================================
--- lemon/lp_base.h	(revision 1270)
+++ lemon/lp_base.h	(revision 1353)
@@ -32,4 +32,6 @@
 #include<lemon/bits/solver_bits.h>
 
+#include<lemon/bits/stl_iterators.h>
+
 ///\file
 ///\brief The interface of the LP solver interface.
@@ -46,6 +48,6 @@
   protected:
 
-    _solver_bits::VarIndex rows;
-    _solver_bits::VarIndex cols;
+    _solver_bits::VarIndex _rows;
+    _solver_bits::VarIndex _cols;
 
   public:
@@ -167,5 +169,5 @@
       ColIt(const LpBase &solver) : _solver(&solver)
       {
-        _solver->cols.firstItem(_id);
+        _solver->_cols.firstItem(_id);
       }
       /// Invalid constructor \& conversion
@@ -180,8 +182,24 @@
       ColIt &operator++()
       {
-        _solver->cols.nextItem(_id);
+        _solver->_cols.nextItem(_id);
         return *this;
       }
     };
+
+    /// \brief Gets the collection of the columns of the LP problem.
+    ///
+    /// This function can be used for iterating on
+    /// the columns of the LP problem. It returns a wrapped ColIt, which looks
+    /// like an STL container (by having begin() and end())
+    /// which you can use in range-based for loops, STL algorithms, etc.
+    /// For example you can write:
+    ///\code
+    /// for(auto c: lp.cols())
+    ///   doSomething(c);
+    ///\endcode
+    LemonRangeWrapper1<ColIt, LpBase> cols() {
+      return LemonRangeWrapper1<ColIt, LpBase>(*this);
+    }
+
 
     /// \brief Returns the ID of the column.
@@ -262,5 +280,5 @@
       RowIt(const LpBase &solver) : _solver(&solver)
       {
-        _solver->rows.firstItem(_id);
+        _solver->_rows.firstItem(_id);
       }
       /// Invalid constructor \& conversion
@@ -275,8 +293,24 @@
       RowIt &operator++()
       {
-        _solver->rows.nextItem(_id);
+        _solver->_rows.nextItem(_id);
         return *this;
       }
     };
+    
+    /// \brief Gets the collection of the rows of the LP problem.
+    ///
+    /// This function can be used for iterating on
+    /// the rows of the LP problem. It returns a wrapped RowIt, which looks
+    /// like an STL container (by having begin() and end())
+    /// which you can use in range-based for loops, STL algorithms, etc.
+    /// For example you can write:
+    ///\code
+    /// for(auto c: lp.rows())
+    ///   doSomething(c);
+    ///\endcode
+    LemonRangeWrapper1<RowIt, LpBase> rows() {
+      return LemonRangeWrapper1<RowIt, LpBase>(*this);
+    }
+    
 
     /// \brief Returns the ID of the row.
@@ -626,5 +660,5 @@
     ///This data structure represents a column of the matrix,
     ///thas is it strores a linear expression of the dual variables
-    ///(\ref Row "Row"s).
+    ///(\ref LpBase::Row "Row"s).
     ///
     ///There are several ways to access and modify the contents of this
@@ -643,5 +677,5 @@
     ///(This code computes the sum of all coefficients).
     ///- Numbers (<tt>double</tt>'s)
-    ///and variables (\ref Row "Row"s) directly convert to an
+    ///and variables (\ref LpBase::Row "Row"s) directly convert to an
     ///\ref DualExpr and the usual linear operations are defined, so
     ///\code
@@ -935,9 +969,9 @@
     //Abstract virtual functions
 
-    virtual int _addColId(int col) { return cols.addIndex(col); }
-    virtual int _addRowId(int row) { return rows.addIndex(row); }
-
-    virtual void _eraseColId(int col) { cols.eraseIndex(col); }
-    virtual void _eraseRowId(int row) { rows.eraseIndex(row); }
+    virtual int _addColId(int col) { return _cols.addIndex(col); }
+    virtual int _addRowId(int row) { return _rows.addIndex(row); }
+
+    virtual void _eraseColId(int col) { _cols.eraseIndex(col); }
+    virtual void _eraseRowId(int row) { _rows.eraseIndex(row); }
 
     virtual int _addCol() = 0;
@@ -1004,5 +1038,5 @@
     Value obj_const_comp;
 
-    LpBase() : rows(), cols(), obj_const_comp(0) {}
+    LpBase() : _rows(), _cols(), obj_const_comp(0) {}
 
   public:
@@ -1116,6 +1150,6 @@
     void col(Col c, const DualExpr &e) {
       e.simplify();
-      _setColCoeffs(cols(id(c)), ExprIterator(e.comps.begin(), rows),
-                    ExprIterator(e.comps.end(), rows));
+      _setColCoeffs(_cols(id(c)), ExprIterator(e.comps.begin(), _rows),
+                    ExprIterator(e.comps.end(), _rows));
     }
 
@@ -1126,5 +1160,5 @@
     DualExpr col(Col c) const {
       DualExpr e;
-      _getColCoeffs(cols(id(c)), InsertIterator(e.comps, rows));
+      _getColCoeffs(_cols(id(c)), InsertIterator(e.comps, _rows));
       return e;
     }
@@ -1155,5 +1189,5 @@
     ///\param t can be
     ///- a standard STL compatible iterable container with
-    ///\ref Row as its \c values_type like
+    ///\ref LpBase::Row "Row" as its \c values_type like
     ///\code
     ///std::vector<LpBase::Row>
@@ -1161,5 +1195,5 @@
     ///\endcode
     ///- a standard STL compatible iterable container with
-    ///\ref Row as its \c mapped_type like
+    ///\ref LpBase::Row "Row" as its \c mapped_type like
     ///\code
     ///std::map<AnyType,LpBase::Row>
@@ -1213,8 +1247,8 @@
     void row(Row r, Value l, const Expr &e, Value u) {
       e.simplify();
-      _setRowCoeffs(rows(id(r)), ExprIterator(e.comps.begin(), cols),
-                    ExprIterator(e.comps.end(), cols));
-      _setRowLowerBound(rows(id(r)),l - *e);
-      _setRowUpperBound(rows(id(r)),u - *e);
+      _setRowCoeffs(_rows(id(r)), ExprIterator(e.comps.begin(), _cols),
+                    ExprIterator(e.comps.end(), _cols));
+      _setRowLowerBound(_rows(id(r)),l - *e);
+      _setRowUpperBound(_rows(id(r)),u - *e);
     }
 
@@ -1235,5 +1269,5 @@
     Expr row(Row r) const {
       Expr e;
-      _getRowCoeffs(rows(id(r)), InsertIterator(e.comps, cols));
+      _getRowCoeffs(_rows(id(r)), InsertIterator(e.comps, _cols));
       return e;
     }
@@ -1248,6 +1282,6 @@
       Row r;
       e.simplify();
-      r._id = _addRowId(_addRow(l - *e, ExprIterator(e.comps.begin(), cols),
-                                ExprIterator(e.comps.end(), cols), u - *e));
+      r._id = _addRowId(_addRow(l - *e, ExprIterator(e.comps.begin(), _cols),
+                                ExprIterator(e.comps.end(), _cols), u - *e));
       return r;
     }
@@ -1261,6 +1295,6 @@
       c.expr().simplify();
       r._id = _addRowId(_addRow(c.lowerBounded()?c.lowerBound()-*c.expr():-INF,
-                                ExprIterator(c.expr().comps.begin(), cols),
-                                ExprIterator(c.expr().comps.end(), cols),
+                                ExprIterator(c.expr().comps.begin(), _cols),
+                                ExprIterator(c.expr().comps.end(), _cols),
                                 c.upperBounded()?c.upperBound()-*c.expr():INF));
       return r;
@@ -1270,6 +1304,6 @@
     ///\param c is the column to be deleted
     void erase(Col c) {
-      _eraseCol(cols(id(c)));
-      _eraseColId(cols(id(c)));
+      _eraseCol(_cols(id(c)));
+      _eraseColId(_cols(id(c)));
     }
     ///Erase a row (i.e a constraint) from the LP
@@ -1277,6 +1311,6 @@
     ///\param r is the row to be deleted
     void erase(Row r) {
-      _eraseRow(rows(id(r)));
-      _eraseRowId(rows(id(r)));
+      _eraseRow(_rows(id(r)));
+      _eraseRowId(_rows(id(r)));
     }
 
@@ -1287,5 +1321,5 @@
     std::string colName(Col c) const {
       std::string name;
-      _getColName(cols(id(c)), name);
+      _getColName(_cols(id(c)), name);
       return name;
     }
@@ -1296,5 +1330,5 @@
     ///\param name The name to be given
     void colName(Col c, const std::string& name) {
-      _setColName(cols(id(c)), name);
+      _setColName(_cols(id(c)), name);
     }
 
@@ -1305,5 +1339,5 @@
     Col colByName(const std::string& name) const {
       int k = _colByName(name);
-      return k != -1 ? Col(cols[k]) : Col(INVALID);
+      return k != -1 ? Col(_cols[k]) : Col(INVALID);
     }
 
@@ -1314,5 +1348,5 @@
     std::string rowName(Row r) const {
       std::string name;
-      _getRowName(rows(id(r)), name);
+      _getRowName(_rows(id(r)), name);
       return name;
     }
@@ -1323,5 +1357,5 @@
     ///\param name The name to be given
     void rowName(Row r, const std::string& name) {
-      _setRowName(rows(id(r)), name);
+      _setRowName(_rows(id(r)), name);
     }
 
@@ -1332,5 +1366,5 @@
     Row rowByName(const std::string& name) const {
       int k = _rowByName(name);
-      return k != -1 ? Row(rows[k]) : Row(INVALID);
+      return k != -1 ? Row(_rows[k]) : Row(INVALID);
     }
 
@@ -1341,5 +1375,5 @@
     ///\param val is the new value of the coefficient
     void coeff(Row r, Col c, Value val) {
-      _setCoeff(rows(id(r)),cols(id(c)), val);
+      _setCoeff(_rows(id(r)),_cols(id(c)), val);
     }
 
@@ -1350,5 +1384,5 @@
     ///\return the corresponding coefficient
     Value coeff(Row r, Col c) const {
-      return _getCoeff(rows(id(r)),cols(id(c)));
+      return _getCoeff(_rows(id(r)),_cols(id(c)));
     }
 
@@ -1359,5 +1393,5 @@
     /// Value or -\ref INF.
     void colLowerBound(Col c, Value value) {
-      _setColLowerBound(cols(id(c)),value);
+      _setColLowerBound(_cols(id(c)),value);
     }
 
@@ -1368,5 +1402,5 @@
     ///\return The lower bound for column \c c
     Value colLowerBound(Col c) const {
-      return _getColLowerBound(cols(id(c)));
+      return _getColLowerBound(_cols(id(c)));
     }
 
@@ -1414,5 +1448,5 @@
     /// Value or \ref INF.
     void colUpperBound(Col c, Value value) {
-      _setColUpperBound(cols(id(c)),value);
+      _setColUpperBound(_cols(id(c)),value);
     };
 
@@ -1423,5 +1457,5 @@
     /// \return The upper bound for column \c c
     Value colUpperBound(Col c) const {
-      return _getColUpperBound(cols(id(c)));
+      return _getColUpperBound(_cols(id(c)));
     }
 
@@ -1470,6 +1504,6 @@
     /// Value, -\ref INF or \ref INF.
     void colBounds(Col c, Value lower, Value upper) {
-      _setColLowerBound(cols(id(c)),lower);
-      _setColUpperBound(cols(id(c)),upper);
+      _setColLowerBound(_cols(id(c)),lower);
+      _setColUpperBound(_cols(id(c)),upper);
     }
 
@@ -1516,5 +1550,5 @@
     /// Value or -\ref INF.
     void rowLowerBound(Row r, Value value) {
-      _setRowLowerBound(rows(id(r)),value);
+      _setRowLowerBound(_rows(id(r)),value);
     }
 
@@ -1525,5 +1559,5 @@
     ///\return The lower bound for row \c r
     Value rowLowerBound(Row r) const {
-      return _getRowLowerBound(rows(id(r)));
+      return _getRowLowerBound(_rows(id(r)));
     }
 
@@ -1534,5 +1568,5 @@
     /// Value or -\ref INF.
     void rowUpperBound(Row r, Value value) {
-      _setRowUpperBound(rows(id(r)),value);
+      _setRowUpperBound(_rows(id(r)),value);
     }
 
@@ -1543,12 +1577,12 @@
     ///\return The upper bound for row \c r
     Value rowUpperBound(Row r) const {
-      return _getRowUpperBound(rows(id(r)));
+      return _getRowUpperBound(_rows(id(r)));
     }
 
     ///Set an element of the objective function
-    void objCoeff(Col c, Value v) {_setObjCoeff(cols(id(c)),v); };
+    void objCoeff(Col c, Value v) {_setObjCoeff(_cols(id(c)),v); };
 
     ///Get an element of the objective function
-    Value objCoeff(Col c) const { return _getObjCoeff(cols(id(c))); };
+    Value objCoeff(Col c) const { return _getObjCoeff(_cols(id(c))); };
 
     ///Set the objective function
@@ -1557,6 +1591,6 @@
     ///
     void obj(const Expr& e) {
-      _setObjCoeffs(ExprIterator(e.comps.begin(), cols),
-                    ExprIterator(e.comps.end(), cols));
+      _setObjCoeffs(ExprIterator(e.comps.begin(), _cols),
+                    ExprIterator(e.comps.end(), _cols));
       obj_const_comp = *e;
     }
@@ -1568,5 +1602,5 @@
     Expr obj() const {
       Expr e;
-      _getObjCoeffs(InsertIterator(e.comps, cols));
+      _getObjCoeffs(InsertIterator(e.comps, _cols));
       *e = obj_const_comp;
       return e;
@@ -1587,5 +1621,5 @@
 
     ///Clear the problem
-    void clear() { _clear(); rows.clear(); cols.clear(); }
+    void clear() { _clear(); _rows.clear(); _cols.clear(); }
 
     /// Set the message level of the solver
@@ -1930,5 +1964,5 @@
     /// Return the primal value of the column.
     /// \pre The problem is solved.
-    Value primal(Col c) const { return _getPrimal(cols(id(c))); }
+    Value primal(Col c) const { return _getPrimal(_cols(id(c))); }
 
     /// Return the primal value of the expression
@@ -1957,5 +1991,5 @@
     /// \note Some solvers does not provide primal ray calculation
     /// functions.
-    Value primalRay(Col c) const { return _getPrimalRay(cols(id(c))); }
+    Value primalRay(Col c) const { return _getPrimalRay(_cols(id(c))); }
 
     /// Return the dual value of the row
@@ -1963,5 +1997,5 @@
     /// Return the dual value of the row.
     /// \pre The problem is solved.
-    Value dual(Row r) const { return _getDual(rows(id(r))); }
+    Value dual(Row r) const { return _getDual(_rows(id(r))); }
 
     /// Return the dual value of the dual expression
@@ -1991,15 +2025,15 @@
     /// \note Some solvers does not provide dual ray calculation
     /// functions.
-    Value dualRay(Row r) const { return _getDualRay(rows(id(r))); }
+    Value dualRay(Row r) const { return _getDualRay(_rows(id(r))); }
 
     /// Return the basis status of the column
 
     /// \see VarStatus
-    VarStatus colStatus(Col c) const { return _getColStatus(cols(id(c))); }
+    VarStatus colStatus(Col c) const { return _getColStatus(_cols(id(c))); }
 
     /// Return the basis status of the row
 
     /// \see VarStatus
-    VarStatus rowStatus(Row r) const { return _getRowStatus(rows(id(r))); }
+    VarStatus rowStatus(Row r) const { return _getRowStatus(_rows(id(r))); }
 
     ///The value of the objective function
@@ -2081,5 +2115,5 @@
     ///
     void colType(Col c, ColTypes col_type) {
-      _setColType(cols(id(c)),col_type);
+      _setColType(_cols(id(c)),col_type);
     }
 
@@ -2089,5 +2123,5 @@
     ///
     ColTypes colType(Col c) const {
-      return _getColType(cols(id(c)));
+      return _getColType(_cols(id(c)));
     }
     ///@}
@@ -2106,5 +2140,5 @@
     ///  Return the value of the row in the solution.
     /// \pre The problem is solved.
-    Value sol(Col c) const { return _getSol(cols(id(c))); }
+    Value sol(Col c) const { return _getSol(_cols(id(c))); }
 
     /// Return the value of the expression in the solution
Index: lemon/maps.h
===================================================================
--- lemon/maps.h	(revision 1270)
+++ lemon/maps.h	(revision 1336)
@@ -26,4 +26,5 @@
 
 #include <lemon/core.h>
+#include <lemon/bits/stl_iterators.h>
 
 ///\file
@@ -2582,4 +2583,14 @@
     };
 
+    /// \brief STL style iterator for the keys mapped to \c true.
+    ///
+    /// This is an STL style wrapper for \ref TrueIt.
+    /// It can be used in range-based for loops, STL algorithms, etc.
+    LemonRangeWrapper1<TrueIt, IterableBoolMap>
+    trueKeys() {
+      return LemonRangeWrapper1<TrueIt, IterableBoolMap>(*this);
+    }
+
+
     /// \brief Iterator for the keys mapped to \c false.
     ///
@@ -2620,4 +2631,14 @@
       const IterableBoolMap* _map;
     };
+
+    /// \brief STL style iterator for the keys mapped to \c false.
+    ///
+    /// This is an STL style wrapper for \ref FalseIt.
+    /// It can be used in range-based for loops, STL algorithms, etc.
+    LemonRangeWrapper1<FalseIt, IterableBoolMap>
+    falseKeys() {
+      return LemonRangeWrapper1<FalseIt, IterableBoolMap>(*this);
+    }
+
 
     /// \brief Iterator for the keys mapped to a given value.
@@ -2664,4 +2685,13 @@
       const IterableBoolMap* _map;
     };
+
+    /// \brief STL style iterator for the keys mapped to a given value.
+    ///
+    /// This is an STL style wrapper for \ref ItemIt.
+    /// It can be used in range-based for loops, STL algorithms, etc.
+    LemonRangeWrapper2<ItemIt, IterableBoolMap, bool>
+    items(bool value) {
+      return LemonRangeWrapper2<ItemIt, IterableBoolMap, bool>(*this, value);
+    }
 
   protected:
@@ -3006,4 +3036,14 @@
     };
 
+    /// \brief STL style iterator for the keys with the same value.
+    ///
+    /// This is an STL style wrapper for \ref ItemIt.
+    /// It can be used in range-based for loops, STL algorithms, etc.
+    LemonRangeWrapper2<ItemIt, IterableIntMap, int>
+    items(int value) {
+      return LemonRangeWrapper2<ItemIt, IterableIntMap, int>(*this, value);
+    }
+
+
   protected:
 
@@ -3249,4 +3289,14 @@
     };
 
+    /// \brief STL style iterator for the keys with the same value.
+    ///
+    /// This is an STL style wrapper for \ref ItemIt.
+    /// It can be used in range-based for loops, STL algorithms, etc.
+    LemonRangeWrapper2<ItemIt, IterableValueMap, V>
+    items(const V& value) {
+      return LemonRangeWrapper2<ItemIt, IterableValueMap, V>(*this, value);
+    }
+
+
   protected:
 
Index: lemon/matching.h
===================================================================
--- lemon/matching.h	(revision 1270)
+++ lemon/matching.h	(revision 1423)
@@ -116,5 +116,5 @@
     int _process, _postpone, _last;
 
-    int _node_num;
+    int _node_num, _unmatched;
 
   private:
@@ -180,4 +180,5 @@
           } else if ((*_status)[v] == UNMATCHED) {
             augmentOnArc(a);
+            --_unmatched;
             return;
           }
@@ -205,4 +206,5 @@
               } else if ((*_status)[x] == UNMATCHED) {
                 augmentOnArc(b);
+                --_unmatched;
                 return;
               }
@@ -229,4 +231,5 @@
           } else if ((*_status)[v] == UNMATCHED) {
             augmentOnArc(a);
+            --_unmatched;
             return;
           }
@@ -438,4 +441,5 @@
         (*_status)[n] = UNMATCHED;
       }
+      _unmatched = _node_num;
     }
 
@@ -449,4 +453,5 @@
         (*_status)[n] = UNMATCHED;
       }
+      _unmatched = _node_num;
       for (NodeIt n(_graph); n != INVALID; ++n) {
         if ((*_matching)[n] == INVALID) {
@@ -458,4 +463,5 @@
               (*_matching)[v] = _graph.oppositeArc(a);
               (*_status)[v] = MATCHED;
+              _unmatched -= 2;
               break;
             }
@@ -480,4 +486,5 @@
         (*_status)[n] = UNMATCHED;
       }
+      _unmatched = _node_num;
       for(EdgeIt e(_graph); e!=INVALID; ++e) {
         if (matching[e]) {
@@ -492,4 +499,6 @@
           (*_matching)[v] = _graph.direct(e, false);
           (*_status)[v] = MATCHED;
+
+          _unmatched -= 2;
         }
       }
@@ -499,14 +508,18 @@
     /// \brief Start Edmonds' algorithm
     ///
-    /// This function runs the original Edmonds' algorithm.
+    /// This function runs the original Edmonds' algorithm. If the
+    /// \c decomposition parameter is set to false, then the Gallai-Edmonds
+    /// decomposition is not computed.
     ///
     /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be
     /// called before using this function.
-    void startSparse() {
-      for(NodeIt n(_graph); n != INVALID; ++n) {
+    void startSparse(bool decomposition = true) {
+      int _unmatched_limit = decomposition ? 0 : 1;
+      for(NodeIt n(_graph); _unmatched > _unmatched_limit; ++n) {
         if ((*_status)[n] == UNMATCHED) {
           (*_blossom_rep)[_blossom_set->insert(n)] = n;
           _tree_set->insert(n);
           (*_status)[n] = EVEN;
+          --_unmatched;
           processSparse(n);
         }
@@ -518,14 +531,18 @@
     ///
     /// This function runs Edmonds' algorithm with a heuristic of postponing
-    /// shrinks, therefore resulting in a faster algorithm for dense graphs.
+    /// shrinks, therefore resulting in a faster algorithm for dense graphs.  If
+    /// the \c decomposition parameter is set to false, then the Gallai-Edmonds
+    /// decomposition is not computed.
     ///
     /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be
     /// called before using this function.
-    void startDense() {
-      for(NodeIt n(_graph); n != INVALID; ++n) {
+    void startDense(bool decomposition = true) {
+      int _unmatched_limit = decomposition ? 0 : 1;
+      for(NodeIt n(_graph); _unmatched > _unmatched_limit; ++n) {
         if ((*_status)[n] == UNMATCHED) {
           (*_blossom_rep)[_blossom_set->insert(n)] = n;
           _tree_set->insert(n);
           (*_status)[n] = EVEN;
+          --_unmatched;
           processDense(n);
         }
@@ -537,13 +554,16 @@
     ///
     /// This function runs Edmonds' algorithm. An additional heuristic of
-    /// postponing shrinks is used for relatively dense graphs
-    /// (for which <tt>m>=2*n</tt> holds).
-    void run() {
+    /// postponing shrinks is used for relatively dense graphs (for which
+    /// <tt>m>=2*n</tt> holds). If the \c decomposition parameter is set to
+    /// false, then the Gallai-Edmonds decomposition is not computed. In some
+    /// cases, this can speed up the algorithm significantly, especially when a
+    /// maximum matching is computed in a dense graph with odd number of nodes.
+    void run(bool decomposition = true) {
       if (countEdges(_graph) < 2 * countNodes(_graph)) {
         greedyInit();
-        startSparse();
+        startSparse(decomposition);
       } else {
         init();
-        startDense();
+        startDense(decomposition);
       }
     }
Index: lemon/path.h
===================================================================
--- lemon/path.h	(revision 1270)
+++ lemon/path.h	(revision 1421)
@@ -31,4 +31,5 @@
 #include <lemon/core.h>
 #include <lemon/concepts/path.h>
+#include <lemon/bits/stl_iterators.h>
 
 namespace lemon {
@@ -43,8 +44,8 @@
   /// \tparam GR The digraph type in which the path is.
   ///
-  /// In a sense, the path can be treated as a list of arcs. The
-  /// LEMON path type stores just this list. As a consequence, it
-  /// cannot enumerate the nodes of the path and the source node of
-  /// a zero length path is undefined.
+  /// In a sense, a path can be treated as a list of arcs. The
+  /// LEMON path type simply stores this list. As a consequence, it
+  /// cannot enumerate the nodes in the path, and the source node of
+  /// a zero-length path is undefined.
   ///
   /// This implementation is a back and front insertable and erasable
@@ -141,4 +142,21 @@
     };
 
+    /// \brief Gets the collection of the arcs of the path.
+    ///
+    /// This function can be used for iterating on the
+    /// arcs of the path. It returns a wrapped
+    /// ArcIt, which looks like an STL container
+    /// (by having begin() and end()) which you can use in range-based
+    /// for loops, STL algorithms, etc.
+    /// For example you can write:
+    ///\code
+    /// for(auto a: p.arcs())
+    ///   doSomething(a);
+    ///\endcode
+    LemonRangeWrapper1<ArcIt, Path> arcs() const {
+      return LemonRangeWrapper1<ArcIt, Path>(*this);
+    }
+
+
     /// \brief Length of the path.
     int length() const { return head.size() + tail.size(); }
@@ -151,5 +169,6 @@
     /// \brief The n-th arc.
     ///
-    /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
+    /// Gives back the n-th arc. This function runs in O(1) time.
+    /// \pre \c n is in the range <tt>[0..length() - 1]</tt>.
     const Arc& nth(int n) const {
       return n < int(head.size()) ? *(head.rbegin() + n) :
@@ -162,4 +181,13 @@
     ArcIt nthIt(int n) const {
       return ArcIt(*this, n);
+    }
+
+    /// \brief The n-th arc.
+    ///
+    /// Gives back the n-th arc. This operator is just an alias for \ref nth(),
+    /// it runs in O(1) time.
+    /// \pre \c n is in the range <tt>[0..length() - 1]</tt>.
+    const Arc& operator[](int n) const {
+      return nth(n);
     }
 
@@ -244,13 +272,13 @@
   /// \tparam GR The digraph type in which the path is.
   ///
-  /// In a sense, the path can be treated as a list of arcs. The
-  /// LEMON path type stores just this list. As a consequence it
-  /// cannot enumerate the nodes in the path and the zero length paths
-  /// cannot store the source.
+  /// In a sense, a path can be treated as a list of arcs. The
+  /// LEMON path type simply stores this list. As a consequence, it
+  /// cannot enumerate the nodes in the path, and the source node of
+  /// a zero-length path is undefined.
   ///
   /// This implementation is a just back insertable and erasable path
   /// type. It can be indexed in O(1) time. The back insertion and
   /// erasure is amortized O(1) time. This implementation is faster
-  /// then the \c Path type because it use just one vector for the
+  /// than the \c Path type because it use just one vector for the
   /// arcs.
   template <typename GR>
@@ -346,4 +374,21 @@
     };
 
+    /// \brief Gets the collection of the arcs of the path.
+    ///
+    /// This function can be used for iterating on the
+    /// arcs of the path. It returns a wrapped
+    /// ArcIt, which looks like an STL container
+    /// (by having begin() and end()) which you can use in range-based
+    /// for loops, STL algorithms, etc.
+    /// For example you can write:
+    ///\code
+    /// for(auto a: p.arcs())
+    ///   doSomething(a);
+    ///\endcode
+    LemonRangeWrapper1<ArcIt, SimplePath> arcs() const {
+      return LemonRangeWrapper1<ArcIt, SimplePath>(*this);
+    }
+
+
     /// \brief Length of the path.
     int length() const { return data.size(); }
@@ -356,5 +401,6 @@
     /// \brief The n-th arc.
     ///
-    /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
+    /// Gives back the n-th arc. This function runs in O(1) time.
+    /// \pre \c n is in the range <tt>[0..length() - 1]</tt>.
     const Arc& nth(int n) const {
       return data[n];
@@ -364,4 +410,13 @@
     ArcIt nthIt(int n) const {
       return ArcIt(*this, n);
+    }
+
+    /// \brief The n-th arc.
+    ///
+    /// Gives back the n-th arc. This operator is just an alias for \ref nth(),
+    /// it runs in O(1) time.
+    /// \pre \c n is in the range <tt>[0..length() - 1]</tt>.
+    const Arc& operator[](int n) const {
+      return data[n];
     }
 
@@ -421,8 +476,8 @@
   /// \tparam GR The digraph type in which the path is.
   ///
-  /// In a sense, the path can be treated as a list of arcs. The
-  /// LEMON path type stores just this list. As a consequence it
-  /// cannot enumerate the nodes in the path and the zero length paths
-  /// cannot store the source.
+  /// In a sense, a path can be treated as a list of arcs. The
+  /// LEMON path type simply stores this list. As a consequence, it
+  /// cannot enumerate the nodes in the path, and the source node of
+  /// a zero-length path is undefined.
   ///
   /// This implementation is a back and front insertable and erasable
@@ -544,8 +599,25 @@
     };
 
+    /// \brief Gets the collection of the arcs of the path.
+    ///
+    /// This function can be used for iterating on the
+    /// arcs of the path. It returns a wrapped
+    /// ArcIt, which looks like an STL container
+    /// (by having begin() and end()) which you can use in range-based
+    /// for loops, STL algorithms, etc.
+    /// For example you can write:
+    ///\code
+    /// for(auto a: p.arcs())
+    ///   doSomething(a);
+    ///\endcode
+    LemonRangeWrapper1<ArcIt, ListPath> arcs() const {
+      return LemonRangeWrapper1<ArcIt, ListPath>(*this);
+    }
+
+
     /// \brief The n-th arc.
     ///
     /// This function looks for the n-th arc in O(n) time.
-    /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
+    /// \pre \c n is in the range <tt>[0..length() - 1]</tt>.
     const Arc& nth(int n) const {
       Node *node = first;
@@ -563,4 +635,13 @@
       }
       return ArcIt(*this, node);
+    }
+
+    /// \brief The n-th arc.
+    ///
+    /// Looks for the n-th arc in O(n) time. This operator is just an alias
+    /// for \ref nth().
+    /// \pre \c n is in the range <tt>[0..length() - 1]</tt>.
+    const Arc& operator[](int n) const {
+      return nth(n);
     }
 
@@ -733,5 +814,5 @@
     /// \c it will put into \c tpath. If \c tpath have arcs
     /// before the operation they are removed first.  The time
-    /// complexity of this function is O(1) plus the the time of emtying
+    /// complexity of this function is O(1) plus the time of emtying
     /// \c tpath. If \c it is \c INVALID then it just clears \c tpath
     void split(ArcIt it, ListPath& tpath) {
@@ -774,8 +855,8 @@
   /// \tparam GR The digraph type in which the path is.
   ///
-  /// In a sense, the path can be treated as a list of arcs. The
-  /// LEMON path type stores just this list. As a consequence it
-  /// cannot enumerate the nodes in the path and the source node of
-  /// a zero length path is undefined.
+  /// In a sense, a path can be treated as a list of arcs. The
+  /// LEMON path type simply stores this list. As a consequence, it
+  /// cannot enumerate the nodes in the path, and the source node of
+  /// a zero-length path is undefined.
   ///
   /// This implementation is completly static, i.e. it can be copy constucted
@@ -783,7 +864,6 @@
   /// modified.
   ///
-  /// Being the the most memory efficient path type in LEMON,
-  /// it is intented to be
-  /// used when you want to store a large number of paths.
+  /// Being the most memory-efficient path type in LEMON, it is
+  /// intented to be used when you want to store a large number of paths.
   template <typename GR>
   class StaticPath {
@@ -796,9 +876,9 @@
     ///
     /// Default constructor
-    StaticPath() : len(0), arcs(0) {}
+    StaticPath() : len(0), _arcs(0) {}
 
     /// \brief Copy constructor
     ///
-    StaticPath(const StaticPath& cpath) : arcs(0) {
+    StaticPath(const StaticPath& cpath) : _arcs(0) {
       pathCopy(cpath, *this);
     }
@@ -808,5 +888,5 @@
     /// This path can be initialized from any other path type.
     template <typename CPath>
-    StaticPath(const CPath& cpath) : arcs(0) {
+    StaticPath(const CPath& cpath) : _arcs(0) {
       pathCopy(cpath, *this);
     }
@@ -816,5 +896,5 @@
     /// Destructor of the path
     ~StaticPath() {
-      if (arcs) delete[] arcs;
+      if (_arcs) delete[] _arcs;
     }
 
@@ -883,10 +963,28 @@
       int idx;
     };
+    
+    /// \brief Gets the collection of the arcs of the path.
+    ///
+    /// This function can be used for iterating on the
+    /// arcs of the path. It returns a wrapped
+    /// ArcIt, which looks like an STL container
+    /// (by having begin() and end()) which you can use in range-based
+    /// for loops, STL algorithms, etc.
+    /// For example you can write:
+    ///\code
+    /// for(auto a: p.arcs())
+    ///   doSomething(a);
+    ///\endcode
+    LemonRangeWrapper1<ArcIt, StaticPath> arcs() const {
+      return LemonRangeWrapper1<ArcIt, StaticPath>(*this);
+    }
+    
 
     /// \brief The n-th arc.
     ///
-    /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
+    /// Gives back the n-th arc. This function runs in O(1) time.
+    /// \pre \c n is in the range <tt>[0..length() - 1]</tt>.
     const Arc& nth(int n) const {
-      return arcs[n];
+      return _arcs[n];
     }
 
@@ -896,4 +994,13 @@
     }
 
+    /// \brief The n-th arc.
+    ///
+    /// Gives back the n-th arc. This operator is just an alias for \ref nth(),
+    /// it runs in O(1) time.
+    /// \pre \c n is in the range <tt>[0..length() - 1]</tt>.
+    const Arc& operator[](int n) const {
+      return _arcs[n];
+    }
+
     /// \brief The length of the path.
     int length() const { return len; }
@@ -902,19 +1009,19 @@
     int empty() const { return len == 0; }
 
-    /// \brief Erase all arcs in the digraph.
+    /// \brief Reset the path to an empty one.
     void clear() {
       len = 0;
-      if (arcs) delete[] arcs;
-      arcs = 0;
+      if (_arcs) delete[] _arcs;
+      _arcs = 0;
     }
 
     /// \brief The first arc of the path.
     const Arc& front() const {
-      return arcs[0];
+      return _arcs[0];
     }
 
     /// \brief The last arc of the path.
     const Arc& back() const {
-      return arcs[len - 1];
+      return _arcs[len - 1];
     }
 
@@ -925,8 +1032,8 @@
     void build(const CPath& path) {
       len = path.length();
-      arcs = new Arc[len];
+      _arcs = new Arc[len];
       int index = 0;
       for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
-        arcs[index] = it;
+        _arcs[index] = it;
         ++index;
       }
@@ -936,9 +1043,9 @@
     void buildRev(const CPath& path) {
       len = path.length();
-      arcs = new Arc[len];
+      _arcs = new Arc[len];
       int index = len;
       for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
         --index;
-        arcs[index] = it;
+        _arcs[index] = it;
       }
     }
@@ -946,5 +1053,5 @@
   private:
     int len;
-    Arc* arcs;
+    Arc* _arcs;
   };
 
@@ -1092,13 +1199,15 @@
   }
 
-  /// \brief Class which helps to iterate through the nodes of a path
-  ///
-  /// In a sense, the path can be treated as a list of arcs. The
-  /// LEMON path type stores only this list. As a consequence, it
-  /// cannot enumerate the nodes in the path and the zero length paths
-  /// cannot have a source node.
-  ///
-  /// This class implements the node iterator of a path structure. To
-  /// provide this feature, the underlying digraph should be passed to
+  /// \brief Class for iterating through the nodes of a path
+  ///
+  /// Class for iterating through the nodes of a path.
+  ///
+  /// In a sense, a path can be treated as a list of arcs. The
+  /// LEMON path type simply stores this list. As a consequence, it
+  /// cannot enumerate the nodes in the path, and the source node of
+  /// a zero-length path is undefined.
+  ///
+  /// However, this class implements a node iterator for path structures.
+  /// To provide this feature, the underlying digraph should be passed to
   /// the constructor of the iterator.
   template <typename Path>
@@ -1158,4 +1267,23 @@
   };
 
+  /// \brief Gets the collection of the nodes of the path.
+  ///
+  /// This function can be used for iterating on the
+  /// nodes of the path. It returns a wrapped
+  /// PathNodeIt, which looks like an STL container
+  /// (by having begin() and end()) which you can use in range-based
+  /// for loops, STL algorithms, etc.
+  /// For example you can write:
+  ///\code
+  /// for(auto u: pathNodes(g,p))
+  ///   doSomething(u);
+  ///\endcode
+  template<typename Path>
+  LemonRangeWrapper2<PathNodeIt<Path>, typename Path::Digraph, Path>
+      pathNodes(const typename Path::Digraph &g, const Path &p) {
+    return
+        LemonRangeWrapper2<PathNodeIt<Path>, typename Path::Digraph, Path>(g,p);
+  }
+
   ///@}
 
Index: lemon/random.h
===================================================================
--- lemon/random.h	(revision 1396)
+++ lemon/random.h	(revision 1404)
@@ -111,5 +111,4 @@
       static const Word loMask = (1u << 31) - 1;
       static const Word hiMask = ~loMask;
-
 
       static Word tempering(Word rnd) {
@@ -244,5 +243,4 @@
     private:
 
-
       void fillState() {
         static const Word mask[2] = { 0x0ul, RandomTraits<Word>::mask };
@@ -252,6 +250,6 @@
         current = state + length;
 
-        register Word *curr = state + length - 1;
-        register long num;
+        Word *curr = state + length - 1;
+        long num;
 
         num = length - shift;
@@ -272,5 +270,4 @@
       }
 
-
       Word *current;
       Word state[length];
@@ -297,5 +294,5 @@
     template <typename Result, typename Word,
               int rest = std::numeric_limits<Result>::digits, int shift = 0,
-              bool last = rest <= std::numeric_limits<Word>::digits>
+              bool last = (rest <= std::numeric_limits<Word>::digits)>
     struct IntConversion {
       static const int bits = std::numeric_limits<Word>::digits;
@@ -466,5 +463,544 @@
     };
 
-  }
+    /// \ingroup misc
+    ///
+    /// \brief Mersenne Twister random number generator
+    ///
+    /// The Mersenne Twister is a twisted generalized feedback
+    /// shift-register generator of Matsumoto and Nishimura. The period
+    /// of this generator is \f$ 2^{19937} - 1\f$ and it is
+    /// equi-distributed in 623 dimensions for 32-bit numbers. The time
+    /// performance of this generator is comparable to the commonly used
+    /// generators.
+    ///
+    /// This is a template implementation of both 32-bit and
+    /// 64-bit architecture optimized versions. The generators differ
+    /// sligthly in the initialization and generation phase so they
+    /// produce two completly different sequences.
+    ///
+    /// \alert Do not use this class directly, but instead one of \ref
+    /// Random, \ref Random32 or \ref Random64.
+    ///
+    /// The generator gives back random numbers of serveral types. To
+    /// get a random number from a range of a floating point type, you
+    /// can use one form of the \c operator() or the \c real() member
+    /// function. If you want to get random number from the {0, 1, ...,
+    /// n-1} integer range, use the \c operator[] or the \c integer()
+    /// method. And to get random number from the whole range of an
+    /// integer type, you can use the argumentless \c integer() or
+    /// \c uinteger() functions. Finally, you can get random bool with
+    /// equal chance of true and false or with given probability of true
+    /// result using the \c boolean() member functions.
+    ///
+    /// Various non-uniform distributions are also supported: normal (Gauss),
+    /// exponential, gamma, Poisson, etc.; and a few two-dimensional
+    /// distributions, too.
+    ///
+    ///\code
+    /// // The commented code is identical to the other
+    /// double a = rnd();                     // [0.0, 1.0)
+    /// // double a = rnd.real();             // [0.0, 1.0)
+    /// double b = rnd(100.0);                // [0.0, 100.0)
+    /// // double b = rnd.real(100.0);        // [0.0, 100.0)
+    /// double c = rnd(1.0, 2.0);             // [1.0, 2.0)
+    /// // double c = rnd.real(1.0, 2.0);     // [1.0, 2.0)
+    /// int d = rnd[100000];                  // 0..99999
+    /// // int d = rnd.integer(100000);       // 0..99999
+    /// int e = rnd[6] + 1;                   // 1..6
+    /// // int e = rnd.integer(1, 1 + 6);     // 1..6
+    /// int b = rnd.uinteger<int>();          // 0 .. 2^31 - 1
+    /// int c = rnd.integer<int>();           // - 2^31 .. 2^31 - 1
+    /// bool g = rnd.boolean();               // P(g = true) = 0.5
+    /// bool h = rnd.boolean(0.8);            // P(h = true) = 0.8
+    ///\endcode
+    ///
+    /// LEMON provides a global instance of the random number generator:
+    /// \ref lemon::rnd "rnd". In most cases, it is a good practice
+    /// to use this global generator to get random numbers.
+    ///
+    /// \sa \ref Random, \ref Random32 or \ref Random64.
+    template<class Word>
+    class Random {
+    private:
+
+      _random_bits::RandomCore<Word> core;
+      _random_bits::BoolProducer<Word> bool_producer;
+
+
+    public:
+
+      ///\name Initialization
+      ///
+      /// @{
+
+      /// \brief Default constructor
+      ///
+      /// Constructor with constant seeding.
+      Random() { core.initState(); }
+
+      /// \brief Constructor with seed
+      ///
+      /// Constructor with seed. The current number type will be converted
+      /// to the architecture word type.
+      template <typename Number>
+      Random(Number seed) {
+        _random_bits::Initializer<Number, Word>::init(core, seed);
+      }
+
+      /// \brief Constructor with array seeding
+      ///
+      /// Constructor with array seeding. The given range should contain
+      /// any number type and the numbers will be converted to the
+      /// architecture word type.
+      template <typename Iterator>
+      Random(Iterator begin, Iterator end) {
+        typedef typename std::iterator_traits<Iterator>::value_type Number;
+        _random_bits::Initializer<Number, Word>::init(core, begin, end);
+      }
+
+      /// \brief Copy constructor
+      ///
+      /// Copy constructor. The generated sequence will be identical to
+      /// the other sequence. It can be used to save the current state
+      /// of the generator and later use it to generate the same
+      /// sequence.
+      Random(const Random& other) {
+        core.copyState(other.core);
+      }
+
+      /// \brief Assign operator
+      ///
+      /// Assign operator. The generated sequence will be identical to
+      /// the other sequence. It can be used to save the current state
+      /// of the generator and later use it to generate the same
+      /// sequence.
+      Random& operator=(const Random& other) {
+        if (&other != this) {
+          core.copyState(other.core);
+        }
+        return *this;
+      }
+
+      /// \brief Seeding random sequence
+      ///
+      /// Seeding the random sequence. The current number type will be
+      /// converted to the architecture word type.
+      template <typename Number>
+      void seed(Number seed) {
+        _random_bits::Initializer<Number, Word>::init(core, seed);
+      }
+
+      /// \brief Seeding random sequence
+      ///
+      /// Seeding the random sequence. The given range should contain
+      /// any number type and the numbers will be converted to the
+      /// architecture word type.
+      template <typename Iterator>
+      void seed(Iterator begin, Iterator end) {
+        typedef typename std::iterator_traits<Iterator>::value_type Number;
+        _random_bits::Initializer<Number, Word>::init(core, begin, end);
+      }
+
+      /// \brief Seeding from file or from process id and time
+      ///
+      /// By default, this function calls the \c seedFromFile() member
+      /// function with the <tt>/dev/urandom</tt> file. If it does not success,
+      /// it uses the \c seedFromTime().
+      /// \return Currently always \c true.
+      bool seed() {
+#ifndef LEMON_WIN32
+        if (seedFromFile("/dev/urandom", 0)) return true;
+#endif
+        if (seedFromTime()) return true;
+        return false;
+      }
+
+      /// \brief Seeding from file
+      ///
+      /// Seeding the random sequence from file. The linux kernel has two
+      /// devices, <tt>/dev/random</tt> and <tt>/dev/urandom</tt> which
+      /// could give good seed values for pseudo random generators (The
+      /// difference between two devices is that the <tt>random</tt> may
+      /// block the reading operation while the kernel can give good
+      /// source of randomness, while the <tt>urandom</tt> does not
+      /// block the input, but it could give back bytes with worse
+      /// entropy).
+      /// \param file The source file
+      /// \param offset The offset, from the file read.
+      /// \return \c true when the seeding successes.
+#ifndef LEMON_WIN32
+      bool seedFromFile(const std::string& file = "/dev/urandom", int offset = 0)
+#else
+        bool seedFromFile(const std::string& file = "", int offset = 0)
+#endif
+      {
+        std::ifstream rs(file.c_str());
+        const int size = 4;
+        Word buf[size];
+        if (offset != 0 && !rs.seekg(offset)) return false;
+        if (!rs.read(reinterpret_cast<char*>(buf), sizeof(buf))) return false;
+        seed(buf, buf + size);
+        return true;
+      }
+
+      /// \brief Seeding from process id and time
+      ///
+      /// Seeding from process id and time. This function uses the
+      /// current process id and the current time for initialize the
+      /// random sequence.
+      /// \return Currently always \c true.
+      bool seedFromTime() {
+#ifndef LEMON_WIN32
+        timeval tv;
+        gettimeofday(&tv, 0);
+        seed(getpid() + tv.tv_sec + tv.tv_usec);
+#else
+        seed(bits::getWinRndSeed());
+#endif
+        return true;
+      }
+
+      /// @}
+
+      ///\name Uniform Distributions
+      ///
+      /// @{
+
+      /// \brief Returns a random real number from the range [0, 1)
+      ///
+      /// It returns a random real number from the range [0, 1). The
+      /// default Number type is \c double.
+      template <typename Number>
+      Number real() {
+        return _random_bits::RealConversion<Number, Word>::convert(core);
+      }
+
+      double real() {
+        return real<double>();
+      }
+
+      /// \brief Returns a random real number from the range [0, 1)
+      ///
+      /// It returns a random double from the range [0, 1).
+      double operator()() {
+        return real<double>();
+      }
+
+      /// \brief Returns a random real number from the range [0, b)
+      ///
+      /// It returns a random real number from the range [0, b).
+      double operator()(double b) {
+        return real<double>() * b;
+      }
+
+      /// \brief Returns a random real number from the range [a, b)
+      ///
+      /// It returns a random real number from the range [a, b).
+      double operator()(double a, double b) {
+        return real<double>() * (b - a) + a;
+      }
+
+      /// \brief Returns a random integer from a range
+      ///
+      /// It returns a random integer from the range {0, 1, ..., b - 1}.
+      template <typename Number>
+      Number integer(Number b) {
+        return _random_bits::Mapping<Number, Word>::map(core, b);
+      }
+
+      /// \brief Returns a random integer from a range
+      ///
+      /// It returns a random integer from the range {a, a + 1, ..., b - 1}.
+      template <typename Number>
+      Number integer(Number a, Number b) {
+        return _random_bits::Mapping<Number, Word>::map(core, b - a) + a;
+      }
+
+      /// \brief Returns a random integer from a range
+      ///
+      /// It returns a random integer from the range {0, 1, ..., b - 1}.
+      template <typename Number>
+      Number operator[](Number b) {
+        return _random_bits::Mapping<Number, Word>::map(core, b);
+      }
+
+      /// \brief Returns a random non-negative integer
+      ///
+      /// It returns a random non-negative integer uniformly from the
+      /// whole range of the current \c Number type. The default result
+      /// type of this function is <tt>unsigned int</tt>.
+      template <typename Number>
+      Number uinteger() {
+        return _random_bits::IntConversion<Number, Word>::convert(core);
+      }
+
+      unsigned int uinteger() {
+        return uinteger<unsigned int>();
+      }
+
+      /// \brief Returns a random integer
+      ///
+      /// It returns a random integer uniformly from the whole range of
+      /// the current \c Number type. The default result type of this
+      /// function is \c int.
+      template <typename Number>
+      Number integer() {
+        static const int nb = std::numeric_limits<Number>::digits +
+          (std::numeric_limits<Number>::is_signed ? 1 : 0);
+        return _random_bits::IntConversion<Number, Word, nb>::convert(core);
+      }
+
+      int integer() {
+        return integer<int>();
+      }
+
+      /// \brief Returns a random bool
+      ///
+      /// It returns a random bool. The generator holds a buffer for
+      /// random bits. Every time when it become empty the generator makes
+      /// a new random word and fill the buffer up.
+      bool boolean() {
+        return bool_producer.convert(core);
+      }
+
+      /// @}
+
+      ///\name Non-uniform Distributions
+      ///
+      ///@{
+
+      /// \brief Returns a random bool with given probability of true result.
+      ///
+      /// It returns a random bool with given probability of true result.
+      bool boolean(double p) {
+        return operator()() < p;
+      }
+
+      /// Standard normal (Gauss) distribution
+
+      /// Standard normal (Gauss) distribution.
+      /// \note The Cartesian form of the Box-Muller
+      /// transformation is used to generate a random normal distribution.
+      double gauss()
+      {
+        double V1,V2,S;
+        do {
+          V1=2*real<double>()-1;
+          V2=2*real<double>()-1;
+          S=V1*V1+V2*V2;
+        } while(S>=1);
+        return std::sqrt(-2*std::log(S)/S)*V1;
+      }
+      /// Normal (Gauss) distribution with given mean and standard deviation
+
+      /// Normal (Gauss) distribution with given mean and standard deviation.
+      /// \sa gauss()
+      double gauss(double mean,double std_dev)
+      {
+        return gauss()*std_dev+mean;
+      }
+
+      /// Lognormal distribution
+
+      /// Lognormal distribution. The parameters are the mean and the standard
+      /// deviation of <tt>exp(X)</tt>.
+      ///
+      double lognormal(double n_mean,double n_std_dev)
+      {
+        return std::exp(gauss(n_mean,n_std_dev));
+      }
+      /// Lognormal distribution
+
+      /// Lognormal distribution. The parameter is an <tt>std::pair</tt> of
+      /// the mean and the standard deviation of <tt>exp(X)</tt>.
+      ///
+      double lognormal(const std::pair<double,double> &params)
+      {
+        return std::exp(gauss(params.first,params.second));
+      }
+      /// Compute the lognormal parameters from mean and standard deviation
+
+      /// This function computes the lognormal parameters from mean and
+      /// standard deviation. The return value can direcly be passed to
+      /// lognormal().
+      std::pair<double,double> lognormalParamsFromMD(double mean,
+                                                     double std_dev)
+      {
+        double fr=std_dev/mean;
+        fr*=fr;
+        double lg=std::log(1+fr);
+        return std::pair<double,double>(std::log(mean)-lg/2.0,std::sqrt(lg));
+      }
+      /// Lognormal distribution with given mean and standard deviation
+
+      /// Lognormal distribution with given mean and standard deviation.
+      ///
+      double lognormalMD(double mean,double std_dev)
+      {
+        return lognormal(lognormalParamsFromMD(mean,std_dev));
+      }
+
+      /// Exponential distribution with given mean
+
+      /// This function generates an exponential distribution random number
+      /// with mean <tt>1/lambda</tt>.
+      ///
+      double exponential(double lambda=1.0)
+      {
+        return -std::log(1.0-real<double>())/lambda;
+      }
+
+      /// Gamma distribution with given integer shape
+
+      /// This function generates a gamma distribution random number.
+      ///
+      ///\param k shape parameter (<tt>k>0</tt> integer)
+      double gamma(int k)
+      {
+        double s = 0;
+        for(int i=0;i<k;i++) s-=std::log(1.0-real<double>());
+        return s;
+      }
+
+      /// Gamma distribution with given shape and scale parameter
+
+      /// This function generates a gamma distribution random number.
+      ///
+      ///\param k shape parameter (<tt>k>0</tt>)
+      ///\param theta scale parameter
+      ///
+      double gamma(double k,double theta=1.0)
+      {
+        double xi,nu;
+        const double delta = k-std::floor(k);
+        const double v0=E/(E-delta);
+        do {
+          double V0=1.0-real<double>();
+          double V1=1.0-real<double>();
+          double V2=1.0-real<double>();
+          if(V2<=v0)
+            {
+              xi=std::pow(V1,1.0/delta);
+              nu=V0*std::pow(xi,delta-1.0);
+            }
+          else
+            {
+              xi=1.0-std::log(V1);
+              nu=V0*std::exp(-xi);
+            }
+        } while(nu>std::pow(xi,delta-1.0)*std::exp(-xi));
+        return theta*(xi+gamma(int(std::floor(k))));
+      }
+
+      /// Weibull distribution
+
+      /// This function generates a Weibull distribution random number.
+      ///
+      ///\param k shape parameter (<tt>k>0</tt>)
+      ///\param lambda scale parameter (<tt>lambda>0</tt>)
+      ///
+      double weibull(double k,double lambda)
+      {
+        return lambda*pow(-std::log(1.0-real<double>()),1.0/k);
+      }
+
+      /// Pareto distribution
+
+      /// This function generates a Pareto distribution random number.
+      ///
+      ///\param k shape parameter (<tt>k>0</tt>)
+      ///\param x_min location parameter (<tt>x_min>0</tt>)
+      ///
+      double pareto(double k,double x_min)
+      {
+        return exponential(gamma(k,1.0/x_min))+x_min;
+      }
+
+      /// Poisson distribution
+
+      /// This function generates a Poisson distribution random number with
+      /// parameter \c lambda.
+      ///
+      /// The probability mass function of this distribusion is
+      /// \f[ \frac{e^{-\lambda}\lambda^k}{k!} \f]
+      /// \note The algorithm is taken from the book of Donald E. Knuth titled
+      /// ''Seminumerical Algorithms'' (1969). Its running time is linear in the
+      /// return value.
+
+      int poisson(double lambda)
+      {
+        const double l = std::exp(-lambda);
+        int k=0;
+        double p = 1.0;
+        do {
+          k++;
+          p*=real<double>();
+        } while (p>=l);
+        return k-1;
+      }
+
+      ///@}
+
+      ///\name Two-Dimensional Distributions
+      ///
+      ///@{
+
+      /// Uniform distribution on the full unit circle
+
+      /// Uniform distribution on the full unit circle.
+      ///
+      dim2::Point<double> disc()
+      {
+        double V1,V2;
+        do {
+          V1=2*real<double>()-1;
+          V2=2*real<double>()-1;
+
+        } while(V1*V1+V2*V2>=1);
+        return dim2::Point<double>(V1,V2);
+      }
+      /// A kind of two-dimensional normal (Gauss) distribution
+
+      /// This function provides a turning symmetric two-dimensional distribution.
+      /// Both coordinates are of standard normal distribution, but they are not
+      /// independent.
+      ///
+      /// \note The coordinates are the two random variables provided by
+      /// the Box-Muller method.
+      dim2::Point<double> gauss2()
+      {
+        double V1,V2,S;
+        do {
+          V1=2*real<double>()-1;
+          V2=2*real<double>()-1;
+          S=V1*V1+V2*V2;
+        } while(S>=1);
+        double W=std::sqrt(-2*std::log(S)/S);
+        return dim2::Point<double>(W*V1,W*V2);
+      }
+      /// A kind of two-dimensional exponential distribution
+
+      /// This function provides a turning symmetric two-dimensional distribution.
+      /// The x-coordinate is of conditionally exponential distribution
+      /// with the condition that x is positive and y=0. If x is negative and
+      /// y=0 then, -x is of exponential distribution. The same is true for the
+      /// y-coordinate.
+      dim2::Point<double> exponential2()
+      {
+        double V1,V2,S;
+        do {
+          V1=2*real<double>()-1;
+          V2=2*real<double>()-1;
+          S=V1*V1+V2*V2;
+        } while(S>=1);
+        double W=-std::log(S)/S;
+        return dim2::Point<double>(W*V1,W*V2);
+      }
+
+      ///@}
+    };
+
+
+  };
 
   /// \ingroup misc
@@ -472,536 +1008,48 @@
   /// \brief Mersenne Twister random number generator
   ///
-  /// The Mersenne Twister is a twisted generalized feedback
-  /// shift-register generator of Matsumoto and Nishimura. The period
-  /// of this generator is \f$ 2^{19937} - 1 \f$ and it is
-  /// equi-distributed in 623 dimensions for 32-bit numbers. The time
-  /// performance of this generator is comparable to the commonly used
-  /// generators.
+  /// This class implements either the 32-bit or the 64-bit version of
+  /// the Mersenne Twister random number generator algorithm
+  /// depending on the system architecture.
+  /// 
+  /// For the API description, see its base class
+  /// \ref _random_bits::Random.
   ///
-  /// This implementation is specialized for both 32-bit and 64-bit
-  /// architectures. The generators differ sligthly in the
-  /// initialization and generation phase so they produce two
-  /// completly different sequences.
+  /// \sa \ref _random_bits::Random
+  typedef _random_bits::Random<unsigned long> Random;
+
+  /// \ingroup misc
   ///
-  /// The generator gives back random numbers of serveral types. To
-  /// get a random number from a range of a floating point type you
-  /// can use one form of the \c operator() or the \c real() member
-  /// function. If you want to get random number from the {0, 1, ...,
-  /// n-1} integer range use the \c operator[] or the \c integer()
-  /// method. And to get random number from the whole range of an
-  /// integer type you can use the argumentless \c integer() or \c
-  /// uinteger() functions. After all you can get random bool with
-  /// equal chance of true and false or given probability of true
-  /// result with the \c boolean() member functions.
+  /// \brief Mersenne Twister random number generator (32-bit version)
   ///
-  ///\code
-  /// // The commented code is identical to the other
-  /// double a = rnd();                     // [0.0, 1.0)
-  /// // double a = rnd.real();             // [0.0, 1.0)
-  /// double b = rnd(100.0);                // [0.0, 100.0)
-  /// // double b = rnd.real(100.0);        // [0.0, 100.0)
-  /// double c = rnd(1.0, 2.0);             // [1.0, 2.0)
-  /// // double c = rnd.real(1.0, 2.0);     // [1.0, 2.0)
-  /// int d = rnd[100000];                  // 0..99999
-  /// // int d = rnd.integer(100000);       // 0..99999
-  /// int e = rnd[6] + 1;                   // 1..6
-  /// // int e = rnd.integer(1, 1 + 6);     // 1..6
-  /// int b = rnd.uinteger<int>();          // 0 .. 2^31 - 1
-  /// int c = rnd.integer<int>();           // - 2^31 .. 2^31 - 1
-  /// bool g = rnd.boolean();               // P(g = true) = 0.5
-  /// bool h = rnd.boolean(0.8);            // P(h = true) = 0.8
-  ///\endcode
+  /// This class implements the 32-bit version of the Mersenne Twister
+  /// random number generator algorithm. It is recommended to be used
+  /// when someone wants to make sure that the \e same pseudo random
+  /// sequence will be generated on every platfrom.
   ///
-  /// LEMON provides a global instance of the random number
-  /// generator which name is \ref lemon::rnd "rnd". Usually it is a
-  /// good programming convenience to use this global generator to get
-  /// random numbers.
-  class Random {
-  private:
-
-    // Architecture word
-    typedef unsigned long Word;
-
-    _random_bits::RandomCore<Word> core;
-    _random_bits::BoolProducer<Word> bool_producer;
-
-
-  public:
-
-    ///\name Initialization
-    ///
-    /// @{
-
-    /// \brief Default constructor
-    ///
-    /// Constructor with constant seeding.
-    Random() { core.initState(); }
-
-    /// \brief Constructor with seed
-    ///
-    /// Constructor with seed. The current number type will be converted
-    /// to the architecture word type.
-    template <typename Number>
-    Random(Number seed) {
-      _random_bits::Initializer<Number, Word>::init(core, seed);
-    }
-
-    /// \brief Constructor with array seeding
-    ///
-    /// Constructor with array seeding. The given range should contain
-    /// any number type and the numbers will be converted to the
-    /// architecture word type.
-    template <typename Iterator>
-    Random(Iterator begin, Iterator end) {
-      typedef typename std::iterator_traits<Iterator>::value_type Number;
-      _random_bits::Initializer<Number, Word>::init(core, begin, end);
-    }
-
-    /// \brief Copy constructor
-    ///
-    /// Copy constructor. The generated sequence will be identical to
-    /// the other sequence. It can be used to save the current state
-    /// of the generator and later use it to generate the same
-    /// sequence.
-    Random(const Random& other) {
-      core.copyState(other.core);
-    }
-
-    /// \brief Assign operator
-    ///
-    /// Assign operator. The generated sequence will be identical to
-    /// the other sequence. It can be used to save the current state
-    /// of the generator and later use it to generate the same
-    /// sequence.
-    Random& operator=(const Random& other) {
-      if (&other != this) {
-        core.copyState(other.core);
-      }
-      return *this;
-    }
-
-    /// \brief Seeding random sequence
-    ///
-    /// Seeding the random sequence. The current number type will be
-    /// converted to the architecture word type.
-    template <typename Number>
-    void seed(Number seed) {
-      _random_bits::Initializer<Number, Word>::init(core, seed);
-    }
-
-    /// \brief Seeding random sequence
-    ///
-    /// Seeding the random sequence. The given range should contain
-    /// any number type and the numbers will be converted to the
-    /// architecture word type.
-    template <typename Iterator>
-    void seed(Iterator begin, Iterator end) {
-      typedef typename std::iterator_traits<Iterator>::value_type Number;
-      _random_bits::Initializer<Number, Word>::init(core, begin, end);
-    }
-
-    /// \brief Seeding from file or from process id and time
-    ///
-    /// By default, this function calls the \c seedFromFile() member
-    /// function with the <tt>/dev/urandom</tt> file. If it does not success,
-    /// it uses the \c seedFromTime().
-    /// \return Currently always \c true.
-    bool seed() {
-#ifndef LEMON_WIN32
-      if (seedFromFile("/dev/urandom", 0)) return true;
+  /// For the API description, see its base class
+  /// \ref _random_bits::Random.
+  ///
+  /// \sa \ref _random_bits::Random
+  typedef _random_bits::Random<unsigned int> Random32;
+
+  /// \ingroup misc
+  ///
+  /// \brief Mersenne Twister random number generator (64-bit version)
+  ///
+  /// This class implements the 64-bit version of the Mersenne Twister
+  /// random number generator algorithm. (Even though it runs
+  /// on 32-bit architectures, too.) It is recommended to be used when
+  /// someone wants to make sure that the \e same pseudo random sequence
+  /// will be generated on every platfrom.
+  ///
+  /// For the API description, see its base class
+  /// \ref _random_bits::Random.
+  ///
+  /// \sa \ref _random_bits::Random
+  typedef _random_bits::Random<unsigned long long> Random64;
+
+  extern Random rnd;
+  
+}
+
 #endif
-      if (seedFromTime()) return true;
-      return false;
-    }
-
-    /// \brief Seeding from file
-    ///
-    /// Seeding the random sequence from file. The linux kernel has two
-    /// devices, <tt>/dev/random</tt> and <tt>/dev/urandom</tt> which
-    /// could give good seed values for pseudo random generators (The
-    /// difference between two devices is that the <tt>random</tt> may
-    /// block the reading operation while the kernel can give good
-    /// source of randomness, while the <tt>urandom</tt> does not
-    /// block the input, but it could give back bytes with worse
-    /// entropy).
-    /// \param file The source file
-    /// \param offset The offset, from the file read.
-    /// \return \c true when the seeding successes.
-#ifndef LEMON_WIN32
-    bool seedFromFile(const std::string& file = "/dev/urandom", int offset = 0)
-#else
-    bool seedFromFile(const std::string& file = "", int offset = 0)
-#endif
-    {
-      std::ifstream rs(file.c_str());
-      const int size = 4;
-      Word buf[size];
-      if (offset != 0 && !rs.seekg(offset)) return false;
-      if (!rs.read(reinterpret_cast<char*>(buf), sizeof(buf))) return false;
-      seed(buf, buf + size);
-      return true;
-    }
-
-    /// \brief Seding from process id and time
-    ///
-    /// Seding from process id and time. This function uses the
-    /// current process id and the current time for initialize the
-    /// random sequence.
-    /// \return Currently always \c true.
-    bool seedFromTime() {
-#ifndef LEMON_WIN32
-      timeval tv;
-      gettimeofday(&tv, 0);
-      seed(getpid() + tv.tv_sec + tv.tv_usec);
-#else
-      seed(bits::getWinRndSeed());
-#endif
-      return true;
-    }
-
-    /// @}
-
-    ///\name Uniform Distributions
-    ///
-    /// @{
-
-    /// \brief Returns a random real number from the range [0, 1)
-    ///
-    /// It returns a random real number from the range [0, 1). The
-    /// default Number type is \c double.
-    template <typename Number>
-    Number real() {
-      return _random_bits::RealConversion<Number, Word>::convert(core);
-    }
-
-    double real() {
-      return real<double>();
-    }
-
-    /// \brief Returns a random real number from the range [0, 1)
-    ///
-    /// It returns a random double from the range [0, 1).
-    double operator()() {
-      return real<double>();
-    }
-
-    /// \brief Returns a random real number from the range [0, b)
-    ///
-    /// It returns a random real number from the range [0, b).
-    double operator()(double b) {
-      return real<double>() * b;
-    }
-
-    /// \brief Returns a random real number from the range [a, b)
-    ///
-    /// It returns a random real number from the range [a, b).
-    double operator()(double a, double b) {
-      return real<double>() * (b - a) + a;
-    }
-
-    /// \brief Returns a random integer from a range
-    ///
-    /// It returns a random integer from the range {0, 1, ..., b - 1}.
-    template <typename Number>
-    Number integer(Number b) {
-      return _random_bits::Mapping<Number, Word>::map(core, b);
-    }
-
-    /// \brief Returns a random integer from a range
-    ///
-    /// It returns a random integer from the range {a, a + 1, ..., b - 1}.
-    template <typename Number>
-    Number integer(Number a, Number b) {
-      return _random_bits::Mapping<Number, Word>::map(core, b - a) + a;
-    }
-
-    /// \brief Returns a random integer from a range
-    ///
-    /// It returns a random integer from the range {0, 1, ..., b - 1}.
-    template <typename Number>
-    Number operator[](Number b) {
-      return _random_bits::Mapping<Number, Word>::map(core, b);
-    }
-
-    /// \brief Returns a random non-negative integer
-    ///
-    /// It returns a random non-negative integer uniformly from the
-    /// whole range of the current \c Number type. The default result
-    /// type of this function is <tt>unsigned int</tt>.
-    template <typename Number>
-    Number uinteger() {
-      return _random_bits::IntConversion<Number, Word>::convert(core);
-    }
-
-    unsigned int uinteger() {
-      return uinteger<unsigned int>();
-    }
-
-    /// \brief Returns a random integer
-    ///
-    /// It returns a random integer uniformly from the whole range of
-    /// the current \c Number type. The default result type of this
-    /// function is \c int.
-    template <typename Number>
-    Number integer() {
-      static const int nb = std::numeric_limits<Number>::digits +
-        (std::numeric_limits<Number>::is_signed ? 1 : 0);
-      return _random_bits::IntConversion<Number, Word, nb>::convert(core);
-    }
-
-    int integer() {
-      return integer<int>();
-    }
-
-    /// \brief Returns a random bool
-    ///
-    /// It returns a random bool. The generator holds a buffer for
-    /// random bits. Every time when it become empty the generator makes
-    /// a new random word and fill the buffer up.
-    bool boolean() {
-      return bool_producer.convert(core);
-    }
-
-    /// @}
-
-    ///\name Non-uniform Distributions
-    ///
-    ///@{
-
-    /// \brief Returns a random bool with given probability of true result.
-    ///
-    /// It returns a random bool with given probability of true result.
-    bool boolean(double p) {
-      return operator()() < p;
-    }
-
-    /// Standard normal (Gauss) distribution
-
-    /// Standard normal (Gauss) distribution.
-    /// \note The Cartesian form of the Box-Muller
-    /// transformation is used to generate a random normal distribution.
-    double gauss()
-    {
-      double V1,V2,S;
-      do {
-        V1=2*real<double>()-1;
-        V2=2*real<double>()-1;
-        S=V1*V1+V2*V2;
-      } while(S>=1);
-      return std::sqrt(-2*std::log(S)/S)*V1;
-    }
-    /// Normal (Gauss) distribution with given mean and standard deviation
-
-    /// Normal (Gauss) distribution with given mean and standard deviation.
-    /// \sa gauss()
-    double gauss(double mean,double std_dev)
-    {
-      return gauss()*std_dev+mean;
-    }
-
-    /// Lognormal distribution
-
-    /// Lognormal distribution. The parameters are the mean and the standard
-    /// deviation of <tt>exp(X)</tt>.
-    ///
-    double lognormal(double n_mean,double n_std_dev)
-    {
-      return std::exp(gauss(n_mean,n_std_dev));
-    }
-    /// Lognormal distribution
-
-    /// Lognormal distribution. The parameter is an <tt>std::pair</tt> of
-    /// the mean and the standard deviation of <tt>exp(X)</tt>.
-    ///
-    double lognormal(const std::pair<double,double> &params)
-    {
-      return std::exp(gauss(params.first,params.second));
-    }
-    /// Compute the lognormal parameters from mean and standard deviation
-
-    /// This function computes the lognormal parameters from mean and
-    /// standard deviation. The return value can direcly be passed to
-    /// lognormal().
-    std::pair<double,double> lognormalParamsFromMD(double mean,
-                                                   double std_dev)
-    {
-      double fr=std_dev/mean;
-      fr*=fr;
-      double lg=std::log(1+fr);
-      return std::pair<double,double>(std::log(mean)-lg/2.0,std::sqrt(lg));
-    }
-    /// Lognormal distribution with given mean and standard deviation
-
-    /// Lognormal distribution with given mean and standard deviation.
-    ///
-    double lognormalMD(double mean,double std_dev)
-    {
-      return lognormal(lognormalParamsFromMD(mean,std_dev));
-    }
-
-    /// Exponential distribution with given mean
-
-    /// This function generates an exponential distribution random number
-    /// with mean <tt>1/lambda</tt>.
-    ///
-    double exponential(double lambda=1.0)
-    {
-      return -std::log(1.0-real<double>())/lambda;
-    }
-
-    /// Gamma distribution with given integer shape
-
-    /// This function generates a gamma distribution random number.
-    ///
-    ///\param k shape parameter (<tt>k>0</tt> integer)
-    double gamma(int k)
-    {
-      double s = 0;
-      for(int i=0;i<k;i++) s-=std::log(1.0-real<double>());
-      return s;
-    }
-
-    /// Gamma distribution with given shape and scale parameter
-
-    /// This function generates a gamma distribution random number.
-    ///
-    ///\param k shape parameter (<tt>k>0</tt>)
-    ///\param theta scale parameter
-    ///
-    double gamma(double k,double theta=1.0)
-    {
-      double xi,nu;
-      const double delta = k-std::floor(k);
-      const double v0=E/(E-delta);
-      do {
-        double V0=1.0-real<double>();
-        double V1=1.0-real<double>();
-        double V2=1.0-real<double>();
-        if(V2<=v0)
-          {
-            xi=std::pow(V1,1.0/delta);
-            nu=V0*std::pow(xi,delta-1.0);
-          }
-        else
-          {
-            xi=1.0-std::log(V1);
-            nu=V0*std::exp(-xi);
-          }
-      } while(nu>std::pow(xi,delta-1.0)*std::exp(-xi));
-      return theta*(xi+gamma(int(std::floor(k))));
-    }
-
-    /// Weibull distribution
-
-    /// This function generates a Weibull distribution random number.
-    ///
-    ///\param k shape parameter (<tt>k>0</tt>)
-    ///\param lambda scale parameter (<tt>lambda>0</tt>)
-    ///
-    double weibull(double k,double lambda)
-    {
-      return lambda*pow(-std::log(1.0-real<double>()),1.0/k);
-    }
-
-    /// Pareto distribution
-
-    /// This function generates a Pareto distribution random number.
-    ///
-    ///\param k shape parameter (<tt>k>0</tt>)
-    ///\param x_min location parameter (<tt>x_min>0</tt>)
-    ///
-    double pareto(double k,double x_min)
-    {
-      return exponential(gamma(k,1.0/x_min))+x_min;
-    }
-
-    /// Poisson distribution
-
-    /// This function generates a Poisson distribution random number with
-    /// parameter \c lambda.
-    ///
-    /// The probability mass function of this distribusion is
-    /// \f[ \frac{e^{-\lambda}\lambda^k}{k!} \f]
-    /// \note The algorithm is taken from the book of Donald E. Knuth titled
-    /// ''Seminumerical Algorithms'' (1969). Its running time is linear in the
-    /// return value.
-
-    int poisson(double lambda)
-    {
-      const double l = std::exp(-lambda);
-      int k=0;
-      double p = 1.0;
-      do {
-        k++;
-        p*=real<double>();
-      } while (p>=l);
-      return k-1;
-    }
-
-    ///@}
-
-    ///\name Two Dimensional Distributions
-    ///
-    ///@{
-
-    /// Uniform distribution on the full unit circle
-
-    /// Uniform distribution on the full unit circle.
-    ///
-    dim2::Point<double> disc()
-    {
-      double V1,V2;
-      do {
-        V1=2*real<double>()-1;
-        V2=2*real<double>()-1;
-
-      } while(V1*V1+V2*V2>=1);
-      return dim2::Point<double>(V1,V2);
-    }
-    /// A kind of two dimensional normal (Gauss) distribution
-
-    /// This function provides a turning symmetric two-dimensional distribution.
-    /// Both coordinates are of standard normal distribution, but they are not
-    /// independent.
-    ///
-    /// \note The coordinates are the two random variables provided by
-    /// the Box-Muller method.
-    dim2::Point<double> gauss2()
-    {
-      double V1,V2,S;
-      do {
-        V1=2*real<double>()-1;
-        V2=2*real<double>()-1;
-        S=V1*V1+V2*V2;
-      } while(S>=1);
-      double W=std::sqrt(-2*std::log(S)/S);
-      return dim2::Point<double>(W*V1,W*V2);
-    }
-    /// A kind of two dimensional exponential distribution
-
-    /// This function provides a turning symmetric two-dimensional distribution.
-    /// The x-coordinate is of conditionally exponential distribution
-    /// with the condition that x is positive and y=0. If x is negative and
-    /// y=0 then, -x is of exponential distribution. The same is true for the
-    /// y-coordinate.
-    dim2::Point<double> exponential2()
-    {
-      double V1,V2,S;
-      do {
-        V1=2*real<double>()-1;
-        V2=2*real<double>()-1;
-        S=V1*V1+V2*V2;
-      } while(S>=1);
-      double W=-std::log(S)/S;
-      return dim2::Point<double>(W*V1,W*V2);
-    }
-
-    ///@}
-  };
-
-
-  extern Random rnd;
-
-}
-
-#endif
Index: lemon/smart_graph.h
===================================================================
--- lemon/smart_graph.h	(revision 1270)
+++ lemon/smart_graph.h	(revision 1336)
@@ -48,6 +48,6 @@
     };
 
-    std::vector<NodeT> nodes;
-    std::vector<ArcT> arcs;
+    std::vector<NodeT> _nodes;
+    std::vector<ArcT> _arcs;
 
   public:
@@ -60,33 +60,33 @@
   public:
 
-    SmartDigraphBase() : nodes(), arcs() { }
+    SmartDigraphBase() : _nodes(), _arcs() { }
     SmartDigraphBase(const SmartDigraphBase &_g)
-      : nodes(_g.nodes), arcs(_g.arcs) { }
+      : _nodes(_g._nodes), _arcs(_g._arcs) { }
 
     typedef True NodeNumTag;
     typedef True ArcNumTag;
 
-    int nodeNum() const { return nodes.size(); }
-    int arcNum() const { return arcs.size(); }
-
-    int maxNodeId() const { return nodes.size()-1; }
-    int maxArcId() const { return arcs.size()-1; }
+    int nodeNum() const { return _nodes.size(); }
+    int arcNum() const { return _arcs.size(); }
+
+    int maxNodeId() const { return _nodes.size()-1; }
+    int maxArcId() const { return _arcs.size()-1; }
 
     Node addNode() {
-      int n = nodes.size();
-      nodes.push_back(NodeT());
-      nodes[n].first_in = -1;
-      nodes[n].first_out = -1;
+      int n = _nodes.size();
+      _nodes.push_back(NodeT());
+      _nodes[n].first_in = -1;
+      _nodes[n].first_out = -1;
       return Node(n);
     }
 
     Arc addArc(Node u, Node v) {
-      int n = arcs.size();
-      arcs.push_back(ArcT());
-      arcs[n].source = u._id;
-      arcs[n].target = v._id;
-      arcs[n].next_out = nodes[u._id].first_out;
-      arcs[n].next_in = nodes[v._id].first_in;
-      nodes[u._id].first_out = nodes[v._id].first_in = n;
+      int n = _arcs.size();
+      _arcs.push_back(ArcT());
+      _arcs[n].source = u._id;
+      _arcs[n].target = v._id;
+      _arcs[n].next_out = _nodes[u._id].first_out;
+      _arcs[n].next_in = _nodes[v._id].first_in;
+      _nodes[u._id].first_out = _nodes[v._id].first_in = n;
 
       return Arc(n);
@@ -94,10 +94,10 @@
 
     void clear() {
-      arcs.clear();
-      nodes.clear();
-    }
-
-    Node source(Arc a) const { return Node(arcs[a._id].source); }
-    Node target(Arc a) const { return Node(arcs[a._id].target); }
+      _arcs.clear();
+      _nodes.clear();
+    }
+
+    Node source(Arc a) const { return Node(_arcs[a._id].source); }
+    Node target(Arc a) const { return Node(_arcs[a._id].target); }
 
     static int id(Node v) { return v._id; }
@@ -108,8 +108,8 @@
 
     bool valid(Node n) const {
-      return n._id >= 0 && n._id < static_cast<int>(nodes.size());
+      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());
+      return a._id >= 0 && a._id < static_cast<int>(_arcs.size());
     }
 
@@ -146,5 +146,5 @@
 
     void first(Node& node) const {
-      node._id = nodes.size() - 1;
+      node._id = _nodes.size() - 1;
     }
 
@@ -154,5 +154,5 @@
 
     void first(Arc& arc) const {
-      arc._id = arcs.size() - 1;
+      arc._id = _arcs.size() - 1;
     }
 
@@ -162,17 +162,17 @@
 
     void firstOut(Arc& arc, const Node& node) const {
-      arc._id = nodes[node._id].first_out;
+      arc._id = _nodes[node._id].first_out;
     }
 
     void nextOut(Arc& arc) const {
-      arc._id = arcs[arc._id].next_out;
+      arc._id = _arcs[arc._id].next_out;
     }
 
     void firstIn(Arc& arc, const Node& node) const {
-      arc._id = nodes[node._id].first_in;
+      arc._id = _nodes[node._id].first_in;
     }
 
     void nextIn(Arc& arc) const {
-      arc._id = arcs[arc._id].next_in;
+      arc._id = _arcs[arc._id].next_in;
     }
 
@@ -267,8 +267,8 @@
     {
       Node b = addNode();
-      nodes[b._id].first_out=nodes[n._id].first_out;
-      nodes[n._id].first_out=-1;
-      for(int i=nodes[b._id].first_out; i!=-1; i=arcs[i].next_out) {
-        arcs[i].source=b._id;
+      _nodes[b._id].first_out=_nodes[n._id].first_out;
+      _nodes[n._id].first_out=-1;
+      for(int i=_nodes[b._id].first_out; i!=-1; i=_arcs[i].next_out) {
+        _arcs[i].source=b._id;
       }
       if(connect) addArc(n,b);
@@ -292,5 +292,5 @@
     /// to build the digraph.
     /// \sa reserveArc()
-    void reserveNode(int n) { nodes.reserve(n); };
+    void reserveNode(int n) { _nodes.reserve(n); };
 
     /// Reserve memory for arcs.
@@ -302,5 +302,5 @@
     /// to build the digraph.
     /// \sa reserveNode()
-    void reserveArc(int m) { arcs.reserve(m); };
+    void reserveArc(int m) { _arcs.reserve(m); };
 
   public:
@@ -312,15 +312,15 @@
     void restoreSnapshot(const Snapshot &s)
     {
-      while(s.arc_num<arcs.size()) {
-        Arc arc = arcFromId(arcs.size()-1);
+      while(s.arc_num<_arcs.size()) {
+        Arc arc = arcFromId(_arcs.size()-1);
         Parent::notifier(Arc()).erase(arc);
-        nodes[arcs.back().source].first_out=arcs.back().next_out;
-        nodes[arcs.back().target].first_in=arcs.back().next_in;
-        arcs.pop_back();
-      }
-      while(s.node_num<nodes.size()) {
-        Node node = nodeFromId(nodes.size()-1);
+        _nodes[_arcs.back().source].first_out=_arcs.back().next_out;
+        _nodes[_arcs.back().target].first_in=_arcs.back().next_in;
+        _arcs.pop_back();
+      }
+      while(s.node_num<_nodes.size()) {
+        Node node = nodeFromId(_nodes.size()-1);
         Parent::notifier(Node()).erase(node);
-        nodes.pop_back();
+        _nodes.pop_back();
       }
     }
@@ -363,6 +363,6 @@
       ///
       Snapshot(SmartDigraph &gr) : _graph(&gr) {
-        node_num=_graph->nodes.size();
-        arc_num=_graph->arcs.size();
+        node_num=_graph->_nodes.size();
+        arc_num=_graph->_arcs.size();
       }
 
@@ -374,6 +374,6 @@
       void save(SmartDigraph &gr) {
         _graph=&gr;
-        node_num=_graph->nodes.size();
-        arc_num=_graph->arcs.size();
+        node_num=_graph->_nodes.size();
+        arc_num=_graph->_arcs.size();
       }
 
@@ -403,6 +403,6 @@
     };
 
-    std::vector<NodeT> nodes;
-    std::vector<ArcT> arcs;
+    std::vector<NodeT> _nodes;
+    std::vector<ArcT> _arcs;
 
   public:
@@ -466,5 +466,5 @@
 
     SmartGraphBase()
-      : nodes(), arcs() {}
+      : _nodes(), _arcs() {}
 
     typedef True NodeNumTag;
@@ -472,17 +472,17 @@
     typedef True ArcNumTag;
 
-    int nodeNum() const { return nodes.size(); }
-    int edgeNum() const { return arcs.size() / 2; }
-    int arcNum() const { return arcs.size(); }
-
-    int maxNodeId() const { return nodes.size()-1; }
-    int maxEdgeId() const { return arcs.size() / 2 - 1; }
-    int maxArcId() const { return arcs.size()-1; }
-
-    Node source(Arc e) const { return Node(arcs[e._id ^ 1].target); }
-    Node target(Arc e) const { return Node(arcs[e._id].target); }
-
-    Node u(Edge e) const { return Node(arcs[2 * e._id].target); }
-    Node v(Edge e) const { return Node(arcs[2 * e._id + 1].target); }
+    int nodeNum() const { return _nodes.size(); }
+    int edgeNum() const { return _arcs.size() / 2; }
+    int arcNum() const { return _arcs.size(); }
+
+    int maxNodeId() const { return _nodes.size()-1; }
+    int maxEdgeId() const { return _arcs.size() / 2 - 1; }
+    int maxArcId() const { return _arcs.size()-1; }
+
+    Node source(Arc e) const { return Node(_arcs[e._id ^ 1].target); }
+    Node target(Arc e) const { return Node(_arcs[e._id].target); }
+
+    Node u(Edge e) const { return Node(_arcs[2 * e._id].target); }
+    Node v(Edge e) const { return Node(_arcs[2 * e._id + 1].target); }
 
     static bool direction(Arc e) {
@@ -495,5 +495,5 @@
 
     void first(Node& node) const {
-      node._id = nodes.size() - 1;
+      node._id = _nodes.size() - 1;
     }
 
@@ -503,5 +503,5 @@
 
     void first(Arc& arc) const {
-      arc._id = arcs.size() - 1;
+      arc._id = _arcs.size() - 1;
     }
 
@@ -511,5 +511,5 @@
 
     void first(Edge& arc) const {
-      arc._id = arcs.size() / 2 - 1;
+      arc._id = _arcs.size() / 2 - 1;
     }
 
@@ -519,21 +519,21 @@
 
     void firstOut(Arc &arc, const Node& v) const {
-      arc._id = nodes[v._id].first_out;
+      arc._id = _nodes[v._id].first_out;
     }
     void nextOut(Arc &arc) const {
-      arc._id = arcs[arc._id].next_out;
+      arc._id = _arcs[arc._id].next_out;
     }
 
     void firstIn(Arc &arc, const Node& v) const {
-      arc._id = ((nodes[v._id].first_out) ^ 1);
+      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);
+      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;
+      int de = _nodes[v._id].first_out;
       if (de != -1) {
         arc._id = de / 2;
@@ -545,5 +545,5 @@
     }
     void nextInc(Edge &arc, bool& d) const {
-      int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
+      int de = (_arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
       if (de != -1) {
         arc._id = de / 2;
@@ -564,17 +564,17 @@
 
     bool valid(Node n) const {
-      return n._id >= 0 && n._id < static_cast<int>(nodes.size());
+      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());
+      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());
+      return e._id >= 0 && 2 * e._id < static_cast<int>(_arcs.size());
     }
 
     Node addNode() {
-      int n = nodes.size();
-      nodes.push_back(NodeT());
-      nodes[n].first_out = -1;
+      int n = _nodes.size();
+      _nodes.push_back(NodeT());
+      _nodes[n].first_out = -1;
 
       return Node(n);
@@ -582,16 +582,16 @@
 
     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);
+      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);
@@ -599,6 +599,6 @@
 
     void clear() {
-      arcs.clear();
-      nodes.clear();
+      _arcs.clear();
+      _nodes.clear();
     }
 
@@ -702,5 +702,5 @@
     /// to build the graph.
     /// \sa reserveEdge()
-    void reserveNode(int n) { nodes.reserve(n); };
+    void reserveNode(int n) { _nodes.reserve(n); };
 
     /// Reserve memory for edges.
@@ -712,5 +712,5 @@
     /// to build the graph.
     /// \sa reserveNode()
-    void reserveEdge(int m) { arcs.reserve(2 * m); };
+    void reserveEdge(int m) { _arcs.reserve(2 * m); };
 
   public:
@@ -723,12 +723,12 @@
     {
       s._graph = this;
-      s.node_num = nodes.size();
-      s.arc_num = arcs.size();
+      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;
+      while(s.arc_num<_arcs.size()) {
+        int n=_arcs.size()-1;
         Edge arc=edgeFromId(n/2);
         Parent::notifier(Edge()).erase(arc);
@@ -737,14 +737,14 @@
         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;
+        _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);
         Parent::notifier(Node()).erase(node);
-        nodes.pop_back();
+        _nodes.pop_back();
       }
     }
@@ -826,6 +826,6 @@
     };
 
-    std::vector<NodeT> nodes;
-    std::vector<ArcT> arcs;
+    std::vector<NodeT> _nodes;
+    std::vector<ArcT> _arcs;
 
     int first_red, first_blue;
@@ -916,5 +916,5 @@
 
     SmartBpGraphBase()
-      : nodes(), arcs(), first_red(-1), first_blue(-1),
+      : _nodes(), _arcs(), first_red(-1), first_blue(-1),
         max_red(-1), max_blue(-1) {}
 
@@ -923,30 +923,30 @@
     typedef True ArcNumTag;
 
-    int nodeNum() const { return nodes.size(); }
+    int nodeNum() const { return _nodes.size(); }
     int redNum() const { return max_red + 1; }
     int blueNum() const { return max_blue + 1; }
-    int edgeNum() const { return arcs.size() / 2; }
-    int arcNum() const { return arcs.size(); }
-
-    int maxNodeId() const { return nodes.size()-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 max_red; }
     int maxBlueId() const { return max_blue; }
-    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; }
+    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; }
 
     static RedNode asRedNodeUnsafe(Node n) { return RedNode(n._id); }
     static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n._id); }
 
-    Node source(Arc a) const { return Node(arcs[a._id ^ 1].target); }
-    Node target(Arc a) const { return Node(arcs[a._id].target); }
+    Node source(Arc a) const { return Node(_arcs[a._id ^ 1].target); }
+    Node target(Arc a) const { return Node(_arcs[a._id].target); }
 
     RedNode redNode(Edge e) const {
-      return RedNode(arcs[2 * e._id].target);
+      return RedNode(_arcs[2 * e._id].target);
     }
     BlueNode blueNode(Edge e) const {
-      return BlueNode(arcs[2 * e._id + 1].target);
+      return BlueNode(_arcs[2 * e._id + 1].target);
     }
 
@@ -960,5 +960,5 @@
 
     void first(Node& node) const {
-      node._id = nodes.size() - 1;
+      node._id = _nodes.size() - 1;
     }
 
@@ -972,5 +972,5 @@
 
     void next(RedNode& node) const {
-      node._id = nodes[node._id].partition_next;
+      node._id = _nodes[node._id].partition_next;
     }
 
@@ -980,9 +980,9 @@
 
     void next(BlueNode& node) const {
-      node._id = nodes[node._id].partition_next;
+      node._id = _nodes[node._id].partition_next;
     }
 
     void first(Arc& arc) const {
-      arc._id = arcs.size() - 1;
+      arc._id = _arcs.size() - 1;
     }
 
@@ -992,5 +992,5 @@
 
     void first(Edge& arc) const {
-      arc._id = arcs.size() / 2 - 1;
+      arc._id = _arcs.size() / 2 - 1;
     }
 
@@ -1000,21 +1000,21 @@
 
     void firstOut(Arc &arc, const Node& v) const {
-      arc._id = nodes[v._id].first_out;
+      arc._id = _nodes[v._id].first_out;
     }
     void nextOut(Arc &arc) const {
-      arc._id = arcs[arc._id].next_out;
+      arc._id = _arcs[arc._id].next_out;
     }
 
     void firstIn(Arc &arc, const Node& v) const {
-      arc._id = ((nodes[v._id].first_out) ^ 1);
+      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);
+      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;
+      int de = _nodes[v._id].first_out;
       if (de != -1) {
         arc._id = de / 2;
@@ -1026,5 +1026,5 @@
     }
     void nextInc(Edge &arc, bool& d) const {
-      int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
+      int de = (_arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
       if (de != -1) {
         arc._id = de / 2;
@@ -1037,6 +1037,6 @@
 
     static int id(Node v) { return v._id; }
-    int id(RedNode v) const { return nodes[v._id].partition_index; }
-    int id(BlueNode v) const { return nodes[v._id].partition_index; }
+    int id(RedNode v) const { return _nodes[v._id].partition_index; }
+    int id(BlueNode v) const { return _nodes[v._id].partition_index; }
     static int id(Arc e) { return e._id; }
     static int id(Edge e) { return e._id; }
@@ -1047,20 +1047,20 @@
 
     bool valid(Node n) const {
-      return n._id >= 0 && n._id < static_cast<int>(nodes.size());
+      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());
+      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());
+      return e._id >= 0 && 2 * e._id < static_cast<int>(_arcs.size());
     }
 
     RedNode addRedNode() {
-      int n = nodes.size();
-      nodes.push_back(NodeT());
-      nodes[n].first_out = -1;
-      nodes[n].red = true;
-      nodes[n].partition_index = ++max_red;
-      nodes[n].partition_next = first_red;
+      int n = _nodes.size();
+      _nodes.push_back(NodeT());
+      _nodes[n].first_out = -1;
+      _nodes[n].red = true;
+      _nodes[n].partition_index = ++max_red;
+      _nodes[n].partition_next = first_red;
       first_red = n;
 
@@ -1069,10 +1069,10 @@
 
     BlueNode addBlueNode() {
-      int n = nodes.size();
-      nodes.push_back(NodeT());
-      nodes[n].first_out = -1;
-      nodes[n].red = false;
-      nodes[n].partition_index = ++max_blue;
-      nodes[n].partition_next = first_blue;
+      int n = _nodes.size();
+      _nodes.push_back(NodeT());
+      _nodes[n].first_out = -1;
+      _nodes[n].red = false;
+      _nodes[n].partition_index = ++max_blue;
+      _nodes[n].partition_next = first_blue;
       first_blue = n;
 
@@ -1081,16 +1081,16 @@
 
     Edge addEdge(RedNode u, BlueNode 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);
+      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);
@@ -1098,6 +1098,6 @@
 
     void clear() {
-      arcs.clear();
-      nodes.clear();
+      _arcs.clear();
+      _nodes.clear();
       first_red = -1;
       first_blue = -1;
@@ -1214,5 +1214,5 @@
     /// to build the graph.
     /// \sa reserveEdge()
-    void reserveNode(int n) { nodes.reserve(n); };
+    void reserveNode(int n) { _nodes.reserve(n); };
 
     /// Reserve memory for edges.
@@ -1224,5 +1224,5 @@
     /// to build the graph.
     /// \sa reserveNode()
-    void reserveEdge(int m) { arcs.reserve(2 * m); };
+    void reserveEdge(int m) { _arcs.reserve(2 * m); };
 
   public:
@@ -1235,12 +1235,12 @@
     {
       s._graph = this;
-      s.node_num = nodes.size();
-      s.arc_num = arcs.size();
+      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;
+      while(s.arc_num<_arcs.size()) {
+        int n=_arcs.size()-1;
         Edge arc=edgeFromId(n/2);
         Parent::notifier(Edge()).erase(arc);
@@ -1249,16 +1249,16 @@
         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;
+        _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;
+          first_red = _nodes[n].partition_next;
           if (first_red != -1) {
-            max_red = nodes[first_red].partition_index;
+            max_red = _nodes[first_red].partition_index;
           } else {
             max_red = -1;
@@ -1266,7 +1266,7 @@
           Parent::notifier(RedNode()).erase(asRedNodeUnsafe(node));
         } else {
-          first_blue = nodes[n].partition_next;
+          first_blue = _nodes[n].partition_next;
           if (first_blue != -1) {
-            max_blue = nodes[first_blue].partition_index;
+            max_blue = _nodes[first_blue].partition_index;
           } else {
             max_blue = -1;
@@ -1275,5 +1275,5 @@
         }
         Parent::notifier(Node()).erase(node);
-        nodes.pop_back();
+        _nodes.pop_back();
       }
     }
Index: lemon/soplex.cc
===================================================================
--- lemon/soplex.cc	(revision 1270)
+++ lemon/soplex.cc	(revision 1336)
@@ -38,6 +38,6 @@
 
   SoplexLp::SoplexLp(const SoplexLp& lp) {
-    rows = lp.rows;
-    cols = lp.cols;
+    _rows = lp._rows;
+    _cols = lp._cols;
 
     soplex = new soplex::SoPlex;
@@ -123,10 +123,10 @@
 
   void SoplexLp::_eraseColId(int i) {
-    cols.eraseIndex(i);
-    cols.relocateIndex(i, cols.maxIndex());
+    _cols.eraseIndex(i);
+    _cols.relocateIndex(i, _cols.maxIndex());
   }
   void SoplexLp::_eraseRowId(int i) {
-    rows.eraseIndex(i);
-    rows.relocateIndex(i, rows.maxIndex());
+    _rows.eraseIndex(i);
+    _rows.relocateIndex(i, _rows.maxIndex());
   }
 
@@ -433,6 +433,6 @@
     _row_names.clear();
     _row_names_ref.clear();
-    cols.clear();
-    rows.clear();
+    _cols.clear();
+    _rows.clear();
     _clear_temporals();
   }
Index: lemon/static_graph.h
===================================================================
--- lemon/static_graph.h	(revision 1328)
+++ lemon/static_graph.h	(revision 1371)
@@ -30,4 +30,5 @@
 
   class StaticDigraphBase {
+
   public:
 
@@ -297,4 +298,12 @@
   /// \sa concepts::Digraph
   class StaticDigraph : public ExtendedStaticDigraphBase {
+
+  private:
+    /// Graphs are \e not copy constructible. Use DigraphCopy instead.
+    StaticDigraph(const StaticDigraph &) : ExtendedStaticDigraphBase() {};
+    /// \brief Assignment of a graph to another one is \e not allowed.
+    /// Use DigraphCopy instead.
+    void operator=(const StaticDigraph&) {}
+
   public:
 
Index: lemon/vf2.h
===================================================================
--- lemon/vf2.h	(revision 1413)
+++ lemon/vf2.h	(revision 1413)
@@ -0,0 +1,663 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2015-2017
+ * EMAXA Kutato-fejleszto Kft. (EMAXA Research Ltd.)
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_VF2_H
+#define LEMON_VF2_H
+
+///\ingroup graph_properties
+///\file
+///\brief VF2 algorithm \cite cordella2004sub.
+
+#include <lemon/core.h>
+#include <lemon/concepts/graph.h>
+#include <lemon/bfs.h>
+#include <lemon/bits/vf2_internals.h>
+
+#include <vector>
+
+namespace lemon {
+  namespace bits {
+    namespace vf2 {
+
+      class AlwaysEq {
+      public:
+        template<class T1, class T2>
+        bool operator()(T1&, T2&) const {
+          return true;
+        }
+      };
+
+      template<class M1, class M2>
+      class MapEq{
+        const M1 &_m1;
+        const M2 &_m2;
+      public:
+        MapEq(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) { }
+        bool operator()(typename M1::Key k1, typename M2::Key k2) const {
+          return _m1[k1] == _m2[k2];
+        }
+      };
+
+      template <class G>
+      class BfsLeaveOrder : public BfsVisitor<G> {
+        int i;
+        const G &_g;
+        std::vector<typename G::Node> &_order;
+      public:
+        BfsLeaveOrder(const G &g, std::vector<typename G::Node> &order)
+          : i(0), _g(g), _order(order){
+        }
+        void process(const typename G::Node &node) {
+          _order[i++]=node;
+        }
+      };
+    }
+  }
+
+
+  ///%VF2 algorithm class.
+
+  ///\ingroup graph_isomorphism This class provides an efficient
+  ///implementation of the %VF2 algorithm \cite cordella2004sub
+  ///for variants of the (Sub)graph Isomorphism problem.
+  ///
+  ///There is also a \ref vf2() "function-type interface" called \ref vf2()
+  ///for the %VF2 algorithm, which is probably more convenient in most
+  ///use cases.
+  ///
+  ///\tparam G1 The type of the graph to be embedded.
+  ///The default type is \ref ListGraph.
+  ///\tparam G2 The type of the graph g1 will be embedded into.
+  ///The default type is \ref ListGraph.
+  ///\tparam M The type of the NodeMap storing the mapping.
+  ///By default, it is G1::NodeMap<G2::Node>
+  ///\tparam NEQ A bool-valued binary functor determinining whether a node is
+  ///mappable to another. By default, it is an always-true operator.
+  ///
+  ///\sa vf2()
+#ifdef DOXYGEN
+  template<class G1, class G2, class M, class NEQ >
+#else
+  template<class G1 = ListGraph,
+           class G2 = ListGraph,
+           class M = typename G1::template NodeMap<G2::Node>,
+           class NEQ = bits::vf2::AlwaysEq >
+#endif
+  class Vf2 {
+    //The graph to be embedded
+    const G1 &_g1;
+
+    //The graph into which g1 is to be embedded
+    const G2 &_g2;
+
+    //Functor with bool operator()(G1::Node,G2::Node), which returns 1
+    //if and only if the two nodes are equivalent
+    NEQ _nEq;
+
+    //Current depth in the search tree
+    int _depth;
+
+    //The current mapping. _mapping[v1]=v2 iff v1 has been mapped to v2,
+    //where v1 is a node of G1 and v2 is a node of G2
+    M &_mapping;
+
+    //_order[i] is the node of g1 for which a pair is searched if depth=i
+    std::vector<typename G1::Node> _order;
+ 
+    //_conn[v2] = number of covered neighbours of v2
+    typename G2::template NodeMap<int> _conn;
+
+    //_currEdgeIts[i] is the last used edge iterator in the i-th
+    //depth to find a pair for node _order[i]
+    std::vector<typename G2::IncEdgeIt> _currEdgeIts;
+
+    //lookup tables for cutting the searchtree
+    typename G1::template NodeMap<int> _rNew1t, _rInOut1t;
+
+    MappingType _mapping_type;
+
+    bool _deallocMappingAfterUse;
+
+    //cut the search tree
+    template<MappingType MT>
+    bool cut(const typename G1::Node n1,const typename G2::Node n2) const {
+      int rNew2=0,rInOut2=0;
+      for(typename G2::IncEdgeIt e2(_g2,n2); e2!=INVALID; ++e2) {
+        const typename G2::Node currNode=_g2.oppositeNode(n2,e2);
+        if(_conn[currNode]>0)
+          ++rInOut2;
+        else if(MT!=SUBGRAPH&&_conn[currNode]==0)
+          ++rNew2;
+      }
+      switch(MT) {
+      case INDUCED:
+        return _rInOut1t[n1]<=rInOut2&&_rNew1t[n1]<=rNew2;
+      case SUBGRAPH:
+        return _rInOut1t[n1]<=rInOut2;
+      case ISOMORPH:
+        return _rInOut1t[n1]==rInOut2&&_rNew1t[n1]==rNew2;
+      default:
+        return false;
+      }
+    }
+
+    template<MappingType MT>
+    bool feas(const typename G1::Node n1,const typename G2::Node n2) {
+      if(!_nEq(n1,n2))
+        return 0;
+
+      for(typename G1::IncEdgeIt e1(_g1,n1); e1!=INVALID; ++e1) {
+        const typename G1::Node& currNode=_g1.oppositeNode(n1,e1);
+        if(_mapping[currNode]!=INVALID)
+          --_conn[_mapping[currNode]];
+      }
+      bool isIso=1;
+      for(typename G2::IncEdgeIt e2(_g2,n2); e2!=INVALID; ++e2) {
+        int& connCurrNode = _conn[_g2.oppositeNode(n2,e2)];
+        if(connCurrNode<-1)
+          ++connCurrNode;
+        else if(MT!=SUBGRAPH&&connCurrNode==-1) {
+          isIso=0;
+          break;
+        }
+      }
+
+      for(typename G1::IncEdgeIt e1(_g1,n1); e1!=INVALID; ++e1) {
+        const typename G2::Node& currNodePair=_mapping[_g1.oppositeNode(n1,e1)];
+        int& connCurrNodePair=_conn[currNodePair];
+        if(currNodePair!=INVALID&&connCurrNodePair!=-1) {
+          switch(MT) {
+          case INDUCED:
+          case ISOMORPH:
+            isIso=0;
+            break;
+          case SUBGRAPH:
+            if(connCurrNodePair<-1)
+              isIso=0;
+            break;
+          }
+          connCurrNodePair=-1;
+        }
+      }
+      return isIso&&cut<MT>(n1,n2);
+    }
+
+    void addPair(const typename G1::Node n1,const typename G2::Node n2) {
+      _conn[n2]=-1;
+      _mapping.set(n1,n2);
+      for(typename G2::IncEdgeIt e2(_g2,n2); e2!=INVALID; ++e2) {
+        int& currConn = _conn[_g2.oppositeNode(n2,e2)];
+        if(currConn!=-1)
+          ++currConn;
+      }
+    }
+
+    void subPair(const typename G1::Node n1,const typename G2::Node n2) {
+      _conn[n2]=0;
+      _mapping.set(n1,INVALID);
+      for(typename G2::IncEdgeIt e2(_g2,n2); e2!=INVALID; ++e2) {
+        int& currConn = _conn[_g2.oppositeNode(n2,e2)];
+        if(currConn>0)
+          --currConn;
+        else if(currConn==-1)
+          ++_conn[n2];
+      }
+    }
+
+    void initOrder() {
+      //determine the order in which we will find pairs for the nodes of g1
+      //BFS order is more efficient in practice than DFS
+      bits::vf2::BfsLeaveOrder<G1> v(_g1,_order);
+      BfsVisit<G1,bits::vf2::BfsLeaveOrder<G1> > bfs(_g1, v);
+      bfs.run();
+    }
+
+    template<MappingType MT>
+    bool extMatch() {
+      while(_depth>=0) {
+        if(_depth==static_cast<int>(_order.size())) {
+          //all nodes of g1 are mapped to nodes of g2
+          --_depth;
+          return true;
+        }
+        typename G1::Node& nodeOfDepth = _order[_depth];
+        const typename G2::Node& pairOfNodeOfDepth = _mapping[nodeOfDepth];
+        typename G2::IncEdgeIt &edgeItOfDepth = _currEdgeIts[_depth];
+        //the node of g2 whose neighbours are the candidates for
+        //the pair of nodeOfDepth
+        typename G2::Node currPNode;
+        if(edgeItOfDepth==INVALID) {
+          typename G1::IncEdgeIt fstMatchedE(_g1,nodeOfDepth);
+          //if pairOfNodeOfDepth!=INVALID, we don't use fstMatchedE
+          if(pairOfNodeOfDepth==INVALID) {
+            for(; fstMatchedE!=INVALID &&
+                  _mapping[_g1.oppositeNode(nodeOfDepth,
+                                            fstMatchedE)]==INVALID;
+                ++fstMatchedE) ; //find fstMatchedE
+          }
+          if(fstMatchedE==INVALID||pairOfNodeOfDepth!=INVALID) {
+            //We found no covered neighbours, this means that
+            //the graph is not connected (or _depth==0). Each
+            //uncovered (and there are some other properties due
+            //to the spec. problem types) node of g2 is
+            //candidate. We can read the iterator of the last
+            //tried node from the match if it is not the first
+            //try (match[nodeOfDepth]!=INVALID)
+            typename G2::NodeIt n2(_g2);
+            //if it's not the first try
+            if(pairOfNodeOfDepth!=INVALID) {
+              n2=++typename G2::NodeIt(_g2,pairOfNodeOfDepth);
+              subPair(nodeOfDepth,pairOfNodeOfDepth);
+            }
+            for(; n2!=INVALID; ++n2)
+              if(MT!=SUBGRAPH) {
+                if(_conn[n2]==0&&feas<MT>(nodeOfDepth,n2))
+                  break;
+              }
+              else if(_conn[n2]>=0&&feas<MT>(nodeOfDepth,n2))
+                break;
+            // n2 is the next candidate
+            if(n2!=INVALID){
+              addPair(nodeOfDepth,n2);
+              ++_depth;
+            }
+            else // there are no more candidates
+              --_depth;
+            continue;
+          }
+          else {
+            currPNode=_mapping[_g1.oppositeNode(nodeOfDepth,
+                                                fstMatchedE)];
+            edgeItOfDepth=typename G2::IncEdgeIt(_g2,currPNode);
+          }
+        }
+        else {
+          currPNode=_g2.oppositeNode(pairOfNodeOfDepth,
+                                     edgeItOfDepth);
+          subPair(nodeOfDepth,pairOfNodeOfDepth);
+          ++edgeItOfDepth;
+        }
+        for(; edgeItOfDepth!=INVALID; ++edgeItOfDepth) {
+          const typename G2::Node currNode =
+            _g2.oppositeNode(currPNode, edgeItOfDepth);
+          if(_conn[currNode]>0&&feas<MT>(nodeOfDepth,currNode)) {
+            addPair(nodeOfDepth,currNode);
+            break;
+          }
+        }
+        edgeItOfDepth==INVALID?--_depth:++_depth;
+      }
+      return false;
+    }
+
+    //calculate the lookup table for cutting the search tree
+    void initRNew1tRInOut1t() {
+      typename G1::template NodeMap<int> tmp(_g1,0);
+      for(unsigned int i=0; i<_order.size(); ++i) {
+        const typename G1::Node& orderI = _order[i];
+        tmp[orderI]=-1;
+        for(typename G1::IncEdgeIt e1(_g1,orderI); e1!=INVALID; ++e1) {
+          const typename G1::Node currNode=_g1.oppositeNode(orderI,e1);
+          if(tmp[currNode]>0)
+            ++_rInOut1t[orderI];
+          else if(tmp[currNode]==0)
+            ++_rNew1t[orderI];
+        }
+        for(typename G1::IncEdgeIt e1(_g1,orderI); e1!=INVALID; ++e1) {
+          const typename G1::Node currNode=_g1.oppositeNode(orderI,e1);
+          if(tmp[currNode]!=-1)
+            ++tmp[currNode];
+        }
+      }
+    }
+  public:
+    ///Constructor
+
+    ///Constructor
+
+    ///\param g1 The graph to be embedded into \e g2.
+    ///\param g2 The graph \e g1 will be embedded into.
+    ///\param m \ref concepts::ReadWriteMap "read-write" NodeMap
+    ///storing the found mapping.
+    ///\param neq A bool-valued binary functor determining whether a node is
+    ///mappable to another. By default it is an always true operator.
+    Vf2(const G1 &g1, const G2 &g2, M &m, const NEQ &neq = NEQ() ) :
+      _g1(g1), _g2(g2), _nEq(neq), _depth(0), _mapping(m),
+      _order(countNodes(g1)), _conn(g2,0),
+      _currEdgeIts(countNodes(g1),INVALID), _rNew1t(g1,0), _rInOut1t(g1,0),
+      _mapping_type(SUBGRAPH), _deallocMappingAfterUse(0)
+    {
+      initOrder();
+      initRNew1tRInOut1t();
+      for(typename G1::NodeIt n(g1);n!=INVALID;++n)
+        m[n]=INVALID;
+    }
+
+    ///Destructor
+
+    ///Destructor.
+    ///
+
+    ~Vf2(){
+      if(_deallocMappingAfterUse)
+        delete &_mapping;
+    }
+
+    ///Returns the current mapping type
+
+    ///Returns the current mapping type
+    ///
+    MappingType mappingType() const {
+      return _mapping_type;
+    }
+    ///Sets mapping type
+
+    ///Sets mapping type.
+    ///
+    ///The mapping type is set to \ref SUBGRAPH by default.
+    ///
+    ///\sa See \ref MappingType for the possible values.
+    void mappingType(MappingType m_type) {
+      _mapping_type = m_type;
+    }
+
+    ///Finds a mapping
+
+    ///It finds a mapping from g1 into g2 according to the mapping
+    ///type set by \ref mappingType(MappingType) "mappingType()".
+    ///
+    ///By subsequent calls, it returns all possible mappings one-by-one.
+    ///
+    ///\retval true if a mapping is found.
+    ///\retval false if there is no (more) mapping.
+    bool find() {
+      switch(_mapping_type) {
+      case SUBGRAPH:
+        return extMatch<SUBGRAPH>();
+      case INDUCED:
+        return extMatch<INDUCED>();
+      case ISOMORPH:
+        return extMatch<ISOMORPH>();
+      default:
+        return false;
+      }
+    }
+  };
+
+  template<class G1, class G2>
+  class Vf2WizardBase {
+  protected:
+    typedef G1 Graph1;
+    typedef G2 Graph2;
+
+    const G1 &_g1;
+    const G2 &_g2;
+
+    MappingType _mapping_type;
+
+    typedef typename G1::template NodeMap<typename G2::Node> Mapping;
+    bool _local_mapping;
+    void *_mapping;
+    void createMapping() {
+      _mapping = new Mapping(_g1);
+    }
+
+    void *myVf2; //used in Vf2Wizard::find
+
+
+    typedef bits::vf2::AlwaysEq NodeEq;
+    NodeEq _node_eq;
+
+    Vf2WizardBase(const G1 &g1,const G2 &g2)
+      : _g1(g1), _g2(g2), _mapping_type(SUBGRAPH), _local_mapping(true) { }
+  };
+
+
+  /// Auxiliary class for the function-type interface of %VF2 algorithm.
+  ///
+  /// This auxiliary class implements the named parameters of
+  /// \ref vf2() "function-type interface" of \ref Vf2 algorithm.
+  ///
+  /// \warning This class is not to be used directly.
+  ///
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm.
+  template<class TR>
+  class Vf2Wizard : public TR {
+    typedef TR Base;
+    typedef typename TR::Graph1 Graph1;
+    typedef typename TR::Graph2 Graph2;
+
+    typedef typename TR::Mapping Mapping;
+    typedef typename TR::NodeEq NodeEq;
+
+    using TR::_g1;
+    using TR::_g2;
+    using TR::_mapping_type;
+    using TR::_mapping;
+    using TR::_node_eq;
+
+  public:
+    ///Constructor
+    Vf2Wizard(const Graph1 &g1,const Graph2 &g2) : Base(g1,g2) {}
+
+    ///Copy constructor
+    Vf2Wizard(const Base &b) : Base(b) {}
+
+    ///Copy constructor
+    Vf2Wizard(const Vf2Wizard &b) : Base(b) {}
+
+
+    template<class T>
+    struct SetMappingBase : public Base{
+      typedef T Mapping;
+      SetMappingBase(const Base &b) : Base(b) {}
+    };
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the mapping.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that stores the found embedding.
+    template<class T>
+    Vf2Wizard< SetMappingBase<T> > mapping(const T &t) {
+      Base::_mapping=reinterpret_cast<void*>(const_cast<T*>(&t));
+      Base::_local_mapping = false;
+      return Vf2Wizard<SetMappingBase<T> >(*this);
+    }
+
+    template<class NE>
+    struct SetNodeEqBase : public Base {
+      typedef NE NodeEq;
+      NodeEq _node_eq;
+      SetNodeEqBase(const Base &b, const NE &node_eq)
+        : Base(b), _node_eq(node_eq){
+      }
+    };
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the node equivalence relation.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the equivalence relation between the nodes.
+    ///
+    ///\param node_eq A bool-valued binary functor determinining
+    ///whether a node is mappable to another. By default it is an
+    ///always true operator.
+    template<class T>
+    Vf2Wizard< SetNodeEqBase<T> > nodeEq(const T &node_eq) {
+      return Vf2Wizard<SetNodeEqBase<T> >(SetNodeEqBase<T>(*this,node_eq));
+    }
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the node labels.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the node labels defining equivalence relation between them.
+    ///
+    ///\param m1 An arbitrary \ref concepts::ReadMap "readable node map"
+    ///of g1.
+    ///\param m2 An arbitrary \ref concepts::ReadMap "readable node map"
+    ///of g2.
+    ///
+    ///The value type of these maps must be equal comparable.
+    template<class M1, class M2>
+    Vf2Wizard< SetNodeEqBase<bits::vf2::MapEq<M1,M2> > >
+    nodeLabels(const M1 &m1,const M2 &m2){
+      return nodeEq(bits::vf2::MapEq<M1,M2>(m1,m2));
+    }
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the mapping type.
+    ///
+    ///\ref named-templ-param "Named parameter" for setting
+    ///the mapping type.
+    ///
+    ///The mapping type is set to \ref SUBGRAPH by default.
+    ///
+    ///\sa See \ref MappingType for the possible values.
+    Vf2Wizard<Base> &mappingType(MappingType m_type) {
+      _mapping_type = m_type;
+      return *this;
+    }
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the mapping type to \ref INDUCED.
+    ///
+    ///\ref named-templ-param "Named parameter" for setting
+    ///the mapping type to \ref INDUCED.
+    Vf2Wizard<Base> &induced() {
+      _mapping_type = INDUCED;
+      return *this;
+    }
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the mapping type to \ref ISOMORPH.
+    ///
+    ///\ref named-templ-param "Named parameter" for setting
+    ///the mapping type to \ref ISOMORPH.
+    Vf2Wizard<Base> &iso() {
+      _mapping_type = ISOMORPH;
+      return *this;
+    }
+
+
+    ///Runs VF2 algorithm.
+
+    ///This method runs VF2 algorithm.
+    ///
+    ///\retval true if a mapping is found.
+    ///\retval false if there is no mapping.
+    bool run(){
+      if(Base::_local_mapping)
+        Base::createMapping();
+
+      Vf2<Graph1, Graph2, Mapping, NodeEq >
+        alg(_g1, _g2, *reinterpret_cast<Mapping*>(_mapping), _node_eq);
+
+      alg.mappingType(_mapping_type);
+
+      bool ret = alg.find();
+
+      if(Base::_local_mapping)
+        delete reinterpret_cast<Mapping*>(_mapping);
+
+      return ret;
+    }
+
+    ///Get a pointer to the generated Vf2 object.
+
+    ///Gives a pointer to the generated Vf2 object.
+    ///
+    ///\return Pointer to the generated Vf2 object.
+    ///\warning Don't forget to delete the referred Vf2 object after use.
+    Vf2<Graph1, Graph2, Mapping, NodeEq >* getPtrToVf2Object() {
+      if(Base::_local_mapping)
+        Base::createMapping();
+      Vf2<Graph1, Graph2, Mapping, NodeEq >* ptr =
+        new Vf2<Graph1, Graph2, Mapping, NodeEq>
+        (_g1, _g2, *reinterpret_cast<Mapping*>(_mapping), _node_eq);
+      ptr->mappingType(_mapping_type);
+      if(Base::_local_mapping)
+        ptr->_deallocMappingAfterUse = true;
+      return ptr;
+    }
+
+    ///Counts the number of mappings.
+
+    ///This method counts the number of mappings.
+    ///
+    /// \return The number of mappings.
+    int count() {
+      if(Base::_local_mapping)
+        Base::createMapping();
+
+      Vf2<Graph1, Graph2, Mapping, NodeEq>
+        alg(_g1, _g2, *reinterpret_cast<Mapping*>(_mapping), _node_eq);
+      if(Base::_local_mapping)
+        alg._deallocMappingAfterUse = true;
+      alg.mappingType(_mapping_type);
+
+      int ret = 0;
+      while(alg.find())
+        ++ret;
+
+      return ret;
+    }
+  };
+
+  ///Function-type interface for VF2 algorithm.
+
+  /// \ingroup graph_isomorphism
+  ///Function-type interface for VF2 algorithm \cite cordella2004sub.
+  ///
+  ///This function has several \ref named-func-param "named parameters"
+  ///declared as the members of class \ref Vf2Wizard.
+  ///The following examples show how to use these parameters.
+  ///\code
+  ///  // Find an embedding of graph g1 into graph g2
+  ///  ListGraph::NodeMap<ListGraph::Node> m(g);
+  ///  vf2(g1,g2).mapping(m).run();
+  ///
+  ///  // Check whether graphs g1 and g2 are isomorphic
+  ///  bool is_iso = vf2(g1,g2).iso().run();
+  ///
+  ///  // Count the number of isomorphisms
+  ///  int num_isos = vf2(g1,g2).iso().count();
+  ///
+  ///  // Iterate through all the induced subgraph mappings of graph g1 into g2
+  ///  auto* myVf2 = vf2(g1,g2).mapping(m).nodeLabels(c1,c2)
+  ///  .induced().getPtrToVf2Object();
+  ///  while(myVf2->find()){
+  ///    //process the current mapping m
+  ///  }
+  ///  delete myVf22;
+  ///\endcode
+  ///\warning Don't forget to put the \ref Vf2Wizard::run() "run()",
+  ///\ref Vf2Wizard::count() "count()" or
+  ///the \ref Vf2Wizard::getPtrToVf2Object() "getPtrToVf2Object()"
+  ///to the end of the expression.
+  ///\sa Vf2Wizard
+  ///\sa Vf2
+  template<class G1, class G2>
+  Vf2Wizard<Vf2WizardBase<G1,G2> > vf2(const G1 &g1, const G2 &g2) {
+    return Vf2Wizard<Vf2WizardBase<G1,G2> >(g1,g2);
+  }
+
+}
+
+#endif
Index: lemon/vf2pp.h
===================================================================
--- lemon/vf2pp.h	(revision 1414)
+++ lemon/vf2pp.h	(revision 1414)
@@ -0,0 +1,860 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2015-2017
+ * EMAXA Kutato-fejleszto Kft. (EMAXA Research Ltd.)
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_VF2PP_H
+#define LEMON_VF2PP_H
+
+///\ingroup graph_properties
+///\file
+///\brief VF2 Plus Plus algorithm.
+
+#include <lemon/core.h>
+#include <lemon/concepts/graph.h>
+#include <lemon/bits/vf2_internals.h>
+
+#include <vector>
+#include <algorithm>
+#include <utility>
+
+namespace lemon {
+
+  ///%VF2 Plus Plus algorithm class \cite VF2PP.
+
+  ///\ingroup graph_isomorphism This class provides an efficient
+  ///implementation of the %VF2 Plus Plus algorithm \cite VF2PP
+  ///for variants of the (Sub)graph Isomorphism problem.
+  ///
+  ///There is also a \ref vf2pp() "function-type interface" called
+  ///\ref vf2pp() for the %VF2 Plus Plus algorithm, which is probably
+  ///more convenient in most use cases.
+  ///
+  ///\tparam G1 The type of the graph to be embedded.
+  ///The default type is \ref ListGraph.
+  ///\tparam G2 The type of the graph g1 will be embedded into.
+  ///The default type is \ref ListGraph.
+  ///\tparam M The type of the NodeMap storing the mapping.
+  ///By default, it is G1::NodeMap<G2::Node>
+  ///\tparam M1 The type of the NodeMap storing the integer node labels of G1.
+  ///The labels must be the numbers {0,1,2,..,K-1}, where K is the number of
+  ///different labels. By default, it is G1::NodeMap<int>.
+  ///\tparam M2 The type of the NodeMap storing the integer node labels of G2.
+  ///The labels must be the numbers {0,1,2,..,K-1}, where K is the number of
+  ///different labels. By default, it is G2::NodeMap<int>.
+  ///
+  ///\sa vf2pp()
+#ifdef DOXYGEN
+  template<class G1, class G2, class M, class M1, class M2 >
+#else
+  template<class G1 = ListGraph,
+           class G2 = ListGraph,
+           class M = typename G1::template NodeMap<G2::Node>,
+           class M1 = typename G1::template NodeMap<int>,
+           class M2 = typename G2::template NodeMap<int> >
+#endif
+  class Vf2pp {
+    //The graph to be embedded
+    const G1 &_g1;
+
+    //The graph into which g1 is to be embedded
+    const G2 &_g2;
+
+    //Current depth in the search tree
+    int _depth;
+
+    //The current mapping. _mapping[v1]=v2 iff v1 has been mapped to v2,
+    //where v1 is a node of G1 and v2 is a node of G2
+    M &_mapping;
+
+    //_order[i] is a node of g1 for which a pair is searched if depth=i
+    std::vector<typename G1::Node> _order;
+
+    //_conn[v2] = number of covered neighbours of v2
+    typename G2::template NodeMap<int> _conn;
+
+    //_currEdgeIts[i] is the last used edge iterator in the i-th
+    //depth to find a pair for node _order[i]
+    std::vector<typename G2::IncEdgeIt> _currEdgeIts;
+ 
+    //_rNewLabels1[v] is a pair of form
+    //(label; num. of uncov. nodes with such label and no covered neighbours)
+    typename G1::template NodeMap<std::vector<std::pair<int,int> > >
+    _rNewLabels1;
+
+    //_rInOutLabels1[v] is the number of covered neighbours of v for each label
+    //in form (label,number of such labels)
+    typename G1::template NodeMap<std::vector<std::pair<int,int> > >
+    _rInOutLabels1;
+
+    //_intLabels1[v]==i means that node v has label i in _g1
+    //(i is in {0,1,2,..,K-1}, where K is the number of diff. labels)
+    M1 &_intLabels1;
+
+    //_intLabels2[v]==i means that node v has label i in _g2
+    //(i is in {0,1,2,..,K-1}, where K is the number of diff. labels)
+    M2 &_intLabels2;
+
+    //largest label
+    const int _maxLabel;
+
+    //lookup tables for manipulating with label class cardinalities
+    //(after use they have to be reset to 0..0)
+    std::vector<int> _labelTmp1,_labelTmp2;
+
+    MappingType _mapping_type;
+
+    //indicates whether the mapping or the labels must be deleted in the destructor
+    bool _deallocMappingAfterUse,_deallocLabelsAfterUse;
+
+
+    //improved cutting function
+    template<MappingType MT>
+    bool cutByLabels(const typename G1::Node n1,const typename G2::Node n2) {
+      for(typename G2::IncEdgeIt e2(_g2,n2); e2!=INVALID; ++e2) {
+        const typename G2::Node currNode=_g2.oppositeNode(n2,e2);
+        if(_conn[currNode]>0)
+          --_labelTmp1[_intLabels2[currNode]];
+        else if(MT!=SUBGRAPH&&_conn[currNode]==0)
+          --_labelTmp2[_intLabels2[currNode]];
+      }
+
+      bool ret=1;
+      if(ret) {
+        for(unsigned int i = 0; i < _rInOutLabels1[n1].size(); ++i)
+          _labelTmp1[_rInOutLabels1[n1][i].first]+=_rInOutLabels1[n1][i].second;
+
+        if(MT!=SUBGRAPH)
+          for(unsigned int i = 0; i < _rNewLabels1[n1].size(); ++i)
+            _labelTmp2[_rNewLabels1[n1][i].first]+=_rNewLabels1[n1][i].second;
+
+        switch(MT) {
+        case INDUCED:
+          for(unsigned int i = 0; i < _rInOutLabels1[n1].size(); ++i)
+            if(_labelTmp1[_rInOutLabels1[n1][i].first]>0) {
+              ret=0;
+              break;
+            }
+          if(ret)
+            for(unsigned int i = 0; i < _rNewLabels1[n1].size(); ++i)
+              if(_labelTmp2[_rNewLabels1[n1][i].first]>0) {
+                ret=0;
+                break;
+              }
+          break;
+        case SUBGRAPH:
+          for(unsigned int i = 0; i < _rInOutLabels1[n1].size(); ++i)
+            if(_labelTmp1[_rInOutLabels1[n1][i].first]>0) {
+              ret=0;
+              break;
+            }
+          break;
+        case ISOMORPH:
+          for(unsigned int i = 0; i < _rInOutLabels1[n1].size(); ++i)
+            if(_labelTmp1[_rInOutLabels1[n1][i].first]!=0) {
+              ret=0;
+              break;
+            }
+          if(ret)
+            for(unsigned int i = 0; i < _rNewLabels1[n1].size(); ++i)
+              if(_labelTmp2[_rNewLabels1[n1][i].first]!=0) {
+                ret=0;
+                break;
+              }
+          break;
+        default:
+          return false;
+        }
+        for(unsigned int i = 0; i < _rInOutLabels1[n1].size(); ++i)
+          _labelTmp1[_rInOutLabels1[n1][i].first]=0;
+
+        if(MT!=SUBGRAPH)
+          for(unsigned int i = 0; i < _rNewLabels1[n1].size(); ++i)
+            _labelTmp2[_rNewLabels1[n1][i].first]=0;
+      }
+
+      for(typename G2::IncEdgeIt e2(_g2,n2); e2!=INVALID; ++e2) {
+        const typename G2::Node currNode=_g2.oppositeNode(n2,e2);
+        _labelTmp1[_intLabels2[currNode]]=0;
+        if(MT!=SUBGRAPH&&_conn[currNode]==0)
+          _labelTmp2[_intLabels2[currNode]]=0;
+      }
+
+      return ret;
+    }
+
+
+    //try to exclude the matching of n1 and n2
+    template<MappingType MT>
+    bool feas(const typename G1::Node n1,const typename G2::Node n2) {
+      if(_intLabels1[n1]!=_intLabels2[n2])
+        return 0;
+
+      for(typename G1::IncEdgeIt e1(_g1,n1); e1!=INVALID; ++e1) {
+        const typename G1::Node& currNode=_g1.oppositeNode(n1,e1);
+        if(_mapping[currNode]!=INVALID)
+          --_conn[_mapping[currNode]];
+      }
+
+      bool isIso=1;
+      for(typename G2::IncEdgeIt e2(_g2,n2); e2!=INVALID; ++e2) {
+        int& connCurrNode = _conn[_g2.oppositeNode(n2,e2)];
+        if(connCurrNode<-1)
+          ++connCurrNode;
+        else if(MT!=SUBGRAPH&&connCurrNode==-1) {
+          isIso=0;
+          break;
+        }
+      }
+
+      if(isIso)
+        for(typename G1::IncEdgeIt e1(_g1,n1); e1!=INVALID; ++e1) {
+          const typename G2::Node& currNodePair =
+            _mapping[_g1.oppositeNode(n1,e1)];
+          int& connCurrNodePair=_conn[currNodePair];
+          if(currNodePair!=INVALID&&connCurrNodePair!=-1) {
+            switch(MT){
+            case INDUCED:
+            case ISOMORPH:
+              isIso=0;
+              break;
+            case SUBGRAPH:
+              if(connCurrNodePair<-1)
+                isIso=0;
+              break;
+            }
+            connCurrNodePair=-1;
+          }
+        }
+      else
+        for(typename G1::IncEdgeIt e1(_g1,n1); e1!=INVALID; ++e1) {
+          const typename G2::Node currNode=_mapping[_g1.oppositeNode(n1,e1)];
+          if(currNode!=INVALID/*&&_conn[currNode]!=-1*/)
+            _conn[currNode]=-1;
+        }
+
+      return isIso&&cutByLabels<MT>(n1,n2);
+    }
+
+    //maps n1 to n2
+    void addPair(const typename G1::Node n1,const typename G2::Node n2) {
+      _conn[n2]=-1;
+      _mapping.set(n1,n2);
+      for(typename G2::IncEdgeIt e2(_g2,n2); e2!=INVALID; ++e2) {
+        int& currConn = _conn[_g2.oppositeNode(n2,e2)];
+        if(currConn!=-1)
+          ++currConn;
+      }
+    }
+
+    //removes mapping of n1 to n2
+    void subPair(const typename G1::Node n1,const typename G2::Node n2) {
+      _conn[n2]=0;
+      _mapping.set(n1,INVALID);
+      for(typename G2::IncEdgeIt e2(_g2,n2); e2!=INVALID; ++e2){
+        int& currConn = _conn[_g2.oppositeNode(n2,e2)];
+        if(currConn>0)
+          --currConn;
+        else if(currConn==-1)
+          ++_conn[n2];
+      }
+    }
+
+    void processBfsTree(typename G1::Node source,unsigned int& orderIndex,
+                         typename G1::template NodeMap<int>& dm1,
+                         typename G1::template NodeMap<bool>& added) {
+      _order[orderIndex]=source;
+      added[source]=1;
+
+      unsigned int endPosOfLevel=orderIndex,
+        startPosOfLevel=orderIndex,
+        lastAdded=orderIndex;
+
+      typename G1::template NodeMap<int> currConn(_g1,0);
+
+      while(orderIndex<=lastAdded){
+        typename G1::Node currNode = _order[orderIndex];
+        for(typename G1::IncEdgeIt e(_g1,currNode); e!=INVALID; ++e) {
+          typename G1::Node n = _g1.oppositeNode(currNode,e);
+          if(!added[n]) {
+            _order[++lastAdded]=n;
+            added[n]=1;
+          }
+        }
+        if(orderIndex>endPosOfLevel){
+          for(unsigned int j = startPosOfLevel; j <= endPosOfLevel; ++j) {
+            int minInd=j;
+            for(unsigned int i = j+1; i <= endPosOfLevel; ++i)
+              if(currConn[_order[i]]>currConn[_order[minInd]]||
+                 (currConn[_order[i]]==currConn[_order[minInd]]&&
+                  (dm1[_order[i]]>dm1[_order[minInd]]||
+                   (dm1[_order[i]]==dm1[_order[minInd]]&&
+                    _labelTmp1[_intLabels1[_order[minInd]]]>
+                    _labelTmp1[_intLabels1[_order[i]]]))))
+                minInd=i;
+
+            --_labelTmp1[_intLabels1[_order[minInd]]];
+            for(typename G1::IncEdgeIt e(_g1,_order[minInd]); e!=INVALID; ++e)
+              ++currConn[_g1.oppositeNode(_order[minInd],e)];
+            std::swap(_order[j],_order[minInd]);
+          }
+          startPosOfLevel=endPosOfLevel+1;
+          endPosOfLevel=lastAdded;
+        }
+        ++orderIndex;
+      }
+    }
+
+
+    //we will find pairs for the nodes of g1 in this order
+    void initOrder(){
+      for(typename G2::NodeIt n2(_g2); n2!=INVALID; ++n2)
+        ++_labelTmp1[_intLabels2[n2]];
+
+      typename G1::template NodeMap<int> dm1(_g1,0);
+      for(typename G1::EdgeIt e(_g1); e!=INVALID; ++e) {
+        ++dm1[_g1.u(e)];
+        ++dm1[_g1.v(e)];
+      }
+
+      typename G1::template NodeMap<bool> added(_g1,0);
+      unsigned int orderIndex=0;
+
+      for(typename G1::NodeIt n(_g1); n!=INVALID;) {
+        if(!added[n]){
+          typename G1::Node minNode = n;
+          for(typename G1::NodeIt n1(_g1,minNode); n1!=INVALID; ++n1)
+            if(!added[n1] &&
+               (_labelTmp1[_intLabels1[minNode]]>
+                _labelTmp1[_intLabels1[n1]]||(dm1[minNode]<dm1[n1]&&
+                                             _labelTmp1[_intLabels1[minNode]]==
+                                             _labelTmp1[_intLabels1[n1]])))
+              minNode=n1;
+          processBfsTree(minNode,orderIndex,dm1,added);
+        }
+        else
+          ++n;
+      }
+      for(unsigned int i = 0; i < _labelTmp1.size(); ++i)
+        _labelTmp1[i]=0;
+    }
+
+
+    template<MappingType MT>
+    bool extMatch(){
+      while(_depth>=0) {
+        if(_depth==static_cast<int>(_order.size())) {
+          //all nodes of g1 are mapped to nodes of g2
+          --_depth;
+          return true;
+        }
+        typename G1::Node& nodeOfDepth = _order[_depth];
+        const typename G2::Node& pairOfNodeOfDepth = _mapping[nodeOfDepth];
+        typename G2::IncEdgeIt &edgeItOfDepth = _currEdgeIts[_depth];
+        //the node of g2 whose neighbours are the candidates for
+        //the pair of _order[_depth]
+        typename G2::Node currPNode;
+        if(edgeItOfDepth==INVALID){
+          typename G1::IncEdgeIt fstMatchedE(_g1,nodeOfDepth);
+          //if _mapping[_order[_depth]]!=INVALID, we don't need fstMatchedE
+          if(pairOfNodeOfDepth==INVALID) {
+            for(; fstMatchedE!=INVALID &&
+                  _mapping[_g1.oppositeNode(nodeOfDepth,
+                                            fstMatchedE)]==INVALID;
+                ++fstMatchedE); //find fstMatchedE, it could be preprocessed
+          }
+          if(fstMatchedE==INVALID||pairOfNodeOfDepth!=INVALID) {
+            //We found no covered neighbours, this means that
+            //the graph is not connected (or _depth==0). Each
+            //uncovered (and there are some other properties due
+            //to the spec. problem types) node of g2 is
+            //candidate. We can read the iterator of the last
+            //tried node from the match if it is not the first
+            //try (match[nodeOfDepth]!=INVALID)
+            typename G2::NodeIt n2(_g2);
+            //if it's not the first try
+            if(pairOfNodeOfDepth!=INVALID) {
+              n2=++typename G2::NodeIt(_g2,pairOfNodeOfDepth);
+              subPair(nodeOfDepth,pairOfNodeOfDepth);
+            }
+            for(; n2!=INVALID; ++n2)
+              if(MT!=SUBGRAPH) {
+                if(_conn[n2]==0&&feas<MT>(nodeOfDepth,n2))
+                  break;
+              }
+              else if(_conn[n2]>=0&&feas<MT>(nodeOfDepth,n2))
+                break;
+            // n2 is the next candidate
+            if(n2!=INVALID) {
+              addPair(nodeOfDepth,n2);
+              ++_depth;
+            }
+            else // there are no more candidates
+              --_depth;
+            continue;
+          }
+          else {
+            currPNode=_mapping[_g1.oppositeNode(nodeOfDepth,
+                                                fstMatchedE)];
+            edgeItOfDepth=typename G2::IncEdgeIt(_g2,currPNode);
+          }
+        }
+        else {
+          currPNode=_g2.oppositeNode(pairOfNodeOfDepth,
+                                     edgeItOfDepth);
+          subPair(nodeOfDepth,pairOfNodeOfDepth);
+          ++edgeItOfDepth;
+        }
+        for(; edgeItOfDepth!=INVALID; ++edgeItOfDepth) {
+          const typename G2::Node currNode =
+            _g2.oppositeNode(currPNode, edgeItOfDepth);
+          if(_conn[currNode]>0&&feas<MT>(nodeOfDepth,currNode)) {
+            addPair(nodeOfDepth,currNode);
+            break;
+          }
+        }
+        edgeItOfDepth==INVALID?--_depth:++_depth;
+      }
+      return false;
+    }
+
+    //calculate the lookup table for cutting the search tree
+    void initRNew1tRInOut1t(){
+      typename G1::template NodeMap<int> tmp(_g1,0);
+      for(unsigned int i=0; i<_order.size(); ++i) {
+        tmp[_order[i]]=-1;
+        for(typename G1::IncEdgeIt e1(_g1,_order[i]); e1!=INVALID; ++e1) {
+          const typename G1::Node currNode=_g1.oppositeNode(_order[i],e1);
+          if(tmp[currNode]>0)
+            ++_labelTmp1[_intLabels1[currNode]];
+          else if(tmp[currNode]==0)
+            ++_labelTmp2[_intLabels1[currNode]];
+        }
+        //_labelTmp1[i]=number of neightbours with label i in set rInOut
+        //_labelTmp2[i]=number of neightbours with label i in set rNew
+        for(typename G1::IncEdgeIt e1(_g1,_order[i]); e1!=INVALID; ++e1) {
+          const int& currIntLabel = _intLabels1[_g1.oppositeNode(_order[i],e1)];
+          if(_labelTmp1[currIntLabel]>0) {
+            _rInOutLabels1[_order[i]]
+              .push_back(std::make_pair(currIntLabel,
+                                        _labelTmp1[currIntLabel]));
+            _labelTmp1[currIntLabel]=0;
+          }
+          else if(_labelTmp2[currIntLabel]>0) {
+            _rNewLabels1[_order[i]].
+              push_back(std::make_pair(currIntLabel,_labelTmp2[currIntLabel]));
+            _labelTmp2[currIntLabel]=0;
+          }
+        }
+
+        for(typename G1::IncEdgeIt e1(_g1,_order[i]); e1!=INVALID; ++e1) {
+          int& tmpCurrNode=tmp[_g1.oppositeNode(_order[i],e1)];
+          if(tmpCurrNode!=-1)
+            ++tmpCurrNode;
+        }
+      }
+    }
+
+    int getMaxLabel() const{
+      int m=-1;
+      for(typename G1::NodeIt n1(_g1); n1!=INVALID; ++n1) {
+        const int& currIntLabel = _intLabels1[n1];
+        if(currIntLabel>m)
+          m=currIntLabel;
+      }
+      for(typename G2::NodeIt n2(_g2); n2!=INVALID; ++n2) {
+        const int& currIntLabel = _intLabels2[n2];
+        if(currIntLabel>m)
+          m=currIntLabel;
+      }
+      return m;
+    }
+
+  public:
+    ///Constructor
+
+    ///Constructor.
+    ///\param g1 The graph to be embedded.
+    ///\param g2 The graph \e g1 will be embedded into.
+    ///\param m The type of the NodeMap storing the mapping.
+    ///By default, it is G1::NodeMap<G2::Node>
+    ///\param intLabel1 The NodeMap storing the integer node labels of G1.
+    ///The labels must be the numbers {0,1,2,..,K-1}, where K is the number of
+    ///different labels.
+    ///\param intLabel1 The NodeMap storing the integer node labels of G2.
+    ///The labels must be the numbers {0,1,2,..,K-1}, where K is the number of
+    ///different labels.
+    Vf2pp(const G1 &g1, const G2 &g2,M &m, M1 &intLabels1, M2 &intLabels2) :
+      _g1(g1), _g2(g2), _depth(0), _mapping(m), _order(countNodes(g1),INVALID),
+      _conn(g2,0), _currEdgeIts(countNodes(g1),INVALID), _rNewLabels1(_g1),
+      _rInOutLabels1(_g1), _intLabels1(intLabels1) ,_intLabels2(intLabels2),
+      _maxLabel(getMaxLabel()), _labelTmp1(_maxLabel+1),_labelTmp2(_maxLabel+1),
+      _mapping_type(SUBGRAPH), _deallocMappingAfterUse(0),
+      _deallocLabelsAfterUse(0)
+    {
+      initOrder();
+      initRNew1tRInOut1t();
+
+      //reset mapping
+      for(typename G1::NodeIt n(g1);n!=INVALID;++n)
+        m[n]=INVALID;
+    }
+
+    ///Destructor
+
+    ///Destructor.
+    ///
+    ~Vf2pp()
+    {
+      if(_deallocMappingAfterUse)
+        delete &_mapping;
+      if(_deallocLabelsAfterUse) {
+        delete &_intLabels1;
+        delete &_intLabels2;
+      }
+    }
+
+    ///Returns the current mapping type.
+
+    ///Returns the current mapping type.
+    ///
+    MappingType mappingType() const
+    {
+      return _mapping_type;
+    }
+
+    ///Sets the mapping type
+
+    ///Sets the mapping type.
+    ///
+    ///The mapping type is set to \ref SUBGRAPH by default.
+    ///
+    ///\sa See \ref MappingType for the possible values.
+    void mappingType(MappingType m_type)
+    {
+      _mapping_type = m_type;
+    }
+
+    ///Finds a mapping.
+
+    ///This method finds a mapping from g1 into g2 according to the mapping
+    ///type set by \ref mappingType(MappingType) "mappingType()".
+    ///
+    ///By subsequent calls, it returns all possible mappings one-by-one.
+    ///
+    ///\retval true if a mapping is found.
+    ///\retval false if there is no (more) mapping.
+    bool find()
+    {
+      switch(_mapping_type)
+        {
+        case SUBGRAPH:
+          return extMatch<SUBGRAPH>();
+        case INDUCED:
+          return extMatch<INDUCED>();
+        case ISOMORPH:
+          return extMatch<ISOMORPH>();
+        default:
+          return false;
+        }
+    }
+  };
+
+  template<typename G1, typename G2>
+  class Vf2ppWizardBase {
+  protected:
+    typedef G1 Graph1;
+    typedef G2 Graph2;
+
+    const G1 &_g1;
+    const G2 &_g2;
+
+    MappingType _mapping_type;
+
+    typedef typename G1::template NodeMap<typename G2::Node> Mapping;
+    bool _local_mapping;
+    void *_mapping;
+    void createMapping() {
+      _mapping = new Mapping(_g1);
+    }
+
+    bool _local_nodeLabels;
+    typedef typename G1::template NodeMap<int> NodeLabels1;
+    typedef typename G2::template NodeMap<int> NodeLabels2;
+    void *_nodeLabels1, *_nodeLabels2;
+    void createNodeLabels() {
+      _nodeLabels1 = new NodeLabels1(_g1,0);
+      _nodeLabels2 = new NodeLabels2(_g2,0);
+    }
+
+    Vf2ppWizardBase(const G1 &g1,const G2 &g2)
+      : _g1(g1), _g2(g2), _mapping_type(SUBGRAPH),
+        _local_mapping(1), _local_nodeLabels(1) { }
+  };
+
+
+  /// \brief Auxiliary class for the function-type interface of %VF2
+  /// Plus Plus algorithm.
+  ///
+  /// This auxiliary class implements the named parameters of
+  /// \ref vf2pp() "function-type interface" of \ref Vf2pp algorithm.
+  ///
+  /// \warning This class is not to be used directly.
+  ///
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm.
+  template<typename TR>
+  class Vf2ppWizard : public TR {
+    typedef TR Base;
+    typedef typename TR::Graph1 Graph1;
+    typedef typename TR::Graph2 Graph2;
+    typedef typename TR::Mapping Mapping;
+    typedef typename TR::NodeLabels1 NodeLabels1;
+    typedef typename TR::NodeLabels2 NodeLabels2;
+
+    using TR::_g1;
+    using TR::_g2;
+    using TR::_mapping_type;
+    using TR::_mapping;
+    using TR::_nodeLabels1;
+    using TR::_nodeLabels2;
+
+  public:
+    ///Constructor
+    Vf2ppWizard(const Graph1 &g1,const Graph2 &g2) : Base(g1,g2) {}
+
+    ///Copy constructor
+    Vf2ppWizard(const Base &b) : Base(b) {}
+
+
+    template<typename T>
+    struct SetMappingBase : public Base {
+      typedef T Mapping;
+      SetMappingBase(const Base &b) : Base(b) {}
+    };
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the mapping.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that stores the found embedding.
+    template<typename T>
+    Vf2ppWizard< SetMappingBase<T> > mapping(const T &t) {
+      Base::_mapping=reinterpret_cast<void*>(const_cast<T*>(&t));
+      Base::_local_mapping = 0;
+      return Vf2ppWizard<SetMappingBase<T> >(*this);
+    }
+
+    template<typename NL1, typename NL2>
+    struct SetNodeLabelsBase : public Base {
+      typedef NL1 NodeLabels1;
+      typedef NL2 NodeLabels2;
+      SetNodeLabelsBase(const Base &b) : Base(b) { }
+    };
+
+    ///\brief \ref named-templ-param "Named parameter" for setting the
+    ///node labels.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the node labels.
+    ///
+    ///\param nodeLabels1 A \ref concepts::ReadMap "readable node map"
+    ///of g1 with integer values. In case of K different labels, the labels
+    ///must be the numbers {0,1,..,K-1}.
+    ///\param nodeLabels2 A \ref concepts::ReadMap "readable node map"
+    ///of g2 with integer values. In case of K different labels, the labels
+    ///must be the numbers {0,1,..,K-1}.
+    template<typename NL1, typename NL2>
+    Vf2ppWizard< SetNodeLabelsBase<NL1,NL2> >
+    nodeLabels(const NL1 &nodeLabels1, const NL2 &nodeLabels2) {
+      Base::_local_nodeLabels = 0;
+      Base::_nodeLabels1=
+        reinterpret_cast<void*>(const_cast<NL1*>(&nodeLabels1));
+      Base::_nodeLabels2=
+        reinterpret_cast<void*>(const_cast<NL2*>(&nodeLabels2));
+      return Vf2ppWizard<SetNodeLabelsBase<NL1,NL2> >
+        (SetNodeLabelsBase<NL1,NL2>(*this));
+    }
+
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the mapping type.
+    ///
+    ///\ref named-templ-param "Named parameter" for setting
+    ///the mapping type.
+    ///
+    ///The mapping type is set to \ref SUBGRAPH by default.
+    ///
+    ///\sa See \ref MappingType for the possible values.
+    Vf2ppWizard<Base> &mappingType(MappingType m_type) {
+      _mapping_type = m_type;
+      return *this;
+    }
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the mapping type to \ref INDUCED.
+    ///
+    ///\ref named-templ-param "Named parameter" for setting
+    ///the mapping type to \ref INDUCED.
+    Vf2ppWizard<Base> &induced() {
+      _mapping_type = INDUCED;
+      return *this;
+    }
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the mapping type to \ref ISOMORPH.
+    ///
+    ///\ref named-templ-param "Named parameter" for setting
+    ///the mapping type to \ref ISOMORPH.
+    Vf2ppWizard<Base> &iso() {
+      _mapping_type = ISOMORPH;
+      return *this;
+    }
+
+    ///Runs the %VF2 Plus Plus algorithm.
+
+    ///This method runs the VF2 Plus Plus algorithm.
+    ///
+    ///\retval true if a mapping is found.
+    ///\retval false if there is no mapping.
+    bool run() {
+      if(Base::_local_mapping)
+        Base::createMapping();
+      if(Base::_local_nodeLabels)
+        Base::createNodeLabels();
+
+      Vf2pp<Graph1, Graph2, Mapping, NodeLabels1, NodeLabels2 >
+        alg(_g1, _g2, *reinterpret_cast<Mapping*>(_mapping),
+            *reinterpret_cast<NodeLabels1*>(_nodeLabels1),
+            *reinterpret_cast<NodeLabels2*>(_nodeLabels2));
+
+      alg.mappingType(_mapping_type);
+
+      const bool ret = alg.find();
+
+      if(Base::_local_nodeLabels) {
+        delete reinterpret_cast<NodeLabels1*>(_nodeLabels1);
+        delete reinterpret_cast<NodeLabels2*>(_nodeLabels2);
+      }
+      if(Base::_local_mapping)
+        delete reinterpret_cast<Mapping*>(_mapping);
+
+      return ret;
+    }
+
+    ///Get a pointer to the generated Vf2pp object.
+
+    ///Gives a pointer to the generated Vf2pp object.
+    ///
+    ///\return Pointer to the generated Vf2pp object.
+    ///\warning Don't forget to delete the referred Vf2pp object after use.
+    Vf2pp<Graph1, Graph2, Mapping, NodeLabels1, NodeLabels2 >*
+    getPtrToVf2ppObject(){
+      if(Base::_local_mapping)
+        Base::createMapping();
+      if(Base::_local_nodeLabels)
+        Base::createNodeLabels();
+
+      Vf2pp<Graph1, Graph2, Mapping, NodeLabels1, NodeLabels2 >* ptr =
+        new Vf2pp<Graph1, Graph2, Mapping, NodeLabels1, NodeLabels2>
+        (_g1, _g2, *reinterpret_cast<Mapping*>(_mapping),
+         *reinterpret_cast<NodeLabels1*>(_nodeLabels1),
+         *reinterpret_cast<NodeLabels2*>(_nodeLabels2));
+      ptr->mappingType(_mapping_type);
+      if(Base::_local_mapping)
+        ptr->_deallocMappingAfterUse=true;
+      if(Base::_local_nodeLabels)
+        ptr->_deallocLabelMapsAfterUse=true;
+
+      return ptr;
+    }
+
+    ///Counts the number of mappings.
+
+    ///This method counts the number of mappings.
+    ///
+    /// \return The number of mappings.
+    int count() {
+      if(Base::_local_mapping)
+        Base::createMapping();
+      if(Base::_local_nodeLabels)
+        Base::createNodeLabels();
+
+      Vf2pp<Graph1, Graph2, Mapping, NodeLabels1, NodeLabels2>
+        alg(_g1, _g2, *reinterpret_cast<Mapping*>(_mapping),
+            *reinterpret_cast<NodeLabels1*>(_nodeLabels1),
+            *reinterpret_cast<NodeLabels2*>(_nodeLabels2));
+
+      alg.mappingType(_mapping_type);
+
+      int ret = 0;
+      while(alg.find())
+        ++ret;
+
+      if(Base::_local_nodeLabels) {
+        delete reinterpret_cast<NodeLabels1*>(_nodeLabels1);
+        delete reinterpret_cast<NodeLabels2*>(_nodeLabels2);
+      }
+      if(Base::_local_mapping)
+        delete reinterpret_cast<Mapping*>(_mapping);
+
+      return ret;
+    }
+  };
+
+
+  ///Function-type interface for VF2 Plus Plus algorithm.
+
+  /// \ingroup graph_isomorphism
+  ///Function-type interface for VF2 Plus Plus algorithm.
+  ///
+  ///This function has several \ref named-func-param "named parameters"
+  ///declared as the members of class \ref Vf2ppWizard.
+  ///The following examples show how to use these parameters.
+  ///\code
+  ///  ListGraph::NodeMap<ListGraph::Node> m(g);
+  ///  // Find an embedding of graph g1 into graph g2
+  ///  vf2pp(g1,g2).mapping(m).run();
+  ///
+  ///  // Check whether graphs g1 and g2 are isomorphic
+  ///  bool is_iso = vf2pp(g1,g2).iso().run();
+  ///
+  ///  // Count the number of isomorphisms
+  ///  int num_isos = vf2pp(g1,g2).iso().count();
+  ///
+  ///  // Iterate through all the induced subgraph mappings
+  ///  // of graph g1 into g2 using the labels c1 and c2
+  ///  auto* myVf2pp = vf2pp(g1,g2).mapping(m).nodeLabels(c1,c2)
+  ///  .induced().getPtrToVf2Object();
+  ///  while(myVf2pp->find()){
+  ///    //process the current mapping m
+  ///  }
+  ///  delete myVf22pp;
+  ///\endcode
+  ///\warning Don't forget to put the \ref Vf2ppWizard::run() "run()",
+  ///\ref Vf2ppWizard::count() "count()" or
+  ///the \ref Vf2ppWizard::getPtrToVf2ppObject() "getPtrToVf2ppObject()"
+  ///to the end of the expression.
+  ///\sa Vf2ppWizard
+  ///\sa Vf2pp
+  template<class G1, class G2>
+  Vf2ppWizard<Vf2ppWizardBase<G1,G2> > vf2pp(const G1 &g1, const G2 &g2) {
+    return Vf2ppWizard<Vf2ppWizardBase<G1,G2> >(g1,g2);
+  }
+
+}
+
+#endif
+
Index: test/CMakeLists.txt
===================================================================
--- test/CMakeLists.txt	(revision 1264)
+++ test/CMakeLists.txt	(revision 1406)
@@ -55,4 +55,5 @@
   tsp_test
   unionfind_test
+  vf2_test
 )
 
Index: test/bellman_ford_test.cc
===================================================================
--- test/bellman_ford_test.cc	(revision 1270)
+++ test/bellman_ford_test.cc	(revision 1378)
@@ -101,5 +101,11 @@
     pp = const_bf_test.negativeCycle();
 
+#ifdef LEMON_CXX11
     for (BF::ActiveIt it(const_bf_test); it != INVALID; ++it) {}
+    for (auto n: const_bf_test.activeNodes()) { ::lemon::ignore_unused_variable_warning(n); }
+    for (Digraph::Node n: const_bf_test.activeNodes()) {
+      ::lemon::ignore_unused_variable_warning(n);
+    }
+#endif
   }
   {
Index: test/digraph_test.cc
===================================================================
--- test/digraph_test.cc	(revision 1270)
+++ test/digraph_test.cc	(revision 1419)
@@ -21,4 +21,5 @@
 #include <lemon/smart_graph.h>
 #include <lemon/static_graph.h>
+#include <lemon/compact_graph.h>
 #include <lemon/full_graph.h>
 
@@ -339,4 +340,8 @@
     checkConcept<ClearableDigraphComponent<>, StaticDigraph>();
   }
+  { // Checking CompactDigraph
+    checkConcept<Digraph, CompactDigraph>();
+    checkConcept<ClearableDigraphComponent<>, CompactDigraph>();
+  }
   { // Checking FullDigraph
     checkConcept<Digraph, FullDigraph>();
@@ -395,10 +400,11 @@
 }
 
+template <typename GR>
 void checkStaticDigraph() {
   SmartDigraph g;
-  SmartDigraph::NodeMap<StaticDigraph::Node> nref(g);
-  SmartDigraph::ArcMap<StaticDigraph::Arc> aref(g);
-
-  StaticDigraph G;
+  SmartDigraph::NodeMap<typename GR::Node> nref(g);
+  SmartDigraph::ArcMap<typename GR::Arc> aref(g);
+
+  GR G;
 
   checkGraphNodeList(G, 0);
@@ -556,5 +562,6 @@
   }
   { // Checking StaticDigraph
-    checkStaticDigraph();
+    checkStaticDigraph<StaticDigraph>();
+    checkStaticDigraph<CompactDigraph>();
   }
   { // Checking FullDigraph
Index: test/graph_test.h
===================================================================
--- test/graph_test.h	(revision 1270)
+++ test/graph_test.h	(revision 1337)
@@ -39,4 +39,25 @@
     check(n==INVALID,"Wrong Node list linking.");
     check(countNodes(G)==cnt,"Wrong Node number.");
+
+#ifdef LEMON_CXX11
+    {
+      typename Graph::NodeIt n(G);
+      for(auto u: G.nodes())
+        {
+          check(n==u,"Wrong STL Node iterator.");
+          ++n;
+        }
+      check(n==INVALID,"Wrong STL Node iterator.");
+    }
+    {
+      typename Graph::NodeIt n(G);
+      for(typename Graph::Node u: G.nodes())
+        {
+          check(n==u,"Wrong STL Node iterator.");
+          ++n;
+        }
+      check(n==INVALID,"Wrong STL Node iterator.");
+    }
+#endif
   }
 
@@ -57,4 +78,24 @@
     check(n==INVALID,"Wrong red Node list linking.");
     check(countRedNodes(G)==cnt,"Wrong red Node number.");
+#ifdef LEMON_CXX11
+    {
+      typename Graph::RedNodeIt n(G);
+      for(auto u: G.redNodes())
+        {
+          check(n==u,"Wrong STL RedNode iterator.");
+          ++n;
+        }
+      check(n==INVALID,"Wrong STL RedNode iterator.");
+    }
+    {
+      typename Graph::RedNodeIt n(G);
+      for(typename Graph::RedNode u: G.redNodes())
+        {
+          check(n==u,"Wrong STL RedNode iterator.");
+          ++n;
+        }
+      check(n==INVALID,"Wrong STL RedNode iterator.");
+    }
+#endif
   }
 
@@ -75,4 +116,25 @@
     check(n==INVALID,"Wrong blue Node list linking.");
     check(countBlueNodes(G)==cnt,"Wrong blue Node number.");
+#ifdef LEMON_CXX11
+    {
+      typename Graph::BlueNodeIt n(G);
+      for(auto u: G.blueNodes())
+        {
+          check(n==u,"Wrong STL BlueNode iterator.");
+          ++n;
+        }
+      check(n==INVALID,"Wrong STL BlueNode iterator.");
+    }
+    {
+      typename Graph::BlueNodeIt n(G);
+      for(typename Graph::BlueNode u: G.blueNodes())
+        {
+          check(n==u,"Wrong STL BlueNode iterator.");
+          ++n;
+        }
+      check(n==INVALID,"Wrong STL BlueNode iterator.");
+    }
+#endif
+
   }
 
@@ -91,4 +153,25 @@
     check(e==INVALID,"Wrong Arc list linking.");
     check(countArcs(G)==cnt,"Wrong Arc number.");
+#ifdef LEMON_CXX11
+    {
+      typename Graph::ArcIt a(G);
+      for(auto e: G.arcs())
+        {
+          check(a==e,"Wrong STL Arc iterator.");
+          ++a;
+        }
+      check(a==INVALID,"Wrong STL Arc iterator.");
+    }
+    {
+      typename Graph::ArcIt a(G);
+      for(typename Graph::Arc e: G.arcs())
+        {
+          check(a==e,"Wrong STL Arc iterator.");
+          ++a;
+        }
+      check(a==INVALID,"Wrong STL Arc iterator.");
+    }
+#endif
+
   }
 
@@ -106,4 +189,25 @@
     check(e==INVALID,"Wrong OutArc list linking.");
     check(countOutArcs(G,n)==cnt,"Wrong OutArc number.");
+#ifdef LEMON_CXX11
+    {
+      typename Graph::OutArcIt a(G,n);
+      for(auto e: G.outArcs(n))
+        {
+          check(a==e,"Wrong STL OutArc iterator.");
+          ++a;
+        }
+      check(a==INVALID,"Wrong STL OutArc iterator.");
+    }
+    {
+      typename Graph::OutArcIt a(G,n);
+      for(typename Graph::Arc e: G.outArcs(n))
+        {
+          check(a==e,"Wrong STL OutArc iterator.");
+          ++a;
+        }
+      check(a==INVALID,"Wrong STL OutArc iterator.");
+    }
+#endif
+
   }
 
@@ -121,4 +225,24 @@
     check(e==INVALID,"Wrong InArc list linking.");
     check(countInArcs(G,n)==cnt,"Wrong InArc number.");
+#ifdef LEMON_CXX11
+    {
+      typename Graph::InArcIt a(G,n);
+      for(auto e: G.inArcs(n))
+        {
+          check(a==e,"Wrong STL InArc iterator.");
+          ++a;
+        }
+      check(a==INVALID,"Wrong STL InArc iterator.");
+    }
+    {
+      typename Graph::InArcIt a(G,n);
+      for(typename Graph::Arc e: G.inArcs(n))
+        {
+          check(a==e,"Wrong STL InArc iterator.");
+          ++a;
+        }
+      check(a==INVALID,"Wrong STL InArc iterator.");
+    }
+#endif
   }
 
@@ -135,4 +259,25 @@
     check(e==INVALID,"Wrong Edge list linking.");
     check(countEdges(G)==cnt,"Wrong Edge number.");
+#ifdef LEMON_CXX11
+    {
+      typename Graph::EdgeIt a(G);
+      for(auto e: G.edges())
+        {
+          check(a==e,"Wrong STL Edge iterator.");
+          ++a;
+        }
+      check(a==INVALID,"Wrong STL Edge iterator.");
+    }
+    {
+      typename Graph::EdgeIt a(G);
+      for(typename Graph::Edge e: G.edges())
+        {
+          check(a==e,"Wrong STL Edge iterator.");
+          ++a;
+        }
+      check(a==INVALID,"Wrong STL Edge iterator.");
+    }
+#endif
+
   }
 
@@ -151,4 +296,25 @@
     check(e==INVALID,"Wrong IncEdge list linking.");
     check(countIncEdges(G,n)==cnt,"Wrong IncEdge number.");
+#ifdef LEMON_CXX11
+    {
+      typename Graph::IncEdgeIt a(G,n);
+      for(auto e: G.incEdges(n))
+        {
+          check(a==e,"Wrong STL IncEdge iterator.");
+          ++a;
+        }
+      check(a==INVALID,"Wrong STL IncEdge iterator.");
+    }
+    {
+      typename Graph::IncEdgeIt a(G,n);
+      for(typename Graph::Edge e: G.incEdges(n))
+        {
+          check(a==e,"Wrong STL IncEdge iterator.");
+          ++a;
+        }
+      check(a==INVALID,"Wrong STL IncEdge iterator.");
+    }
+#endif
+
   }
 
Index: test/lp_test.cc
===================================================================
--- test/lp_test.cc	(revision 1300)
+++ test/lp_test.cc	(revision 1337)
@@ -21,5 +21,5 @@
 #include "test_tools.h"
 #include <lemon/tolerance.h>
-
+#include <lemon/concept_check.h>
 #include <lemon/config.h>
 
@@ -48,4 +48,9 @@
   int count=0;
   for (LpBase::ColIt c(lp); c!=INVALID; ++c) ++count;
+#ifdef LEMON_CXX11
+  int cnt = 0;
+  for(auto c: lp.cols()) { cnt++; ::lemon::ignore_unused_variable_warning(c); }
+  check(count == cnt, "Wrong STL iterator");
+#endif
   return count;
 }
@@ -54,4 +59,9 @@
   int count=0;
   for (LpBase::RowIt r(lp); r!=INVALID; ++r) ++count;
+#ifdef LEMON_CXX11
+  int cnt = 0;
+  for(auto r: lp.rows()) { cnt++; ::lemon::ignore_unused_variable_warning(r); }
+  check(count == cnt, "Wrong STL iterator");
+#endif
   return count;
 }
Index: test/maps_test.cc
===================================================================
--- test/maps_test.cc	(revision 1270)
+++ test/maps_test.cc	(revision 1337)
@@ -731,4 +731,28 @@
     check(n == 3, "Wrong number");
     check(map1.falseNum() == 3, "Wrong number");
+
+#ifdef LEMON_CXX11
+    {
+      int c = 0;
+      for(auto v: map1.items(false)) { c++; ::lemon::ignore_unused_variable_warning(v); }
+      check(c == map1.falseNum(), "Wrong number");
+    }
+    {
+      int c = 0;
+      for(auto v: map1.items(true)) { c++; ::lemon::ignore_unused_variable_warning(v); }
+      check(c == map1.trueNum(), "Wrong number");
+    }
+    {
+      int c = 0;
+      for(auto v: map1.falseKeys()) { c++; ::lemon::ignore_unused_variable_warning(v); }
+      check(c == map1.falseNum(), "Wrong number");
+    }
+    {
+      int c = 0;
+      for(auto v: map1.trueKeys()) { c++; ::lemon::ignore_unused_variable_warning(v); }
+      check(c == map1.trueNum(), "Wrong number");
+    }
+#endif
+
   }
 
@@ -781,4 +805,13 @@
     }
     check(n == num, "Wrong number");
+#ifdef LEMON_CXX11
+    {
+      int c = 0;
+      for(auto v: map1.items(0)) { c++; ::lemon::ignore_unused_variable_warning(v); }
+      check(c == (num + 1) / 2, "Wrong number");
+      for(auto v: map1.items(1)) { c++; ::lemon::ignore_unused_variable_warning(v); }
+      check(c == num, "Wrong number");
+    }
+#endif
 
   }
@@ -839,4 +872,14 @@
     }
     check(n == num, "Wrong number");
+
+#ifdef LEMON_CXX11
+    {
+      int c = 0;
+      for(auto v: map1.items(0.0)) { c++; ::lemon::ignore_unused_variable_warning(v); }
+      check(c == (num + 1) / 2, "Wrong number");
+      for(auto v: map1.items(1.0)) { c++; ::lemon::ignore_unused_variable_warning(v); }
+      check(c == num, "Wrong number");
+    }
+#endif
 
   }
Index: test/matching_test.cc
===================================================================
--- test/matching_test.cc	(revision 1270)
+++ test/matching_test.cc	(revision 1423)
@@ -135,4 +135,7 @@
   mat_test.startDense();
   mat_test.run();
+  mat_test.startSparse(false);
+  mat_test.startDense(false);
+  mat_test.run(false);
 
   const_mat_test.matchingSize();
@@ -403,4 +406,5 @@
       edgeMap("weight", weight).run();
 
+    int size;
     bool perfect;
     {
@@ -408,5 +412,72 @@
       mm.run();
       checkMatching(graph, mm);
+      size = mm.matchingSize();
       perfect = 2 * mm.matchingSize() == countNodes(graph);
+    }
+
+    {
+      MaxMatching<SmartGraph> mm(graph);
+      mm.init();
+      mm.startSparse();
+      checkMatching(graph, mm);
+      check(size == mm.matchingSize(), "Inconsistent matching size");
+    }
+
+    {
+      MaxMatching<SmartGraph> mm(graph);
+      mm.init();
+      mm.startDense();
+      checkMatching(graph, mm);
+      check(size == mm.matchingSize(), "Inconsistent matching size");
+    }
+
+    {
+      MaxMatching<SmartGraph> mm(graph);
+      mm.greedyInit();
+      mm.startSparse();
+      checkMatching(graph, mm);
+      check(size == mm.matchingSize(), "Inconsistent matching size");
+    }
+
+    {
+      MaxMatching<SmartGraph> mm(graph);
+      mm.greedyInit();
+      mm.startDense();
+      checkMatching(graph, mm);
+      check(size == mm.matchingSize(), "Inconsistent matching size");
+    }
+
+    {
+      MaxMatching<SmartGraph> mm(graph);
+      mm.run(false);
+      check(size == mm.matchingSize(), "Inconsistent max cardinality matching");
+    }
+
+    {
+      MaxMatching<SmartGraph> mm(graph);
+      mm.init();
+      mm.startSparse(false);
+      check(size == mm.matchingSize(), "Inconsistent matching size");
+    }
+
+    {
+      MaxMatching<SmartGraph> mm(graph);
+      mm.init();
+      mm.startDense(false);
+      check(size == mm.matchingSize(), "Inconsistent matching size");
+    }
+
+    {
+      MaxMatching<SmartGraph> mm(graph);
+      mm.greedyInit();
+      mm.startSparse(false);
+      check(size == mm.matchingSize(), "Inconsistent matching size");
+    }
+
+    {
+      MaxMatching<SmartGraph> mm(graph);
+      mm.greedyInit();
+      mm.startDense(false);
+      check(size == mm.matchingSize(), "Inconsistent matching size");
     }
 
Index: test/path_test.cc
===================================================================
--- test/path_test.cc	(revision 1270)
+++ test/path_test.cc	(revision 1421)
@@ -108,4 +108,9 @@
     checkBackAndFrontInsertablePath<ListPath<GR> >();
     checkBackInsertablePath<SimplePath<GR> >();
+
+    checkSubscriptOperator<Path<GR> >();
+    checkSubscriptOperator<SimplePath<GR> >();
+    checkSubscriptOperator<StaticPath<GR> >();
+    checkSubscriptOperator<ListPath<GR> >();
 
     checkListPathSplitAndSplice();
@@ -274,4 +279,23 @@
   }
 
+  template <typename P>
+  void checkSubscriptOperator() {
+    SimplePath<GR> p0;
+    p0.addBack(a1);
+    p0.addBack(a3);
+    p0.addBack(a2);
+    P p = p0;
+    check(!p.empty(), "Wrong empty()");
+    check(p.length() == 3, "Wrong length");
+    check(p.front() == a1, "Wrong front()");
+    check(p.back() == a2, "Wrong back()");
+    check(p.nth(0) == a1, "Wrong nth()");
+    check(p.nth(1) == a3, "Wrong nth()");
+    check(p.nth(2) == a2, "Wrong nth()");
+    check(p[0] == a1, "Wrong operator[]");
+    check(p[1] == a3, "Wrong operator[]");
+    check(p[2] == a2, "Wrong operator[]");
+  }
+
   void checkListPathSplitAndSplice() {
 
Index: test/random_test.cc
===================================================================
--- test/random_test.cc	(revision 463)
+++ test/random_test.cc	(revision 1379)
@@ -22,4 +22,31 @@
 int seed_array[] = {1, 2};
 
+int rnd_seq32[] = {
+2732, 43567, 42613, 52416, 45891, 21243, 30403, 32103, 
+62501, 33003, 12172, 5192, 32511, 50057, 43723, 7813, 
+23720, 35343, 6637, 30280, 44566, 31019, 18898, 33867, 
+5994, 1688, 11513, 59011, 48056, 25544, 39168, 25365, 
+17530, 8366, 27063, 49861, 55169, 63848, 11863, 49608
+};
+int rnd_seq64[] = {
+56382, 63883, 59577, 64750, 9644, 59886, 57647, 18152, 
+28520, 64078, 17818, 49294, 26424, 26697, 53684, 19209, 
+35404, 12121, 12837, 11827, 32156, 58333, 62553, 7907, 
+64427, 39399, 21971, 48789, 46981, 15716, 53335, 65256, 
+12999, 15308, 10906, 42162, 47587, 43006, 53921, 18716
+};
+
+void seq_test() {
+  for(int i=0;i<5;i++) {
+    lemon::Random32 r32(i);
+    lemon::Random64 r64(i);
+    for(int j=0;j<8;j++) {
+      check(r32[65536]==rnd_seq32[i*8+j], "Wrong random sequence");
+      check(r64[65536]==rnd_seq64[i*8+j], "Wrong random sequence");
+    }
+  }
+}
+
+
 int main()
 {
@@ -37,4 +64,5 @@
                   (sizeof(seed_array) / sizeof(seed_array[0])));
 
+  seq_test();
   return 0;
 }
Index: test/vf2_test.cc
===================================================================
--- test/vf2_test.cc	(revision 1406)
+++ test/vf2_test.cc	(revision 1406)
@@ -0,0 +1,459 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2015-2017
+ * EMAXA Kutato-fejleszto Kft. (EMAXA Research Ltd.)
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#include <lemon/vf2.h>
+#include <lemon/vf2pp.h>
+#include <lemon/concepts/digraph.h>
+#include <lemon/smart_graph.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/concepts/maps.h>
+
+#include <test/test_tools.h>
+#include <sstream>
+
+using namespace lemon;
+
+char petersen_lgf[] =
+  "@nodes\n"
+  "label col1 col2\n"
+  "0 1 1\n"
+  "1 1 2\n"
+  "2 1 3\n"
+  "3 1 4\n"
+  "4 2 5\n"
+  "5 2 1\n"
+  "6 2 2\n"
+  "7 2 3\n"
+  "8 2 4\n"
+  "9 2 5\n"
+  "@arcs\n"
+  "     -\n"
+  "0 1\n"
+  "1 2\n"
+  "2 3\n"
+  "3 4\n"
+  "4 0\n"
+  "0 5\n"
+  "1 6\n"
+  "2 7\n"
+  "3 8\n"
+  "4 9\n"
+  "5 8\n"
+  "5 7\n"
+  "9 6\n"
+  "9 7\n"
+  "6 8\n";
+
+char c5_lgf[] =
+  "@nodes\n"
+  "label col\n"
+  "0 1\n"
+  "1 2\n"
+  "2 3\n"
+  "3 4\n"
+  "4 5\n"
+  "@arcs\n"
+  "     -\n"
+  "0 1\n"
+  "1 2\n"
+  "2 3\n"
+  "3 4\n"
+  "4 0\n";
+
+char c7_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "@arcs\n"
+  "     -\n"
+  "0 1\n"
+  "1 2\n"
+  "2 3\n"
+  "3 4\n"
+  "4 5\n"
+  "5 6\n"
+  "6 0\n";
+
+char c10_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "8\n"
+  "9\n"
+  "@arcs\n"
+  "     -\n"
+  "0 1\n"
+  "1 2\n"
+  "2 3\n"
+  "3 4\n"
+  "4 5\n"
+  "5 6\n"
+  "6 7\n"
+  "7 8\n"
+  "8 9\n"
+  "9 0\n";
+
+char p10_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "8\n"
+  "9\n"
+  "@arcs\n"
+  "     -\n"
+  "0 1\n"
+  "1 2\n"
+  "2 3\n"
+  "3 4\n"
+  "4 5\n"
+  "5 6\n"
+  "6 7\n"
+  "7 8\n"
+  "8 9\n";
+
+SmartGraph petersen, c5, c7, c10, p10;
+SmartGraph::NodeMap<int> petersen_col1(petersen);
+SmartGraph::NodeMap<int> petersen_col2(petersen);
+SmartGraph::NodeMap<int> c5_col(c5);
+
+void make_graphs() {
+  std::stringstream ss(petersen_lgf);
+  graphReader(petersen, ss)
+    .nodeMap("col1", petersen_col1)
+    .nodeMap("col2", petersen_col2)
+    .run();
+
+  ss.clear();
+  ss.str("");
+  ss << c5_lgf;
+  //std::stringstream ss2(c5_lgf);
+  graphReader(c5, ss)
+    .nodeMap("col", c5_col)
+    .run();
+
+  ss.clear();
+  ss.str("");
+  ss << c7_lgf;
+  graphReader(c7, ss).run();
+
+  ss.clear();
+  ss.str("");
+  ss << c10_lgf;
+  graphReader(c10, ss).run();
+
+  ss.clear();
+  ss.str("");
+  ss << p10_lgf;
+  graphReader(p10, ss).run();
+
+}
+
+class EqComparable {
+public:
+  bool operator==(const EqComparable&) {
+    return false;
+  }
+};
+
+template<class A, class B>
+class EqClass {
+public:
+  bool operator()(A, B){
+    return false;
+  }
+};
+
+class IntConvertible1 {
+public:
+  operator int() {
+    return 0;
+  }
+};
+
+class IntConvertible2 {
+public:
+  operator int() {
+    return 0;
+  }
+};
+
+template<class G1,class G2>
+void checkVf2Compile() {
+  G1 g;
+  G2 h;
+  concepts::ReadWriteMap<typename G1::Node, typename G2::Node> r;
+  bool succ;
+  ::lemon::ignore_unused_variable_warning(succ);
+
+  succ = vf2(g,h).run();
+  succ = vf2(g,h).induced().run();
+  succ = vf2(g,h).iso().run();
+  succ = vf2(g,h).mapping(r).run();
+
+  Vf2<G1,G2,concepts::ReadWriteMap<typename G1::Node, typename G2::Node>,
+      EqClass<typename G1::Node,typename G2::Node> >
+    myVf2(g,h,r,EqClass<typename G1::Node,typename G2::Node>());
+  myVf2.find();
+
+  succ = vf2(g,h).induced().mapping(r).run();
+  succ = vf2(g,h).iso().mapping(r).run();
+
+  concepts::ReadMap<typename G1::Node, EqComparable> l1;
+  concepts::ReadMap<typename G2::Node, EqComparable> l2;
+  succ = vf2(g,h).nodeLabels(l1,l2).mapping(r).run();
+  succ = vf2(g,h).nodeEq(EqClass<typename G1::Node,typename G2::Node>())
+    .mapping(r).run();
+}
+
+void vf2Compile() {
+  checkVf2Compile<concepts::Graph,concepts::Graph>();
+  checkVf2Compile<concepts::Graph,SmartGraph>();
+  checkVf2Compile<SmartGraph,concepts::Graph>();
+}
+
+template<class G1,class G2>
+void checkVf2ppCompile() {
+  G1 g;
+  G2 h;
+  concepts::ReadWriteMap<typename G1::Node, typename G2::Node> r;
+  bool succ;
+  ::lemon::ignore_unused_variable_warning(succ);
+
+  succ = vf2pp(g,h).run();
+  succ = vf2pp(g,h).induced().run();
+  succ = vf2pp(g,h).iso().run();
+  succ = vf2pp(g,h).mapping(r).run();
+  succ = vf2pp(g,h).induced().mapping(r).run();
+  succ = vf2pp(g,h).iso().mapping(r).run();
+
+  concepts::ReadMap<typename G1::Node, int> c1;
+  concepts::ReadMap<typename G2::Node, int> c2;
+  Vf2pp<G1,G2,concepts::ReadWriteMap<typename G1::Node, typename G2::Node>,
+        concepts::ReadMap<typename G1::Node, int>,
+        concepts::ReadMap<typename G2::Node, int> >
+    myVf2pp(g,h,r,c1,c2);
+  myVf2pp.find();
+
+  succ = vf2pp(g,h).nodeLabels(c1,c2).mapping(r).run();
+  succ = vf2pp(g,h).nodeLabels(c1,c2).mapping(r).run();
+
+  concepts::ReadMap<typename G1::Node, char> c1_c;
+  concepts::ReadMap<typename G2::Node, char> c2_c;
+  Vf2pp<G1,G2,concepts::ReadWriteMap<typename G1::Node, typename G2::Node>,
+        concepts::ReadMap<typename G1::Node, char>,
+        concepts::ReadMap<typename G2::Node, char> >
+    myVf2pp_c(g,h,r,c1_c,c2_c);
+  myVf2pp_c.find();
+
+  succ = vf2pp(g,h).nodeLabels(c1_c,c2_c).mapping(r).run();
+  succ = vf2pp(g,h).nodeLabels(c1_c,c2_c).mapping(r).run();
+
+  concepts::ReadMap<typename G1::Node, IntConvertible1> c1_IntConv;
+  concepts::ReadMap<typename G2::Node, IntConvertible2> c2_IntConv;
+  Vf2pp<G1,G2,concepts::ReadWriteMap<typename G1::Node, typename G2::Node>,
+        concepts::ReadMap<typename G1::Node, IntConvertible1>,
+        concepts::ReadMap<typename G2::Node, IntConvertible2> >
+    myVf2pp_IntConv(g,h,r,c1_IntConv,c2_IntConv);
+  myVf2pp_IntConv.find();
+
+  succ = vf2pp(g,h).nodeLabels(c1_IntConv,c2_IntConv).mapping(r).run();
+  succ = vf2pp(g,h).nodeLabels(c1_IntConv,c2_IntConv).mapping(r).run();
+}
+
+void vf2ppCompile() {
+  checkVf2ppCompile<concepts::Graph,concepts::Graph>();
+  checkVf2ppCompile<concepts::Graph,SmartGraph>();
+  checkVf2ppCompile<SmartGraph,concepts::Graph>();
+}
+
+template<class G1, class G2, class I>
+void checkSubIso(const G1 &g1, const G2 &g2, const I &i) {
+  std::set<typename G2::Node> image;
+  for (typename G1::NodeIt n(g1);n!=INVALID;++n){
+    check(i[n]!=INVALID, "Wrong isomorphism: incomplete mapping.");
+    check(image.count(i[n])==0,"Wrong isomorphism: not injective.");
+    image.insert(i[n]);
+  }
+  for (typename G1::EdgeIt e(g1);e!=INVALID;++e) {
+    check(findEdge(g2,i[g1.u(e)],i[g1.v(e)])!=INVALID,
+          "Wrong isomorphism: missing edge(checkSub).");
+  }
+}
+
+template<class G1, class G2, class I>
+void checkIndIso(const G1 &g1, const G2 &g2, const I &i) {
+  std::set<typename G2::Node> image;
+  for (typename G1::NodeIt n(g1);n!=INVALID;++n) {
+    check(i[n]!=INVALID, "Wrong isomorphism: incomplete mapping.");
+    check(image.count(i[n])==0,"Wrong isomorphism: not injective.");
+    image.insert(i[n]);
+  }
+  for (typename G1::NodeIt n(g1); n!=INVALID; ++n) {
+    for (typename G1::NodeIt m(g1); m!=INVALID; ++m) {
+      if((findEdge(g1,n,m)==INVALID) != (findEdge(g2,i[n],i[m])==INVALID)) {
+        std::cout << "Wrong isomorphism: edge mismatch";
+        exit(1);
+      }
+    }
+  }
+}
+
+template<class G1,class G2,class T>
+bool checkSub(const G1 &g1, const G2 &g2, const T &vf2) {
+  typename G1:: template NodeMap<typename G2::Node> iso(g1,INVALID);
+  if (const_cast<T&>(vf2).mapping(iso).run()) {
+    checkSubIso(g1,g2,iso);
+    return true;
+  }
+  return false;
+}
+
+template<class G1,class G2,class T>
+bool checkInd(const G1 &g1, const G2 &g2, const T &vf2) {
+  typename G1:: template NodeMap<typename G2::Node> iso(g1,INVALID);
+  if (const_cast<T&>(vf2).induced().mapping(iso).run()) {
+    checkIndIso(g1,g2,iso);
+    return true;
+  }
+  return false;
+}
+
+template<class G1,class G2,class T>
+bool checkIso(const G1 &g1, const G2 &g2, const T &vf2) {
+  typename G1:: template NodeMap<typename G2::Node> iso(g1,INVALID);
+  if (const_cast<T&>(vf2).iso().mapping(iso).run()) {
+    check(countNodes(g1)==countNodes(g2),
+          "Wrong iso alg.: they are not isomophic.");
+    checkIndIso(g1,g2,iso);
+    return true;
+  }
+  return false;
+}
+
+template<class G1, class G2, class L1, class L2, class I>
+void checkLabel(const G1 &g1, const G2 &,
+                const L1 &l1, const L2 &l2, const I &i) {
+  for (typename G1::NodeIt n(g1);n!=INVALID;++n) {
+    check(l1[n]==l2[i[n]],"Wrong isomorphism: label mismatch.");
+  }
+}
+
+template<class G1,class G2,class L1,class L2,class T>
+bool checkSub(const G1 &g1, const G2 &g2, const L1 &l1, const L2 &l2, const T &vf2) {
+  typename G1:: template NodeMap<typename G2::Node> iso(g1,INVALID);
+  if (const_cast<T&>(vf2).nodeLabels(l1,l2).mapping(iso).run()){
+    checkSubIso(g1,g2,iso);
+    checkLabel(g1,g2,l1,l2,iso);
+    return true;
+  }
+  return false;
+}
+
+template<class G1,class G2>
+void checkSub(const G1 &g1, const G2 &g2, bool expected, const char* msg) {
+  check(checkSub(g1,g2,vf2(g1,g2)) == expected, msg);
+  check(checkSub(g1,g2,vf2pp(g1,g2)) == expected, msg);
+}
+
+template<class G1,class G2>
+void checkInd(const G1 &g1, const G2 &g2, bool expected, const char* msg) {
+  check(checkInd(g1,g2,vf2(g1,g2)) == expected, msg);
+  check(checkInd(g1,g2,vf2pp(g1,g2)) == expected, msg);
+}
+
+template<class G1,class G2>
+void checkIso(const G1 &g1, const G2 &g2, bool expected, const char* msg) {
+  check(checkIso(g1,g2,vf2(g1,g2)) == expected, msg);
+  check(checkIso(g1,g2,vf2pp(g1,g2)) == expected, msg);
+}
+
+template<class G1,class G2,class L1,class L2>
+void checkSub(const G1 &g1, const G2 &g2, const L1 &l1, const L2 &l2, bool expected, const char* msg) {
+  check(checkSub(g1,g2,l1,l2,vf2(g1,g2)) == expected, msg);
+  check(checkSub(g1,g2,l1,l2,vf2pp(g1,g2)) == expected, msg);
+}
+
+int main() {
+  make_graphs();
+
+  checkSub(c5,petersen,true,
+      "There should exist a C5->Petersen mapping.");
+  checkSub(c7,petersen,false,
+      "There should not exist a C7->Petersen mapping.");
+  checkSub(p10,petersen,true,
+      "There should exist a P10->Petersen mapping.");
+  checkSub(c10,petersen,false,
+      "There should not exist a C10->Petersen mapping.");
+  checkSub(petersen,petersen,true,
+      "There should exist a Petersen->Petersen mapping.");
+
+  checkInd(c5,petersen,true,
+      "There should exist a C5->Petersen spanned mapping.");
+  checkInd(c7,petersen,false,
+      "There should exist a C7->Petersen spanned mapping.");
+  checkInd(p10,petersen,false,
+      "There should not exist a P10->Petersen spanned mapping.");
+  checkInd(c10,petersen,false,
+      "There should not exist a C10->Petersen spanned mapping.");
+  checkInd(petersen,petersen,true,
+        "There should exist a Petersen->Petersen spanned mapping.");
+
+  checkSub(petersen,c10,false,
+      "There should not exist a Petersen->C10 mapping.");
+  checkSub(p10,c10,true,
+      "There should exist a P10->C10 mapping.");
+  checkInd(p10,c10,false,
+      "There should not exist a P10->C10 spanned mapping.");
+  checkSub(c10,p10,false,
+      "There should not exist a C10->P10 mapping.");
+
+  checkIso(p10,c10,false,
+      "P10 and C10 are not isomorphic.");
+  checkIso(c10,c10,true,
+      "C10 and C10 are isomorphic.");
+
+  checkSub(c5,petersen,c5_col,petersen_col1,false,
+      "There should exist a C5->Petersen mapping.");
+  checkSub(c5,petersen,c5_col,petersen_col2,true,
+      "There should exist a C5->Petersen mapping.");
+
+  check(!vf2(p10,c10).iso().run(), "P10 and C10 are not isomorphic.");
+  check(!vf2pp(p10,c10).iso().run(), "P10 and C10 are not isomorphic.");
+
+  check(vf2(c10,c10).iso().run(), "C10 and C10 are isomorphic.");
+  check(vf2pp(c10,c10).iso().run(), "C10 and C10 are isomorphic.");
+}
