Index: .hgignore
===================================================================
--- .hgignore	(revision 484)
+++ .hgignore	(revision 385)
@@ -23,5 +23,4 @@
 lemon/stamp-h2
 doc/Doxyfile
-cmake/cmake.version
 .dirstamp
 .libs/*
@@ -38,4 +37,5 @@
 ^objs.*/.*
 ^test/[a-z_]*$
+^tools/[a-z-_]*$
 ^demo/.*_demo$
 ^build/.*
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt	(revision 489)
+++ CMakeLists.txt	(revision 274)
@@ -1,10 +1,6 @@
 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
 
-IF(EXISTS ${CMAKE_SOURCE_DIR}/cmake/version.cmake)
-  INCLUDE(${CMAKE_SOURCE_DIR}/cmake/version.cmake)
-ELSE(EXISTS ${CMAKE_SOURCE_DIR}/cmake/version.cmake)
-  SET(PROJECT_NAME "LEMON")
-  SET(PROJECT_VERSION "hg-tip" CACHE STRING "LEMON version string.")
-ENDIF(EXISTS ${CMAKE_SOURCE_DIR}/cmake/version.cmake)
+SET(PROJECT_NAME "LEMON")
+SET(PROJECT_VERSION "hg-tip" CACHE STRING "The version string.")
 
 PROJECT(${PROJECT_NAME})
@@ -14,7 +10,4 @@
 INCLUDE(FindDoxygen)
 INCLUDE(FindGhostscript)
-
-INCLUDE(CheckTypeSize)
-CHECK_TYPE_SIZE("long long" LONG_LONG)
 
 ENABLE_TESTING()
@@ -26,6 +19,12 @@
 
 IF(WIN32)
+  INSTALL(FILES ${CMAKE_SOURCE_DIR}/cmake/nsis/lemon.ico
+    DESTINATION bin)
+ENDIF(WIN32)
+
+IF(WIN32)
   SET(CPACK_PACKAGE_NAME ${PROJECT_NAME})
-  SET(CPACK_PACKAGE_VENDOR "EGRES")
+  SET(CPACK_PACKAGE_VENDOR
+    "EGRES - Egervary Research Group on Combinatorial Optimization")
   SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
     "LEMON - Library of Efficient Models and Optimization in Networks")
@@ -39,33 +38,34 @@
     "${PROJECT_NAME} ${PROJECT_VERSION}")
 
-  SET(CPACK_COMPONENTS_ALL headers library html_documentation)
+  # Variables to generate a component-based installer.
+  #SET(CPACK_COMPONENTS_ALL headers library html_documentation)
 
-  SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ headers")
-  SET(CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "Dynamic-link library")
-  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DISPLAY_NAME "HTML documentation")
+  #SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ headers")
+  #SET(CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "Static library")
+  #SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DISPLAY_NAME "HTML documentation")
 
-  SET(CPACK_COMPONENT_HEADERS_DESCRIPTION
-    "C++ header files")
-  SET(CPACK_COMPONENT_LIBRARY_DESCRIPTION
-    "DLL and import library")
-  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DESCRIPTION
-    "Doxygen generated documentation")
+  #SET(CPACK_COMPONENT_HEADERS_DESCRIPTION
+  #  "C++ header files for use with the LEMON library")
+  #SET(CPACK_COMPONENT_LIBRARY_DESCRIPTION
+  #  "Static library used to build programs with LEMON")
+  #SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DESCRIPTION
+  #  "Doxygen generated documentation")
 
-  SET(CPACK_COMPONENT_HEADERS_DEPENDS library)
+  #SET(CPACK_COMPONENT_HEADERS_DEPENDS library)
 
-  SET(CPACK_COMPONENT_HEADERS_GROUP "Development")
-  SET(CPACK_COMPONENT_LIBRARY_GROUP "Development")
-  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_GROUP "Documentation")
+  #SET(CPACK_COMPONENT_HEADERS_GROUP "Development")
+  #SET(CPACK_COMPONENT_LIBRARY_GROUP "Development")
+  #SET(CPACK_COMPONENT_HTML_DOCUMENTATION_GROUP "Documentation")
 
-  SET(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION
-    "Components needed to develop software using LEMON")
-  SET(CPACK_COMPONENT_GROUP_DOCUMENTATION_DESCRIPTION
-    "Documentation of LEMON")
+  #SET(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION
+  #  "Components needed to develop software using LEMON")
+  #SET(CPACK_COMPONENT_GROUP_DOCUMENTATION_DESCRIPTION
+  #  "Documentation of LEMON")
 
-  SET(CPACK_ALL_INSTALL_TYPES Full Developer)
+  #SET(CPACK_ALL_INSTALL_TYPES Full Developer)
 
-  SET(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer Full)
-  SET(CPACK_COMPONENT_LIBRARY_INSTALL_TYPES Developer Full)
-  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_INSTALL_TYPES Full)
+  #SET(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer Full)
+  #SET(CPACK_COMPONENT_LIBRARY_INSTALL_TYPES Developer Full)
+  #SET(CPACK_COMPONENT_HTML_DOCUMENTATION_INSTALL_TYPES Full)
 
   SET(CPACK_GENERATOR "NSIS")
@@ -79,5 +79,5 @@
   SET(CPACK_NSIS_CONTACT "lemon-user@lemon.cs.elte.hu")
   SET(CPACK_NSIS_CREATE_ICONS_EXTRA "
-    CreateShortCut \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Documentation.lnk\\\" \\\"$INSTDIR\\\\share\\\\doc\\\\index.html\\\"
+    CreateShortCut \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Documentation.lnk\\\" \\\"$INSTDIR\\\\doc\\\\index.html\\\"
     ")
   SET(CPACK_NSIS_DELETE_ICONS_EXTRA "
Index: LICENSE
===================================================================
--- LICENSE	(revision 107)
+++ LICENSE	(revision 440)
@@ -2,5 +2,5 @@
 copyright/license.
 
-Copyright (C) 2003-2008 Egervary Jeno Kombinatorikus Optimalizalasi
+Copyright (C) 2003-2009 Egervary Jeno Kombinatorikus Optimalizalasi
 Kutatocsoport (Egervary Combinatorial Optimization Research Group,
 EGRES).
Index: Makefile.am
===================================================================
--- Makefile.am	(revision 478)
+++ Makefile.am	(revision 363)
@@ -1,3 +1,5 @@
 ACLOCAL_AMFLAGS = -I m4
+
+AM_CXXFLAGS = $(WARNINGCXXFLAGS)
 
 AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir)
@@ -11,9 +13,5 @@
 	m4/lx_check_soplex.m4 \
 	CMakeLists.txt \
-	cmake/FindGhostscript.cmake \
-	cmake/version.cmake.in \
-	cmake/version.cmake \
-	cmake/nsis/lemon.ico \
-	cmake/nsis/uninstall.ico
+	cmake
 
 pkgconfigdir = $(libdir)/pkgconfig
Index: cmake/FindGhostscript.cmake
===================================================================
--- cmake/FindGhostscript.cmake	(revision 489)
+++ cmake/FindGhostscript.cmake	(revision 225)
@@ -4,5 +4,5 @@
   NAMES gs gswin32c
   PATHS "$ENV{ProgramFiles}/gs"
-  PATH_SUFFIXES gs8.61/bin gs8.62/bin gs8.63/bin gs8.64/bin gs8.65/bin
+  PATH_SUFFIXES gs8.61/bin gs8.62/bin
   DOC "Ghostscript: PostScript and PDF language interpreter and previewer."
 )
Index: ake/version.cmake.in
===================================================================
--- cmake/version.cmake.in	(revision 478)
+++ 	(revision )
@@ -1,2 +1,0 @@
-SET(PROJECT_NAME "@PACKAGE_NAME@")
-SET(PROJECT_VERSION "@PACKAGE_VERSION@" CACHE STRING "LEMON version string.")
Index: configure.ac
===================================================================
--- configure.ac	(revision 485)
+++ configure.ac	(revision 363)
@@ -20,14 +20,6 @@
 AC_CONFIG_HEADERS([config.h lemon/config.h])
 
-lx_cmdline_cxxflags_set=${CXXFLAGS+set}
-
 dnl Do compilation tests using the C++ compiler.
 AC_LANG([C++])
-
-dnl Check the existence of long long type.
-AC_CHECK_TYPE(long long, [long_long_found=yes], [long_long_found=no])
-if test x"$long_long_found" = x"yes"; then
-  AC_DEFINE([HAVE_LONG_LONG], [1], [Define to 1 if you have long long.])
-fi
 
 dnl Checks for programs.
@@ -53,7 +45,8 @@
 
 dnl Set custom compiler flags when using g++.
-if test x"$lx_cmdline_cxxflags_set" != x"set" -a "$GXX" = yes -a "$ICC" = no; then
-  CXXFLAGS="$CXXFLAGS -Wall -W -Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -Woverloaded-virtual -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas"
+if test "$GXX" = yes -a "$ICC" = no; then
+  WARNINGCXXFLAGS="-Wall -W -Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas"
 fi
+AC_SUBST([WARNINGCXXFLAGS])
 
 dnl Checks for libraries.
@@ -104,9 +97,8 @@
 dnl Add dependencies on files generated by configure.
 AC_SUBST([CONFIG_STATUS_DEPENDENCIES],
-  ['$(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/lemon/lemon.pc.in $(top_srcdir)/cmake/version.cmake.in'])
+  ['$(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/lemon/lemon.pc.in'])
 
 AC_CONFIG_FILES([
 Makefile
-cmake/version.cmake
 doc/Doxyfile
 lemon/lemon.pc
@@ -121,7 +113,5 @@
 echo
 echo C++ compiler.................. : $CXX
-echo C++ compiles flags............ : $CXXFLAGS
-echo
-echo Compiler supports long long... : $long_long_found
+echo C++ compiles flags............ : $WARNINGCXXFLAGS $CXXFLAGS
 echo
 #echo GLPK support.................. : $lx_glpk_found
Index: demo/arg_parser_demo.cc
===================================================================
--- demo/arg_parser_demo.cc	(revision 311)
+++ demo/arg_parser_demo.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: demo/graph_to_eps_demo.cc
===================================================================
--- demo/graph_to_eps_demo.cc	(revision 313)
+++ demo/graph_to_eps_demo.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -86,5 +86,5 @@
     coords(coords).
     title("Sample .eps figure").
-    copyright("(C) 2003-2008 LEMON Project").
+    copyright("(C) 2003-2009 LEMON Project").
     run();
 
@@ -93,5 +93,5 @@
     coords(coords).
     title("Sample .eps figure").
-    copyright("(C) 2003-2008 LEMON Project").
+    copyright("(C) 2003-2009 LEMON Project").
     absoluteNodeSizes().absoluteArcWidths().
     nodeScale(2).nodeSizes(sizes).
@@ -106,5 +106,5 @@
   graphToEps(g,"graph_to_eps_demo_out_3_arr.eps").
     title("Sample .eps figure (with arrowheads)").
-    copyright("(C) 2003-2008 LEMON Project").
+    copyright("(C) 2003-2009 LEMON Project").
     absoluteNodeSizes().absoluteArcWidths().
     nodeColors(composeMap(palette,colors)).
@@ -133,5 +133,5 @@
   graphToEps(g,"graph_to_eps_demo_out_4_par.eps").
     title("Sample .eps figure (parallel arcs)").
-    copyright("(C) 2003-2008 LEMON Project").
+    copyright("(C) 2003-2009 LEMON Project").
     absoluteNodeSizes().absoluteArcWidths().
     nodeShapes(shapes).
@@ -148,5 +148,5 @@
   graphToEps(g,"graph_to_eps_demo_out_5_par_arr.eps").
     title("Sample .eps figure (parallel arcs and arrowheads)").
-    copyright("(C) 2003-2008 LEMON Project").
+    copyright("(C) 2003-2009 LEMON Project").
     absoluteNodeSizes().absoluteArcWidths().
     nodeScale(2).nodeSizes(sizes).
@@ -164,5 +164,5 @@
   graphToEps(g,"graph_to_eps_demo_out_6_par_arr_a4.eps").
     title("Sample .eps figure (fits to A4)").
-    copyright("(C) 2003-2008 LEMON Project").
+    copyright("(C) 2003-2009 LEMON Project").
     scaleToA4().
     absoluteNodeSizes().absoluteArcWidths().
@@ -194,5 +194,5 @@
     scale(60).
     title("Sample .eps figure (Palette demo)").
-    copyright("(C) 2003-2008 LEMON Project").
+    copyright("(C) 2003-2009 LEMON Project").
     coords(hcoords).
     absoluteNodeSizes().absoluteArcWidths().
Index: demo/lgf_demo.cc
===================================================================
--- demo/lgf_demo.cc	(revision 294)
+++ demo/lgf_demo.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: doc/CMakeLists.txt
===================================================================
--- doc/CMakeLists.txt	(revision 489)
+++ doc/CMakeLists.txt	(revision 335)
@@ -10,9 +10,9 @@
 
 IF(DOXYGEN_EXECUTABLE AND GHOSTSCRIPT_EXECUTABLE)
-  FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/)
   IF(UNIX)
     ADD_CUSTOM_TARGET(html
       COMMAND rm -rf gen-images
       COMMAND mkdir gen-images
+      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/grid_graph.png ${CMAKE_CURRENT_SOURCE_DIR}/images/grid_graph.eps
       COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps
       COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_1.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_1.eps
@@ -36,7 +36,8 @@
       WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
   ENDIF(UNIX)
-  INSTALL(
-    DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
-    DESTINATION share/doc
-    COMPONENT html_documentation)
 ENDIF(DOXYGEN_EXECUTABLE AND GHOSTSCRIPT_EXECUTABLE)
+
+INSTALL(
+  DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
+  DESTINATION doc
+  COMPONENT html_documentation)
Index: doc/Doxyfile.in
===================================================================
--- doc/Doxyfile.in	(revision 316)
+++ doc/Doxyfile.in	(revision 367)
@@ -67,5 +67,5 @@
 ENABLED_SECTIONS       = 
 MAX_INITIALIZER_LINES  = 5
-SHOW_USED_FILES        = YES
+SHOW_USED_FILES        = NO
 SHOW_DIRECTORIES       = YES
 SHOW_FILES             = YES
Index: doc/Makefile.am
===================================================================
--- doc/Makefile.am	(revision 317)
+++ doc/Makefile.am	(revision 337)
@@ -15,4 +15,5 @@
 
 DOC_EPS_IMAGES18 = \
+	grid_graph.eps \
 	nodeshape_0.eps \
 	nodeshape_1.eps \
Index: doc/coding_style.dox
===================================================================
--- doc/coding_style.dox	(revision 210)
+++ doc/coding_style.dox	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: doc/dirs.dox
===================================================================
--- doc/dirs.dox	(revision 318)
+++ doc/dirs.dox	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -72,5 +72,5 @@
 \brief Auxiliary tools for implementation.
 
-This directory contains some auxiliary classes for implementing graphs, 
+This directory contains some auxiliary classes for implementing graphs,
 maps and some other classes.
 As a user you typically don't have to deal with these files.
Index: doc/groups.dox
===================================================================
--- doc/groups.dox	(revision 318)
+++ doc/groups.dox	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -17,4 +17,6 @@
  */
 
+namespace lemon {
+
 /**
 @defgroup datas Data Structures
@@ -61,4 +63,77 @@
 
 /**
+@defgroup graph_adaptors Adaptor Classes for graphs
+@ingroup graphs
+\brief This group contains several adaptor classes for digraphs and graphs
+
+The main parts of LEMON are the different graph structures, generic
+graph algorithms, graph concepts which couple these, and graph
+adaptors. While the previous notions are more or less clear, the
+latter one needs further explanation. Graph adaptors are graph classes
+which serve for considering graph structures in different ways.
+
+A short example makes this much clearer.  Suppose that we have an
+instance \c g of a directed graph type say ListDigraph and an algorithm
+\code
+template <typename Digraph>
+int algorithm(const Digraph&);
+\endcode
+is needed to run on the reverse oriented graph.  It may be expensive
+(in time or in memory usage) to copy \c g with the reversed
+arcs.  In this case, an adaptor class is used, which (according
+to LEMON digraph concepts) works as a digraph.  The adaptor uses the
+original digraph structure and digraph operations when methods of the
+reversed oriented graph are called.  This means that the adaptor have
+minor memory usage, and do not perform sophisticated algorithmic
+actions.  The purpose of it is to give a tool for the cases when a
+graph have to be used in a specific alteration.  If this alteration is
+obtained by a usual construction like filtering the arc-set or
+considering a new orientation, then an adaptor is worthwhile to use.
+To come back to the reverse oriented graph, in this situation
+\code
+template<typename Digraph> class ReverseDigraph;
+\endcode
+template class can be used. The code looks as follows
+\code
+ListDigraph g;
+ReverseDigraph<ListGraph> rg(g);
+int result = algorithm(rg);
+\endcode
+After running the algorithm, the original graph \c g is untouched.
+This techniques gives rise to an elegant code, and based on stable
+graph adaptors, complex algorithms can be implemented easily.
+
+In flow, circulation and bipartite matching problems, the residual
+graph is of particular importance. Combining an adaptor implementing
+this, shortest path algorithms and minimum mean cycle algorithms,
+a range of weighted and cardinality optimization algorithms can be
+obtained. For other examples, the interested user is referred to the
+detailed documentation of particular adaptors.
+
+The behavior of graph adaptors can be very different. Some of them keep
+capabilities of the original graph while in other cases this would be
+meaningless. This means that the concepts that they are models of depend
+on the graph adaptor, and the wrapped graph(s).
+If an arc of \c rg is deleted, this is carried out by deleting the
+corresponding arc of \c g, thus the adaptor modifies the original graph.
+
+But for a residual graph, this operation has no sense.
+Let us stand one more example here to simplify your work.
+RevGraphAdaptor has constructor
+\code
+ReverseDigraph(Digraph& digraph);
+\endcode
+This means that in a situation, when a <tt>const ListDigraph&</tt>
+reference to a graph is given, then it have to be instantiated with
+<tt>Digraph=const ListDigraph</tt>.
+\code
+int algorithm1(const ListDigraph& g) {
+  RevGraphAdaptor<const ListDigraph> rg(g);
+  return algorithm2(rg);
+}
+\endcode
+*/
+
+/**
 @defgroup semi_adaptors Semi-Adaptor Classes for Graphs
 @ingroup graphs
@@ -89,5 +164,8 @@
 
 This group describes maps that are specifically designed to assign
-values to the nodes and arcs of graphs.
+values to the nodes and arcs/edges of graphs.
+
+If you are looking for the standard graph maps (\c NodeMap, \c ArcMap,
+\c EdgeMap), see the \ref graph_concepts "Graph Structure Concepts".
 */
 
@@ -100,5 +178,5 @@
 maps from other maps.
 
-Most of them are \ref lemon::concepts::ReadMap "read-only maps".
+Most of them are \ref concepts::ReadMap "read-only maps".
 They can make arithmetic and logical operations between one or two maps
 (negation, shifting, addition, multiplication, logical 'and', 'or',
@@ -202,6 +280,6 @@
 \brief Common graph search algorithms.
 
-This group describes the common graph search algorithms like
-Breadth-First Search (BFS) and Depth-First Search (DFS).
+This group describes the common graph search algorithms, namely
+\e breadth-first \e search (BFS) and \e depth-first \e search (DFS).
 */
 
@@ -211,5 +289,18 @@
 \brief Algorithms for finding shortest paths.
 
-This group describes the algorithms for finding shortest paths in graphs.
+This group describes the algorithms for finding shortest paths in digraphs.
+
+ - \ref Dijkstra algorithm for finding shortest paths from a source node
+   when all arc lengths are non-negative.
+ - \ref BellmanFord "Bellman-Ford" algorithm for finding shortest paths
+   from a source node when arc lenghts can be either positive or negative,
+   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.
 */
 
@@ -222,25 +313,26 @@
 feasible circulations.
 
-The maximum flow problem is to find a flow between a single source and
-a single target that is maximum. Formally, there is a \f$G=(V,A)\f$
-directed graph, an \f$c_a:A\rightarrow\mathbf{R}^+_0\f$ capacity
-function and given \f$s, t \in V\f$ source and target node. The
-maximum flow is the \f$f_a\f$ solution of the next optimization problem:
-
-\f[ 0 \le f_a \le c_a \f]
-\f[ \sum_{v\in\delta^{-}(u)}f_{vu}=\sum_{v\in\delta^{+}(u)}f_{uv}
-\qquad \forall u \in V \setminus \{s,t\}\f]
-\f[ \max \sum_{v\in\delta^{+}(s)}f_{uv} - \sum_{v\in\delta^{-}(s)}f_{vu}\f]
+The \e maximum \e flow \e problem is to find a flow of maximum value between
+a single source and a single target. Formally, there is a \f$G=(V,A)\f$
+digraph, a \f$cap:A\rightarrow\mathbf{R}^+_0\f$ capacity function and
+\f$s, t \in V\f$ source and target nodes.
+A maximum flow is an \f$f:A\rightarrow\mathbf{R}^+_0\f$ solution of the
+following optimization problem.
+
+\f[ \max\sum_{a\in\delta_{out}(s)}f(a) - \sum_{a\in\delta_{in}(s)}f(a) \f]
+\f[ \sum_{a\in\delta_{out}(v)} f(a) = \sum_{a\in\delta_{in}(v)} f(a)
+    \qquad \forall v\in V\setminus\{s,t\} \f]
+\f[ 0 \leq f(a) \leq cap(a) \qquad \forall a\in A \f]
 
 LEMON contains several algorithms for solving maximum flow problems:
-- \ref lemon::EdmondsKarp "Edmonds-Karp"
-- \ref lemon::Preflow "Goldberg's Preflow algorithm"
-- \ref lemon::DinitzSleatorTarjan "Dinitz's blocking flow algorithm with dynamic trees"
-- \ref lemon::GoldbergTarjan "Preflow algorithm with dynamic trees"
-
-In most cases the \ref lemon::Preflow "Preflow" algorithm provides the
-fastest method to compute the maximum flow. All impelementations
-provides functions to query the minimum cut, which is the dual linear
-programming problem of the maximum flow.
+- \ref EdmondsKarp Edmonds-Karp algorithm.
+- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm.
+- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees.
+- \ref GoldbergTarjan Preflow push-relabel algorithm with dynamic trees.
+
+In most cases the \ref Preflow "Preflow" algorithm provides the
+fastest method for computing a maximum flow. All implementations
+provides functions to also query the minimum cut, which is the dual
+problem of the maximum flow.
 */
 
@@ -253,4 +345,31 @@
 This group describes the algorithms for finding minimum cost flows and
 circulations.
+
+The \e minimum \e cost \e flow \e problem is to find a feasible flow of
+minimum total cost from a set of supply nodes to a set of demand nodes
+in a network with capacity constraints and arc costs.
+Formally, let \f$G=(V,A)\f$ be a digraph,
+\f$lower, upper: A\rightarrow\mathbf{Z}^+_0\f$ denote the lower and
+upper bounds for the flow values on the arcs,
+\f$cost: A\rightarrow\mathbf{Z}^+_0\f$ denotes the cost per unit flow
+on the arcs, and
+\f$supply: V\rightarrow\mathbf{Z}\f$ denotes the supply/demand values
+of the nodes.
+A minimum cost flow is an \f$f:A\rightarrow\mathbf{R}^+_0\f$ solution of
+the following optimization problem.
+
+\f[ \min\sum_{a\in A} f(a) cost(a) \f]
+\f[ \sum_{a\in\delta_{out}(v)} f(a) - \sum_{a\in\delta_{in}(v)} f(a) =
+    supply(v) \qquad \forall v\in V \f]
+\f[ lower(a) \leq f(a) \leq upper(a) \qquad \forall a\in A \f]
+
+LEMON contains several algorithms for solving minimum cost flow problems:
+ - \ref CycleCanceling Cycle-canceling algorithms.
+ - \ref CapacityScaling Successive shortest path algorithm with optional
+   capacity scaling.
+ - \ref CostScaling Push-relabel and augment-relabel algorithms based on
+   cost scaling.
+ - \ref NetworkSimplex Primal network simplex algorithm with various
+   pivot strategies.
 */
 
@@ -263,24 +382,24 @@
 This group describes the algorithms for finding minimum cut in graphs.
 
-The minimum cut problem is to find a non-empty and non-complete
-\f$X\f$ subset of the vertices with minimum overall capacity on
-outgoing arcs. Formally, there is \f$G=(V,A)\f$ directed graph, an
-\f$c_a:A\rightarrow\mathbf{R}^+_0\f$ capacity function. The minimum
+The \e minimum \e cut \e problem is to find a non-empty and non-complete
+\f$X\f$ subset of the nodes with minimum overall capacity on
+outgoing arcs. Formally, there is a \f$G=(V,A)\f$ digraph, a
+\f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function. The minimum
 cut is the \f$X\f$ solution of the next optimization problem:
 
 \f[ \min_{X \subset V, X\not\in \{\emptyset, V\}}
-\sum_{uv\in A, u\in X, v\not\in X}c_{uv}\f]
+    \sum_{uv\in A, u\in X, v\not\in X}cap(uv) \f]
 
 LEMON contains several algorithms related to minimum cut problems:
 
-- \ref lemon::HaoOrlin "Hao-Orlin algorithm" to calculate minimum cut
-  in directed graphs
-- \ref lemon::NagamochiIbaraki "Nagamochi-Ibaraki algorithm" to
-  calculate minimum cut in undirected graphs
-- \ref lemon::GomoryHuTree "Gomory-Hu tree computation" to calculate all
-  pairs minimum cut in undirected graphs
+- \ref HaoOrlin "Hao-Orlin algorithm" for calculating minimum cut
+  in directed graphs.
+- \ref NagamochiIbaraki "Nagamochi-Ibaraki algorithm" for
+  calculating minimum cut in undirected graphs.
+- \ref GomoryHuTree "Gomory-Hu tree computation" for calculating
+  all-pairs minimum cut in undirected graphs.
 
 If you want to find minimum cut just between two distinict nodes,
-please see the \ref max_flow "Maximum Flow page".
+see the \ref max_flow "maximum flow problem".
 */
 
@@ -321,28 +440,26 @@
 graphs.  The matching problems in bipartite graphs are generally
 easier than in general graphs. The goal of the matching optimization
-can be the finding maximum cardinality, maximum weight or minimum cost
+can be finding maximum cardinality, maximum weight or minimum cost
 matching. The search can be constrained to find perfect or
 maximum cardinality matching.
 
-LEMON contains the next algorithms:
-- \ref lemon::MaxBipartiteMatching "MaxBipartiteMatching" Hopcroft-Karp
-  augmenting path algorithm for calculate maximum cardinality matching in
-  bipartite graphs
-- \ref lemon::PrBipartiteMatching "PrBipartiteMatching" Push-Relabel
-  algorithm for calculate maximum cardinality matching in bipartite graphs
-- \ref lemon::MaxWeightedBipartiteMatching "MaxWeightedBipartiteMatching"
-  Successive shortest path algorithm for calculate maximum weighted matching
-  and maximum weighted bipartite matching in bipartite graph
-- \ref lemon::MinCostMaxBipartiteMatching "MinCostMaxBipartiteMatching"
-  Successive shortest path algorithm for calculate minimum cost maximum
-  matching in bipartite graph
-- \ref lemon::MaxMatching "MaxMatching" Edmond's blossom shrinking algorithm
-  for calculate maximum cardinality matching in general graph
-- \ref lemon::MaxWeightedMatching "MaxWeightedMatching" Edmond's blossom
-  shrinking algorithm for calculate maximum weighted matching in general
-  graph
-- \ref lemon::MaxWeightedPerfectMatching "MaxWeightedPerfectMatching"
-  Edmond's blossom shrinking algorithm for calculate maximum weighted
-  perfect matching in general graph
+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.
+- \ref MaxWeightedMatching Edmond's blossom shrinking algorithm for calculating
+  maximum weighted matching in general graphs.
+- \ref MaxWeightedPerfectMatching
+  Edmond's blossom shrinking algorithm for calculating maximum weighted
+  perfect matching in general graphs.
 
 \image html bipartite_matching.png
@@ -356,5 +473,5 @@
 
 This group describes the algorithms for finding a minimum cost spanning
-tree in a graph
+tree in a graph.
 */
 
@@ -465,5 +582,5 @@
 
 /**
-@defgroup lemon_io LEMON Input-Output
+@defgroup lemon_io LEMON Graph Format
 @ingroup io_group
 \brief Reading and writing LEMON Graph Format.
@@ -480,4 +597,20 @@
 This group describes general \c EPS drawing methods and special
 graph exporting tools.
+*/
+
+/**
+@defgroup dimacs_group DIMACS format
+@ingroup io_group
+\brief Read and write files in DIMACS format
+
+Tools to read a digraph from or write it to a file in DIMACS format data.
+*/
+
+/**
+@defgroup nauty_group NAUTY Format
+@ingroup io_group
+\brief Read \e Nauty format
+
+Tool to read graphs from \e Nauty format data.
 */
 
@@ -531,5 +664,5 @@
 \anchor demoprograms
 
-@defgroup demos Demo programs
+@defgroup demos Demo Programs
 
 Some demo programs are listed here. Their full source codes can be found in
@@ -541,5 +674,5 @@
 
 /**
-@defgroup tools Standalone utility applications
+@defgroup tools Standalone Utility Applications
 
 Some utility applications are listed here.
@@ -549,2 +682,3 @@
 */
 
+}
Index: doc/images/grid_graph.eps
===================================================================
--- doc/images/grid_graph.eps	(revision 335)
+++ doc/images/grid_graph.eps	(revision 335)
@@ -0,0 +1,286 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: Grid undirected graph
+%%Copyright: (C) 2006 LEMON Project
+%%Creator: LEMON, graphToEps()
+%%CreationDate: Fri Sep 29 11:55:56 2006
+%%BoundingBox: 0 0 985 1144
+%%EndComments
+/lb { setlinewidth setrgbcolor newpath moveto
+      4 2 roll 1 index 1 index curveto stroke } bind def
+/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
+/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
+/sq { newpath 2 index 1 index add 2 index 2 index add moveto
+      2 index 1 index sub 2 index 2 index add lineto
+      2 index 1 index sub 2 index 2 index sub lineto
+      2 index 1 index add 2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/di { newpath 2 index 1 index add 2 index moveto
+      2 index             2 index 2 index add lineto
+      2 index 1 index sub 2 index             lineto
+      2 index             2 index 2 index sub lineto
+      closepath pop pop pop} bind def
+/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
+     setrgbcolor 1.1 div c fill
+   } bind def
+/arrl 1 def
+/arrw 0.3 def
+/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
+/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
+       /w exch def /len exch def
+       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
+       len w sub arrl sub dx dy lrl
+       arrw dy dx neg lrl
+       dx arrl w add mul dy w 2 div arrw add mul sub
+       dy arrl w add mul dx w 2 div arrw add mul add rlineto
+       dx arrl w add mul neg dy w 2 div arrw add mul sub
+       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
+       arrw dy dx neg lrl
+       len w sub arrl sub neg dx dy lrl
+       closepath fill } bind def
+/cshow { 2 index 2 index moveto dup stringwidth pop
+         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
+
+gsave
+2 2 scale
+50 40 translate
+5.5000 5.5000 scale
+% 1.14018 1.14018 translate
+%Edges:
+gsave
+70 80 70 90 0 0 0 0.5000 l
+70 70 70 80 0 0 0 0.5000 l
+70 60 70 70 0 0 0 0.5000 l
+70 50 70 60 0 0 0 0.5000 l
+70 40 70 50 0 0 0 0.5000 l
+70 30 70 40 0 0 0 0.5000 l
+70 20 70 30 0 0 0 0.5000 l
+70 10 70 20 0 0 0 0.5000 l
+70 0 70 10 0 0 0 0.5000 l
+60 80 60 90 0 0 0 0.5000 l
+60 70 60 80 0 0 0 0.5000 l
+60 60 60 70 0 0 0 0.5000 l
+60 50 60 60 0 0 0 0.5000 l
+60 40 60 50 0 0 0 0.5000 l
+60 30 60 40 0 0 0 0.5000 l
+60 20 60 30 0 0 0 0.5000 l
+60 10 60 20 0 0 0 0.5000 l
+60 0 60 10 0 0 0 0.5000 l
+50 80 50 90 0 0 0 0.5000 l
+50 70 50 80 0 0 0 0.5000 l
+50 60 50 70 0 0 0 0.5000 l
+50 50 50 60 0 0 0 0.5000 l
+50 40 50 50 0 0 0 0.5000 l
+50 30 50 40 0 0 0 0.5000 l
+50 20 50 30 0 0 0 0.5000 l
+50 10 50 20 0 0 0 0.5000 l
+50 0 50 10 0 0 0 0.5000 l
+40 80 40 90 0 0 0 0.5000 l
+40 70 40 80 0 0 0 0.5000 l
+40 60 40 70 0 0 0 0.5000 l
+40 50 40 60 0 0 0 0.5000 l
+40 40 40 50 0 0 0 0.5000 l
+40 30 40 40 0 0 0 0.5000 l
+40 20 40 30 0 0 0 0.5000 l
+40 10 40 20 0 0 0 0.5000 l
+40 0 40 10 0 0 0 0.5000 l
+30 80 30 90 0 0 0 0.5000 l
+30 70 30 80 0 0 0 0.5000 l
+30 60 30 70 0 0 0 0.5000 l
+30 50 30 60 0 0 0 0.5000 l
+30 40 30 50 0 0 0 0.5000 l
+30 30 30 40 0 0 0 0.5000 l
+30 20 30 30 0 0 0 0.5000 l
+30 10 30 20 0 0 0 0.5000 l
+30 0 30 10 0 0 0 0.5000 l
+20 80 20 90 0 0 0 0.5000 l
+20 70 20 80 0 0 0 0.5000 l
+20 60 20 70 0 0 0 0.5000 l
+20 50 20 60 0 0 0 0.5000 l
+20 40 20 50 0 0 0 0.5000 l
+20 30 20 40 0 0 0 0.5000 l
+20 20 20 30 0 0 0 0.5000 l
+20 10 20 20 0 0 0 0.5000 l
+20 0 20 10 0 0 0 0.5000 l
+10 80 10 90 0 0 0 0.5000 l
+10 70 10 80 0 0 0 0.5000 l
+10 60 10 70 0 0 0 0.5000 l
+10 50 10 60 0 0 0 0.5000 l
+10 40 10 50 0 0 0 0.5000 l
+10 30 10 40 0 0 0 0.5000 l
+10 20 10 30 0 0 0 0.5000 l
+10 10 10 20 0 0 0 0.5000 l
+10 0 10 10 0 0 0 0.5000 l
+0 80 0 90 0 0 0 0.5000 l
+0 70 0 80 0 0 0 0.5000 l
+0 60 0 70 0 0 0 0.5000 l
+0 50 0 60 0 0 0 0.5000 l
+0 40 0 50 0 0 0 0.5000 l
+0 30 0 40 0 0 0 0.5000 l
+0 20 0 30 0 0 0 0.5000 l
+0 10 0 20 0 0 0 0.5000 l
+0 0 0 10 0 0 0 0.5000 l
+60 90 70 90 0 0 0 0.5000 l
+60 80 70 80 0 0 0 0.5000 l
+60 70 70 70 0 0 0 0.5000 l
+60 60 70 60 0 0 0 0.5000 l
+60 50 70 50 0 0 0 0.5000 l
+60 40 70 40 0 0 0 0.5000 l
+60 30 70 30 0 0 0 0.5000 l
+60 20 70 20 0 0 0 0.5000 l
+60 10 70 10 0 0 0 0.5000 l
+60 0 70 0 0 0 0 0.5000 l
+50 90 60 90 0 0 0 0.5000 l
+50 80 60 80 0 0 0 0.5000 l
+50 70 60 70 0 0 0 0.5000 l
+50 60 60 60 0 0 0 0.5000 l
+50 50 60 50 0 0 0 0.5000 l
+50 40 60 40 0 0 0 0.5000 l
+50 30 60 30 0 0 0 0.5000 l
+50 20 60 20 0 0 0 0.5000 l
+50 10 60 10 0 0 0 0.5000 l
+50 0 60 0 0 0 0 0.5000 l
+40 90 50 90 0 0 0 0.5000 l
+40 80 50 80 0 0 0 0.5000 l
+40 70 50 70 0 0 0 0.5000 l
+40 60 50 60 0 0 0 0.5000 l
+40 50 50 50 0 0 0 0.5000 l
+40 40 50 40 0 0 0 0.5000 l
+40 30 50 30 0 0 0 0.5000 l
+40 20 50 20 0 0 0 0.5000 l
+40 10 50 10 0 0 0 0.5000 l
+40 0 50 0 0 0 0 0.5000 l
+30 90 40 90 0 0 0 0.5000 l
+30 80 40 80 0 0 0 0.5000 l
+30 70 40 70 0 0 0 0.5000 l
+30 60 40 60 0 0 0 0.5000 l
+30 50 40 50 0 0 0 0.5000 l
+30 40 40 40 0 0 0 0.5000 l
+30 30 40 30 0 0 0 0.5000 l
+30 20 40 20 0 0 0 0.5000 l
+30 10 40 10 0 0 0 0.5000 l
+30 0 40 0 0 0 0 0.5000 l
+20 90 30 90 0 0 0 0.5000 l
+20 80 30 80 0 0 0 0.5000 l
+20 70 30 70 0 0 0 0.5000 l
+20 60 30 60 0 0 0 0.5000 l
+20 50 30 50 0 0 0 0.5000 l
+20 40 30 40 0 0 0 0.5000 l
+20 30 30 30 0 0 0 0.5000 l
+20 20 30 20 0 0 0 0.5000 l
+20 10 30 10 0 0 0 0.5000 l
+20 0 30 0 0 0 0 0.5000 l
+10 90 20 90 0 0 0 0.5000 l
+10 80 20 80 0 0 0 0.5000 l
+10 70 20 70 0 0 0 0.5000 l
+10 60 20 60 0 0 0 0.5000 l
+10 50 20 50 0 0 0 0.5000 l
+10 40 20 40 0 0 0 0.5000 l
+10 30 20 30 0 0 0 0.5000 l
+10 20 20 20 0 0 0 0.5000 l
+10 10 20 10 0 0 0 0.5000 l
+10 0 20 0 0 0 0 0.5000 l
+0 90 10 90 0 0 0 0.5000 l
+0 80 10 80 0 0 0 0.5000 l
+0 70 10 70 0 0 0 0.5000 l
+0 60 10 60 0 0 0 0.5000 l
+0 50 10 50 0 0 0 0.5000 l
+0 40 10 40 0 0 0 0.5000 l
+0 30 10 30 0 0 0 0.5000 l
+0 20 10 20 0 0 0 0.5000 l
+0 10 10 10 0 0 0 0.5000 l
+0 0 10 0 0 0 0 0.5000 l
+grestore
+%Nodes:
+gsave
+70 90 1.4000 0 0 0 nc
+70 80 1.4000 1 1 1 nc
+70 70 1.4000 1 1 1 nc
+70 60 1.4000 1 1 1 nc
+70 50 1.4000 1 1 1 nc
+70 40 1.4000 1 1 1 nc
+70 30 1.4000 1 1 1 nc
+70 20 1.4000 1 1 1 nc
+70 10 1.4000 1 1 1 nc
+70 0 1.4000 0 0 0 nc
+60 90 1.4000 1 1 1 nc
+60 80 1.4000 1 1 1 nc
+60 70 1.4000 1 1 1 nc
+60 60 1.4000 1 1 1 nc
+60 50 1.4000 1 1 1 nc
+60 40 1.4000 1 1 1 nc
+60 30 1.4000 1 1 1 nc
+60 20 1.4000 1 1 1 nc
+60 10 1.4000 1 1 1 nc
+60 0 1.4000 1 1 1 nc
+50 90 1.4000 1 1 1 nc
+50 80 1.4000 1 1 1 nc
+50 70 1.4000 1 1 1 nc
+50 60 1.4000 1 1 1 nc
+50 50 1.4000 1 1 1 nc
+50 40 1.4000 1 1 1 nc
+50 30 1.4000 1 1 1 nc
+50 20 1.4000 1 1 1 nc
+50 10 1.4000 1 1 1 nc
+50 0 1.4000 1 1 1 nc
+40 90 1.4000 1 1 1 nc
+40 80 1.4000 1 1 1 nc
+40 70 1.4000 1 1 1 nc
+40 60 1.4000 1 1 1 nc
+40 50 1.4000 1 1 1 nc
+40 40 1.4000 1 1 1 nc
+40 30 1.4000 1 1 1 nc
+40 20 1.4000 1 1 1 nc
+40 10 1.4000 1 1 1 nc
+40 0 1.4000 1 1 1 nc
+30 90 1.4000 1 1 1 nc
+30 80 1.4000 1 1 1 nc
+30 70 1.4000 1 1 1 nc
+30 60 1.4000 1 1 1 nc
+30 50 1.4000 1 1 1 nc
+30 40 1.4000 1 1 1 nc
+30 30 1.4000 1 1 1 nc
+30 20 1.4000 1 1 1 nc
+30 10 1.4000 1 1 1 nc
+30 0 1.4000 1 1 1 nc
+20 90 1.4000 1 1 1 nc
+20 80 1.4000 1 1 1 nc
+20 70 1.4000 1 1 1 nc
+20 60 1.4000 1 1 1 nc
+20 50 1.4000 1 1 1 nc
+20 40 1.4000 1 1 1 nc
+20 30 1.4000 1 1 1 nc
+20 20 1.4000 1 1 1 nc
+20 10 1.4000 1 1 1 nc
+20 0 1.4000 1 1 1 nc
+10 90 1.4000 1 1 1 nc
+10 80 1.4000 1 1 1 nc
+10 70 1.4000 1 1 1 nc
+10 60 1.4000 1 1 1 nc
+10 50 1.4000 1 1 1 nc
+10 40 1.4000 1 1 1 nc
+10 30 1.4000 1 1 1 nc
+10 20 1.4000 1 1 1 nc
+10 10 1.4000 1 1 1 nc
+10 0 1.4000 1 1 1 nc
+0 90 1.4000 0 0 0 nc
+0 80 1.4000 1 1 1 nc
+0 70 1.4000 1 1 1 nc
+0 60 1.4000 1 1 1 nc
+0 50 1.4000 1 1 1 nc
+0 40 1.4000 1 1 1 nc
+0 30 1.4000 1 1 1 nc
+0 20 1.4000 1 1 1 nc
+0 10 1.4000 1 1 1 nc
+0 0 1.4000 0 0 0 nc
+grestore
+gsave
+/fosi 3.5 def
+(Helvetica) findfont fosi scalefont setfont
+0 0 0 setrgbcolor
+0 95 ((0,height-1)) cshow
+67 95 ((width-1,height-1)) cshow
+0 -5 ((0,0)) cshow
+70 -5 ((width-1,0)) cshow
+grestore
+grestore
+showpage
Index: doc/lgf.dox
===================================================================
--- doc/lgf.dox	(revision 313)
+++ doc/lgf.dox	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: doc/license.dox
===================================================================
--- doc/license.dox	(revision 209)
+++ doc/license.dox	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: doc/mainpage.dox
===================================================================
--- doc/mainpage.dox	(revision 314)
+++ doc/mainpage.dox	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: doc/migration.dox
===================================================================
--- doc/migration.dox	(revision 314)
+++ doc/migration.dox	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -26,5 +26,5 @@
 
 Many of these changes adjusted automatically by the
-<tt>script/lemon-0.x-to-1.x.sh</tt> tool. Those requiring manual
+<tt>lemon-0.x-to-1.x.sh</tt> tool. Those requiring manual
 update are typeset <b>boldface</b>.
 
@@ -54,7 +54,9 @@
 
 \warning
-<b>The <tt>script/lemon-0.x-to-1.x.sh</tt> tool replaces all instances of
-the words \c graph, \c digraph, \c edge and \c arc, so it replaces them
-in strings, comments etc. as well as in all identifiers.</b>
+<b>The <tt>lemon-0.x-to-1.x.sh</tt> script replaces the words \c graph,
+\c ugraph, \c edge and \c uedge in your own identifiers and in
+strings, comments etc. as well as in all LEMON specific identifiers.
+So use the script carefully and make a backup copy of your source files
+before applying the script to them.</b>
 
 \section migration-lgf LGF tools
Index: doc/named-param.dox
===================================================================
--- doc/named-param.dox	(revision 269)
+++ doc/named-param.dox	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: doc/namespaces.dox
===================================================================
--- doc/namespaces.dox	(revision 209)
+++ doc/namespaces.dox	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: doc/template.h
===================================================================
--- doc/template.h	(revision 209)
+++ doc/template.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/CMakeLists.txt
===================================================================
--- lemon/CMakeLists.txt	(revision 482)
+++ lemon/CMakeLists.txt	(revision 225)
@@ -5,7 +5,5 @@
   base.cc
   color.cc
-  random.cc
-  bits/windows.cc
-)
+  random.cc)
 
 INSTALL(
Index: lemon/Makefile.am
===================================================================
--- lemon/Makefile.am	(revision 482)
+++ lemon/Makefile.am	(revision 440)
@@ -8,28 +8,35 @@
 
 lemon_libemon_la_SOURCES = \
-        lemon/arg_parser.cc \
-        lemon/base.cc \
-        lemon/color.cc \
-        lemon/random.cc \
-	lemon/bits/windows.cc
+	lemon/arg_parser.cc \
+	lemon/base.cc \
+	lemon/color.cc \
+	lemon/random.cc
 
-#lemon_libemon_la_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS) $(SOPLEX_CXXFLAGS)
+#lemon_libemon_la_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS) $(SOPLEX_CXXFLAGS) $(AM_CXXFLAGS)
 #lemon_libemon_la_LDFLAGS = $(GLPK_LIBS) $(CPLEX_LIBS) $(SOPLEX_LIBS)
 
 lemon_HEADERS += \
-        lemon/arg_parser.h \
+	lemon/adaptors.h \
+	lemon/arg_parser.h \
 	lemon/assert.h \
-        lemon/bfs.h \
-        lemon/bin_heap.h \
-        lemon/color.h \
+	lemon/bfs.h \
+	lemon/bin_heap.h \
+	lemon/circulation.h \
+	lemon/color.h \
 	lemon/concept_check.h \
-        lemon/counter.h \
+	lemon/counter.h \
 	lemon/core.h \
-        lemon/dfs.h \
-        lemon/dijkstra.h \
-        lemon/dim2.h \
+	lemon/dfs.h \
+	lemon/dijkstra.h \
+	lemon/dim2.h \
+	lemon/dimacs.h \
+	lemon/elevator.h \
 	lemon/error.h \
-        lemon/graph_to_eps.h \
+	lemon/full_graph.h \
+	lemon/graph_to_eps.h \
+	lemon/grid_graph.h \
+	lemon/hypercube_graph.h \
 	lemon/kruskal.h \
+	lemon/hao_orlin.h \
 	lemon/lgf_reader.h \
 	lemon/lgf_writer.h \
@@ -37,11 +44,14 @@
 	lemon/maps.h \
 	lemon/math.h \
+	lemon/max_matching.h \
+	lemon/nauty_reader.h \
 	lemon/path.h \
-        lemon/random.h \
+	lemon/preflow.h \
+	lemon/random.h \
 	lemon/smart_graph.h \
-        lemon/time_measure.h \
-        lemon/tolerance.h \
-	lemon/unionfind.h \
-	lemon/bits/windows.h
+	lemon/suurballe.h \
+	lemon/time_measure.h \
+	lemon/tolerance.h \
+	lemon/unionfind.h
 
 bits_HEADERS += \
@@ -49,11 +59,13 @@
 	lemon/bits/array_map.h \
 	lemon/bits/base_extender.h \
-        lemon/bits/bezier.h \
+	lemon/bits/bezier.h \
 	lemon/bits/default_map.h \
-        lemon/bits/enable_if.h \
+	lemon/bits/enable_if.h \
+	lemon/bits/graph_adaptor_extender.h \
 	lemon/bits/graph_extender.h \
 	lemon/bits/map_extender.h \
 	lemon/bits/path_dump.h \
 	lemon/bits/traits.h \
+	lemon/bits/variant.h \
 	lemon/bits/vector_map.h
 
Index: lemon/adaptors.h
===================================================================
--- lemon/adaptors.h	(revision 440)
+++ lemon/adaptors.h	(revision 440)
@@ -0,0 +1,3347 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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_ADAPTORS_H
+#define LEMON_ADAPTORS_H
+
+/// \ingroup graph_adaptors
+/// \file
+/// \brief Several graph adaptors
+///
+/// This file contains several useful adaptors for digraphs and graphs.
+
+#include <lemon/core.h>
+#include <lemon/maps.h>
+#include <lemon/bits/variant.h>
+
+#include <lemon/bits/graph_adaptor_extender.h>
+#include <lemon/tolerance.h>
+
+#include <algorithm>
+
+namespace lemon {
+
+  template<typename _Digraph>
+  class DigraphAdaptorBase {
+  public:
+    typedef _Digraph Digraph;
+    typedef DigraphAdaptorBase Adaptor;
+    typedef Digraph ParentDigraph;
+
+  protected:
+    Digraph* _digraph;
+    DigraphAdaptorBase() : _digraph(0) { }
+    void setDigraph(Digraph& digraph) { _digraph = &digraph; }
+
+  public:
+    DigraphAdaptorBase(Digraph& digraph) : _digraph(&digraph) { }
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::Arc Arc;
+
+    void first(Node& i) const { _digraph->first(i); }
+    void first(Arc& i) const { _digraph->first(i); }
+    void firstIn(Arc& i, const Node& n) const { _digraph->firstIn(i, n); }
+    void firstOut(Arc& i, const Node& n ) const { _digraph->firstOut(i, n); }
+
+    void next(Node& i) const { _digraph->next(i); }
+    void next(Arc& i) const { _digraph->next(i); }
+    void nextIn(Arc& i) const { _digraph->nextIn(i); }
+    void nextOut(Arc& i) const { _digraph->nextOut(i); }
+
+    Node source(const Arc& a) const { return _digraph->source(a); }
+    Node target(const Arc& a) const { return _digraph->target(a); }
+
+    typedef NodeNumTagIndicator<Digraph> NodeNumTag;
+    int nodeNum() const { return _digraph->nodeNum(); }
+
+    typedef EdgeNumTagIndicator<Digraph> EdgeNumTag;
+    int arcNum() const { return _digraph->arcNum(); }
+
+    typedef FindEdgeTagIndicator<Digraph> FindEdgeTag;
+    Arc findArc(const Node& u, const Node& v, const Arc& prev = INVALID) {
+      return _digraph->findArc(u, v, prev);
+    }
+
+    Node addNode() { return _digraph->addNode(); }
+    Arc addArc(const Node& u, const Node& v) { return _digraph->addArc(u, v); }
+
+    void erase(const Node& n) const { _digraph->erase(n); }
+    void erase(const Arc& a) const { _digraph->erase(a); }
+
+    void clear() const { _digraph->clear(); }
+
+    int id(const Node& n) const { return _digraph->id(n); }
+    int id(const Arc& a) const { return _digraph->id(a); }
+
+    Node nodeFromId(int ix) const { return _digraph->nodeFromId(ix); }
+    Arc arcFromId(int ix) const { return _digraph->arcFromId(ix); }
+
+    int maxNodeId() const { return _digraph->maxNodeId(); }
+    int maxArcId() const { return _digraph->maxArcId(); }
+
+    typedef typename ItemSetTraits<Digraph, Node>::ItemNotifier NodeNotifier;
+    NodeNotifier& notifier(Node) const { return _digraph->notifier(Node()); }
+
+    typedef typename ItemSetTraits<Digraph, Arc>::ItemNotifier ArcNotifier;
+    ArcNotifier& notifier(Arc) const { return _digraph->notifier(Arc()); }
+
+    template <typename _Value>
+    class NodeMap : public Digraph::template NodeMap<_Value> {
+    public:
+
+      typedef typename Digraph::template NodeMap<_Value> Parent;
+
+      explicit NodeMap(const Adaptor& adaptor)
+        : Parent(*adaptor._digraph) {}
+
+      NodeMap(const Adaptor& adaptor, const _Value& value)
+        : Parent(*adaptor._digraph, value) { }
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    template <typename _Value>
+    class ArcMap : public Digraph::template ArcMap<_Value> {
+    public:
+
+      typedef typename Digraph::template ArcMap<_Value> Parent;
+
+      explicit ArcMap(const Adaptor& adaptor)
+        : Parent(*adaptor._digraph) {}
+
+      ArcMap(const Adaptor& adaptor, const _Value& value)
+        : Parent(*adaptor._digraph, value) {}
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+  };
+
+  template<typename _Graph>
+  class GraphAdaptorBase {
+  public:
+    typedef _Graph Graph;
+    typedef Graph ParentGraph;
+
+  protected:
+    Graph* _graph;
+
+    GraphAdaptorBase() : _graph(0) {}
+
+    void setGraph(Graph& graph) { _graph = &graph; }
+
+  public:
+    GraphAdaptorBase(Graph& graph) : _graph(&graph) {}
+
+    typedef typename Graph::Node Node;
+    typedef typename Graph::Arc Arc;
+    typedef typename Graph::Edge Edge;
+
+    void first(Node& i) const { _graph->first(i); }
+    void first(Arc& i) const { _graph->first(i); }
+    void first(Edge& i) const { _graph->first(i); }
+    void firstIn(Arc& i, const Node& n) const { _graph->firstIn(i, n); }
+    void firstOut(Arc& i, const Node& n ) const { _graph->firstOut(i, n); }
+    void firstInc(Edge &i, bool &d, const Node &n) const {
+      _graph->firstInc(i, d, n);
+    }
+
+    void next(Node& i) const { _graph->next(i); }
+    void next(Arc& i) const { _graph->next(i); }
+    void next(Edge& i) const { _graph->next(i); }
+    void nextIn(Arc& i) const { _graph->nextIn(i); }
+    void nextOut(Arc& i) const { _graph->nextOut(i); }
+    void nextInc(Edge &i, bool &d) const { _graph->nextInc(i, d); }
+
+    Node u(const Edge& e) const { return _graph->u(e); }
+    Node v(const Edge& e) const { return _graph->v(e); }
+
+    Node source(const Arc& a) const { return _graph->source(a); }
+    Node target(const Arc& a) const { return _graph->target(a); }
+
+    typedef NodeNumTagIndicator<Graph> NodeNumTag;
+    int nodeNum() const { return _graph->nodeNum(); }
+
+    typedef EdgeNumTagIndicator<Graph> EdgeNumTag;
+    int arcNum() const { return _graph->arcNum(); }
+    int edgeNum() const { return _graph->edgeNum(); }
+
+    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
+    Arc findArc(const Node& u, const Node& v, const Arc& prev = INVALID) {
+      return _graph->findArc(u, v, prev);
+    }
+    Edge findEdge(const Node& u, const Node& v, const Edge& prev = INVALID) {
+      return _graph->findEdge(u, v, prev);
+    }
+
+    Node addNode() { return _graph->addNode(); }
+    Edge addEdge(const Node& u, const Node& v) { return _graph->addEdge(u, v); }
+
+    void erase(const Node& i) { _graph->erase(i); }
+    void erase(const Edge& i) { _graph->erase(i); }
+
+    void clear() { _graph->clear(); }
+
+    bool direction(const Arc& a) const { return _graph->direction(a); }
+    Arc direct(const Edge& e, bool d) const { return _graph->direct(e, d); }
+
+    int id(const Node& v) const { return _graph->id(v); }
+    int id(const Arc& a) const { return _graph->id(a); }
+    int id(const Edge& e) const { return _graph->id(e); }
+
+    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
+    Arc arcFromId(int ix) const { return _graph->arcFromId(ix); }
+    Edge edgeFromId(int ix) const { return _graph->edgeFromId(ix); }
+
+    int maxNodeId() const { return _graph->maxNodeId(); }
+    int maxArcId() const { return _graph->maxArcId(); }
+    int maxEdgeId() const { return _graph->maxEdgeId(); }
+
+    typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
+    NodeNotifier& notifier(Node) const { return _graph->notifier(Node()); }
+
+    typedef typename ItemSetTraits<Graph, Arc>::ItemNotifier ArcNotifier;
+    ArcNotifier& notifier(Arc) const { return _graph->notifier(Arc()); }
+
+    typedef typename ItemSetTraits<Graph, Edge>::ItemNotifier EdgeNotifier;
+    EdgeNotifier& notifier(Edge) const { return _graph->notifier(Edge()); }
+
+    template <typename _Value>
+    class NodeMap : public Graph::template NodeMap<_Value> {
+    public:
+      typedef typename Graph::template NodeMap<_Value> Parent;
+      explicit NodeMap(const GraphAdaptorBase<Graph>& adapter)
+        : Parent(*adapter._graph) {}
+      NodeMap(const GraphAdaptorBase<Graph>& adapter, const _Value& value)
+        : Parent(*adapter._graph, value) {}
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    template <typename _Value>
+    class ArcMap : public Graph::template ArcMap<_Value> {
+    public:
+      typedef typename Graph::template ArcMap<_Value> Parent;
+      explicit ArcMap(const GraphAdaptorBase<Graph>& adapter)
+        : Parent(*adapter._graph) {}
+      ArcMap(const GraphAdaptorBase<Graph>& adapter, const _Value& value)
+        : Parent(*adapter._graph, value) {}
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+    template <typename _Value>
+    class EdgeMap : public Graph::template EdgeMap<_Value> {
+    public:
+      typedef typename Graph::template EdgeMap<_Value> Parent;
+      explicit EdgeMap(const GraphAdaptorBase<Graph>& adapter)
+        : Parent(*adapter._graph) {}
+      EdgeMap(const GraphAdaptorBase<Graph>& adapter, const _Value& value)
+        : Parent(*adapter._graph, value) {}
+
+    private:
+      EdgeMap& operator=(const EdgeMap& cmap) {
+        return operator=<EdgeMap>(cmap);
+      }
+
+      template <typename CMap>
+      EdgeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+  };
+
+  template <typename _Digraph>
+  class ReverseDigraphBase : public DigraphAdaptorBase<_Digraph> {
+  public:
+    typedef _Digraph Digraph;
+    typedef DigraphAdaptorBase<_Digraph> Parent;
+  protected:
+    ReverseDigraphBase() : Parent() { }
+  public:
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+
+    void firstIn(Arc& a, const Node& n) const { Parent::firstOut(a, n); }
+    void firstOut(Arc& a, const Node& n ) const { Parent::firstIn(a, n); }
+
+    void nextIn(Arc& a) const { Parent::nextOut(a); }
+    void nextOut(Arc& a) const { Parent::nextIn(a); }
+
+    Node source(const Arc& a) const { return Parent::target(a); }
+    Node target(const Arc& a) const { return Parent::source(a); }
+
+    Arc addArc(const Node& u, const Node& v) { return Parent::addArc(v, u); }
+
+    typedef FindEdgeTagIndicator<Digraph> FindEdgeTag;
+    Arc findArc(const Node& u, const Node& v,
+                const Arc& prev = INVALID) {
+      return Parent::findArc(v, u, prev);
+    }
+
+  };
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief A digraph adaptor which reverses the orientation of the arcs.
+  ///
+  /// ReverseDigraph reverses the arcs in the adapted digraph. The
+  /// SubDigraph is conform to the \ref concepts::Digraph
+  /// "Digraph concept".
+  ///
+  /// \tparam _Digraph It must be conform to the \ref concepts::Digraph
+  /// "Digraph concept". The type can be specified to be const.
+  template<typename _Digraph>
+  class ReverseDigraph :
+    public DigraphAdaptorExtender<ReverseDigraphBase<_Digraph> > {
+  public:
+    typedef _Digraph Digraph;
+    typedef DigraphAdaptorExtender<
+      ReverseDigraphBase<_Digraph> > Parent;
+  protected:
+    ReverseDigraph() { }
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Creates a reverse digraph adaptor for the given digraph
+    explicit ReverseDigraph(Digraph& digraph) {
+      Parent::setDigraph(digraph);
+    }
+  };
+
+  /// \brief Just gives back a reverse digraph adaptor
+  ///
+  /// Just gives back a reverse digraph adaptor
+  template<typename Digraph>
+  ReverseDigraph<const Digraph> reverseDigraph(const Digraph& digraph) {
+    return ReverseDigraph<const Digraph>(digraph);
+  }
+
+  template <typename _Digraph, typename _NodeFilterMap,
+            typename _ArcFilterMap, bool _checked = true>
+  class SubDigraphBase : public DigraphAdaptorBase<_Digraph> {
+  public:
+    typedef _Digraph Digraph;
+    typedef _NodeFilterMap NodeFilterMap;
+    typedef _ArcFilterMap ArcFilterMap;
+
+    typedef SubDigraphBase Adaptor;
+    typedef DigraphAdaptorBase<_Digraph> Parent;
+  protected:
+    NodeFilterMap* _node_filter;
+    ArcFilterMap* _arc_filter;
+    SubDigraphBase()
+      : Parent(), _node_filter(0), _arc_filter(0) { }
+
+    void setNodeFilterMap(NodeFilterMap& node_filter) {
+      _node_filter = &node_filter;
+    }
+    void setArcFilterMap(ArcFilterMap& arc_filter) {
+      _arc_filter = &arc_filter;
+    }
+
+  public:
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+
+    void first(Node& i) const {
+      Parent::first(i);
+      while (i != INVALID && !(*_node_filter)[i]) Parent::next(i);
+    }
+
+    void first(Arc& i) const {
+      Parent::first(i);
+      while (i != INVALID && (!(*_arc_filter)[i]
+                              || !(*_node_filter)[Parent::source(i)]
+                              || !(*_node_filter)[Parent::target(i)]))
+        Parent::next(i);
+    }
+
+    void firstIn(Arc& i, const Node& n) const {
+      Parent::firstIn(i, n);
+      while (i != INVALID && (!(*_arc_filter)[i]
+                              || !(*_node_filter)[Parent::source(i)]))
+        Parent::nextIn(i);
+    }
+
+    void firstOut(Arc& i, const Node& n) const {
+      Parent::firstOut(i, n);
+      while (i != INVALID && (!(*_arc_filter)[i]
+                              || !(*_node_filter)[Parent::target(i)]))
+        Parent::nextOut(i);
+    }
+
+    void next(Node& i) const {
+      Parent::next(i);
+      while (i != INVALID && !(*_node_filter)[i]) Parent::next(i);
+    }
+
+    void next(Arc& i) const {
+      Parent::next(i);
+      while (i != INVALID && (!(*_arc_filter)[i]
+                              || !(*_node_filter)[Parent::source(i)]
+                              || !(*_node_filter)[Parent::target(i)]))
+        Parent::next(i);
+    }
+
+    void nextIn(Arc& i) const {
+      Parent::nextIn(i);
+      while (i != INVALID && (!(*_arc_filter)[i]
+                              || !(*_node_filter)[Parent::source(i)]))
+        Parent::nextIn(i);
+    }
+
+    void nextOut(Arc& i) const {
+      Parent::nextOut(i);
+      while (i != INVALID && (!(*_arc_filter)[i]
+                              || !(*_node_filter)[Parent::target(i)]))
+        Parent::nextOut(i);
+    }
+
+    void hide(const Node& n) const { _node_filter->set(n, false); }
+    void hide(const Arc& a) const { _arc_filter->set(a, false); }
+
+    void unHide(const Node& n) const { _node_filter->set(n, true); }
+    void unHide(const Arc& a) const { _arc_filter->set(a, true); }
+
+    bool hidden(const Node& n) const { return !(*_node_filter)[n]; }
+    bool hidden(const Arc& a) const { return !(*_arc_filter)[a]; }
+
+    typedef False NodeNumTag;
+    typedef False EdgeNumTag;
+
+    typedef FindEdgeTagIndicator<Digraph> FindEdgeTag;
+    Arc findArc(const Node& source, const Node& target,
+                const Arc& prev = INVALID) {
+      if (!(*_node_filter)[source] || !(*_node_filter)[target]) {
+        return INVALID;
+      }
+      Arc arc = Parent::findArc(source, target, prev);
+      while (arc != INVALID && !(*_arc_filter)[arc]) {
+        arc = Parent::findArc(source, target, arc);
+      }
+      return arc;
+    }
+
+    template <typename _Value>
+    class NodeMap : public SubMapExtender<Adaptor,
+      typename Parent::template NodeMap<_Value> > {
+    public:
+      typedef _Value Value;
+      typedef SubMapExtender<Adaptor, typename Parent::
+                             template NodeMap<Value> > MapParent;
+
+      NodeMap(const Adaptor& adaptor)
+        : MapParent(adaptor) {}
+      NodeMap(const Adaptor& adaptor, const Value& value)
+        : MapParent(adaptor, value) {}
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        MapParent::operator=(cmap);
+        return *this;
+      }
+    };
+
+    template <typename _Value>
+    class ArcMap : public SubMapExtender<Adaptor,
+      typename Parent::template ArcMap<_Value> > {
+    public:
+      typedef _Value Value;
+      typedef SubMapExtender<Adaptor, typename Parent::
+                             template ArcMap<Value> > MapParent;
+
+      ArcMap(const Adaptor& adaptor)
+        : MapParent(adaptor) {}
+      ArcMap(const Adaptor& adaptor, const Value& value)
+        : MapParent(adaptor, value) {}
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        MapParent::operator=(cmap);
+        return *this;
+      }
+    };
+
+  };
+
+  template <typename _Digraph, typename _NodeFilterMap, typename _ArcFilterMap>
+  class SubDigraphBase<_Digraph, _NodeFilterMap, _ArcFilterMap, false>
+    : public DigraphAdaptorBase<_Digraph> {
+  public:
+    typedef _Digraph Digraph;
+    typedef _NodeFilterMap NodeFilterMap;
+    typedef _ArcFilterMap ArcFilterMap;
+
+    typedef SubDigraphBase Adaptor;
+    typedef DigraphAdaptorBase<Digraph> Parent;
+  protected:
+    NodeFilterMap* _node_filter;
+    ArcFilterMap* _arc_filter;
+    SubDigraphBase()
+      : Parent(), _node_filter(0), _arc_filter(0) { }
+
+    void setNodeFilterMap(NodeFilterMap& node_filter) {
+      _node_filter = &node_filter;
+    }
+    void setArcFilterMap(ArcFilterMap& arc_filter) {
+      _arc_filter = &arc_filter;
+    }
+
+  public:
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+
+    void first(Node& i) const {
+      Parent::first(i);
+      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
+    }
+
+    void first(Arc& i) const {
+      Parent::first(i);
+      while (i!=INVALID && !(*_arc_filter)[i]) Parent::next(i);
+    }
+
+    void firstIn(Arc& i, const Node& n) const {
+      Parent::firstIn(i, n);
+      while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextIn(i);
+    }
+
+    void firstOut(Arc& i, const Node& n) const {
+      Parent::firstOut(i, n);
+      while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextOut(i);
+    }
+
+    void next(Node& i) const {
+      Parent::next(i);
+      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
+    }
+    void next(Arc& i) const {
+      Parent::next(i);
+      while (i!=INVALID && !(*_arc_filter)[i]) Parent::next(i);
+    }
+    void nextIn(Arc& i) const {
+      Parent::nextIn(i);
+      while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextIn(i);
+    }
+
+    void nextOut(Arc& i) const {
+      Parent::nextOut(i);
+      while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextOut(i);
+    }
+
+    void hide(const Node& n) const { _node_filter->set(n, false); }
+    void hide(const Arc& e) const { _arc_filter->set(e, false); }
+
+    void unHide(const Node& n) const { _node_filter->set(n, true); }
+    void unHide(const Arc& e) const { _arc_filter->set(e, true); }
+
+    bool hidden(const Node& n) const { return !(*_node_filter)[n]; }
+    bool hidden(const Arc& e) const { return !(*_arc_filter)[e]; }
+
+    typedef False NodeNumTag;
+    typedef False EdgeNumTag;
+
+    typedef FindEdgeTagIndicator<Digraph> FindEdgeTag;
+    Arc findArc(const Node& source, const Node& target,
+                const Arc& prev = INVALID) {
+      if (!(*_node_filter)[source] || !(*_node_filter)[target]) {
+        return INVALID;
+      }
+      Arc arc = Parent::findArc(source, target, prev);
+      while (arc != INVALID && !(*_arc_filter)[arc]) {
+        arc = Parent::findArc(source, target, arc);
+      }
+      return arc;
+    }
+
+    template <typename _Value>
+    class NodeMap : public SubMapExtender<Adaptor,
+      typename Parent::template NodeMap<_Value> > {
+    public:
+      typedef _Value Value;
+      typedef SubMapExtender<Adaptor, typename Parent::
+                             template NodeMap<Value> > MapParent;
+
+      NodeMap(const Adaptor& adaptor)
+        : MapParent(adaptor) {}
+      NodeMap(const Adaptor& adaptor, const Value& value)
+        : MapParent(adaptor, value) {}
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        MapParent::operator=(cmap);
+        return *this;
+      }
+    };
+
+    template <typename _Value>
+    class ArcMap : public SubMapExtender<Adaptor,
+      typename Parent::template ArcMap<_Value> > {
+    public:
+      typedef _Value Value;
+      typedef SubMapExtender<Adaptor, typename Parent::
+                             template ArcMap<Value> > MapParent;
+
+      ArcMap(const Adaptor& adaptor)
+        : MapParent(adaptor) {}
+      ArcMap(const Adaptor& adaptor, const Value& value)
+        : MapParent(adaptor, value) {}
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        MapParent::operator=(cmap);
+        return *this;
+      }
+    };
+
+  };
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief An adaptor for hiding nodes and arcs in a digraph
+  ///
+  /// SubDigraph hides nodes and arcs in a digraph. A bool node map
+  /// and a bool arc map must be specified, which define the filters
+  /// for nodes and arcs. Just the nodes and arcs with true value are
+  /// shown in the subdigraph. The SubDigraph is conform to the \ref
+  /// concepts::Digraph "Digraph concept". If the \c _checked parameter
+  /// is true, then the arcs incident to filtered nodes are also
+  /// filtered out.
+  ///
+  /// \tparam _Digraph It must be conform to the \ref
+  /// concepts::Digraph "Digraph concept". The type can be specified
+  /// to const.
+  /// \tparam _NodeFilterMap A bool valued node map of the the adapted digraph.
+  /// \tparam _ArcFilterMap A bool valued arc map of the the adapted digraph.
+  /// \tparam _checked If the parameter is false then the arc filtering
+  /// is not checked with respect to node filter. Otherwise, each arc
+  /// is automatically filtered, which is incident to a filtered node.
+  ///
+  /// \see FilterNodes
+  /// \see FilterArcs
+  template<typename _Digraph,
+           typename _NodeFilterMap = typename _Digraph::template NodeMap<bool>,
+           typename _ArcFilterMap = typename _Digraph::template ArcMap<bool>,
+           bool _checked = true>
+  class SubDigraph
+    : public DigraphAdaptorExtender<
+      SubDigraphBase<_Digraph, _NodeFilterMap, _ArcFilterMap, _checked> > {
+  public:
+    typedef _Digraph Digraph;
+    typedef _NodeFilterMap NodeFilterMap;
+    typedef _ArcFilterMap ArcFilterMap;
+
+    typedef DigraphAdaptorExtender<
+      SubDigraphBase<Digraph, NodeFilterMap, ArcFilterMap, _checked> >
+    Parent;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+
+  protected:
+    SubDigraph() { }
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Creates a subdigraph for the given digraph with
+    /// given node and arc map filters.
+    SubDigraph(Digraph& digraph, NodeFilterMap& node_filter,
+               ArcFilterMap& arc_filter) {
+      setDigraph(digraph);
+      setNodeFilterMap(node_filter);
+      setArcFilterMap(arc_filter);
+    }
+
+    /// \brief Hides the node of the graph
+    ///
+    /// This function hides \c n in the digraph, i.e. the iteration
+    /// jumps over it. This is done by simply setting the value of \c n
+    /// to be false in the corresponding node-map.
+    void hide(const Node& n) const { Parent::hide(n); }
+
+    /// \brief Hides the arc of the graph
+    ///
+    /// This function hides \c a in the digraph, i.e. the iteration
+    /// jumps over it. This is done by simply setting the value of \c a
+    /// to be false in the corresponding arc-map.
+    void hide(const Arc& a) const { Parent::hide(a); }
+
+    /// \brief Unhides the node of the graph
+    ///
+    /// The value of \c n is set to be true in the node-map which stores
+    /// hide information. If \c n was hidden previuosly, then it is shown
+    /// again
+    void unHide(const Node& n) const { Parent::unHide(n); }
+
+    /// \brief Unhides the arc of the graph
+    ///
+    /// The value of \c a is set to be true in the arc-map which stores
+    /// hide information. If \c a was hidden previuosly, then it is shown
+    /// again
+    void unHide(const Arc& a) const { Parent::unHide(a); }
+
+    /// \brief Returns true if \c n is hidden.
+    ///
+    /// Returns true if \c n is hidden.
+    ///
+    bool hidden(const Node& n) const { return Parent::hidden(n); }
+
+    /// \brief Returns true if \c a is hidden.
+    ///
+    /// Returns true if \c a is hidden.
+    ///
+    bool hidden(const Arc& a) const { return Parent::hidden(a); }
+
+  };
+
+  /// \brief Just gives back a subdigraph
+  ///
+  /// Just gives back a subdigraph
+  template<typename Digraph, typename NodeFilterMap, typename ArcFilterMap>
+  SubDigraph<const Digraph, NodeFilterMap, ArcFilterMap>
+  subDigraph(const Digraph& digraph, NodeFilterMap& nfm, ArcFilterMap& afm) {
+    return SubDigraph<const Digraph, NodeFilterMap, ArcFilterMap>
+      (digraph, nfm, afm);
+  }
+
+  template<typename Digraph, typename NodeFilterMap, typename ArcFilterMap>
+  SubDigraph<const Digraph, const NodeFilterMap, ArcFilterMap>
+  subDigraph(const Digraph& digraph,
+             const NodeFilterMap& nfm, ArcFilterMap& afm) {
+    return SubDigraph<const Digraph, const NodeFilterMap, ArcFilterMap>
+      (digraph, nfm, afm);
+  }
+
+  template<typename Digraph, typename NodeFilterMap, typename ArcFilterMap>
+  SubDigraph<const Digraph, NodeFilterMap, const ArcFilterMap>
+  subDigraph(const Digraph& digraph,
+             NodeFilterMap& nfm, const ArcFilterMap& afm) {
+    return SubDigraph<const Digraph, NodeFilterMap, const ArcFilterMap>
+      (digraph, nfm, afm);
+  }
+
+  template<typename Digraph, typename NodeFilterMap, typename ArcFilterMap>
+  SubDigraph<const Digraph, const NodeFilterMap, const ArcFilterMap>
+  subDigraph(const Digraph& digraph,
+             const NodeFilterMap& nfm, const ArcFilterMap& afm) {
+    return SubDigraph<const Digraph, const NodeFilterMap,
+      const ArcFilterMap>(digraph, nfm, afm);
+  }
+
+
+  template <typename _Graph, typename NodeFilterMap,
+            typename EdgeFilterMap, bool _checked = true>
+  class SubGraphBase : public GraphAdaptorBase<_Graph> {
+  public:
+    typedef _Graph Graph;
+    typedef SubGraphBase Adaptor;
+    typedef GraphAdaptorBase<_Graph> Parent;
+  protected:
+
+    NodeFilterMap* _node_filter_map;
+    EdgeFilterMap* _edge_filter_map;
+
+    SubGraphBase()
+      : Parent(), _node_filter_map(0), _edge_filter_map(0) { }
+
+    void setNodeFilterMap(NodeFilterMap& node_filter_map) {
+      _node_filter_map=&node_filter_map;
+    }
+    void setEdgeFilterMap(EdgeFilterMap& edge_filter_map) {
+      _edge_filter_map=&edge_filter_map;
+    }
+
+  public:
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+    typedef typename Parent::Edge Edge;
+
+    void first(Node& i) const {
+      Parent::first(i);
+      while (i!=INVALID && !(*_node_filter_map)[i]) Parent::next(i);
+    }
+
+    void first(Arc& i) const {
+      Parent::first(i);
+      while (i!=INVALID && (!(*_edge_filter_map)[i]
+                            || !(*_node_filter_map)[Parent::source(i)]
+                            || !(*_node_filter_map)[Parent::target(i)]))
+        Parent::next(i);
+    }
+
+    void first(Edge& i) const {
+      Parent::first(i);
+      while (i!=INVALID && (!(*_edge_filter_map)[i]
+                            || !(*_node_filter_map)[Parent::u(i)]
+                            || !(*_node_filter_map)[Parent::v(i)]))
+        Parent::next(i);
+    }
+
+    void firstIn(Arc& i, const Node& n) const {
+      Parent::firstIn(i, n);
+      while (i!=INVALID && (!(*_edge_filter_map)[i]
+                            || !(*_node_filter_map)[Parent::source(i)]))
+        Parent::nextIn(i);
+    }
+
+    void firstOut(Arc& i, const Node& n) const {
+      Parent::firstOut(i, n);
+      while (i!=INVALID && (!(*_edge_filter_map)[i]
+                            || !(*_node_filter_map)[Parent::target(i)]))
+        Parent::nextOut(i);
+    }
+
+    void firstInc(Edge& i, bool& d, const Node& n) const {
+      Parent::firstInc(i, d, n);
+      while (i!=INVALID && (!(*_edge_filter_map)[i]
+                            || !(*_node_filter_map)[Parent::u(i)]
+                            || !(*_node_filter_map)[Parent::v(i)]))
+        Parent::nextInc(i, d);
+    }
+
+    void next(Node& i) const {
+      Parent::next(i);
+      while (i!=INVALID && !(*_node_filter_map)[i]) Parent::next(i);
+    }
+
+    void next(Arc& i) const {
+      Parent::next(i);
+      while (i!=INVALID && (!(*_edge_filter_map)[i]
+                            || !(*_node_filter_map)[Parent::source(i)]
+                            || !(*_node_filter_map)[Parent::target(i)]))
+        Parent::next(i);
+    }
+
+    void next(Edge& i) const {
+      Parent::next(i);
+      while (i!=INVALID && (!(*_edge_filter_map)[i]
+                            || !(*_node_filter_map)[Parent::u(i)]
+                            || !(*_node_filter_map)[Parent::v(i)]))
+        Parent::next(i);
+    }
+
+    void nextIn(Arc& i) const {
+      Parent::nextIn(i);
+      while (i!=INVALID && (!(*_edge_filter_map)[i]
+                            || !(*_node_filter_map)[Parent::source(i)]))
+        Parent::nextIn(i);
+    }
+
+    void nextOut(Arc& i) const {
+      Parent::nextOut(i);
+      while (i!=INVALID && (!(*_edge_filter_map)[i]
+                            || !(*_node_filter_map)[Parent::target(i)]))
+        Parent::nextOut(i);
+    }
+
+    void nextInc(Edge& i, bool& d) const {
+      Parent::nextInc(i, d);
+      while (i!=INVALID && (!(*_edge_filter_map)[i]
+                            || !(*_node_filter_map)[Parent::u(i)]
+                            || !(*_node_filter_map)[Parent::v(i)]))
+        Parent::nextInc(i, d);
+    }
+
+    void hide(const Node& n) const { _node_filter_map->set(n, false); }
+    void hide(const Edge& e) const { _edge_filter_map->set(e, false); }
+
+    void unHide(const Node& n) const { _node_filter_map->set(n, true); }
+    void unHide(const Edge& e) const { _edge_filter_map->set(e, true); }
+
+    bool hidden(const Node& n) const { return !(*_node_filter_map)[n]; }
+    bool hidden(const Edge& e) const { return !(*_edge_filter_map)[e]; }
+
+    typedef False NodeNumTag;
+    typedef False EdgeNumTag;
+
+    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
+    Arc findArc(const Node& u, const Node& v,
+                const Arc& prev = INVALID) {
+      if (!(*_node_filter_map)[u] || !(*_node_filter_map)[v]) {
+        return INVALID;
+      }
+      Arc arc = Parent::findArc(u, v, prev);
+      while (arc != INVALID && !(*_edge_filter_map)[arc]) {
+        arc = Parent::findArc(u, v, arc);
+      }
+      return arc;
+    }
+    Edge findEdge(const Node& u, const Node& v,
+                  const Edge& prev = INVALID) {
+      if (!(*_node_filter_map)[u] || !(*_node_filter_map)[v]) {
+        return INVALID;
+      }
+      Edge edge = Parent::findEdge(u, v, prev);
+      while (edge != INVALID && !(*_edge_filter_map)[edge]) {
+        edge = Parent::findEdge(u, v, edge);
+      }
+      return edge;
+    }
+
+    template <typename _Value>
+    class NodeMap : public SubMapExtender<Adaptor,
+      typename Parent::template NodeMap<_Value> > {
+    public:
+      typedef _Value Value;
+      typedef SubMapExtender<Adaptor, typename Parent::
+                             template NodeMap<Value> > MapParent;
+
+      NodeMap(const Adaptor& adaptor)
+        : MapParent(adaptor) {}
+      NodeMap(const Adaptor& adaptor, const Value& value)
+        : MapParent(adaptor, value) {}
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        MapParent::operator=(cmap);
+        return *this;
+      }
+    };
+
+    template <typename _Value>
+    class ArcMap : public SubMapExtender<Adaptor,
+      typename Parent::template ArcMap<_Value> > {
+    public:
+      typedef _Value Value;
+      typedef SubMapExtender<Adaptor, typename Parent::
+                             template ArcMap<Value> > MapParent;
+
+      ArcMap(const Adaptor& adaptor)
+        : MapParent(adaptor) {}
+      ArcMap(const Adaptor& adaptor, const Value& value)
+        : MapParent(adaptor, value) {}
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        MapParent::operator=(cmap);
+        return *this;
+      }
+    };
+
+    template <typename _Value>
+    class EdgeMap : public SubMapExtender<Adaptor,
+      typename Parent::template EdgeMap<_Value> > {
+    public:
+      typedef _Value Value;
+      typedef SubMapExtender<Adaptor, typename Parent::
+                             template EdgeMap<Value> > MapParent;
+
+      EdgeMap(const Adaptor& adaptor)
+        : MapParent(adaptor) {}
+
+      EdgeMap(const Adaptor& adaptor, const Value& value)
+        : MapParent(adaptor, value) {}
+
+    private:
+      EdgeMap& operator=(const EdgeMap& cmap) {
+        return operator=<EdgeMap>(cmap);
+      }
+
+      template <typename CMap>
+      EdgeMap& operator=(const CMap& cmap) {
+        MapParent::operator=(cmap);
+        return *this;
+      }
+    };
+
+  };
+
+  template <typename _Graph, typename NodeFilterMap, typename EdgeFilterMap>
+  class SubGraphBase<_Graph, NodeFilterMap, EdgeFilterMap, false>
+    : public GraphAdaptorBase<_Graph> {
+  public:
+    typedef _Graph Graph;
+    typedef SubGraphBase Adaptor;
+    typedef GraphAdaptorBase<_Graph> Parent;
+  protected:
+    NodeFilterMap* _node_filter_map;
+    EdgeFilterMap* _edge_filter_map;
+    SubGraphBase() : Parent(),
+                     _node_filter_map(0), _edge_filter_map(0) { }
+
+    void setNodeFilterMap(NodeFilterMap& node_filter_map) {
+      _node_filter_map=&node_filter_map;
+    }
+    void setEdgeFilterMap(EdgeFilterMap& edge_filter_map) {
+      _edge_filter_map=&edge_filter_map;
+    }
+
+  public:
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+    typedef typename Parent::Edge Edge;
+
+    void first(Node& i) const {
+      Parent::first(i);
+      while (i!=INVALID && !(*_node_filter_map)[i]) Parent::next(i);
+    }
+
+    void first(Arc& i) const {
+      Parent::first(i);
+      while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::next(i);
+    }
+
+    void first(Edge& i) const {
+      Parent::first(i);
+      while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::next(i);
+    }
+
+    void firstIn(Arc& i, const Node& n) const {
+      Parent::firstIn(i, n);
+      while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::nextIn(i);
+    }
+
+    void firstOut(Arc& i, const Node& n) const {
+      Parent::firstOut(i, n);
+      while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::nextOut(i);
+    }
+
+    void firstInc(Edge& i, bool& d, const Node& n) const {
+      Parent::firstInc(i, d, n);
+      while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::nextInc(i, d);
+    }
+
+    void next(Node& i) const {
+      Parent::next(i);
+      while (i!=INVALID && !(*_node_filter_map)[i]) Parent::next(i);
+    }
+    void next(Arc& i) const {
+      Parent::next(i);
+      while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::next(i);
+    }
+    void next(Edge& i) const {
+      Parent::next(i);
+      while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::next(i);
+    }
+    void nextIn(Arc& i) const {
+      Parent::nextIn(i);
+      while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::nextIn(i);
+    }
+
+    void nextOut(Arc& i) const {
+      Parent::nextOut(i);
+      while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::nextOut(i);
+    }
+    void nextInc(Edge& i, bool& d) const {
+      Parent::nextInc(i, d);
+      while (i!=INVALID && !(*_edge_filter_map)[i]) Parent::nextInc(i, d);
+    }
+
+    void hide(const Node& n) const { _node_filter_map->set(n, false); }
+    void hide(const Edge& e) const { _edge_filter_map->set(e, false); }
+
+    void unHide(const Node& n) const { _node_filter_map->set(n, true); }
+    void unHide(const Edge& e) const { _edge_filter_map->set(e, true); }
+
+    bool hidden(const Node& n) const { return !(*_node_filter_map)[n]; }
+    bool hidden(const Edge& e) const { return !(*_edge_filter_map)[e]; }
+
+    typedef False NodeNumTag;
+    typedef False EdgeNumTag;
+
+    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
+    Arc findArc(const Node& u, const Node& v,
+                const Arc& prev = INVALID) {
+      Arc arc = Parent::findArc(u, v, prev);
+      while (arc != INVALID && !(*_edge_filter_map)[arc]) {
+        arc = Parent::findArc(u, v, arc);
+      }
+      return arc;
+    }
+    Edge findEdge(const Node& u, const Node& v,
+                  const Edge& prev = INVALID) {
+      Edge edge = Parent::findEdge(u, v, prev);
+      while (edge != INVALID && !(*_edge_filter_map)[edge]) {
+        edge = Parent::findEdge(u, v, edge);
+      }
+      return edge;
+    }
+
+    template <typename _Value>
+    class NodeMap : public SubMapExtender<Adaptor,
+      typename Parent::template NodeMap<_Value> > {
+    public:
+      typedef _Value Value;
+      typedef SubMapExtender<Adaptor, typename Parent::
+                             template NodeMap<Value> > MapParent;
+
+      NodeMap(const Adaptor& adaptor)
+        : MapParent(adaptor) {}
+      NodeMap(const Adaptor& adaptor, const Value& value)
+        : MapParent(adaptor, value) {}
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        MapParent::operator=(cmap);
+        return *this;
+      }
+    };
+
+    template <typename _Value>
+    class ArcMap : public SubMapExtender<Adaptor,
+      typename Parent::template ArcMap<_Value> > {
+    public:
+      typedef _Value Value;
+      typedef SubMapExtender<Adaptor, typename Parent::
+                             template ArcMap<Value> > MapParent;
+
+      ArcMap(const Adaptor& adaptor)
+        : MapParent(adaptor) {}
+      ArcMap(const Adaptor& adaptor, const Value& value)
+        : MapParent(adaptor, value) {}
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        MapParent::operator=(cmap);
+        return *this;
+      }
+    };
+
+    template <typename _Value>
+    class EdgeMap : public SubMapExtender<Adaptor,
+      typename Parent::template EdgeMap<_Value> > {
+    public:
+      typedef _Value Value;
+      typedef SubMapExtender<Adaptor, typename Parent::
+                             template EdgeMap<Value> > MapParent;
+
+      EdgeMap(const Adaptor& adaptor)
+        : MapParent(adaptor) {}
+
+      EdgeMap(const Adaptor& adaptor, const _Value& value)
+        : MapParent(adaptor, value) {}
+
+    private:
+      EdgeMap& operator=(const EdgeMap& cmap) {
+        return operator=<EdgeMap>(cmap);
+      }
+
+      template <typename CMap>
+      EdgeMap& operator=(const CMap& cmap) {
+        MapParent::operator=(cmap);
+        return *this;
+      }
+    };
+
+  };
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief A graph adaptor for hiding nodes and edges in an
+  /// undirected graph.
+  ///
+  /// SubGraph hides nodes and edges in a graph. A bool node map and a
+  /// bool edge map must be specified, which define the filters for
+  /// nodes and edges. Just the nodes and edges with true value are
+  /// shown in the subgraph. The SubGraph is conform to the \ref
+  /// concepts::Graph "Graph concept". If the \c _checked parameter is
+  /// true, then the edges incident to filtered nodes are also
+  /// filtered out.
+  ///
+  /// \tparam _Graph It must be conform to the \ref
+  /// concepts::Graph "Graph concept". The type can be specified
+  /// to const.
+  /// \tparam _NodeFilterMap A bool valued node map of the the adapted graph.
+  /// \tparam _EdgeFilterMap A bool valued edge map of the the adapted graph.
+  /// \tparam _checked If the parameter is false then the edge filtering
+  /// is not checked with respect to node filter. Otherwise, each edge
+  /// is automatically filtered, which is incident to a filtered node.
+  ///
+  /// \see FilterNodes
+  /// \see FilterEdges
+  template<typename _Graph, typename NodeFilterMap,
+           typename EdgeFilterMap, bool _checked = true>
+  class SubGraph
+    : public GraphAdaptorExtender<
+      SubGraphBase<_Graph, NodeFilterMap, EdgeFilterMap, _checked> > {
+  public:
+    typedef _Graph Graph;
+    typedef GraphAdaptorExtender<
+      SubGraphBase<_Graph, NodeFilterMap, EdgeFilterMap> > Parent;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Edge Edge;
+
+  protected:
+    SubGraph() { }
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Creates a subgraph for the given graph with given node and
+    /// edge map filters.
+    SubGraph(Graph& _graph, NodeFilterMap& node_filter_map,
+             EdgeFilterMap& edge_filter_map) {
+      setGraph(_graph);
+      setNodeFilterMap(node_filter_map);
+      setEdgeFilterMap(edge_filter_map);
+    }
+
+    /// \brief Hides the node of the graph
+    ///
+    /// This function hides \c n in the graph, i.e. the iteration
+    /// jumps over it. This is done by simply setting the value of \c n
+    /// to be false in the corresponding node-map.
+    void hide(const Node& n) const { Parent::hide(n); }
+
+    /// \brief Hides the edge of the graph
+    ///
+    /// This function hides \c e in the graph, i.e. the iteration
+    /// jumps over it. This is done by simply setting the value of \c e
+    /// to be false in the corresponding edge-map.
+    void hide(const Edge& e) const { Parent::hide(e); }
+
+    /// \brief Unhides the node of the graph
+    ///
+    /// The value of \c n is set to be true in the node-map which stores
+    /// hide information. If \c n was hidden previuosly, then it is shown
+    /// again
+    void unHide(const Node& n) const { Parent::unHide(n); }
+
+    /// \brief Unhides the edge of the graph
+    ///
+    /// The value of \c e is set to be true in the edge-map which stores
+    /// hide information. If \c e was hidden previuosly, then it is shown
+    /// again
+    void unHide(const Edge& e) const { Parent::unHide(e); }
+
+    /// \brief Returns true if \c n is hidden.
+    ///
+    /// Returns true if \c n is hidden.
+    ///
+    bool hidden(const Node& n) const { return Parent::hidden(n); }
+
+    /// \brief Returns true if \c e is hidden.
+    ///
+    /// Returns true if \c e is hidden.
+    ///
+    bool hidden(const Edge& e) const { return Parent::hidden(e); }
+  };
+
+  /// \brief Just gives back a subgraph
+  ///
+  /// Just gives back a subgraph
+  template<typename Graph, typename NodeFilterMap, typename ArcFilterMap>
+  SubGraph<const Graph, NodeFilterMap, ArcFilterMap>
+  subGraph(const Graph& graph, NodeFilterMap& nfm, ArcFilterMap& efm) {
+    return SubGraph<const Graph, NodeFilterMap, ArcFilterMap>(graph, nfm, efm);
+  }
+
+  template<typename Graph, typename NodeFilterMap, typename ArcFilterMap>
+  SubGraph<const Graph, const NodeFilterMap, ArcFilterMap>
+  subGraph(const Graph& graph,
+           const NodeFilterMap& nfm, ArcFilterMap& efm) {
+    return SubGraph<const Graph, const NodeFilterMap, ArcFilterMap>
+      (graph, nfm, efm);
+  }
+
+  template<typename Graph, typename NodeFilterMap, typename ArcFilterMap>
+  SubGraph<const Graph, NodeFilterMap, const ArcFilterMap>
+  subGraph(const Graph& graph,
+           NodeFilterMap& nfm, const ArcFilterMap& efm) {
+    return SubGraph<const Graph, NodeFilterMap, const ArcFilterMap>
+      (graph, nfm, efm);
+  }
+
+  template<typename Graph, typename NodeFilterMap, typename ArcFilterMap>
+  SubGraph<const Graph, const NodeFilterMap, const ArcFilterMap>
+  subGraph(const Graph& graph,
+           const NodeFilterMap& nfm, const ArcFilterMap& efm) {
+    return SubGraph<const Graph, const NodeFilterMap, const ArcFilterMap>
+      (graph, nfm, efm);
+  }
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief An adaptor for hiding nodes from a digraph or a graph.
+  ///
+  /// FilterNodes adaptor hides nodes in a graph or a digraph. A bool
+  /// node map must be specified, which defines the filters for
+  /// nodes. Just the unfiltered nodes and the arcs or edges incident
+  /// to unfiltered nodes are shown in the subdigraph or subgraph. The
+  /// FilterNodes is conform to the \ref concepts::Digraph
+  /// "Digraph concept" or \ref concepts::Graph "Graph concept" depending
+  /// on the \c _Digraph template parameter. If the \c _checked
+  /// parameter is true, then the arc or edges incident to filtered nodes
+  /// are also filtered out.
+  ///
+  /// \tparam _Digraph It must be conform to the \ref
+  /// concepts::Digraph "Digraph concept" or \ref concepts::Graph
+  /// "Graph concept". The type can be specified to be const.
+  /// \tparam _NodeFilterMap A bool valued node map of the the adapted graph.
+  /// \tparam _checked If the parameter is false then the arc or edge
+  /// filtering is not checked with respect to node filter. In this
+  /// case just isolated nodes can be filtered out from the
+  /// graph.
+#ifdef DOXYGEN
+  template<typename _Digraph,
+           typename _NodeFilterMap = typename _Digraph::template NodeMap<bool>,
+           bool _checked = true>
+#else
+  template<typename _Digraph,
+           typename _NodeFilterMap = typename _Digraph::template NodeMap<bool>,
+           bool _checked = true,
+           typename Enable = void>
+#endif
+  class FilterNodes
+    : public SubDigraph<_Digraph, _NodeFilterMap,
+                        ConstMap<typename _Digraph::Arc, bool>, _checked> {
+  public:
+
+    typedef _Digraph Digraph;
+    typedef _NodeFilterMap NodeFilterMap;
+
+    typedef SubDigraph<Digraph, NodeFilterMap,
+                       ConstMap<typename Digraph::Arc, bool>, _checked>
+    Parent;
+
+    typedef typename Parent::Node Node;
+
+  protected:
+    ConstMap<typename Digraph::Arc, bool> const_true_map;
+
+    FilterNodes() : const_true_map(true) {
+      Parent::setArcFilterMap(const_true_map);
+    }
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Creates an adaptor for the given digraph or graph with
+    /// given node filter map.
+    FilterNodes(Digraph& _digraph, NodeFilterMap& node_filter) :
+      Parent(), const_true_map(true) {
+      Parent::setDigraph(_digraph);
+      Parent::setNodeFilterMap(node_filter);
+      Parent::setArcFilterMap(const_true_map);
+    }
+
+    /// \brief Hides the node of the graph
+    ///
+    /// This function hides \c n in the digraph or graph, i.e. the iteration
+    /// jumps over it. This is done by simply setting the value of \c n
+    /// to be false in the corresponding node map.
+    void hide(const Node& n) const { Parent::hide(n); }
+
+    /// \brief Unhides the node of the graph
+    ///
+    /// The value of \c n is set to be true in the node-map which stores
+    /// hide information. If \c n was hidden previuosly, then it is shown
+    /// again
+    void unHide(const Node& n) const { Parent::unHide(n); }
+
+    /// \brief Returns true if \c n is hidden.
+    ///
+    /// Returns true if \c n is hidden.
+    ///
+    bool hidden(const Node& n) const { return Parent::hidden(n); }
+
+  };
+
+  template<typename _Graph, typename _NodeFilterMap, bool _checked>
+  class FilterNodes<_Graph, _NodeFilterMap, _checked,
+                    typename enable_if<UndirectedTagIndicator<_Graph> >::type>
+    : public SubGraph<_Graph, _NodeFilterMap,
+                      ConstMap<typename _Graph::Edge, bool>, _checked> {
+  public:
+    typedef _Graph Graph;
+    typedef _NodeFilterMap NodeFilterMap;
+    typedef SubGraph<Graph, NodeFilterMap,
+                     ConstMap<typename Graph::Edge, bool> > Parent;
+
+    typedef typename Parent::Node Node;
+  protected:
+    ConstMap<typename Graph::Edge, bool> const_true_map;
+
+    FilterNodes() : const_true_map(true) {
+      Parent::setEdgeFilterMap(const_true_map);
+    }
+
+  public:
+
+    FilterNodes(Graph& _graph, NodeFilterMap& node_filter_map) :
+      Parent(), const_true_map(true) {
+      Parent::setGraph(_graph);
+      Parent::setNodeFilterMap(node_filter_map);
+      Parent::setEdgeFilterMap(const_true_map);
+    }
+
+    void hide(const Node& n) const { Parent::hide(n); }
+    void unHide(const Node& n) const { Parent::unHide(n); }
+    bool hidden(const Node& n) const { return Parent::hidden(n); }
+
+  };
+
+
+  /// \brief Just gives back a FilterNodes adaptor
+  ///
+  /// Just gives back a FilterNodes adaptor
+  template<typename Digraph, typename NodeFilterMap>
+  FilterNodes<const Digraph, NodeFilterMap>
+  filterNodes(const Digraph& digraph, NodeFilterMap& nfm) {
+    return FilterNodes<const Digraph, NodeFilterMap>(digraph, nfm);
+  }
+
+  template<typename Digraph, typename NodeFilterMap>
+  FilterNodes<const Digraph, const NodeFilterMap>
+  filterNodes(const Digraph& digraph, const NodeFilterMap& nfm) {
+    return FilterNodes<const Digraph, const NodeFilterMap>(digraph, nfm);
+  }
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief An adaptor for hiding arcs from a digraph.
+  ///
+  /// FilterArcs adaptor hides arcs in a digraph. A bool arc map must
+  /// be specified, which defines the filters for arcs. Just the
+  /// unfiltered arcs are shown in the subdigraph. The FilterArcs is
+  /// conform to the \ref concepts::Digraph "Digraph concept".
+  ///
+  /// \tparam _Digraph It must be conform to the \ref concepts::Digraph
+  /// "Digraph concept". The type can be specified to be const.
+  /// \tparam _ArcFilterMap A bool valued arc map of the the adapted
+  /// graph.
+  template<typename _Digraph, typename _ArcFilterMap>
+  class FilterArcs :
+    public SubDigraph<_Digraph, ConstMap<typename _Digraph::Node, bool>,
+                      _ArcFilterMap, false> {
+  public:
+    typedef _Digraph Digraph;
+    typedef _ArcFilterMap ArcFilterMap;
+
+    typedef SubDigraph<Digraph, ConstMap<typename Digraph::Node, bool>,
+                       ArcFilterMap, false> Parent;
+
+    typedef typename Parent::Arc Arc;
+
+  protected:
+    ConstMap<typename Digraph::Node, bool> const_true_map;
+
+    FilterArcs() : const_true_map(true) {
+      Parent::setNodeFilterMap(const_true_map);
+    }
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Creates a FilterArcs adaptor for the given graph with
+    /// given arc map filter.
+    FilterArcs(Digraph& digraph, ArcFilterMap& arc_filter)
+      : Parent(), const_true_map(true) {
+      Parent::setDigraph(digraph);
+      Parent::setNodeFilterMap(const_true_map);
+      Parent::setArcFilterMap(arc_filter);
+    }
+
+    /// \brief Hides the arc of the graph
+    ///
+    /// This function hides \c a in the graph, i.e. the iteration
+    /// jumps over it. This is done by simply setting the value of \c a
+    /// to be false in the corresponding arc map.
+    void hide(const Arc& a) const { Parent::hide(a); }
+
+    /// \brief Unhides the arc of the graph
+    ///
+    /// The value of \c a is set to be true in the arc-map which stores
+    /// hide information. If \c a was hidden previuosly, then it is shown
+    /// again
+    void unHide(const Arc& a) const { Parent::unHide(a); }
+
+    /// \brief Returns true if \c a is hidden.
+    ///
+    /// Returns true if \c a is hidden.
+    ///
+    bool hidden(const Arc& a) const { return Parent::hidden(a); }
+
+  };
+
+  /// \brief Just gives back an FilterArcs adaptor
+  ///
+  /// Just gives back an FilterArcs adaptor
+  template<typename Digraph, typename ArcFilterMap>
+  FilterArcs<const Digraph, ArcFilterMap>
+  filterArcs(const Digraph& digraph, ArcFilterMap& afm) {
+    return FilterArcs<const Digraph, ArcFilterMap>(digraph, afm);
+  }
+
+  template<typename Digraph, typename ArcFilterMap>
+  FilterArcs<const Digraph, const ArcFilterMap>
+  filterArcs(const Digraph& digraph, const ArcFilterMap& afm) {
+    return FilterArcs<const Digraph, const ArcFilterMap>(digraph, afm);
+  }
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief An adaptor for hiding edges from a graph.
+  ///
+  /// FilterEdges adaptor hides edges in a digraph. A bool edge map must
+  /// be specified, which defines the filters for edges. Just the
+  /// unfiltered edges are shown in the subdigraph. The FilterEdges is
+  /// conform to the \ref concepts::Graph "Graph concept".
+  ///
+  /// \tparam _Graph It must be conform to the \ref concepts::Graph
+  /// "Graph concept". The type can be specified to be const.
+  /// \tparam _EdgeFilterMap A bool valued edge map of the the adapted
+  /// graph.
+  template<typename _Graph, typename _EdgeFilterMap>
+  class FilterEdges :
+    public SubGraph<_Graph, ConstMap<typename _Graph::Node,bool>,
+                    _EdgeFilterMap, false> {
+  public:
+    typedef _Graph Graph;
+    typedef _EdgeFilterMap EdgeFilterMap;
+    typedef SubGraph<Graph, ConstMap<typename Graph::Node,bool>,
+                     EdgeFilterMap, false> Parent;
+    typedef typename Parent::Edge Edge;
+  protected:
+    ConstMap<typename Graph::Node, bool> const_true_map;
+
+    FilterEdges() : const_true_map(true) {
+      Parent::setNodeFilterMap(const_true_map);
+    }
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Creates a FilterEdges adaptor for the given graph with
+    /// given edge map filters.
+    FilterEdges(Graph& _graph, EdgeFilterMap& edge_filter_map) :
+      Parent(), const_true_map(true) {
+      Parent::setGraph(_graph);
+      Parent::setNodeFilterMap(const_true_map);
+      Parent::setEdgeFilterMap(edge_filter_map);
+    }
+
+    /// \brief Hides the edge of the graph
+    ///
+    /// This function hides \c e in the graph, i.e. the iteration
+    /// jumps over it. This is done by simply setting the value of \c e
+    /// to be false in the corresponding edge-map.
+    void hide(const Edge& e) const { Parent::hide(e); }
+
+    /// \brief Unhides the edge of the graph
+    ///
+    /// The value of \c e is set to be true in the edge-map which stores
+    /// hide information. If \c e was hidden previuosly, then it is shown
+    /// again
+    void unHide(const Edge& e) const { Parent::unHide(e); }
+
+    /// \brief Returns true if \c e is hidden.
+    ///
+    /// Returns true if \c e is hidden.
+    ///
+    bool hidden(const Edge& e) const { return Parent::hidden(e); }
+
+  };
+
+  /// \brief Just gives back a FilterEdges adaptor
+  ///
+  /// Just gives back a FilterEdges adaptor
+  template<typename Graph, typename EdgeFilterMap>
+  FilterEdges<const Graph, EdgeFilterMap>
+  filterEdges(const Graph& graph, EdgeFilterMap& efm) {
+    return FilterEdges<const Graph, EdgeFilterMap>(graph, efm);
+  }
+
+  template<typename Graph, typename EdgeFilterMap>
+  FilterEdges<const Graph, const EdgeFilterMap>
+  filterEdges(const Graph& graph, const EdgeFilterMap& efm) {
+    return FilterEdges<const Graph, const EdgeFilterMap>(graph, efm);
+  }
+
+  template <typename _Digraph>
+  class UndirectorBase {
+  public:
+    typedef _Digraph Digraph;
+    typedef UndirectorBase Adaptor;
+
+    typedef True UndirectedTag;
+
+    typedef typename Digraph::Arc Edge;
+    typedef typename Digraph::Node Node;
+
+    class Arc : public Edge {
+      friend class UndirectorBase;
+    protected:
+      bool _forward;
+
+      Arc(const Edge& edge, bool forward) :
+        Edge(edge), _forward(forward) {}
+
+    public:
+      Arc() {}
+
+      Arc(Invalid) : Edge(INVALID), _forward(true) {}
+
+      bool operator==(const Arc &other) const {
+        return _forward == other._forward &&
+          static_cast<const Edge&>(*this) == static_cast<const Edge&>(other);
+      }
+      bool operator!=(const Arc &other) const {
+        return _forward != other._forward ||
+          static_cast<const Edge&>(*this) != static_cast<const Edge&>(other);
+      }
+      bool operator<(const Arc &other) const {
+        return _forward < other._forward ||
+          (_forward == other._forward &&
+           static_cast<const Edge&>(*this) < static_cast<const Edge&>(other));
+      }
+    };
+
+
+
+    void first(Node& n) const {
+      _digraph->first(n);
+    }
+
+    void next(Node& n) const {
+      _digraph->next(n);
+    }
+
+    void first(Arc& a) const {
+      _digraph->first(a);
+      a._forward = true;
+    }
+
+    void next(Arc& a) const {
+      if (a._forward) {
+        a._forward = false;
+      } else {
+        _digraph->next(a);
+        a._forward = true;
+      }
+    }
+
+    void first(Edge& e) const {
+      _digraph->first(e);
+    }
+
+    void next(Edge& e) const {
+      _digraph->next(e);
+    }
+
+    void firstOut(Arc& a, const Node& n) const {
+      _digraph->firstIn(a, n);
+      if( static_cast<const Edge&>(a) != INVALID ) {
+        a._forward = false;
+      } else {
+        _digraph->firstOut(a, n);
+        a._forward = true;
+      }
+    }
+    void nextOut(Arc &a) const {
+      if (!a._forward) {
+        Node n = _digraph->target(a);
+        _digraph->nextIn(a);
+        if (static_cast<const Edge&>(a) == INVALID ) {
+          _digraph->firstOut(a, n);
+          a._forward = true;
+        }
+      }
+      else {
+        _digraph->nextOut(a);
+      }
+    }
+
+    void firstIn(Arc &a, const Node &n) const {
+      _digraph->firstOut(a, n);
+      if (static_cast<const Edge&>(a) != INVALID ) {
+        a._forward = false;
+      } else {
+        _digraph->firstIn(a, n);
+        a._forward = true;
+      }
+    }
+    void nextIn(Arc &a) const {
+      if (!a._forward) {
+        Node n = _digraph->source(a);
+        _digraph->nextOut(a);
+        if( static_cast<const Edge&>(a) == INVALID ) {
+          _digraph->firstIn(a, n);
+          a._forward = true;
+        }
+      }
+      else {
+        _digraph->nextIn(a);
+      }
+    }
+
+    void firstInc(Edge &e, bool &d, const Node &n) const {
+      d = true;
+      _digraph->firstOut(e, n);
+      if (e != INVALID) return;
+      d = false;
+      _digraph->firstIn(e, n);
+    }
+
+    void nextInc(Edge &e, bool &d) const {
+      if (d) {
+        Node s = _digraph->source(e);
+        _digraph->nextOut(e);
+        if (e != INVALID) return;
+        d = false;
+        _digraph->firstIn(e, s);
+      } else {
+        _digraph->nextIn(e);
+      }
+    }
+
+    Node u(const Edge& e) const {
+      return _digraph->source(e);
+    }
+
+    Node v(const Edge& e) const {
+      return _digraph->target(e);
+    }
+
+    Node source(const Arc &a) const {
+      return a._forward ? _digraph->source(a) : _digraph->target(a);
+    }
+
+    Node target(const Arc &a) const {
+      return a._forward ? _digraph->target(a) : _digraph->source(a);
+    }
+
+    static Arc direct(const Edge &e, bool d) {
+      return Arc(e, d);
+    }
+    Arc direct(const Edge &e, const Node& n) const {
+      return Arc(e, _digraph->source(e) == n);
+    }
+
+    static bool direction(const Arc &a) { return a._forward; }
+
+    Node nodeFromId(int ix) const { return _digraph->nodeFromId(ix); }
+    Arc arcFromId(int ix) const {
+      return direct(_digraph->arcFromId(ix >> 1), bool(ix & 1));
+    }
+    Edge edgeFromId(int ix) const { return _digraph->arcFromId(ix); }
+
+    int id(const Node &n) const { return _digraph->id(n); }
+    int id(const Arc &a) const {
+      return  (_digraph->id(a) << 1) | (a._forward ? 1 : 0);
+    }
+    int id(const Edge &e) const { return _digraph->id(e); }
+
+    int maxNodeId() const { return _digraph->maxNodeId(); }
+    int maxArcId() const { return (_digraph->maxArcId() << 1) | 1; }
+    int maxEdgeId() const { return _digraph->maxArcId(); }
+
+    Node addNode() { return _digraph->addNode(); }
+    Edge addEdge(const Node& u, const Node& v) {
+      return _digraph->addArc(u, v);
+    }
+
+    void erase(const Node& i) { _digraph->erase(i); }
+    void erase(const Edge& i) { _digraph->erase(i); }
+
+    void clear() { _digraph->clear(); }
+
+    typedef NodeNumTagIndicator<Digraph> NodeNumTag;
+    int nodeNum() const { return 2 * _digraph->arcNum(); }
+    typedef EdgeNumTagIndicator<Digraph> EdgeNumTag;
+    int arcNum() const { return 2 * _digraph->arcNum(); }
+    int edgeNum() const { return _digraph->arcNum(); }
+
+    typedef FindEdgeTagIndicator<Digraph> FindEdgeTag;
+    Arc findArc(Node s, Node t, Arc p = INVALID) const {
+      if (p == INVALID) {
+        Edge arc = _digraph->findArc(s, t);
+        if (arc != INVALID) return direct(arc, true);
+        arc = _digraph->findArc(t, s);
+        if (arc != INVALID) return direct(arc, false);
+      } else if (direction(p)) {
+        Edge arc = _digraph->findArc(s, t, p);
+        if (arc != INVALID) return direct(arc, true);
+        arc = _digraph->findArc(t, s);
+        if (arc != INVALID) return direct(arc, false);
+      } else {
+        Edge arc = _digraph->findArc(t, s, p);
+        if (arc != INVALID) return direct(arc, false);
+      }
+      return INVALID;
+    }
+
+    Edge findEdge(Node s, Node t, Edge p = INVALID) const {
+      if (s != t) {
+        if (p == INVALID) {
+          Edge arc = _digraph->findArc(s, t);
+          if (arc != INVALID) return arc;
+          arc = _digraph->findArc(t, s);
+          if (arc != INVALID) return arc;
+        } else if (_digraph->s(p) == s) {
+          Edge arc = _digraph->findArc(s, t, p);
+          if (arc != INVALID) return arc;
+          arc = _digraph->findArc(t, s);
+          if (arc != INVALID) return arc;
+        } else {
+          Edge arc = _digraph->findArc(t, s, p);
+          if (arc != INVALID) return arc;
+        }
+      } else {
+        return _digraph->findArc(s, t, p);
+      }
+      return INVALID;
+    }
+
+  private:
+
+    template <typename _Value>
+    class ArcMapBase {
+    private:
+
+      typedef typename Digraph::template ArcMap<_Value> MapImpl;
+
+    public:
+
+      typedef typename MapTraits<MapImpl>::ReferenceMapTag ReferenceMapTag;
+
+      typedef _Value Value;
+      typedef Arc Key;
+
+      ArcMapBase(const Adaptor& adaptor) :
+        _forward(*adaptor._digraph), _backward(*adaptor._digraph) {}
+
+      ArcMapBase(const Adaptor& adaptor, const Value& v)
+        : _forward(*adaptor._digraph, v), _backward(*adaptor._digraph, v) {}
+
+      void set(const Arc& a, const Value& v) {
+        if (direction(a)) {
+          _forward.set(a, v);
+        } else {
+          _backward.set(a, v);
+        }
+      }
+
+      typename MapTraits<MapImpl>::ConstReturnValue
+      operator[](const Arc& a) const {
+        if (direction(a)) {
+          return _forward[a];
+        } else {
+          return _backward[a];
+        }
+      }
+
+      typename MapTraits<MapImpl>::ReturnValue
+      operator[](const Arc& a) {
+        if (direction(a)) {
+          return _forward[a];
+        } else {
+          return _backward[a];
+        }
+      }
+
+    protected:
+
+      MapImpl _forward, _backward;
+
+    };
+
+  public:
+
+    template <typename _Value>
+    class NodeMap : public Digraph::template NodeMap<_Value> {
+    public:
+
+      typedef _Value Value;
+      typedef typename Digraph::template NodeMap<Value> Parent;
+
+      explicit NodeMap(const Adaptor& adaptor)
+        : Parent(*adaptor._digraph) {}
+
+      NodeMap(const Adaptor& adaptor, const _Value& value)
+        : Parent(*adaptor._digraph, value) { }
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    template <typename _Value>
+    class ArcMap
+      : public SubMapExtender<Adaptor, ArcMapBase<_Value> >
+    {
+    public:
+      typedef _Value Value;
+      typedef SubMapExtender<Adaptor, ArcMapBase<Value> > Parent;
+
+      ArcMap(const Adaptor& adaptor)
+        : Parent(adaptor) {}
+
+      ArcMap(const Adaptor& adaptor, const Value& value)
+        : Parent(adaptor, value) {}
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+    template <typename _Value>
+    class EdgeMap : public Digraph::template ArcMap<_Value> {
+    public:
+
+      typedef _Value Value;
+      typedef typename Digraph::template ArcMap<Value> Parent;
+
+      explicit EdgeMap(const Adaptor& adaptor)
+        : Parent(*adaptor._digraph) {}
+
+      EdgeMap(const Adaptor& adaptor, const Value& value)
+        : Parent(*adaptor._digraph, value) {}
+
+    private:
+      EdgeMap& operator=(const EdgeMap& cmap) {
+        return operator=<EdgeMap>(cmap);
+      }
+
+      template <typename CMap>
+      EdgeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    typedef typename ItemSetTraits<Digraph, Node>::ItemNotifier NodeNotifier;
+    NodeNotifier& notifier(Node) const { return _digraph->notifier(Node()); }
+
+  protected:
+
+    UndirectorBase() : _digraph(0) {}
+
+    Digraph* _digraph;
+
+    void setDigraph(Digraph& digraph) {
+      _digraph = &digraph;
+    }
+
+  };
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief Undirect the graph
+  ///
+  /// This adaptor makes an undirected graph from a directed
+  /// graph. All arcs of the underlying digraph will be showed in the
+  /// adaptor as an edge. The Orienter adaptor is conform to the \ref
+  /// concepts::Graph "Graph concept".
+  ///
+  /// \tparam _Digraph It must be conform to the \ref
+  /// concepts::Digraph "Digraph concept". The type can be specified
+  /// to const.
+  template<typename _Digraph>
+  class Undirector
+    : public GraphAdaptorExtender<UndirectorBase<_Digraph> > {
+  public:
+    typedef _Digraph Digraph;
+    typedef GraphAdaptorExtender<UndirectorBase<Digraph> > Parent;
+  protected:
+    Undirector() { }
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Creates a undirected graph from the given digraph
+    Undirector(_Digraph& digraph) {
+      setDigraph(digraph);
+    }
+
+    /// \brief ArcMap combined from two original ArcMap
+    ///
+    /// This class adapts two original digraph ArcMap to
+    /// get an arc map on the undirected graph.
+    template <typename _ForwardMap, typename _BackwardMap>
+    class CombinedArcMap {
+    public:
+
+      typedef _ForwardMap ForwardMap;
+      typedef _BackwardMap BackwardMap;
+
+      typedef typename MapTraits<ForwardMap>::ReferenceMapTag ReferenceMapTag;
+
+      typedef typename ForwardMap::Value Value;
+      typedef typename Parent::Arc Key;
+
+      /// \brief Constructor
+      ///
+      /// Constructor
+      CombinedArcMap(ForwardMap& forward, BackwardMap& backward)
+        : _forward(&forward), _backward(&backward) {}
+
+
+      /// \brief Sets the value associated with a key.
+      ///
+      /// Sets the value associated with a key.
+      void set(const Key& e, const Value& a) {
+        if (Parent::direction(e)) {
+          _forward->set(e, a);
+        } else {
+          _backward->set(e, a);
+        }
+      }
+
+      /// \brief Returns the value associated with a key.
+      ///
+      /// Returns the value associated with a key.
+      typename MapTraits<ForwardMap>::ConstReturnValue
+      operator[](const Key& e) const {
+        if (Parent::direction(e)) {
+          return (*_forward)[e];
+        } else {
+          return (*_backward)[e];
+        }
+      }
+
+      /// \brief Returns the value associated with a key.
+      ///
+      /// Returns the value associated with a key.
+      typename MapTraits<ForwardMap>::ReturnValue
+      operator[](const Key& e) {
+        if (Parent::direction(e)) {
+          return (*_forward)[e];
+        } else {
+          return (*_backward)[e];
+        }
+      }
+
+    protected:
+
+      ForwardMap* _forward;
+      BackwardMap* _backward;
+
+    };
+
+    /// \brief Just gives back a combined arc map
+    ///
+    /// Just gives back a combined arc map
+    template <typename ForwardMap, typename BackwardMap>
+    static CombinedArcMap<ForwardMap, BackwardMap>
+    combinedArcMap(ForwardMap& forward, BackwardMap& backward) {
+      return CombinedArcMap<ForwardMap, BackwardMap>(forward, backward);
+    }
+
+    template <typename ForwardMap, typename BackwardMap>
+    static CombinedArcMap<const ForwardMap, BackwardMap>
+    combinedArcMap(const ForwardMap& forward, BackwardMap& backward) {
+      return CombinedArcMap<const ForwardMap,
+        BackwardMap>(forward, backward);
+    }
+
+    template <typename ForwardMap, typename BackwardMap>
+    static CombinedArcMap<ForwardMap, const BackwardMap>
+    combinedArcMap(ForwardMap& forward, const BackwardMap& backward) {
+      return CombinedArcMap<ForwardMap,
+        const BackwardMap>(forward, backward);
+    }
+
+    template <typename ForwardMap, typename BackwardMap>
+    static CombinedArcMap<const ForwardMap, const BackwardMap>
+    combinedArcMap(const ForwardMap& forward, const BackwardMap& backward) {
+      return CombinedArcMap<const ForwardMap,
+        const BackwardMap>(forward, backward);
+    }
+
+  };
+
+  /// \brief Just gives back an undirected view of the given digraph
+  ///
+  /// Just gives back an undirected view of the given digraph
+  template<typename Digraph>
+  Undirector<const Digraph>
+  undirector(const Digraph& digraph) {
+    return Undirector<const Digraph>(digraph);
+  }
+
+  template <typename _Graph, typename _DirectionMap>
+  class OrienterBase {
+  public:
+
+    typedef _Graph Graph;
+    typedef _DirectionMap DirectionMap;
+
+    typedef typename Graph::Node Node;
+    typedef typename Graph::Edge Arc;
+
+    void reverseArc(const Arc& arc) {
+      _direction->set(arc, !(*_direction)[arc]);
+    }
+
+    void first(Node& i) const { _graph->first(i); }
+    void first(Arc& i) const { _graph->first(i); }
+    void firstIn(Arc& i, const Node& n) const {
+      bool d;
+      _graph->firstInc(i, d, n);
+      while (i != INVALID && d == (*_direction)[i]) _graph->nextInc(i, d);
+    }
+    void firstOut(Arc& i, const Node& n ) const {
+      bool d;
+      _graph->firstInc(i, d, n);
+      while (i != INVALID && d != (*_direction)[i]) _graph->nextInc(i, d);
+    }
+
+    void next(Node& i) const { _graph->next(i); }
+    void next(Arc& i) const { _graph->next(i); }
+    void nextIn(Arc& i) const {
+      bool d = !(*_direction)[i];
+      _graph->nextInc(i, d);
+      while (i != INVALID && d == (*_direction)[i]) _graph->nextInc(i, d);
+    }
+    void nextOut(Arc& i) const {
+      bool d = (*_direction)[i];
+      _graph->nextInc(i, d);
+      while (i != INVALID && d != (*_direction)[i]) _graph->nextInc(i, d);
+    }
+
+    Node source(const Arc& e) const {
+      return (*_direction)[e] ? _graph->u(e) : _graph->v(e);
+    }
+    Node target(const Arc& e) const {
+      return (*_direction)[e] ? _graph->v(e) : _graph->u(e);
+    }
+
+    typedef NodeNumTagIndicator<Graph> NodeNumTag;
+    int nodeNum() const { return _graph->nodeNum(); }
+
+    typedef EdgeNumTagIndicator<Graph> EdgeNumTag;
+    int arcNum() const { return _graph->edgeNum(); }
+
+    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
+    Arc findArc(const Node& u, const Node& v,
+                const Arc& prev = INVALID) {
+      Arc arc = prev;
+      bool d = arc == INVALID ? true : (*_direction)[arc];
+      if (d) {
+        arc = _graph->findEdge(u, v, arc);
+        while (arc != INVALID && !(*_direction)[arc]) {
+          _graph->findEdge(u, v, arc);
+        }
+        if (arc != INVALID) return arc;
+      }
+      _graph->findEdge(v, u, arc);
+      while (arc != INVALID && (*_direction)[arc]) {
+        _graph->findEdge(u, v, arc);
+      }
+      return arc;
+    }
+
+    Node addNode() {
+      return Node(_graph->addNode());
+    }
+
+    Arc addArc(const Node& u, const Node& v) {
+      Arc arc = _graph->addArc(u, v);
+      _direction->set(arc, _graph->source(arc) == u);
+      return arc;
+    }
+
+    void erase(const Node& i) { _graph->erase(i); }
+    void erase(const Arc& i) { _graph->erase(i); }
+
+    void clear() { _graph->clear(); }
+
+    int id(const Node& v) const { return _graph->id(v); }
+    int id(const Arc& e) const { return _graph->id(e); }
+
+    Node nodeFromId(int idx) const { return _graph->nodeFromId(idx); }
+    Arc arcFromId(int idx) const { return _graph->edgeFromId(idx); }
+
+    int maxNodeId() const { return _graph->maxNodeId(); }
+    int maxArcId() const { return _graph->maxEdgeId(); }
+
+    typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
+    NodeNotifier& notifier(Node) const { return _graph->notifier(Node()); }
+
+    typedef typename ItemSetTraits<Graph, Arc>::ItemNotifier ArcNotifier;
+    ArcNotifier& notifier(Arc) const { return _graph->notifier(Arc()); }
+
+    template <typename _Value>
+    class NodeMap : public _Graph::template NodeMap<_Value> {
+    public:
+
+      typedef typename _Graph::template NodeMap<_Value> Parent;
+
+      explicit NodeMap(const OrienterBase& adapter)
+        : Parent(*adapter._graph) {}
+
+      NodeMap(const OrienterBase& adapter, const _Value& value)
+        : Parent(*adapter._graph, value) {}
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+
+    };
+
+    template <typename _Value>
+    class ArcMap : public _Graph::template EdgeMap<_Value> {
+    public:
+
+      typedef typename Graph::template EdgeMap<_Value> Parent;
+
+      explicit ArcMap(const OrienterBase& adapter)
+        : Parent(*adapter._graph) { }
+
+      ArcMap(const OrienterBase& adapter, const _Value& value)
+        : Parent(*adapter._graph, value) { }
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+
+
+  protected:
+    Graph* _graph;
+    DirectionMap* _direction;
+
+    void setDirectionMap(DirectionMap& direction) {
+      _direction = &direction;
+    }
+
+    void setGraph(Graph& graph) {
+      _graph = &graph;
+    }
+
+  };
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief Orients the edges of the graph to get a digraph
+  ///
+  /// This adaptor orients each edge in the undirected graph. The
+  /// direction of the arcs stored in an edge node map.  The arcs can
+  /// be easily reverted by the \c reverseArc() member function in the
+  /// adaptor. The Orienter adaptor is conform to the \ref
+  /// concepts::Digraph "Digraph concept".
+  ///
+  /// \tparam _Graph It must be conform to the \ref concepts::Graph
+  /// "Graph concept". The type can be specified to be const.
+  /// \tparam _DirectionMap A bool valued edge map of the the adapted
+  /// graph.
+  ///
+  /// \sa orienter
+  template<typename _Graph,
+           typename DirectionMap = typename _Graph::template EdgeMap<bool> >
+  class Orienter :
+    public DigraphAdaptorExtender<OrienterBase<_Graph, DirectionMap> > {
+  public:
+    typedef _Graph Graph;
+    typedef DigraphAdaptorExtender<
+      OrienterBase<_Graph, DirectionMap> > Parent;
+    typedef typename Parent::Arc Arc;
+  protected:
+    Orienter() { }
+  public:
+
+    /// \brief Constructor of the adaptor
+    ///
+    /// Constructor of the adaptor
+    Orienter(Graph& graph, DirectionMap& direction) {
+      setGraph(graph);
+      setDirectionMap(direction);
+    }
+
+    /// \brief Reverse arc
+    ///
+    /// It reverse the given arc. It simply negate the direction in the map.
+    void reverseArc(const Arc& a) {
+      Parent::reverseArc(a);
+    }
+  };
+
+  /// \brief Just gives back a Orienter
+  ///
+  /// Just gives back a Orienter
+  template<typename Graph, typename DirectionMap>
+  Orienter<const Graph, DirectionMap>
+  orienter(const Graph& graph, DirectionMap& dm) {
+    return Orienter<const Graph, DirectionMap>(graph, dm);
+  }
+
+  template<typename Graph, typename DirectionMap>
+  Orienter<const Graph, const DirectionMap>
+  orienter(const Graph& graph, const DirectionMap& dm) {
+    return Orienter<const Graph, const DirectionMap>(graph, dm);
+  }
+
+  namespace _adaptor_bits {
+
+    template<typename _Digraph,
+             typename _CapacityMap = typename _Digraph::template ArcMap<int>,
+             typename _FlowMap = _CapacityMap,
+             typename _Tolerance = Tolerance<typename _CapacityMap::Value> >
+    class ResForwardFilter {
+    public:
+
+      typedef _Digraph Digraph;
+      typedef _CapacityMap CapacityMap;
+      typedef _FlowMap FlowMap;
+      typedef _Tolerance Tolerance;
+
+      typedef typename Digraph::Arc Key;
+      typedef bool Value;
+
+    private:
+
+      const CapacityMap* _capacity;
+      const FlowMap* _flow;
+      Tolerance _tolerance;
+    public:
+
+      ResForwardFilter(const CapacityMap& capacity, const FlowMap& flow,
+                       const Tolerance& tolerance = Tolerance())
+        : _capacity(&capacity), _flow(&flow), _tolerance(tolerance) { }
+
+      bool operator[](const typename Digraph::Arc& a) const {
+        return _tolerance.positive((*_capacity)[a] - (*_flow)[a]);
+      }
+    };
+
+    template<typename _Digraph,
+             typename _CapacityMap = typename _Digraph::template ArcMap<int>,
+             typename _FlowMap = _CapacityMap,
+             typename _Tolerance = Tolerance<typename _CapacityMap::Value> >
+    class ResBackwardFilter {
+    public:
+
+      typedef _Digraph Digraph;
+      typedef _CapacityMap CapacityMap;
+      typedef _FlowMap FlowMap;
+      typedef _Tolerance Tolerance;
+
+      typedef typename Digraph::Arc Key;
+      typedef bool Value;
+
+    private:
+
+      const CapacityMap* _capacity;
+      const FlowMap* _flow;
+      Tolerance _tolerance;
+
+    public:
+
+      ResBackwardFilter(const CapacityMap& capacity, const FlowMap& flow,
+                        const Tolerance& tolerance = Tolerance())
+        : _capacity(&capacity), _flow(&flow), _tolerance(tolerance) { }
+
+      bool operator[](const typename Digraph::Arc& a) const {
+        return _tolerance.positive((*_flow)[a]);
+      }
+    };
+
+  }
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief An adaptor for composing the residual graph for directed
+  /// flow and circulation problems.
+  ///
+  /// An adaptor for composing the residual graph for directed flow and
+  /// circulation problems.  Let \f$ G=(V, A) \f$ be a directed graph
+  /// and let \f$ F \f$ be a number type. Let moreover \f$ f,c:A\to F \f$,
+  /// be functions on the arc-set.
+  ///
+  /// Then Residual implements the digraph structure with
+  /// node-set \f$ V \f$ and arc-set \f$ A_{forward}\cup A_{backward} \f$,
+  /// where \f$ A_{forward}=\{uv : uv\in A, f(uv)<c(uv)\} \f$ and
+  /// \f$ A_{backward}=\{vu : uv\in A, f(uv)>0\} \f$, i.e. the so
+  /// called residual graph.  When we take the union
+  /// \f$ A_{forward}\cup A_{backward} \f$, multiplicities are counted,
+  /// i.e.  if an arc is in both \f$ A_{forward} \f$ and
+  /// \f$ A_{backward} \f$, then in the adaptor it appears in both
+  /// orientation.
+  ///
+  /// \tparam _Digraph It must be conform to the \ref concepts::Digraph
+  /// "Digraph concept". The type is implicitly const.
+  /// \tparam _CapacityMap An arc map of some numeric type, it defines
+  /// the capacities in the flow problem. The map is implicitly const.
+  /// \tparam _FlowMap An arc map of some numeric type, it defines
+  /// the capacities in the flow problem.
+  /// \tparam _Tolerance Handler for inexact computation.
+  template<typename _Digraph,
+           typename _CapacityMap = typename _Digraph::template ArcMap<int>,
+           typename _FlowMap = _CapacityMap,
+           typename _Tolerance = Tolerance<typename _CapacityMap::Value> >
+  class Residual :
+    public FilterArcs<
+    Undirector<const _Digraph>,
+    typename Undirector<const _Digraph>::template CombinedArcMap<
+      _adaptor_bits::ResForwardFilter<const _Digraph, _CapacityMap,
+                                      _FlowMap, _Tolerance>,
+      _adaptor_bits::ResBackwardFilter<const _Digraph, _CapacityMap,
+                                       _FlowMap, _Tolerance> > >
+  {
+  public:
+
+    typedef _Digraph Digraph;
+    typedef _CapacityMap CapacityMap;
+    typedef _FlowMap FlowMap;
+    typedef _Tolerance Tolerance;
+
+    typedef typename CapacityMap::Value Value;
+    typedef Residual Adaptor;
+
+  protected:
+
+    typedef Undirector<const Digraph> Undirected;
+
+    typedef _adaptor_bits::ResForwardFilter<const Digraph, CapacityMap,
+                                            FlowMap, Tolerance> ForwardFilter;
+
+    typedef _adaptor_bits::ResBackwardFilter<const Digraph, CapacityMap,
+                                             FlowMap, Tolerance> BackwardFilter;
+
+    typedef typename Undirected::
+    template CombinedArcMap<ForwardFilter, BackwardFilter> ArcFilter;
+
+    typedef FilterArcs<Undirected, ArcFilter> Parent;
+
+    const CapacityMap* _capacity;
+    FlowMap* _flow;
+
+    Undirected _graph;
+    ForwardFilter _forward_filter;
+    BackwardFilter _backward_filter;
+    ArcFilter _arc_filter;
+
+  public:
+
+    /// \brief Constructor of the residual digraph.
+    ///
+    /// Constructor of the residual graph. The parameters are the digraph,
+    /// the flow map, the capacity map and a tolerance object.
+    Residual(const Digraph& digraph, const CapacityMap& capacity,
+             FlowMap& flow, const Tolerance& tolerance = Tolerance())
+      : Parent(), _capacity(&capacity), _flow(&flow), _graph(digraph),
+        _forward_filter(capacity, flow, tolerance),
+        _backward_filter(capacity, flow, tolerance),
+        _arc_filter(_forward_filter, _backward_filter)
+    {
+      Parent::setDigraph(_graph);
+      Parent::setArcFilterMap(_arc_filter);
+    }
+
+    typedef typename Parent::Arc Arc;
+
+    /// \brief Gives back the residual capacity of the arc.
+    ///
+    /// Gives back the residual capacity of the arc.
+    Value residualCapacity(const Arc& a) const {
+      if (Undirected::direction(a)) {
+        return (*_capacity)[a] - (*_flow)[a];
+      } else {
+        return (*_flow)[a];
+      }
+    }
+
+    /// \brief Augment on the given arc in the residual graph.
+    ///
+    /// Augment on the given arc in the residual graph. It increase
+    /// or decrease the flow on the original arc depend on the direction
+    /// of the residual arc.
+    void augment(const Arc& a, const Value& v) const {
+      if (Undirected::direction(a)) {
+        _flow->set(a, (*_flow)[a] + v);
+      } else {
+        _flow->set(a, (*_flow)[a] - v);
+      }
+    }
+
+    /// \brief Returns the direction of the arc.
+    ///
+    /// Returns true when the arc is same oriented as the original arc.
+    static bool forward(const Arc& a) {
+      return Undirected::direction(a);
+    }
+
+    /// \brief Returns the direction of the arc.
+    ///
+    /// Returns true when the arc is opposite oriented as the original arc.
+    static bool backward(const Arc& a) {
+      return !Undirected::direction(a);
+    }
+
+    /// \brief Gives back the forward oriented residual arc.
+    ///
+    /// Gives back the forward oriented residual arc.
+    static Arc forward(const typename Digraph::Arc& a) {
+      return Undirected::direct(a, true);
+    }
+
+    /// \brief Gives back the backward oriented residual arc.
+    ///
+    /// Gives back the backward oriented residual arc.
+    static Arc backward(const typename Digraph::Arc& a) {
+      return Undirected::direct(a, false);
+    }
+
+    /// \brief Residual capacity map.
+    ///
+    /// In generic residual graph the residual capacity can be obtained
+    /// as a map.
+    class ResidualCapacity {
+    protected:
+      const Adaptor* _adaptor;
+    public:
+      /// The Key type
+      typedef Arc Key;
+      /// The Value type
+      typedef typename _CapacityMap::Value Value;
+
+      /// Constructor
+      ResidualCapacity(const Adaptor& adaptor) : _adaptor(&adaptor) {}
+
+      /// \e
+      Value operator[](const Arc& a) const {
+        return _adaptor->residualCapacity(a);
+      }
+
+    };
+
+  };
+
+  template <typename _Digraph>
+  class SplitNodesBase {
+  public:
+
+    typedef _Digraph Digraph;
+    typedef DigraphAdaptorBase<const _Digraph> Parent;
+    typedef SplitNodesBase Adaptor;
+
+    typedef typename Digraph::Node DigraphNode;
+    typedef typename Digraph::Arc DigraphArc;
+
+    class Node;
+    class Arc;
+
+  private:
+
+    template <typename T> class NodeMapBase;
+    template <typename T> class ArcMapBase;
+
+  public:
+
+    class Node : public DigraphNode {
+      friend class SplitNodesBase;
+      template <typename T> friend class NodeMapBase;
+    private:
+
+      bool _in;
+      Node(DigraphNode node, bool in)
+        : DigraphNode(node), _in(in) {}
+
+    public:
+
+      Node() {}
+      Node(Invalid) : DigraphNode(INVALID), _in(true) {}
+
+      bool operator==(const Node& node) const {
+        return DigraphNode::operator==(node) && _in == node._in;
+      }
+
+      bool operator!=(const Node& node) const {
+        return !(*this == node);
+      }
+
+      bool operator<(const Node& node) const {
+        return DigraphNode::operator<(node) ||
+          (DigraphNode::operator==(node) && _in < node._in);
+      }
+    };
+
+    class Arc {
+      friend class SplitNodesBase;
+      template <typename T> friend class ArcMapBase;
+    private:
+      typedef BiVariant<DigraphArc, DigraphNode> ArcImpl;
+
+      explicit Arc(const DigraphArc& arc) : _item(arc) {}
+      explicit Arc(const DigraphNode& node) : _item(node) {}
+
+      ArcImpl _item;
+
+    public:
+      Arc() {}
+      Arc(Invalid) : _item(DigraphArc(INVALID)) {}
+
+      bool operator==(const Arc& arc) const {
+        if (_item.firstState()) {
+          if (arc._item.firstState()) {
+            return _item.first() == arc._item.first();
+          }
+        } else {
+          if (arc._item.secondState()) {
+            return _item.second() == arc._item.second();
+          }
+        }
+        return false;
+      }
+
+      bool operator!=(const Arc& arc) const {
+        return !(*this == arc);
+      }
+
+      bool operator<(const Arc& arc) const {
+        if (_item.firstState()) {
+          if (arc._item.firstState()) {
+            return _item.first() < arc._item.first();
+          }
+          return false;
+        } else {
+          if (arc._item.secondState()) {
+            return _item.second() < arc._item.second();
+          }
+          return true;
+        }
+      }
+
+      operator DigraphArc() const { return _item.first(); }
+      operator DigraphNode() const { return _item.second(); }
+
+    };
+
+    void first(Node& n) const {
+      _digraph->first(n);
+      n._in = true;
+    }
+
+    void next(Node& n) const {
+      if (n._in) {
+        n._in = false;
+      } else {
+        n._in = true;
+        _digraph->next(n);
+      }
+    }
+
+    void first(Arc& e) const {
+      e._item.setSecond();
+      _digraph->first(e._item.second());
+      if (e._item.second() == INVALID) {
+        e._item.setFirst();
+        _digraph->first(e._item.first());
+      }
+    }
+
+    void next(Arc& e) const {
+      if (e._item.secondState()) {
+        _digraph->next(e._item.second());
+        if (e._item.second() == INVALID) {
+          e._item.setFirst();
+          _digraph->first(e._item.first());
+        }
+      } else {
+        _digraph->next(e._item.first());
+      }
+    }
+
+    void firstOut(Arc& e, const Node& n) const {
+      if (n._in) {
+        e._item.setSecond(n);
+      } else {
+        e._item.setFirst();
+        _digraph->firstOut(e._item.first(), n);
+      }
+    }
+
+    void nextOut(Arc& e) const {
+      if (!e._item.firstState()) {
+        e._item.setFirst(INVALID);
+      } else {
+        _digraph->nextOut(e._item.first());
+      }
+    }
+
+    void firstIn(Arc& e, const Node& n) const {
+      if (!n._in) {
+        e._item.setSecond(n);
+      } else {
+        e._item.setFirst();
+        _digraph->firstIn(e._item.first(), n);
+      }
+    }
+
+    void nextIn(Arc& e) const {
+      if (!e._item.firstState()) {
+        e._item.setFirst(INVALID);
+      } else {
+        _digraph->nextIn(e._item.first());
+      }
+    }
+
+    Node source(const Arc& e) const {
+      if (e._item.firstState()) {
+        return Node(_digraph->source(e._item.first()), false);
+      } else {
+        return Node(e._item.second(), true);
+      }
+    }
+
+    Node target(const Arc& e) const {
+      if (e._item.firstState()) {
+        return Node(_digraph->target(e._item.first()), true);
+      } else {
+        return Node(e._item.second(), false);
+      }
+    }
+
+    int id(const Node& n) const {
+      return (_digraph->id(n) << 1) | (n._in ? 0 : 1);
+    }
+    Node nodeFromId(int ix) const {
+      return Node(_digraph->nodeFromId(ix >> 1), (ix & 1) == 0);
+    }
+    int maxNodeId() const {
+      return 2 * _digraph->maxNodeId() + 1;
+    }
+
+    int id(const Arc& e) const {
+      if (e._item.firstState()) {
+        return _digraph->id(e._item.first()) << 1;
+      } else {
+        return (_digraph->id(e._item.second()) << 1) | 1;
+      }
+    }
+    Arc arcFromId(int ix) const {
+      if ((ix & 1) == 0) {
+        return Arc(_digraph->arcFromId(ix >> 1));
+      } else {
+        return Arc(_digraph->nodeFromId(ix >> 1));
+      }
+    }
+    int maxArcId() const {
+      return std::max(_digraph->maxNodeId() << 1,
+                      (_digraph->maxArcId() << 1) | 1);
+    }
+
+    static bool inNode(const Node& n) {
+      return n._in;
+    }
+
+    static bool outNode(const Node& n) {
+      return !n._in;
+    }
+
+    static bool origArc(const Arc& e) {
+      return e._item.firstState();
+    }
+
+    static bool bindArc(const Arc& e) {
+      return e._item.secondState();
+    }
+
+    static Node inNode(const DigraphNode& n) {
+      return Node(n, true);
+    }
+
+    static Node outNode(const DigraphNode& n) {
+      return Node(n, false);
+    }
+
+    static Arc arc(const DigraphNode& n) {
+      return Arc(n);
+    }
+
+    static Arc arc(const DigraphArc& e) {
+      return Arc(e);
+    }
+
+    typedef True NodeNumTag;
+
+    int nodeNum() const {
+      return  2 * countNodes(*_digraph);
+    }
+
+    typedef True EdgeNumTag;
+    int arcNum() const {
+      return countArcs(*_digraph) + countNodes(*_digraph);
+    }
+
+    typedef True FindEdgeTag;
+    Arc findArc(const Node& u, const Node& v,
+                const Arc& prev = INVALID) const {
+      if (inNode(u)) {
+        if (outNode(v)) {
+          if (static_cast<const DigraphNode&>(u) ==
+              static_cast<const DigraphNode&>(v) && prev == INVALID) {
+            return Arc(u);
+          }
+        }
+      } else {
+        if (inNode(v)) {
+          return Arc(::lemon::findArc(*_digraph, u, v, prev));
+        }
+      }
+      return INVALID;
+    }
+
+  private:
+
+    template <typename _Value>
+    class NodeMapBase
+      : public MapTraits<typename Parent::template NodeMap<_Value> > {
+      typedef typename Parent::template NodeMap<_Value> NodeImpl;
+    public:
+      typedef Node Key;
+      typedef _Value Value;
+
+      NodeMapBase(const Adaptor& adaptor)
+        : _in_map(*adaptor._digraph), _out_map(*adaptor._digraph) {}
+      NodeMapBase(const Adaptor& adaptor, const Value& value)
+        : _in_map(*adaptor._digraph, value),
+          _out_map(*adaptor._digraph, value) {}
+
+      void set(const Node& key, const Value& val) {
+        if (Adaptor::inNode(key)) { _in_map.set(key, val); }
+        else {_out_map.set(key, val); }
+      }
+
+      typename MapTraits<NodeImpl>::ReturnValue
+      operator[](const Node& key) {
+        if (Adaptor::inNode(key)) { return _in_map[key]; }
+        else { return _out_map[key]; }
+      }
+
+      typename MapTraits<NodeImpl>::ConstReturnValue
+      operator[](const Node& key) const {
+        if (Adaptor::inNode(key)) { return _in_map[key]; }
+        else { return _out_map[key]; }
+      }
+
+    private:
+      NodeImpl _in_map, _out_map;
+    };
+
+    template <typename _Value>
+    class ArcMapBase
+      : public MapTraits<typename Parent::template ArcMap<_Value> > {
+      typedef typename Parent::template ArcMap<_Value> ArcImpl;
+      typedef typename Parent::template NodeMap<_Value> NodeImpl;
+    public:
+      typedef Arc Key;
+      typedef _Value Value;
+
+      ArcMapBase(const Adaptor& adaptor)
+        : _arc_map(*adaptor._digraph), _node_map(*adaptor._digraph) {}
+      ArcMapBase(const Adaptor& adaptor, const Value& value)
+        : _arc_map(*adaptor._digraph, value),
+          _node_map(*adaptor._digraph, value) {}
+
+      void set(const Arc& key, const Value& val) {
+        if (Adaptor::origArc(key)) {
+          _arc_map.set(key._item.first(), val);
+        } else {
+          _node_map.set(key._item.second(), val);
+        }
+      }
+
+      typename MapTraits<ArcImpl>::ReturnValue
+      operator[](const Arc& key) {
+        if (Adaptor::origArc(key)) {
+          return _arc_map[key._item.first()];
+        } else {
+          return _node_map[key._item.second()];
+        }
+      }
+
+      typename MapTraits<ArcImpl>::ConstReturnValue
+      operator[](const Arc& key) const {
+        if (Adaptor::origArc(key)) {
+          return _arc_map[key._item.first()];
+        } else {
+          return _node_map[key._item.second()];
+        }
+      }
+
+    private:
+      ArcImpl _arc_map;
+      NodeImpl _node_map;
+    };
+
+  public:
+
+    template <typename _Value>
+    class NodeMap
+      : public SubMapExtender<Adaptor, NodeMapBase<_Value> >
+    {
+    public:
+      typedef _Value Value;
+      typedef SubMapExtender<Adaptor, NodeMapBase<Value> > Parent;
+
+      NodeMap(const Adaptor& adaptor)
+        : Parent(adaptor) {}
+
+      NodeMap(const Adaptor& adaptor, const Value& value)
+        : Parent(adaptor, value) {}
+
+    private:
+      NodeMap& operator=(const NodeMap& cmap) {
+        return operator=<NodeMap>(cmap);
+      }
+
+      template <typename CMap>
+      NodeMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+    template <typename _Value>
+    class ArcMap
+      : public SubMapExtender<Adaptor, ArcMapBase<_Value> >
+    {
+    public:
+      typedef _Value Value;
+      typedef SubMapExtender<Adaptor, ArcMapBase<Value> > Parent;
+
+      ArcMap(const Adaptor& adaptor)
+        : Parent(adaptor) {}
+
+      ArcMap(const Adaptor& adaptor, const Value& value)
+        : Parent(adaptor, value) {}
+
+    private:
+      ArcMap& operator=(const ArcMap& cmap) {
+        return operator=<ArcMap>(cmap);
+      }
+
+      template <typename CMap>
+      ArcMap& operator=(const CMap& cmap) {
+        Parent::operator=(cmap);
+        return *this;
+      }
+    };
+
+  protected:
+
+    SplitNodesBase() : _digraph(0) {}
+
+    Digraph* _digraph;
+
+    void setDigraph(Digraph& digraph) {
+      _digraph = &digraph;
+    }
+
+  };
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief Split the nodes of a directed graph
+  ///
+  /// The SplitNodes adaptor splits each node into an in-node and an
+  /// out-node. Formaly, the adaptor replaces each \f$ u \f$ node in
+  /// the digraph with two nodes(namely node \f$ u_{in} \f$ and node
+  /// \f$ u_{out} \f$). If there is a \f$ (v, u) \f$ arc in the
+  /// original digraph the new target of the arc will be \f$ u_{in} \f$
+  /// and similarly the source of the original \f$ (u, v) \f$ arc
+  /// will be \f$ u_{out} \f$.  The adaptor will add for each node in
+  /// the original digraph an additional arc which connects
+  /// \f$ (u_{in}, u_{out}) \f$.
+  ///
+  /// The aim of this class is to run algorithm with node costs if the
+  /// algorithm can use directly just arc costs. In this case we should use
+  /// a \c SplitNodes and set the node cost of the graph to the
+  /// bind arc in the adapted graph.
+  ///
+  /// \tparam _Digraph It must be conform to the \ref concepts::Digraph
+  /// "Digraph concept". The type can be specified to be const.
+  template <typename _Digraph>
+  class SplitNodes
+    : public DigraphAdaptorExtender<SplitNodesBase<_Digraph> > {
+  public:
+    typedef _Digraph Digraph;
+    typedef DigraphAdaptorExtender<SplitNodesBase<Digraph> > Parent;
+
+    typedef typename Digraph::Node DigraphNode;
+    typedef typename Digraph::Arc DigraphArc;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+
+    /// \brief Constructor of the adaptor.
+    ///
+    /// Constructor of the adaptor.
+    SplitNodes(Digraph& g) {
+      Parent::setDigraph(g);
+    }
+
+    /// \brief Returns true when the node is in-node.
+    ///
+    /// Returns true when the node is in-node.
+    static bool inNode(const Node& n) {
+      return Parent::inNode(n);
+    }
+
+    /// \brief Returns true when the node is out-node.
+    ///
+    /// Returns true when the node is out-node.
+    static bool outNode(const Node& n) {
+      return Parent::outNode(n);
+    }
+
+    /// \brief Returns true when the arc is arc in the original digraph.
+    ///
+    /// Returns true when the arc is arc in the original digraph.
+    static bool origArc(const Arc& a) {
+      return Parent::origArc(a);
+    }
+
+    /// \brief Returns true when the arc binds an in-node and an out-node.
+    ///
+    /// Returns true when the arc binds an in-node and an out-node.
+    static bool bindArc(const Arc& a) {
+      return Parent::bindArc(a);
+    }
+
+    /// \brief Gives back the in-node created from the \c node.
+    ///
+    /// Gives back the in-node created from the \c node.
+    static Node inNode(const DigraphNode& n) {
+      return Parent::inNode(n);
+    }
+
+    /// \brief Gives back the out-node created from the \c node.
+    ///
+    /// Gives back the out-node created from the \c node.
+    static Node outNode(const DigraphNode& n) {
+      return Parent::outNode(n);
+    }
+
+    /// \brief Gives back the arc binds the two part of the node.
+    ///
+    /// Gives back the arc binds the two part of the node.
+    static Arc arc(const DigraphNode& n) {
+      return Parent::arc(n);
+    }
+
+    /// \brief Gives back the arc of the original arc.
+    ///
+    /// Gives back the arc of the original arc.
+    static Arc arc(const DigraphArc& a) {
+      return Parent::arc(a);
+    }
+
+    /// \brief NodeMap combined from two original NodeMap
+    ///
+    /// This class adapt two of the original digraph NodeMap to
+    /// get a node map on the adapted digraph.
+    template <typename InNodeMap, typename OutNodeMap>
+    class CombinedNodeMap {
+    public:
+
+      typedef Node Key;
+      typedef typename InNodeMap::Value Value;
+
+      /// \brief Constructor
+      ///
+      /// Constructor.
+      CombinedNodeMap(InNodeMap& in_map, OutNodeMap& out_map)
+        : _in_map(in_map), _out_map(out_map) {}
+
+      /// \brief The subscript operator.
+      ///
+      /// The subscript operator.
+      Value& operator[](const Key& key) {
+        if (Parent::inNode(key)) {
+          return _in_map[key];
+        } else {
+          return _out_map[key];
+        }
+      }
+
+      /// \brief The const subscript operator.
+      ///
+      /// The const subscript operator.
+      Value operator[](const Key& key) const {
+        if (Parent::inNode(key)) {
+          return _in_map[key];
+        } else {
+          return _out_map[key];
+        }
+      }
+
+      /// \brief The setter function of the map.
+      ///
+      /// The setter function of the map.
+      void set(const Key& key, const Value& value) {
+        if (Parent::inNode(key)) {
+          _in_map.set(key, value);
+        } else {
+          _out_map.set(key, value);
+        }
+      }
+
+    private:
+
+      InNodeMap& _in_map;
+      OutNodeMap& _out_map;
+
+    };
+
+
+    /// \brief Just gives back a combined node map
+    ///
+    /// Just gives back a combined node map
+    template <typename InNodeMap, typename OutNodeMap>
+    static CombinedNodeMap<InNodeMap, OutNodeMap>
+    combinedNodeMap(InNodeMap& in_map, OutNodeMap& out_map) {
+      return CombinedNodeMap<InNodeMap, OutNodeMap>(in_map, out_map);
+    }
+
+    template <typename InNodeMap, typename OutNodeMap>
+    static CombinedNodeMap<const InNodeMap, OutNodeMap>
+    combinedNodeMap(const InNodeMap& in_map, OutNodeMap& out_map) {
+      return CombinedNodeMap<const InNodeMap, OutNodeMap>(in_map, out_map);
+    }
+
+    template <typename InNodeMap, typename OutNodeMap>
+    static CombinedNodeMap<InNodeMap, const OutNodeMap>
+    combinedNodeMap(InNodeMap& in_map, const OutNodeMap& out_map) {
+      return CombinedNodeMap<InNodeMap, const OutNodeMap>(in_map, out_map);
+    }
+
+    template <typename InNodeMap, typename OutNodeMap>
+    static CombinedNodeMap<const InNodeMap, const OutNodeMap>
+    combinedNodeMap(const InNodeMap& in_map, const OutNodeMap& out_map) {
+      return CombinedNodeMap<const InNodeMap,
+        const OutNodeMap>(in_map, out_map);
+    }
+
+    /// \brief ArcMap combined from an original ArcMap and a NodeMap
+    ///
+    /// This class adapt an original ArcMap and a NodeMap to get an
+    /// arc map on the adapted digraph
+    template <typename DigraphArcMap, typename DigraphNodeMap>
+    class CombinedArcMap {
+    public:
+
+      typedef Arc Key;
+      typedef typename DigraphArcMap::Value Value;
+
+      /// \brief Constructor
+      ///
+      /// Constructor.
+      CombinedArcMap(DigraphArcMap& arc_map, DigraphNodeMap& node_map)
+        : _arc_map(arc_map), _node_map(node_map) {}
+
+      /// \brief The subscript operator.
+      ///
+      /// The subscript operator.
+      void set(const Arc& arc, const Value& val) {
+        if (Parent::origArc(arc)) {
+          _arc_map.set(arc, val);
+        } else {
+          _node_map.set(arc, val);
+        }
+      }
+
+      /// \brief The const subscript operator.
+      ///
+      /// The const subscript operator.
+      Value operator[](const Key& arc) const {
+        if (Parent::origArc(arc)) {
+          return _arc_map[arc];
+        } else {
+          return _node_map[arc];
+        }
+      }
+
+      /// \brief The const subscript operator.
+      ///
+      /// The const subscript operator.
+      Value& operator[](const Key& arc) {
+        if (Parent::origArc(arc)) {
+          return _arc_map[arc];
+        } else {
+          return _node_map[arc];
+        }
+      }
+
+    private:
+      DigraphArcMap& _arc_map;
+      DigraphNodeMap& _node_map;
+    };
+
+    /// \brief Just gives back a combined arc map
+    ///
+    /// Just gives back a combined arc map
+    template <typename DigraphArcMap, typename DigraphNodeMap>
+    static CombinedArcMap<DigraphArcMap, DigraphNodeMap>
+    combinedArcMap(DigraphArcMap& arc_map, DigraphNodeMap& node_map) {
+      return CombinedArcMap<DigraphArcMap, DigraphNodeMap>(arc_map, node_map);
+    }
+
+    template <typename DigraphArcMap, typename DigraphNodeMap>
+    static CombinedArcMap<const DigraphArcMap, DigraphNodeMap>
+    combinedArcMap(const DigraphArcMap& arc_map, DigraphNodeMap& node_map) {
+      return CombinedArcMap<const DigraphArcMap,
+        DigraphNodeMap>(arc_map, node_map);
+    }
+
+    template <typename DigraphArcMap, typename DigraphNodeMap>
+    static CombinedArcMap<DigraphArcMap, const DigraphNodeMap>
+    combinedArcMap(DigraphArcMap& arc_map, const DigraphNodeMap& node_map) {
+      return CombinedArcMap<DigraphArcMap,
+        const DigraphNodeMap>(arc_map, node_map);
+    }
+
+    template <typename DigraphArcMap, typename DigraphNodeMap>
+    static CombinedArcMap<const DigraphArcMap, const DigraphNodeMap>
+    combinedArcMap(const DigraphArcMap& arc_map,
+                   const DigraphNodeMap& node_map) {
+      return CombinedArcMap<const DigraphArcMap,
+        const DigraphNodeMap>(arc_map, node_map);
+    }
+
+  };
+
+  /// \brief Just gives back a node splitter
+  ///
+  /// Just gives back a node splitter
+  template<typename Digraph>
+  SplitNodes<Digraph>
+  splitNodes(const Digraph& digraph) {
+    return SplitNodes<Digraph>(digraph);
+  }
+
+
+} //namespace lemon
+
+#endif //LEMON_ADAPTORS_H
Index: lemon/arg_parser.cc
===================================================================
--- lemon/arg_parser.cc	(revision 311)
+++ lemon/arg_parser.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/arg_parser.h
===================================================================
--- lemon/arg_parser.h	(revision 311)
+++ lemon/arg_parser.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/assert.h
===================================================================
--- lemon/assert.h	(revision 290)
+++ lemon/assert.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/base.cc
===================================================================
--- lemon/base.cc	(revision 220)
+++ lemon/base.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bfs.h
===================================================================
--- lemon/bfs.h	(revision 301)
+++ lemon/bfs.h	(revision 492)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -50,9 +50,9 @@
     ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
-    ///Instantiates a PredMap.
-
-    ///This function instantiates a PredMap.
+    ///Instantiates a \c PredMap.
+
+    ///This function instantiates a \ref PredMap.
     ///\param g is the digraph, to which we would like to define the
-    ///PredMap.
+    ///\ref PredMap.
     static PredMap *createPredMap(const Digraph &g)
     {
@@ -65,9 +65,9 @@
     ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
-    ///Instantiates a ProcessedMap.
-
-    ///This function instantiates a ProcessedMap.
+    ///Instantiates a \c ProcessedMap.
+
+    ///This function instantiates a \ref ProcessedMap.
     ///\param g is the digraph, to which
-    ///we would like to define the ProcessedMap
+    ///we would like to define the \ref ProcessedMap
 #ifdef DOXYGEN
     static ProcessedMap *createProcessedMap(const Digraph &g)
@@ -84,9 +84,9 @@
     ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     typedef typename Digraph::template NodeMap<bool> ReachedMap;
-    ///Instantiates a ReachedMap.
-
-    ///This function instantiates a ReachedMap.
+    ///Instantiates a \c ReachedMap.
+
+    ///This function instantiates a \ref ReachedMap.
     ///\param g is the digraph, to which
-    ///we would like to define the ReachedMap.
+    ///we would like to define the \ref ReachedMap.
     static ReachedMap *createReachedMap(const Digraph &g)
     {
@@ -99,9 +99,9 @@
     ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     typedef typename Digraph::template NodeMap<int> DistMap;
-    ///Instantiates a DistMap.
-
-    ///This function instantiates a DistMap.
+    ///Instantiates a \c DistMap.
+
+    ///This function instantiates a \ref DistMap.
     ///\param g is the digraph, to which we would like to define the
-    ///DistMap.
+    ///\ref DistMap.
     static DistMap *createDistMap(const Digraph &g)
     {
@@ -120,11 +120,5 @@
   ///
   ///\tparam GR The type of the digraph the algorithm runs on.
-  ///The default value is \ref ListDigraph. The value of GR is not used
-  ///directly by \ref Bfs, it is only passed to \ref BfsDefaultTraits.
-  ///\tparam TR Traits class to set various data types used by the algorithm.
-  ///The default traits class is
-  ///\ref BfsDefaultTraits "BfsDefaultTraits<GR>".
-  ///See \ref BfsDefaultTraits for the documentation of
-  ///a Bfs traits class.
+  ///The default type is \ref ListDigraph.
 #ifdef DOXYGEN
   template <typename GR,
@@ -152,5 +146,5 @@
     typedef PredMapPath<Digraph, PredMap> Path;
 
-    ///The traits class.
+    ///The \ref BfsDefaultTraits "traits class" of the algorithm.
     typedef TR Traits;
 
@@ -214,5 +208,5 @@
     typedef Bfs Create;
 
-    ///\name Named template parameters
+    ///\name Named Template Parameters
 
     ///@{
@@ -228,8 +222,9 @@
     };
     ///\brief \ref named-templ-param "Named parameter" for setting
-    ///PredMap type.
+    ///\c PredMap type.
     ///
     ///\ref named-templ-param "Named parameter" for setting
-    ///PredMap type.
+    ///\c PredMap type.
+    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetPredMap : public Bfs< Digraph, SetPredMapTraits<T> > {
@@ -247,8 +242,9 @@
     };
     ///\brief \ref named-templ-param "Named parameter" for setting
-    ///DistMap type.
+    ///\c DistMap type.
     ///
     ///\ref named-templ-param "Named parameter" for setting
-    ///DistMap type.
+    ///\c DistMap type.
+    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetDistMap : public Bfs< Digraph, SetDistMapTraits<T> > {
@@ -266,8 +262,9 @@
     };
     ///\brief \ref named-templ-param "Named parameter" for setting
-    ///ReachedMap type.
+    ///\c ReachedMap type.
     ///
     ///\ref named-templ-param "Named parameter" for setting
-    ///ReachedMap type.
+    ///\c ReachedMap type.
+    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     template <class T>
     struct SetReachedMap : public Bfs< Digraph, SetReachedMapTraits<T> > {
@@ -285,8 +282,9 @@
     };
     ///\brief \ref named-templ-param "Named parameter" for setting
-    ///ProcessedMap type.
+    ///\c ProcessedMap type.
     ///
     ///\ref named-templ-param "Named parameter" for setting
-    ///ProcessedMap type.
+    ///\c ProcessedMap type.
+    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetProcessedMap : public Bfs< Digraph, SetProcessedMapTraits<T> > {
@@ -303,8 +301,8 @@
     };
     ///\brief \ref named-templ-param "Named parameter" for setting
-    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
+    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
     ///
     ///\ref named-templ-param "Named parameter" for setting
-    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
+    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
     ///If you don't set it explicitly, it will be automatically allocated.
     struct SetStandardProcessedMap :
@@ -341,7 +339,8 @@
 
     ///Sets the map that stores the predecessor arcs.
-    ///If you don't use this function before calling \ref run(),
-    ///it will allocate one. The destructor deallocates this
-    ///automatically allocated map, of course.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
     ///\return <tt> (*this) </tt>
     Bfs &predMap(PredMap &m)
@@ -358,7 +357,8 @@
 
     ///Sets the map that indicates which nodes are reached.
-    ///If you don't use this function before calling \ref run(),
-    ///it will allocate one. The destructor deallocates this
-    ///automatically allocated map, of course.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
     ///\return <tt> (*this) </tt>
     Bfs &reachedMap(ReachedMap &m)
@@ -375,7 +375,8 @@
 
     ///Sets the map that indicates which nodes are processed.
-    ///If you don't use this function before calling \ref run(),
-    ///it will allocate one. The destructor deallocates this
-    ///automatically allocated map, of course.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
     ///\return <tt> (*this) </tt>
     Bfs &processedMap(ProcessedMap &m)
@@ -393,7 +394,8 @@
     ///Sets the map that stores the distances of the nodes calculated by
     ///the algorithm.
-    ///If you don't use this function before calling \ref run(),
-    ///it will allocate one. The destructor deallocates this
-    ///automatically allocated map, of course.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
     ///\return <tt> (*this) </tt>
     Bfs &distMap(DistMap &m)
@@ -409,20 +411,17 @@
   public:
 
-    ///\name Execution control
-    ///The simplest way to execute the algorithm is to use
-    ///one of the member functions called \ref lemon::Bfs::run() "run()".
-    ///\n
-    ///If you need more control on the execution, first you must call
-    ///\ref lemon::Bfs::init() "init()", then you can add several source
-    ///nodes with \ref lemon::Bfs::addSource() "addSource()".
-    ///Finally \ref lemon::Bfs::start() "start()" will perform the
-    ///actual path computation.
+    ///\name Execution Control
+    ///The simplest way to execute the BFS algorithm is to use one of the
+    ///member functions called \ref run(Node) "run()".\n
+    ///If you need more control on the execution, first you have to call
+    ///\ref init(), then you can add several source nodes with
+    ///\ref addSource(). Finally the actual path computation can be
+    ///performed with one of the \ref start() functions.
 
     ///@{
 
+    ///\brief Initializes the internal data structures.
+    ///
     ///Initializes the internal data structures.
-
-    ///Initializes the internal data structures.
-    ///
     void init()
     {
@@ -558,14 +557,14 @@
     }
 
-    ///\brief Returns \c false if there are nodes
-    ///to be processed.
-    ///
-    ///Returns \c false if there are nodes
-    ///to be processed in the queue.
+    ///Returns \c false if there are nodes to be processed.
+
+    ///Returns \c false if there are nodes to be processed
+    ///in the queue.
     bool emptyQueue() const { return _queue_tail==_queue_head; }
 
     ///Returns the number of the nodes to be processed.
 
-    ///Returns the number of the nodes to be processed in the queue.
+    ///Returns the number of the nodes to be processed
+    ///in the queue.
     int queueSize() const { return _queue_head-_queue_tail; }
 
@@ -732,8 +731,8 @@
 
     ///\name Query Functions
-    ///The result of the %BFS algorithm can be obtained using these
+    ///The results of the BFS algorithm can be obtained using these
     ///functions.\n
-    ///Either \ref lemon::Bfs::run() "run()" or \ref lemon::Bfs::start()
-    ///"start()" must be called before using them.
+    ///Either \ref run(Node) "run()" or \ref start() should be called
+    ///before using them.
 
     ///@{
@@ -743,8 +742,8 @@
     ///Returns the shortest path to a node.
     ///
-    ///\warning \c t should be reachable from the root(s).
-    ///
-    ///\pre Either \ref run() or \ref start() must be called before
-    ///using this function.
+    ///\warning \c t should be reached from the root(s).
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
     Path path(Node t) const { return Path(*G, *_pred, t); }
 
@@ -753,9 +752,9 @@
     ///Returns the distance of a node from the root(s).
     ///
-    ///\warning If node \c v is not reachable from the root(s), then
+    ///\warning If node \c v is not reached from the root(s), then
     ///the return value of this function is undefined.
     ///
-    ///\pre Either \ref run() or \ref start() must be called before
-    ///using this function.
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
     int dist(Node v) const { return (*_dist)[v]; }
 
@@ -764,12 +763,12 @@
     ///This function returns the 'previous arc' of the shortest path
     ///tree for the node \c v, i.e. it returns the last arc of a
-    ///shortest path from the root(s) to \c v. It is \c INVALID if \c v
-    ///is not reachable from the root(s) or if \c v is a root.
+    ///shortest path from a root to \c v. It is \c INVALID if \c v
+    ///is not reached from the root(s) or if \c v is a root.
     ///
     ///The shortest path tree used here is equal to the shortest path
     ///tree used in \ref predNode().
     ///
-    ///\pre Either \ref run() or \ref start() must be called before
-    ///using this function.
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
     Arc predArc(Node v) const { return (*_pred)[v];}
 
@@ -778,12 +777,12 @@
     ///This function returns the 'previous node' of the shortest path
     ///tree for the node \c v, i.e. it returns the last but one node
-    ///from a shortest path from the root(s) to \c v. It is \c INVALID
-    ///if \c v is not reachable from the root(s) or if \c v is a root.
+    ///from a shortest path from a root to \c v. It is \c INVALID
+    ///if \c v is not reached from the root(s) or if \c v is a root.
     ///
     ///The shortest path tree used here is equal to the shortest path
     ///tree used in \ref predArc().
     ///
-    ///\pre Either \ref run() or \ref start() must be called before
-    ///using this function.
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
     Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
                                   G->source((*_pred)[v]); }
@@ -795,5 +794,5 @@
     ///of the nodes calculated by the algorithm.
     ///
-    ///\pre Either \ref run() or \ref init()
+    ///\pre Either \ref run(Node) "run()" or \ref init()
     ///must be called before using this function.
     const DistMap &distMap() const { return *_dist;}
@@ -805,12 +804,13 @@
     ///arcs, which form the shortest path tree.
     ///
-    ///\pre Either \ref run() or \ref init()
+    ///\pre Either \ref run(Node) "run()" or \ref init()
     ///must be called before using this function.
     const PredMap &predMap() const { return *_pred;}
 
-    ///Checks if a node is reachable from the root(s).
-
-    ///Returns \c true if \c v is reachable from the root(s).
-    ///\pre Either \ref run() or \ref start()
+    ///Checks if a node is reached from the root(s).
+
+    ///Returns \c true if \c v is reached from the root(s).
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
     ///must be called before using this function.
     bool reached(Node v) const { return (*_reached)[v]; }
@@ -958,6 +958,6 @@
   /// This auxiliary class is created to implement the
   /// \ref bfs() "function-type interface" of \ref Bfs algorithm.
-  /// It does not have own \ref run() method, it uses the functions
-  /// and features of the plain \ref Bfs.
+  /// It does not have own \ref run(Node) "run()" method, it uses the
+  /// functions and features of the plain \ref Bfs.
   ///
   /// This class should only be used through the \ref bfs() function,
@@ -1179,5 +1179,5 @@
   ///  bool reached = bfs(g).path(p).dist(d).run(s,t);
   ///\endcode
-  ///\warning Don't forget to put the \ref BfsWizard::run() "run()"
+  ///\warning Don't forget to put the \ref BfsWizard::run(Node) "run()"
   ///to the end of the parameter list.
   ///\sa BfsWizard
@@ -1195,7 +1195,7 @@
   /// This class defines the interface of the BfsVisit events, and
   /// it could be the base of a real visitor class.
-  template <typename _Digraph>
+  template <typename GR>
   struct BfsVisitor {
-    typedef _Digraph Digraph;
+    typedef GR Digraph;
     typedef typename Digraph::Arc Arc;
     typedef typename Digraph::Node Node;
@@ -1225,7 +1225,7 @@
   };
 #else
-  template <typename _Digraph>
+  template <typename GR>
   struct BfsVisitor {
-    typedef _Digraph Digraph;
+    typedef GR Digraph;
     typedef typename Digraph::Arc Arc;
     typedef typename Digraph::Node Node;
@@ -1255,10 +1255,10 @@
   ///
   /// Default traits class of BfsVisit class.
-  /// \tparam _Digraph The type of the digraph the algorithm runs on.
-  template<class _Digraph>
+  /// \tparam GR The type of the digraph the algorithm runs on.
+  template<class GR>
   struct BfsVisitDefaultTraits {
 
     /// \brief The type of the digraph the algorithm runs on.
-    typedef _Digraph Digraph;
+    typedef GR Digraph;
 
     /// \brief The type of the map that indicates which nodes are reached.
@@ -1281,10 +1281,10 @@
   /// \ingroup search
   ///
-  /// \brief %BFS algorithm class with visitor interface.
+  /// \brief BFS algorithm class with visitor interface.
   ///
-  /// This class provides an efficient implementation of the %BFS algorithm
+  /// This class provides an efficient implementation of the BFS algorithm
   /// with visitor interface.
   ///
-  /// The %BfsVisit class provides an alternative interface to the Bfs
+  /// The BfsVisit class provides an alternative interface to the Bfs
   /// class. It works with callback mechanism, the BfsVisit object calls
   /// the member functions of the \c Visitor class on every BFS event.
@@ -1295,23 +1295,23 @@
   /// instead.
   ///
-  /// \tparam _Digraph The type of the digraph the algorithm runs on.
-  /// The default value is
-  /// \ref ListDigraph. The value of _Digraph is not used directly by
-  /// \ref BfsVisit, it is only passed to \ref BfsVisitDefaultTraits.
-  /// \tparam _Visitor The Visitor type that is used by the algorithm.
-  /// \ref BfsVisitor "BfsVisitor<_Digraph>" is an empty visitor, which
+  /// \tparam GR The type of the digraph the algorithm runs on.
+  /// The default type is \ref ListDigraph.
+  /// The value of GR is not used directly by \ref BfsVisit,
+  /// it is only passed to \ref BfsVisitDefaultTraits.
+  /// \tparam VS The Visitor type that is used by the algorithm.
+  /// \ref BfsVisitor "BfsVisitor<GR>" is an empty visitor, which
   /// does not observe the BFS events. If you want to observe the BFS
   /// events, you should implement your own visitor class.
-  /// \tparam _Traits Traits class to set various data types used by the
+  /// \tparam TR Traits class to set various data types used by the
   /// algorithm. The default traits class is
-  /// \ref BfsVisitDefaultTraits "BfsVisitDefaultTraits<_Digraph>".
+  /// \ref BfsVisitDefaultTraits "BfsVisitDefaultTraits<GR>".
   /// See \ref BfsVisitDefaultTraits for the documentation of
   /// a BFS visit traits class.
 #ifdef DOXYGEN
-  template <typename _Digraph, typename _Visitor, typename _Traits>
+  template <typename GR, typename VS, typename TR>
 #else
-  template <typename _Digraph = ListDigraph,
-            typename _Visitor = BfsVisitor<_Digraph>,
-            typename _Traits = BfsVisitDefaultTraits<_Digraph> >
+  template <typename GR = ListDigraph,
+            typename VS = BfsVisitor<GR>,
+            typename TR = BfsVisitDefaultTraits<GR> >
 #endif
   class BfsVisit {
@@ -1319,5 +1319,5 @@
 
     ///The traits class.
-    typedef _Traits Traits;
+    typedef TR Traits;
 
     ///The type of the digraph the algorithm runs on.
@@ -1325,5 +1325,5 @@
 
     ///The visitor type used by the algorithm.
-    typedef _Visitor Visitor;
+    typedef VS Visitor;
 
     ///The type of the map that indicates which nodes are reached.
@@ -1365,5 +1365,5 @@
     typedef BfsVisit Create;
 
-    /// \name Named template parameters
+    /// \name Named Template Parameters
 
     ///@{
@@ -1407,7 +1407,8 @@
     ///
     /// Sets the map that indicates which nodes are reached.
-    /// If you don't use this function before calling \ref run(),
-    /// it will allocate one. The destructor deallocates this
-    /// automatically allocated map, of course.
+    /// If you don't use this function before calling \ref run(Node) "run()"
+    /// or \ref init(), an instance will be allocated automatically.
+    /// The destructor deallocates this automatically allocated map,
+    /// of course.
     /// \return <tt> (*this) </tt>
     BfsVisit &reachedMap(ReachedMap &m) {
@@ -1422,14 +1423,11 @@
   public:
 
-    /// \name Execution control
-    /// The simplest way to execute the algorithm is to use
-    /// one of the member functions called \ref lemon::BfsVisit::run()
-    /// "run()".
-    /// \n
-    /// If you need more control on the execution, first you must call
-    /// \ref lemon::BfsVisit::init() "init()", then you can add several
-    /// source nodes with \ref lemon::BfsVisit::addSource() "addSource()".
-    /// Finally \ref lemon::BfsVisit::start() "start()" will perform the
-    /// actual path computation.
+    /// \name Execution Control
+    /// The simplest way to execute the BFS algorithm is to use one of the
+    /// member functions called \ref run(Node) "run()".\n
+    /// If you need more control on the execution, first you have to call
+    /// \ref init(), then you can add several source nodes with
+    /// \ref addSource(). Finally the actual path computation can be
+    /// performed with one of the \ref start() functions.
 
     /// @{
@@ -1731,17 +1729,18 @@
 
     /// \name Query Functions
-    /// The result of the %BFS algorithm can be obtained using these
+    /// The results of the BFS algorithm can be obtained using these
     /// functions.\n
-    /// Either \ref lemon::BfsVisit::run() "run()" or
-    /// \ref lemon::BfsVisit::start() "start()" must be called before
-    /// using them.
+    /// Either \ref run(Node) "run()" or \ref start() should be called
+    /// before using them.
+
     ///@{
 
-    /// \brief Checks if a node is reachable from the root(s).
-    ///
-    /// Returns \c true if \c v is reachable from the root(s).
-    /// \pre Either \ref run() or \ref start()
+    /// \brief Checks if a node is reached from the root(s).
+    ///
+    /// Returns \c true if \c v is reached from the root(s).
+    ///
+    /// \pre Either \ref run(Node) "run()" or \ref init()
     /// must be called before using this function.
-    bool reached(Node v) { return (*_reached)[v]; }
+    bool reached(Node v) const { return (*_reached)[v]; }
 
     ///@}
Index: lemon/bin_heap.h
===================================================================
--- lemon/bin_heap.h	(revision 209)
+++ lemon/bin_heap.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/alteration_notifier.h
===================================================================
--- lemon/bits/alteration_notifier.h	(revision 314)
+++ lemon/bits/alteration_notifier.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -36,59 +36,60 @@
   // a container.
   //
-  // The simple graph's can be refered as two containers, one node container
-  // and one edge container. But they are not standard containers they
-  // does not store values directly they are just key continars for more
-  // value containers which are the node and edge maps.
-  //
-  // The graph's node and edge sets can be changed as we add or erase
+  // The simple graphs can be refered as two containers: a node container
+  // and an edge container. But they do not store values directly, they
+  // are just key continars for more value containers, which are the
+  // node and edge maps.
+  //
+  // The node and edge sets of the graphs can be changed as we add or erase
   // nodes and edges in the graph. LEMON would like to handle easily
   // that the node and edge maps should contain values for all nodes or
   // edges. If we want to check on every indicing if the map contains
   // the current indicing key that cause a drawback in the performance
-  // in the library. We use another solution we notify all maps about
+  // in the library. We use another solution: we notify all maps about
   // an alteration in the graph, which cause only drawback on the
   // alteration of the graph.
   //
-  // This class provides an interface to the container. The \e first() and \e
-  // next() member functions make possible to iterate on the keys of the
-  // container. The \e id() function returns an integer id for each key.
-  // The \e maxId() function gives back an upper bound of the ids.
+  // This class provides an interface to a node or edge container.
+  // The first() and next() member functions make possible
+  // to iterate on the keys of the container.
+  // The id() function returns an integer id for each key.
+  // The maxId() function gives back an upper bound of the ids.
   //
   // For the proper functonality of this class, we should notify it
-  // about each alteration in the container. The alterations have four type
-  // as \e add(), \e erase(), \e build() and \e clear(). The \e add() and
-  // \e erase() signals that only one or few items added or erased to or
-  // from the graph. If all items are erased from the graph or from an empty
-  // graph a new graph is builded then it can be signaled with the
+  // about each alteration in the container. The alterations have four type:
+  // add(), erase(), build() and clear(). The add() and
+  // erase() signal that only one or few items added or erased to or
+  // from the graph. If all items are erased from the graph or if a new graph
+  // is built from an empty graph, then it can be signaled with the
   // clear() and build() members. Important rule that if we erase items
-  // from graph we should first signal the alteration and after that erase
+  // from graphs we should first signal the alteration and after that erase
   // them from the container, on the other way on item addition we should
   // first extend the container and just after that signal the alteration.
   //
   // The alteration can be observed with a class inherited from the
-  // \e ObserverBase nested class. The signals can be handled with
+  // ObserverBase nested class. The signals can be handled with
   // overriding the virtual functions defined in the base class.  The
   // observer base can be attached to the notifier with the
-  // \e attach() member and can be detached with detach() function. The
+  // attach() member and can be detached with detach() function. The
   // alteration handlers should not call any function which signals
   // an other alteration in the same notifier and should not
   // detach any observer from the notifier.
   //
-  // Alteration observers try to be exception safe. If an \e add() or
-  // a \e clear() function throws an exception then the remaining
+  // Alteration observers try to be exception safe. If an add() or
+  // a clear() function throws an exception then the remaining
   // observeres will not be notified and the fulfilled additions will
-  // be rolled back by calling the \e erase() or \e clear()
-  // functions. Thence the \e erase() and \e clear() should not throw
-  // exception. Actullay, it can be throw only \ref ImmediateDetach
-  // exception which detach the observer from the notifier.
-  //
-  // There are some place when the alteration observing is not completly
+  // be rolled back by calling the erase() or clear() functions.
+  // Hence erase() and clear() should not throw exception.
+  // Actullay, they can throw only \ref ImmediateDetach exception,
+  // which detach the observer from the notifier.
+  //
+  // There are some cases, when the alteration observing is not completly
   // reliable. If we want to carry out the node degree in the graph
-  // as in the \ref InDegMap and we use the reverseEdge that cause
+  // as in the \ref InDegMap and we use the reverseArc(), then it cause
   // unreliable functionality. Because the alteration observing signals
-  // only erasing and adding but not the reversing it will stores bad
-  // degrees. The sub graph adaptors cannot signal the alterations because
-  // just a setting in the filter map can modify the graph and this cannot
-  // be watched in any way.
+  // only erasing and adding but not the reversing, it will stores bad
+  // degrees. Apart form that the subgraph adaptors cannot even signal
+  // the alterations because just a setting in the filter map can modify
+  // the graph and this cannot be watched in any way.
   //
   // \param _Container The container which is observed.
@@ -104,11 +105,11 @@
     typedef _Item Item;
 
-    // \brief Exception which can be called from \e clear() and
-    // \e erase().
-    //
-    // From the \e clear() and \e erase() function only this
+    // \brief Exception which can be called from clear() and
+    // erase().
+    //
+    // From the clear() and erase() function only this
     // exception is allowed to throw. The exception immediatly
     // detaches the current observer from the notifier. Because the
-    // \e clear() and \e erase() should not throw other exceptions
+    // clear() and erase() should not throw other exceptions
     // it can be used to invalidate the observer.
     struct ImmediateDetach {};
@@ -122,6 +123,5 @@
     // The observer interface contains some pure virtual functions
     // to override. The add() and erase() functions are
-    // to notify the oberver when one item is added or
-    // erased.
+    // to notify the oberver when one item is added or erased.
     //
     // The build() and clear() members are to notify the observer
Index: lemon/bits/array_map.h
===================================================================
--- lemon/bits/array_map.h	(revision 314)
+++ lemon/bits/array_map.h	(revision 492)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -37,10 +37,9 @@
   // \brief Graph map based on the array storage.
   //
-  // The ArrayMap template class is graph map structure what
-  // automatically updates the map when a key is added to or erased from
-  // the map. This map uses the allocators to implement
-  // the container functionality.
+  // The ArrayMap template class is graph map structure that automatically
+  // updates the map when a key is added to or erased from the graph.
+  // This map uses the allocators to implement the container functionality.
   //
-  // The template parameters are the Graph the current Item type and
+  // The template parameters are the Graph, the current Item type and
   // the Value type of the map.
   template <typename _Graph, typename _Item, typename _Value>
@@ -48,12 +47,12 @@
     : public ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
   public:
-    // The graph type of the maps.
+    // The graph type.
     typedef _Graph Graph;
-    // The item type of the map.
+    // The item type.
     typedef _Item Item;
     // The reference map tag.
     typedef True ReferenceMapTag;
 
-    // The key type of the maps.
+    // The key type of the map.
     typedef _Item Key;
     // The value type of the map.
@@ -137,5 +136,5 @@
     // \brief Template assign operator.
     //
-    // The given parameter should be conform to the ReadMap
+    // The given parameter should conform to the ReadMap
     // concecpt and could be indiced by the current item set of
     // the NodeMap. In this case the value for each item
@@ -201,5 +200,5 @@
     // \brief Adds a new key to the map.
     //
-    // It adds a new key to the map. It called by the observer notifier
+    // It adds a new key to the map. It is called by the observer notifier
     // and it overrides the add() member function of the observer base.
     virtual void add(const Key& key) {
@@ -229,5 +228,5 @@
     // \brief Adds more new keys to the map.
     //
-    // It adds more new keys to the map. It called by the observer notifier
+    // It adds more new keys to the map. It is called by the observer notifier
     // and it overrides the add() member function of the observer base.
     virtual void add(const std::vector<Key>& keys) {
@@ -273,5 +272,5 @@
     // \brief Erase a key from the map.
     //
-    // Erase a key from the map. It called by the observer notifier
+    // Erase a key from the map. It is called by the observer notifier
     // and it overrides the erase() member function of the observer base.
     virtual void erase(const Key& key) {
@@ -282,5 +281,5 @@
     // \brief Erase more keys from the map.
     //
-    // Erase more keys from the map. It called by the observer notifier
+    // Erase more keys from the map. It is called by the observer notifier
     // and it overrides the erase() member function of the observer base.
     virtual void erase(const std::vector<Key>& keys) {
@@ -291,7 +290,7 @@
     }
 
-    // \brief Buildes the map.
-    //
-    // It buildes the map. It called by the observer notifier
+    // \brief Builds the map.
+    //
+    // It builds the map. It is called by the observer notifier
     // and it overrides the build() member function of the observer base.
     virtual void build() {
@@ -307,5 +306,5 @@
     // \brief Clear the map.
     //
-    // It erase all items from the map. It called by the observer notifier
+    // It erase all items from the map. It is called by the observer notifier
     // and it overrides the clear() member function of the observer base.
     virtual void clear() {
Index: lemon/bits/base_extender.h
===================================================================
--- lemon/bits/base_extender.h	(revision 314)
+++ lemon/bits/base_extender.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -31,5 +31,5 @@
 //\ingroup digraphbits
 //\file
-//\brief Extenders for the digraph types
+//\brief Extenders for the graph types
 namespace lemon {
 
Index: lemon/bits/bezier.h
===================================================================
--- lemon/bits/bezier.h	(revision 314)
+++ lemon/bits/bezier.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/default_map.h
===================================================================
--- lemon/bits/default_map.h	(revision 491)
+++ lemon/bits/default_map.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -20,5 +20,4 @@
 #define LEMON_BITS_DEFAULT_MAP_H
 
-#include <lemon/config.h>
 #include <lemon/bits/array_map.h>
 #include <lemon/bits/vector_map.h>
@@ -98,5 +97,5 @@
 
 
-#if defined HAVE_LONG_LONG
+#if defined __GNUC__ && !defined __STRICT_ANSI__
 
   // long long
Index: lemon/bits/enable_if.h
===================================================================
--- lemon/bits/enable_if.h	(revision 314)
+++ lemon/bits/enable_if.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/graph_adaptor_extender.h
===================================================================
--- lemon/bits/graph_adaptor_extender.h	(revision 440)
+++ lemon/bits/graph_adaptor_extender.h	(revision 440)
@@ -0,0 +1,403 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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_BITS_GRAPH_ADAPTOR_EXTENDER_H
+#define LEMON_BITS_GRAPH_ADAPTOR_EXTENDER_H
+
+#include <lemon/core.h>
+#include <lemon/error.h>
+
+#include <lemon/bits/default_map.h>
+
+namespace lemon {
+
+  template <typename _Digraph>
+  class DigraphAdaptorExtender : public _Digraph {
+  public:
+
+    typedef _Digraph Parent;
+    typedef _Digraph Digraph;
+    typedef DigraphAdaptorExtender Adaptor;
+
+    // Base extensions
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+
+    int maxId(Node) const {
+      return Parent::maxNodeId();
+    }
+
+    int maxId(Arc) const {
+      return Parent::maxArcId();
+    }
+
+    Node fromId(int id, Node) const {
+      return Parent::nodeFromId(id);
+    }
+
+    Arc fromId(int id, Arc) const {
+      return Parent::arcFromId(id);
+    }
+
+    Node oppositeNode(const Node &n, const Arc &e) const {
+      if (n == Parent::source(e))
+        return Parent::target(e);
+      else if(n==Parent::target(e))
+        return Parent::source(e);
+      else
+        return INVALID;
+    }
+
+    class NodeIt : public Node {
+      const Adaptor* _adaptor;
+    public:
+
+      NodeIt() {}
+
+      NodeIt(Invalid i) : Node(i) { }
+
+      explicit NodeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
+        _adaptor->first(static_cast<Node&>(*this));
+      }
+
+      NodeIt(const Adaptor& adaptor, const Node& node)
+        : Node(node), _adaptor(&adaptor) {}
+
+      NodeIt& operator++() {
+        _adaptor->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class ArcIt : public Arc {
+      const Adaptor* _adaptor;
+    public:
+
+      ArcIt() { }
+
+      ArcIt(Invalid i) : Arc(i) { }
+
+      explicit ArcIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
+        _adaptor->first(static_cast<Arc&>(*this));
+      }
+
+      ArcIt(const Adaptor& adaptor, const Arc& e) :
+        Arc(e), _adaptor(&adaptor) { }
+
+      ArcIt& operator++() {
+        _adaptor->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class OutArcIt : public Arc {
+      const Adaptor* _adaptor;
+    public:
+
+      OutArcIt() { }
+
+      OutArcIt(Invalid i) : Arc(i) { }
+
+      OutArcIt(const Adaptor& adaptor, const Node& node)
+        : _adaptor(&adaptor) {
+        _adaptor->firstOut(*this, node);
+      }
+
+      OutArcIt(const Adaptor& adaptor, const Arc& arc)
+        : Arc(arc), _adaptor(&adaptor) {}
+
+      OutArcIt& operator++() {
+        _adaptor->nextOut(*this);
+        return *this;
+      }
+
+    };
+
+
+    class InArcIt : public Arc {
+      const Adaptor* _adaptor;
+    public:
+
+      InArcIt() { }
+
+      InArcIt(Invalid i) : Arc(i) { }
+
+      InArcIt(const Adaptor& adaptor, const Node& node)
+        : _adaptor(&adaptor) {
+        _adaptor->firstIn(*this, node);
+      }
+
+      InArcIt(const Adaptor& adaptor, const Arc& arc) :
+        Arc(arc), _adaptor(&adaptor) {}
+
+      InArcIt& operator++() {
+        _adaptor->nextIn(*this);
+        return *this;
+      }
+
+    };
+
+    Node baseNode(const OutArcIt &e) const {
+      return Parent::source(e);
+    }
+    Node runningNode(const OutArcIt &e) const {
+      return Parent::target(e);
+    }
+
+    Node baseNode(const InArcIt &e) const {
+      return Parent::target(e);
+    }
+    Node runningNode(const InArcIt &e) const {
+      return Parent::source(e);
+    }
+
+  };
+
+
+  /// \ingroup digraphbits
+  ///
+  /// \brief Extender for the GraphAdaptors
+  template <typename _Graph>
+  class GraphAdaptorExtender : public _Graph {
+  public:
+
+    typedef _Graph Parent;
+    typedef _Graph Graph;
+    typedef GraphAdaptorExtender Adaptor;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+    typedef typename Parent::Edge Edge;
+
+    // Graph extension
+
+    int maxId(Node) const {
+      return Parent::maxNodeId();
+    }
+
+    int maxId(Arc) const {
+      return Parent::maxArcId();
+    }
+
+    int maxId(Edge) const {
+      return Parent::maxEdgeId();
+    }
+
+    Node fromId(int id, Node) const {
+      return Parent::nodeFromId(id);
+    }
+
+    Arc fromId(int id, Arc) const {
+      return Parent::arcFromId(id);
+    }
+
+    Edge fromId(int id, Edge) const {
+      return Parent::edgeFromId(id);
+    }
+
+    Node oppositeNode(const Node &n, const Edge &e) const {
+      if( n == Parent::u(e))
+        return Parent::v(e);
+      else if( n == Parent::v(e))
+        return Parent::u(e);
+      else
+        return INVALID;
+    }
+
+    Arc oppositeArc(const Arc &a) const {
+      return Parent::direct(a, !Parent::direction(a));
+    }
+
+    using Parent::direct;
+    Arc direct(const Edge &e, const Node &s) const {
+      return Parent::direct(e, Parent::u(e) == s);
+    }
+
+
+    class NodeIt : public Node {
+      const Adaptor* _adaptor;
+    public:
+
+      NodeIt() {}
+
+      NodeIt(Invalid i) : Node(i) { }
+
+      explicit NodeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
+        _adaptor->first(static_cast<Node&>(*this));
+      }
+
+      NodeIt(const Adaptor& adaptor, const Node& node)
+        : Node(node), _adaptor(&adaptor) {}
+
+      NodeIt& operator++() {
+        _adaptor->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class ArcIt : public Arc {
+      const Adaptor* _adaptor;
+    public:
+
+      ArcIt() { }
+
+      ArcIt(Invalid i) : Arc(i) { }
+
+      explicit ArcIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
+        _adaptor->first(static_cast<Arc&>(*this));
+      }
+
+      ArcIt(const Adaptor& adaptor, const Arc& e) :
+        Arc(e), _adaptor(&adaptor) { }
+
+      ArcIt& operator++() {
+        _adaptor->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class OutArcIt : public Arc {
+      const Adaptor* _adaptor;
+    public:
+
+      OutArcIt() { }
+
+      OutArcIt(Invalid i) : Arc(i) { }
+
+      OutArcIt(const Adaptor& adaptor, const Node& node)
+        : _adaptor(&adaptor) {
+        _adaptor->firstOut(*this, node);
+      }
+
+      OutArcIt(const Adaptor& adaptor, const Arc& arc)
+        : Arc(arc), _adaptor(&adaptor) {}
+
+      OutArcIt& operator++() {
+        _adaptor->nextOut(*this);
+        return *this;
+      }
+
+    };
+
+
+    class InArcIt : public Arc {
+      const Adaptor* _adaptor;
+    public:
+
+      InArcIt() { }
+
+      InArcIt(Invalid i) : Arc(i) { }
+
+      InArcIt(const Adaptor& adaptor, const Node& node)
+        : _adaptor(&adaptor) {
+        _adaptor->firstIn(*this, node);
+      }
+
+      InArcIt(const Adaptor& adaptor, const Arc& arc) :
+        Arc(arc), _adaptor(&adaptor) {}
+
+      InArcIt& operator++() {
+        _adaptor->nextIn(*this);
+        return *this;
+      }
+
+    };
+
+    class EdgeIt : public Parent::Edge {
+      const Adaptor* _adaptor;
+    public:
+
+      EdgeIt() { }
+
+      EdgeIt(Invalid i) : Edge(i) { }
+
+      explicit EdgeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
+        _adaptor->first(static_cast<Edge&>(*this));
+      }
+
+      EdgeIt(const Adaptor& adaptor, const Edge& e) :
+        Edge(e), _adaptor(&adaptor) { }
+
+      EdgeIt& operator++() {
+        _adaptor->next(*this);
+        return *this;
+      }
+
+    };
+
+    class IncEdgeIt : public Edge {
+      friend class GraphAdaptorExtender;
+      const Adaptor* _adaptor;
+      bool direction;
+    public:
+
+      IncEdgeIt() { }
+
+      IncEdgeIt(Invalid i) : Edge(i), direction(false) { }
+
+      IncEdgeIt(const Adaptor& adaptor, const Node &n) : _adaptor(&adaptor) {
+        _adaptor->firstInc(static_cast<Edge&>(*this), direction, n);
+      }
+
+      IncEdgeIt(const Adaptor& adaptor, const Edge &e, const Node &n)
+        : _adaptor(&adaptor), Edge(e) {
+        direction = (_adaptor->u(e) == n);
+      }
+
+      IncEdgeIt& operator++() {
+        _adaptor->nextInc(*this, direction);
+        return *this;
+      }
+    };
+
+    Node baseNode(const OutArcIt &a) const {
+      return Parent::source(a);
+    }
+    Node runningNode(const OutArcIt &a) const {
+      return Parent::target(a);
+    }
+
+    Node baseNode(const InArcIt &a) const {
+      return Parent::target(a);
+    }
+    Node runningNode(const InArcIt &a) const {
+      return Parent::source(a);
+    }
+
+    Node baseNode(const IncEdgeIt &e) const {
+      return e.direction ? Parent::u(e) : Parent::v(e);
+    }
+    Node runningNode(const IncEdgeIt &e) const {
+      return e.direction ? Parent::v(e) : Parent::u(e);
+    }
+
+  };
+
+}
+
+
+#endif
Index: lemon/bits/graph_extender.h
===================================================================
--- lemon/bits/graph_extender.h	(revision 314)
+++ lemon/bits/graph_extender.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -30,10 +30,10 @@
 //\ingroup graphbits
 //\file
-//\brief Extenders for the digraph types
+//\brief Extenders for the graph types
 namespace lemon {
 
   // \ingroup graphbits
   //
-  // \brief Extender for the Digraphs
+  // \brief Extender for the digraph implementations
   template <typename Base>
   class DigraphExtender : public Base {
Index: lemon/bits/map_extender.h
===================================================================
--- lemon/bits/map_extender.h	(revision 314)
+++ lemon/bits/map_extender.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/path_dump.h
===================================================================
--- lemon/bits/path_dump.h	(revision 209)
+++ lemon/bits/path_dump.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/bits/traits.h
===================================================================
--- lemon/bits/traits.h	(revision 314)
+++ lemon/bits/traits.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -219,4 +219,17 @@
 
   template <typename Graph, typename Enable = void>
+  struct ArcNumTagIndicator {
+    static const bool value = false;
+  };
+
+  template <typename Graph>
+  struct ArcNumTagIndicator<
+    Graph,
+    typename enable_if<typename Graph::ArcNumTag, void>::type
+  > {
+    static const bool value = true;
+  };
+
+  template <typename Graph, typename Enable = void>
   struct EdgeNumTagIndicator {
     static const bool value = false;
@@ -232,4 +245,17 @@
 
   template <typename Graph, typename Enable = void>
+  struct FindArcTagIndicator {
+    static const bool value = false;
+  };
+
+  template <typename Graph>
+  struct FindArcTagIndicator<
+    Graph,
+    typename enable_if<typename Graph::FindArcTag, void>::type
+  > {
+    static const bool value = true;
+  };
+
+  template <typename Graph, typename Enable = void>
   struct FindEdgeTagIndicator {
     static const bool value = false;
Index: lemon/bits/variant.h
===================================================================
--- lemon/bits/variant.h	(revision 440)
+++ lemon/bits/variant.h	(revision 440)
@@ -0,0 +1,494 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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_BITS_VARIANT_H
+#define LEMON_BITS_VARIANT_H
+
+#include <lemon/assert.h>
+
+// \file
+// \brief Variant types
+
+namespace lemon {
+
+  namespace _variant_bits {
+
+    template <int left, int right>
+    struct CTMax {
+      static const int value = left < right ? right : left;
+    };
+
+  }
+
+
+  // \brief Simple Variant type for two types
+  //
+  // Simple Variant type for two types. The Variant type is a type-safe
+  // union. C++ has strong limitations for using unions, for
+  // example you cannot store a type with non-default constructor or
+  // destructor in a union. This class always knowns the current
+  // state of the variant and it cares for the proper construction
+  // and destruction.
+  template <typename _First, typename _Second>
+  class BiVariant {
+  public:
+
+    // \brief The \c First type.
+    typedef _First First;
+    // \brief The \c Second type.
+    typedef _Second Second;
+
+    // \brief Constructor
+    //
+    // This constructor initalizes to the default value of the \c First
+    // type.
+    BiVariant() {
+      flag = true;
+      new(reinterpret_cast<First*>(data)) First();
+    }
+
+    // \brief Constructor
+    //
+    // This constructor initalizes to the given value of the \c First
+    // type.
+    BiVariant(const First& f) {
+      flag = true;
+      new(reinterpret_cast<First*>(data)) First(f);
+    }
+
+    // \brief Constructor
+    //
+    // This constructor initalizes to the given value of the \c
+    // Second type.
+    BiVariant(const Second& s) {
+      flag = false;
+      new(reinterpret_cast<Second*>(data)) Second(s);
+    }
+
+    // \brief Copy constructor
+    //
+    // Copy constructor
+    BiVariant(const BiVariant& bivariant) {
+      flag = bivariant.flag;
+      if (flag) {
+        new(reinterpret_cast<First*>(data)) First(bivariant.first());
+      } else {
+        new(reinterpret_cast<Second*>(data)) Second(bivariant.second());
+      }
+    }
+
+    // \brief Destrcutor
+    //
+    // Destructor
+    ~BiVariant() {
+      destroy();
+    }
+
+    // \brief Set to the default value of the \c First type.
+    //
+    // This function sets the variant to the default value of the \c
+    // First type.
+    BiVariant& setFirst() {
+      destroy();
+      flag = true;
+      new(reinterpret_cast<First*>(data)) First();
+      return *this;
+    }
+
+    // \brief Set to the given value of the \c First type.
+    //
+    // This function sets the variant to the given value of the \c
+    // First type.
+    BiVariant& setFirst(const First& f) {
+      destroy();
+      flag = true;
+      new(reinterpret_cast<First*>(data)) First(f);
+      return *this;
+    }
+
+    // \brief Set to the default value of the \c Second type.
+    //
+    // This function sets the variant to the default value of the \c
+    // Second type.
+    BiVariant& setSecond() {
+      destroy();
+      flag = false;
+      new(reinterpret_cast<Second*>(data)) Second();
+      return *this;
+    }
+
+    // \brief Set to the given value of the \c Second type.
+    //
+    // This function sets the variant to the given value of the \c
+    // Second type.
+    BiVariant& setSecond(const Second& s) {
+      destroy();
+      flag = false;
+      new(reinterpret_cast<Second*>(data)) Second(s);
+      return *this;
+    }
+
+    // \brief Operator form of the \c setFirst()
+    BiVariant& operator=(const First& f) {
+      return setFirst(f);
+    }
+
+    // \brief Operator form of the \c setSecond()
+    BiVariant& operator=(const Second& s) {
+      return setSecond(s);
+    }
+
+    // \brief Assign operator
+    BiVariant& operator=(const BiVariant& bivariant) {
+      if (this == &bivariant) return *this;
+      destroy();
+      flag = bivariant.flag;
+      if (flag) {
+        new(reinterpret_cast<First*>(data)) First(bivariant.first());
+      } else {
+        new(reinterpret_cast<Second*>(data)) Second(bivariant.second());
+      }
+      return *this;
+    }
+
+    // \brief Reference to the value
+    //
+    // Reference to the value of the \c First type.
+    // \pre The BiVariant should store value of \c First type.
+    First& first() {
+      LEMON_DEBUG(flag, "Variant wrong state");
+      return *reinterpret_cast<First*>(data);
+    }
+
+    // \brief Const reference to the value
+    //
+    // Const reference to the value of the \c First type.
+    // \pre The BiVariant should store value of \c First type.
+    const First& first() const {
+      LEMON_DEBUG(flag, "Variant wrong state");
+      return *reinterpret_cast<const First*>(data);
+    }
+
+    // \brief Operator form of the \c first()
+    operator First&() { return first(); }
+    // \brief Operator form of the const \c first()
+    operator const First&() const { return first(); }
+
+    // \brief Reference to the value
+    //
+    // Reference to the value of the \c Second type.
+    // \pre The BiVariant should store value of \c Second type.
+    Second& second() {
+      LEMON_DEBUG(!flag, "Variant wrong state");
+      return *reinterpret_cast<Second*>(data);
+    }
+
+    // \brief Const reference to the value
+    //
+    // Const reference to the value of the \c Second type.
+    // \pre The BiVariant should store value of \c Second type.
+    const Second& second() const {
+      LEMON_DEBUG(!flag, "Variant wrong state");
+      return *reinterpret_cast<const Second*>(data);
+    }
+
+    // \brief Operator form of the \c second()
+    operator Second&() { return second(); }
+    // \brief Operator form of the const \c second()
+    operator const Second&() const { return second(); }
+
+    // \brief %True when the variant is in the first state
+    //
+    // %True when the variant stores value of the \c First type.
+    bool firstState() const { return flag; }
+
+    // \brief %True when the variant is in the second state
+    //
+    // %True when the variant stores value of the \c Second type.
+    bool secondState() const { return !flag; }
+
+  private:
+
+    void destroy() {
+      if (flag) {
+        reinterpret_cast<First*>(data)->~First();
+      } else {
+        reinterpret_cast<Second*>(data)->~Second();
+      }
+    }
+
+    char data[_variant_bits::CTMax<sizeof(First), sizeof(Second)>::value];
+    bool flag;
+  };
+
+  namespace _variant_bits {
+
+    template <int _idx, typename _TypeMap>
+    struct Memory {
+
+      typedef typename _TypeMap::template Map<_idx>::Type Current;
+
+      static void destroy(int index, char* place) {
+        if (index == _idx) {
+          reinterpret_cast<Current*>(place)->~Current();
+        } else {
+          Memory<_idx - 1, _TypeMap>::destroy(index, place);
+        }
+      }
+
+      static void copy(int index, char* to, const char* from) {
+        if (index == _idx) {
+          new (reinterpret_cast<Current*>(to))
+            Current(reinterpret_cast<const Current*>(from));
+        } else {
+          Memory<_idx - 1, _TypeMap>::copy(index, to, from);
+        }
+      }
+
+    };
+
+    template <typename _TypeMap>
+    struct Memory<-1, _TypeMap> {
+
+      static void destroy(int, char*) {
+        LEMON_DEBUG(false, "Variant wrong index.");
+      }
+
+      static void copy(int, char*, const char*) {
+        LEMON_DEBUG(false, "Variant wrong index.");
+      }
+    };
+
+    template <int _idx, typename _TypeMap>
+    struct Size {
+      static const int value =
+      CTMax<sizeof(typename _TypeMap::template Map<_idx>::Type),
+            Size<_idx - 1, _TypeMap>::value>::value;
+    };
+
+    template <typename _TypeMap>
+    struct Size<0, _TypeMap> {
+      static const int value =
+      sizeof(typename _TypeMap::template Map<0>::Type);
+    };
+
+  }
+
+  // \brief Variant type
+  //
+  // Simple Variant type. The Variant type is a type-safe union.
+  // C++ has strong limitations for using unions, for example you
+  // cannot store type with non-default constructor or destructor in
+  // a union. This class always knowns the current state of the
+  // variant and it cares for the proper construction and
+  // destruction.
+  //
+  // \param _num The number of the types which can be stored in the
+  // variant type.
+  // \param _TypeMap This class describes the types of the Variant. The
+  // _TypeMap::Map<index>::Type should be a valid type for each index
+  // in the range {0, 1, ..., _num - 1}. The \c VariantTypeMap is helper
+  // class to define such type mappings up to 10 types.
+  //
+  // And the usage of the class:
+  //\code
+  // typedef Variant<3, VariantTypeMap<int, std::string, double> > MyVariant;
+  // MyVariant var;
+  // var.set<0>(12);
+  // std::cout << var.get<0>() << std::endl;
+  // var.set<1>("alpha");
+  // std::cout << var.get<1>() << std::endl;
+  // var.set<2>(0.75);
+  // std::cout << var.get<2>() << std::endl;
+  //\endcode
+  //
+  // The result of course:
+  //\code
+  // 12
+  // alpha
+  // 0.75
+  //\endcode
+  template <int _num, typename _TypeMap>
+  class Variant {
+  public:
+
+    static const int num = _num;
+
+    typedef _TypeMap TypeMap;
+
+    // \brief Constructor
+    //
+    // This constructor initalizes to the default value of the \c type
+    // with 0 index.
+    Variant() {
+      flag = 0;
+      new(reinterpret_cast<typename TypeMap::template Map<0>::Type*>(data))
+        typename TypeMap::template Map<0>::Type();
+    }
+
+
+    // \brief Copy constructor
+    //
+    // Copy constructor
+    Variant(const Variant& variant) {
+      flag = variant.flag;
+      _variant_bits::Memory<num - 1, TypeMap>::copy(flag, data, variant.data);
+    }
+
+    // \brief Assign operator
+    //
+    // Assign operator
+    Variant& operator=(const Variant& variant) {
+      if (this == &variant) return *this;
+      _variant_bits::Memory<num - 1, TypeMap>::
+        destroy(flag, data);
+      flag = variant.flag;
+      _variant_bits::Memory<num - 1, TypeMap>::
+        copy(flag, data, variant.data);
+      return *this;
+    }
+
+    // \brief Destrcutor
+    //
+    // Destructor
+    ~Variant() {
+      _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
+    }
+
+    // \brief Set to the default value of the type with \c _idx index.
+    //
+    // This function sets the variant to the default value of the
+    // type with \c _idx index.
+    template <int _idx>
+    Variant& set() {
+      _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
+      flag = _idx;
+      new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data))
+        typename TypeMap::template Map<_idx>::Type();
+      return *this;
+    }
+
+    // \brief Set to the given value of the type with \c _idx index.
+    //
+    // This function sets the variant to the given value of the type
+    // with \c _idx index.
+    template <int _idx>
+    Variant& set(const typename _TypeMap::template Map<_idx>::Type& init) {
+      _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
+      flag = _idx;
+      new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data))
+        typename TypeMap::template Map<_idx>::Type(init);
+      return *this;
+    }
+
+    // \brief Gets the current value of the type with \c _idx index.
+    //
+    // Gets the current value of the type with \c _idx index.
+    template <int _idx>
+    const typename TypeMap::template Map<_idx>::Type& get() const {
+      LEMON_DEBUG(_idx == flag, "Variant wrong index");
+      return *reinterpret_cast<const typename TypeMap::
+        template Map<_idx>::Type*>(data);
+    }
+
+    // \brief Gets the current value of the type with \c _idx index.
+    //
+    // Gets the current value of the type with \c _idx index.
+    template <int _idx>
+    typename _TypeMap::template Map<_idx>::Type& get() {
+      LEMON_DEBUG(_idx == flag, "Variant wrong index");
+      return *reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>
+        (data);
+    }
+
+    // \brief Returns the current state of the variant.
+    //
+    // Returns the current state of the variant.
+    int state() const {
+      return flag;
+    }
+
+  private:
+
+    char data[_variant_bits::Size<num - 1, TypeMap>::value];
+    int flag;
+  };
+
+  namespace _variant_bits {
+
+    template <int _index, typename _List>
+    struct Get {
+      typedef typename Get<_index - 1, typename _List::Next>::Type Type;
+    };
+
+    template <typename _List>
+    struct Get<0, _List> {
+      typedef typename _List::Type Type;
+    };
+
+    struct List {};
+
+    template <typename _Type, typename _List>
+    struct Insert {
+      typedef _List Next;
+      typedef _Type Type;
+    };
+
+    template <int _idx, typename _T0, typename _T1, typename _T2,
+              typename _T3, typename _T4, typename _T5, typename _T6,
+              typename _T7, typename _T8, typename _T9>
+    struct Mapper {
+      typedef List L10;
+      typedef Insert<_T9, L10> L9;
+      typedef Insert<_T8, L9> L8;
+      typedef Insert<_T7, L8> L7;
+      typedef Insert<_T6, L7> L6;
+      typedef Insert<_T5, L6> L5;
+      typedef Insert<_T4, L5> L4;
+      typedef Insert<_T3, L4> L3;
+      typedef Insert<_T2, L3> L2;
+      typedef Insert<_T1, L2> L1;
+      typedef Insert<_T0, L1> L0;
+      typedef typename Get<_idx, L0>::Type Type;
+    };
+
+  }
+
+  // \brief Helper class for Variant
+  //
+  // Helper class to define type mappings for Variant. This class
+  // converts the template parameters to be mappable by integer.
+  // \see Variant
+  template <
+    typename _T0,
+    typename _T1 = void, typename _T2 = void, typename _T3 = void,
+    typename _T4 = void, typename _T5 = void, typename _T6 = void,
+    typename _T7 = void, typename _T8 = void, typename _T9 = void>
+  struct VariantTypeMap {
+    template <int _idx>
+    struct Map {
+      typedef typename _variant_bits::
+      Mapper<_idx, _T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9>::Type
+      Type;
+    };
+  };
+
+}
+
+
+#endif
Index: lemon/bits/vector_map.h
===================================================================
--- lemon/bits/vector_map.h	(revision 314)
+++ lemon/bits/vector_map.h	(revision 492)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -39,7 +39,7 @@
   // \brief Graph map based on the std::vector storage.
   //
-  // The VectorMap template class is graph map structure what
-  // automatically updates the map when a key is added to or erased from
-  // the map. This map type uses the std::vector to store the values.
+  // The VectorMap template class is graph map structure that automatically
+  // updates the map when a key is added to or erased from the graph.
+  // This map type uses std::vector to store the values.
   //
   // \tparam _Graph The graph this map is attached to.
@@ -125,5 +125,5 @@
     // \brief Template assign operator.
     //
-    // The given parameter should be conform to the ReadMap
+    // The given parameter should conform to the ReadMap
     // concecpt and could be indiced by the current item set of
     // the NodeMap. In this case the value for each item
@@ -170,5 +170,5 @@
     // \brief Adds a new key to the map.
     //
-    // It adds a new key to the map. It called by the observer notifier
+    // It adds a new key to the map. It is called by the observer notifier
     // and it overrides the add() member function of the observer base.
     virtual void add(const Key& key) {
@@ -181,5 +181,5 @@
     // \brief Adds more new keys to the map.
     //
-    // It adds more new keys to the map. It called by the observer notifier
+    // It adds more new keys to the map. It is called by the observer notifier
     // and it overrides the add() member function of the observer base.
     virtual void add(const std::vector<Key>& keys) {
@@ -196,5 +196,5 @@
     // \brief Erase a key from the map.
     //
-    // Erase a key from the map. It called by the observer notifier
+    // Erase a key from the map. It is called by the observer notifier
     // and it overrides the erase() member function of the observer base.
     virtual void erase(const Key& key) {
@@ -204,5 +204,5 @@
     // \brief Erase more keys from the map.
     //
-    // Erase more keys from the map. It called by the observer notifier
+    // It erases more keys from the map. It is called by the observer notifier
     // and it overrides the erase() member function of the observer base.
     virtual void erase(const std::vector<Key>& keys) {
@@ -212,7 +212,7 @@
     }
 
-    // \brief Buildes the map.
-    //
-    // It buildes the map. It called by the observer notifier
+    // \brief Build the map.
+    //
+    // It builds the map. It is called by the observer notifier
     // and it overrides the build() member function of the observer base.
     virtual void build() {
@@ -224,5 +224,5 @@
     // \brief Clear the map.
     //
-    // It erase all items from the map. It called by the observer notifier
+    // It erases all items from the map. It is called by the observer notifier
     // and it overrides the clear() member function of the observer base.
     virtual void clear() {
Index: mon/bits/windows.cc
===================================================================
--- lemon/bits/windows.cc	(revision 483)
+++ 	(revision )
@@ -1,132 +1,0 @@
-/* -*- mode: C++; indent-tabs-mode: nil; -*-
- *
- * This file is a part of LEMON, a generic C++ optimization library.
- *
- * Copyright (C) 2003-2009
- * 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.
- *
- */
-
-///\file
-///\brief Some basic non-inline functions and static global data.
-
-#include<lemon/bits/windows.h>
-
-#ifdef WIN32
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN
-#endif
-#ifndef NOMINMAX
-#define NOMINMAX
-#endif
-#ifdef UNICODE
-#undef UNICODE
-#endif
-#include <windows.h>
-#ifdef LOCALE_INVARIANT
-#define MY_LOCALE LOCALE_INVARIANT
-#else
-#define MY_LOCALE LOCALE_NEUTRAL
-#endif
-#else
-#include <unistd.h>
-#include <ctime>
-#include <sys/times.h>
-#include <sys/time.h>
-#endif
-
-#include <cmath>
-#include <sstream>
-
-namespace lemon {
-  namespace bits {
-    void getWinProcTimes(double &rtime,
-                         double &utime, double &stime,
-                         double &cutime, double &cstime)
-    {
-#ifdef WIN32
-      static const double ch = 4294967296.0e-7;
-      static const double cl = 1.0e-7;
-
-      FILETIME system;
-      GetSystemTimeAsFileTime(&system);
-      rtime = ch * system.dwHighDateTime + cl * system.dwLowDateTime;
-
-      FILETIME create, exit, kernel, user;
-      if (GetProcessTimes(GetCurrentProcess(),&create, &exit, &kernel, &user)) {
-        utime = ch * user.dwHighDateTime + cl * user.dwLowDateTime;
-        stime = ch * kernel.dwHighDateTime + cl * kernel.dwLowDateTime;
-        cutime = 0;
-        cstime = 0;
-      } else {
-        rtime = 0;
-        utime = 0;
-        stime = 0;
-        cutime = 0;
-        cstime = 0;
-      }
-#else
-      timeval tv;
-      gettimeofday(&tv, 0);
-      rtime=tv.tv_sec+double(tv.tv_usec)/1e6;
-
-      tms ts;
-      double tck=sysconf(_SC_CLK_TCK);
-      times(&ts);
-      utime=ts.tms_utime/tck;
-      stime=ts.tms_stime/tck;
-      cutime=ts.tms_cutime/tck;
-      cstime=ts.tms_cstime/tck;
-#endif
-    }
-
-    std::string getWinFormattedDate()
-    {
-      std::ostringstream os;
-#ifdef WIN32
-      SYSTEMTIME time;
-      GetSystemTime(&time);
-      char buf1[11], buf2[9], buf3[5];
-	  if (GetDateFormat(MY_LOCALE, 0, &time,
-                        ("ddd MMM dd"), buf1, 11) &&
-          GetTimeFormat(MY_LOCALE, 0, &time,
-                        ("HH':'mm':'ss"), buf2, 9) &&
-          GetDateFormat(MY_LOCALE, 0, &time,
-                        ("yyyy"), buf3, 5)) {
-        os << buf1 << ' ' << buf2 << ' ' << buf3;
-      }
-      else os << "unknown";
-#else
-      timeval tv;
-      gettimeofday(&tv, 0);
-
-      char cbuf[26];
-      ctime_r(&tv.tv_sec,cbuf);
-      os << cbuf;
-#endif
-      return os.str();
-    }
-
-    int getWinRndSeed()
-    {
-#ifdef WIN32
-      FILETIME time;
-      GetSystemTimeAsFileTime(&time);
-      return GetCurrentProcessId() + time.dwHighDateTime + time.dwLowDateTime;
-#else
-      timeval tv;
-      gettimeofday(&tv, 0);
-      return getpid() + tv.tv_sec + tv.tv_usec;
-#endif
-    }
-  }
-}
Index: mon/bits/windows.h
===================================================================
--- lemon/bits/windows.h	(revision 482)
+++ 	(revision )
@@ -1,34 +1,0 @@
-/* -*- mode: C++; indent-tabs-mode: nil; -*-
- *
- * This file is a part of LEMON, a generic C++ optimization library.
- *
- * Copyright (C) 2003-2009
- * 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_WINDOWS_H
-#define LEMON_WINDOWS_H
-
-#include <string>
-
-namespace lemon {
-  namespace bits {
-    void getWinProcTimes(double &rtime,
-                         double &utime, double &stime,
-                         double &cutime, double &cstime);
-    std::string getWinFormattedDate();
-    int getWinRndSeed();
-  }
-}
-
-#endif
Index: lemon/circulation.h
===================================================================
--- lemon/circulation.h	(revision 492)
+++ lemon/circulation.h	(revision 492)
@@ -0,0 +1,753 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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_CIRCULATION_H
+#define LEMON_CIRCULATION_H
+
+#include <lemon/tolerance.h>
+#include <lemon/elevator.h>
+
+///\ingroup max_flow
+///\file
+///\brief Push-relabel algorithm for finding a feasible circulation.
+///
+namespace lemon {
+
+  /// \brief Default traits class of Circulation class.
+  ///
+  /// Default traits class of Circulation class.
+  /// \tparam GR Digraph type.
+  /// \tparam LM Lower bound capacity map type.
+  /// \tparam UM Upper bound capacity map type.
+  /// \tparam DM Delta map type.
+  template <typename GR, typename LM,
+            typename UM, typename DM>
+  struct CirculationDefaultTraits {
+
+    /// \brief The type of the digraph the algorithm runs on.
+    typedef GR Digraph;
+
+    /// \brief The type of the map that stores the circulation lower
+    /// bound.
+    ///
+    /// The type of the map that stores the circulation lower bound.
+    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
+    typedef LM LCapMap;
+
+    /// \brief The type of the map that stores the circulation upper
+    /// bound.
+    ///
+    /// The type of the map that stores the circulation upper bound.
+    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
+    typedef UM UCapMap;
+
+    /// \brief The type of the map that stores the lower bound for
+    /// the supply of the nodes.
+    ///
+    /// The type of the map that stores the lower bound for the supply
+    /// of the nodes. It must meet the \ref concepts::ReadMap "ReadMap"
+    /// concept.
+    typedef DM DeltaMap;
+
+    /// \brief The type of the flow values.
+    typedef typename DeltaMap::Value Value;
+
+    /// \brief The type of the map that stores the flow values.
+    ///
+    /// The type of the map that stores the flow values.
+    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    typedef typename Digraph::template ArcMap<Value> FlowMap;
+
+    /// \brief Instantiates a FlowMap.
+    ///
+    /// This function instantiates a \ref FlowMap.
+    /// \param digraph The digraph, to which we would like to define
+    /// the flow map.
+    static FlowMap* createFlowMap(const Digraph& digraph) {
+      return new FlowMap(digraph);
+    }
+
+    /// \brief The elevator type used by the algorithm.
+    ///
+    /// The elevator type used by the algorithm.
+    ///
+    /// \sa Elevator
+    /// \sa LinkedElevator
+    typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
+
+    /// \brief Instantiates an Elevator.
+    ///
+    /// This function instantiates an \ref Elevator.
+    /// \param digraph The digraph, to which we would like to define
+    /// the elevator.
+    /// \param max_level The maximum level of the elevator.
+    static Elevator* createElevator(const Digraph& digraph, int max_level) {
+      return new Elevator(digraph, max_level);
+    }
+
+    /// \brief The tolerance used by the algorithm
+    ///
+    /// The tolerance used by the algorithm to handle inexact computation.
+    typedef lemon::Tolerance<Value> Tolerance;
+
+  };
+
+  /**
+     \brief Push-relabel algorithm for the network circulation problem.
+
+     \ingroup max_flow
+     This class implements a push-relabel algorithm for the network
+     circulation problem.
+     It is to find a feasible circulation when lower and upper bounds
+     are given for the flow values on the arcs and lower bounds
+     are given for the supply values of the nodes.
+
+     The exact formulation of this problem is the following.
+     Let \f$G=(V,A)\f$ be a digraph,
+     \f$lower, upper: A\rightarrow\mathbf{R}^+_0\f$,
+     \f$delta: V\rightarrow\mathbf{R}\f$. Find a feasible circulation
+     \f$f: A\rightarrow\mathbf{R}^+_0\f$ so that
+     \f[ \sum_{a\in\delta_{out}(v)} f(a) - \sum_{a\in\delta_{in}(v)} f(a)
+     \geq delta(v) \quad \forall v\in V, \f]
+     \f[ lower(a)\leq f(a) \leq upper(a) \quad \forall a\in A. \f]
+     \note \f$delta(v)\f$ specifies a lower bound for the supply of node
+     \f$v\f$. It can be either positive or negative, however note that
+     \f$\sum_{v\in V}delta(v)\f$ should be zero or negative in order to
+     have a feasible solution.
+
+     \note A special case of this problem is when
+     \f$\sum_{v\in V}delta(v) = 0\f$. Then the supply of each node \f$v\f$
+     will be \e equal \e to \f$delta(v)\f$, if a circulation can be found.
+     Thus a feasible solution for the
+     \ref min_cost_flow "minimum cost flow" problem can be calculated
+     in this way.
+
+     \tparam GR The type of the digraph the algorithm runs on.
+     \tparam LM The type of the lower bound capacity map. The default
+     map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+     \tparam UM The type of the upper bound capacity map. The default
+     map type is \c LM.
+     \tparam DM The type of the map that stores the lower bound
+     for the supply of the nodes. The default map type is
+     \ref concepts::Digraph::NodeMap "GR::NodeMap<UM::Value>".
+  */
+#ifdef DOXYGEN
+template< typename GR,
+          typename LM,
+          typename UM,
+          typename DM,
+          typename TR >
+#else
+template< typename GR,
+          typename LM = typename GR::template ArcMap<int>,
+          typename UM = LM,
+          typename DM = typename GR::template NodeMap<typename UM::Value>,
+          typename TR = CirculationDefaultTraits<GR, LM, UM, DM> >
+#endif
+  class Circulation {
+  public:
+
+    ///The \ref CirculationDefaultTraits "traits class" of the algorithm.
+    typedef TR Traits;
+    ///The type of the digraph the algorithm runs on.
+    typedef typename Traits::Digraph Digraph;
+    ///The type of the flow values.
+    typedef typename Traits::Value Value;
+
+    /// The type of the lower bound capacity map.
+    typedef typename Traits::LCapMap LCapMap;
+    /// The type of the upper bound capacity map.
+    typedef typename Traits::UCapMap UCapMap;
+    /// \brief The type of the map that stores the lower bound for
+    /// the supply of the nodes.
+    typedef typename Traits::DeltaMap DeltaMap;
+    ///The type of the flow map.
+    typedef typename Traits::FlowMap FlowMap;
+
+    ///The type of the elevator.
+    typedef typename Traits::Elevator Elevator;
+    ///The type of the tolerance.
+    typedef typename Traits::Tolerance Tolerance;
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+    const Digraph &_g;
+    int _node_num;
+
+    const LCapMap *_lo;
+    const UCapMap *_up;
+    const DeltaMap *_delta;
+
+    FlowMap *_flow;
+    bool _local_flow;
+
+    Elevator* _level;
+    bool _local_level;
+
+    typedef typename Digraph::template NodeMap<Value> ExcessMap;
+    ExcessMap* _excess;
+
+    Tolerance _tol;
+    int _el;
+
+  public:
+
+    typedef Circulation Create;
+
+    ///\name Named Template Parameters
+
+    ///@{
+
+    template <typename _FlowMap>
+    struct SetFlowMapTraits : public Traits {
+      typedef _FlowMap FlowMap;
+      static FlowMap *createFlowMap(const Digraph&) {
+        LEMON_ASSERT(false, "FlowMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// FlowMap type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting FlowMap
+    /// type.
+    template <typename _FlowMap>
+    struct SetFlowMap
+      : public Circulation<Digraph, LCapMap, UCapMap, DeltaMap,
+                           SetFlowMapTraits<_FlowMap> > {
+      typedef Circulation<Digraph, LCapMap, UCapMap, DeltaMap,
+                          SetFlowMapTraits<_FlowMap> > Create;
+    };
+
+    template <typename _Elevator>
+    struct SetElevatorTraits : public Traits {
+      typedef _Elevator Elevator;
+      static Elevator *createElevator(const Digraph&, int) {
+        LEMON_ASSERT(false, "Elevator is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// Elevator type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting Elevator
+    /// type. If this named parameter is used, then an external
+    /// elevator object must be passed to the algorithm using the
+    /// \ref elevator(Elevator&) "elevator()" function before calling
+    /// \ref run() or \ref init().
+    /// \sa SetStandardElevator
+    template <typename _Elevator>
+    struct SetElevator
+      : public Circulation<Digraph, LCapMap, UCapMap, DeltaMap,
+                           SetElevatorTraits<_Elevator> > {
+      typedef Circulation<Digraph, LCapMap, UCapMap, DeltaMap,
+                          SetElevatorTraits<_Elevator> > Create;
+    };
+
+    template <typename _Elevator>
+    struct SetStandardElevatorTraits : public Traits {
+      typedef _Elevator Elevator;
+      static Elevator *createElevator(const Digraph& digraph, int max_level) {
+        return new Elevator(digraph, max_level);
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// Elevator type with automatic allocation
+    ///
+    /// \ref named-templ-param "Named parameter" for setting Elevator
+    /// type with automatic allocation.
+    /// The Elevator should have standard constructor interface to be
+    /// able to automatically created by the algorithm (i.e. the
+    /// digraph and the maximum level should be passed to it).
+    /// However an external elevator object could also be passed to the
+    /// algorithm with the \ref elevator(Elevator&) "elevator()" function
+    /// before calling \ref run() or \ref init().
+    /// \sa SetElevator
+    template <typename _Elevator>
+    struct SetStandardElevator
+      : public Circulation<Digraph, LCapMap, UCapMap, DeltaMap,
+                       SetStandardElevatorTraits<_Elevator> > {
+      typedef Circulation<Digraph, LCapMap, UCapMap, DeltaMap,
+                      SetStandardElevatorTraits<_Elevator> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    Circulation() {}
+
+  public:
+
+    /// The constructor of the class.
+
+    /// The constructor of the class.
+    /// \param g The digraph the algorithm runs on.
+    /// \param lo The lower bound capacity of the arcs.
+    /// \param up The upper bound capacity of the arcs.
+    /// \param delta The lower bound for the supply of the nodes.
+    Circulation(const Digraph &g,const LCapMap &lo,
+                const UCapMap &up,const DeltaMap &delta)
+      : _g(g), _node_num(),
+        _lo(&lo),_up(&up),_delta(&delta),_flow(0),_local_flow(false),
+        _level(0), _local_level(false), _excess(0), _el() {}
+
+    /// Destructor.
+    ~Circulation() {
+      destroyStructures();
+    }
+
+
+  private:
+
+    void createStructures() {
+      _node_num = _el = countNodes(_g);
+
+      if (!_flow) {
+        _flow = Traits::createFlowMap(_g);
+        _local_flow = true;
+      }
+      if (!_level) {
+        _level = Traits::createElevator(_g, _node_num);
+        _local_level = true;
+      }
+      if (!_excess) {
+        _excess = new ExcessMap(_g);
+      }
+    }
+
+    void destroyStructures() {
+      if (_local_flow) {
+        delete _flow;
+      }
+      if (_local_level) {
+        delete _level;
+      }
+      if (_excess) {
+        delete _excess;
+      }
+    }
+
+  public:
+
+    /// Sets the lower bound capacity map.
+
+    /// Sets the lower bound capacity map.
+    /// \return <tt>(*this)</tt>
+    Circulation& lowerCapMap(const LCapMap& map) {
+      _lo = &map;
+      return *this;
+    }
+
+    /// Sets the upper bound capacity map.
+
+    /// Sets the upper bound capacity map.
+    /// \return <tt>(*this)</tt>
+    Circulation& upperCapMap(const LCapMap& map) {
+      _up = &map;
+      return *this;
+    }
+
+    /// Sets the lower bound map for the supply of the nodes.
+
+    /// Sets the lower bound map for the supply of the nodes.
+    /// \return <tt>(*this)</tt>
+    Circulation& deltaMap(const DeltaMap& map) {
+      _delta = &map;
+      return *this;
+    }
+
+    /// \brief Sets the flow map.
+    ///
+    /// Sets the flow map.
+    /// If you don't use this function before calling \ref run() or
+    /// \ref init(), an instance will be allocated automatically.
+    /// The destructor deallocates this automatically allocated map,
+    /// of course.
+    /// \return <tt>(*this)</tt>
+    Circulation& flowMap(FlowMap& map) {
+      if (_local_flow) {
+        delete _flow;
+        _local_flow = false;
+      }
+      _flow = &map;
+      return *this;
+    }
+
+    /// \brief Sets the elevator used by algorithm.
+    ///
+    /// Sets the elevator used by algorithm.
+    /// If you don't use this function before calling \ref run() or
+    /// \ref init(), an instance will be allocated automatically.
+    /// The destructor deallocates this automatically allocated elevator,
+    /// of course.
+    /// \return <tt>(*this)</tt>
+    Circulation& elevator(Elevator& elevator) {
+      if (_local_level) {
+        delete _level;
+        _local_level = false;
+      }
+      _level = &elevator;
+      return *this;
+    }
+
+    /// \brief Returns a const reference to the elevator.
+    ///
+    /// Returns a const reference to the elevator.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    const Elevator& elevator() const {
+      return *_level;
+    }
+
+    /// \brief Sets the tolerance used by algorithm.
+    ///
+    /// Sets the tolerance used by algorithm.
+    Circulation& tolerance(const Tolerance& tolerance) const {
+      _tol = tolerance;
+      return *this;
+    }
+
+    /// \brief Returns a const reference to the tolerance.
+    ///
+    /// Returns a const reference to the tolerance.
+    const Tolerance& tolerance() const {
+      return tolerance;
+    }
+
+    /// \name Execution Control
+    /// The simplest way to execute the algorithm is to call \ref run().\n
+    /// If you need more control on the initial solution or the execution,
+    /// first you have to call one of the \ref init() functions, then
+    /// the \ref start() function.
+
+    ///@{
+
+    /// Initializes the internal data structures.
+
+    /// Initializes the internal data structures and sets all flow values
+    /// to the lower bound.
+    void init()
+    {
+      createStructures();
+
+      for(NodeIt n(_g);n!=INVALID;++n) {
+        _excess->set(n, (*_delta)[n]);
+      }
+
+      for (ArcIt e(_g);e!=INVALID;++e) {
+        _flow->set(e, (*_lo)[e]);
+        _excess->set(_g.target(e), (*_excess)[_g.target(e)] + (*_flow)[e]);
+        _excess->set(_g.source(e), (*_excess)[_g.source(e)] - (*_flow)[e]);
+      }
+
+      // global relabeling tested, but in general case it provides
+      // worse performance for random digraphs
+      _level->initStart();
+      for(NodeIt n(_g);n!=INVALID;++n)
+        _level->initAddItem(n);
+      _level->initFinish();
+      for(NodeIt n(_g);n!=INVALID;++n)
+        if(_tol.positive((*_excess)[n]))
+          _level->activate(n);
+    }
+
+    /// Initializes the internal data structures using a greedy approach.
+
+    /// Initializes the internal data structures using a greedy approach
+    /// to construct the initial solution.
+    void greedyInit()
+    {
+      createStructures();
+
+      for(NodeIt n(_g);n!=INVALID;++n) {
+        _excess->set(n, (*_delta)[n]);
+      }
+
+      for (ArcIt e(_g);e!=INVALID;++e) {
+        if (!_tol.positive((*_excess)[_g.target(e)] + (*_up)[e])) {
+          _flow->set(e, (*_up)[e]);
+          _excess->set(_g.target(e), (*_excess)[_g.target(e)] + (*_up)[e]);
+          _excess->set(_g.source(e), (*_excess)[_g.source(e)] - (*_up)[e]);
+        } else if (_tol.positive((*_excess)[_g.target(e)] + (*_lo)[e])) {
+          _flow->set(e, (*_lo)[e]);
+          _excess->set(_g.target(e), (*_excess)[_g.target(e)] + (*_lo)[e]);
+          _excess->set(_g.source(e), (*_excess)[_g.source(e)] - (*_lo)[e]);
+        } else {
+          Value fc = -(*_excess)[_g.target(e)];
+          _flow->set(e, fc);
+          _excess->set(_g.target(e), 0);
+          _excess->set(_g.source(e), (*_excess)[_g.source(e)] - fc);
+        }
+      }
+
+      _level->initStart();
+      for(NodeIt n(_g);n!=INVALID;++n)
+        _level->initAddItem(n);
+      _level->initFinish();
+      for(NodeIt n(_g);n!=INVALID;++n)
+        if(_tol.positive((*_excess)[n]))
+          _level->activate(n);
+    }
+
+    ///Executes the algorithm
+
+    ///This function executes the algorithm.
+    ///
+    ///\return \c true if a feasible circulation is found.
+    ///
+    ///\sa barrier()
+    ///\sa barrierMap()
+    bool start()
+    {
+
+      Node act;
+      Node bact=INVALID;
+      Node last_activated=INVALID;
+      while((act=_level->highestActive())!=INVALID) {
+        int actlevel=(*_level)[act];
+        int mlevel=_node_num;
+        Value exc=(*_excess)[act];
+
+        for(OutArcIt e(_g,act);e!=INVALID; ++e) {
+          Node v = _g.target(e);
+          Value fc=(*_up)[e]-(*_flow)[e];
+          if(!_tol.positive(fc)) continue;
+          if((*_level)[v]<actlevel) {
+            if(!_tol.less(fc, exc)) {
+              _flow->set(e, (*_flow)[e] + exc);
+              _excess->set(v, (*_excess)[v] + exc);
+              if(!_level->active(v) && _tol.positive((*_excess)[v]))
+                _level->activate(v);
+              _excess->set(act,0);
+              _level->deactivate(act);
+              goto next_l;
+            }
+            else {
+              _flow->set(e, (*_up)[e]);
+              _excess->set(v, (*_excess)[v] + fc);
+              if(!_level->active(v) && _tol.positive((*_excess)[v]))
+                _level->activate(v);
+              exc-=fc;
+            }
+          }
+          else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
+        }
+        for(InArcIt e(_g,act);e!=INVALID; ++e) {
+          Node v = _g.source(e);
+          Value fc=(*_flow)[e]-(*_lo)[e];
+          if(!_tol.positive(fc)) continue;
+          if((*_level)[v]<actlevel) {
+            if(!_tol.less(fc, exc)) {
+              _flow->set(e, (*_flow)[e] - exc);
+              _excess->set(v, (*_excess)[v] + exc);
+              if(!_level->active(v) && _tol.positive((*_excess)[v]))
+                _level->activate(v);
+              _excess->set(act,0);
+              _level->deactivate(act);
+              goto next_l;
+            }
+            else {
+              _flow->set(e, (*_lo)[e]);
+              _excess->set(v, (*_excess)[v] + fc);
+              if(!_level->active(v) && _tol.positive((*_excess)[v]))
+                _level->activate(v);
+              exc-=fc;
+            }
+          }
+          else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
+        }
+
+        _excess->set(act, exc);
+        if(!_tol.positive(exc)) _level->deactivate(act);
+        else if(mlevel==_node_num) {
+          _level->liftHighestActiveToTop();
+          _el = _node_num;
+          return false;
+        }
+        else {
+          _level->liftHighestActive(mlevel+1);
+          if(_level->onLevel(actlevel)==0) {
+            _el = actlevel;
+            return false;
+          }
+        }
+      next_l:
+        ;
+      }
+      return true;
+    }
+
+    /// Runs the algorithm.
+
+    /// This function runs the algorithm.
+    ///
+    /// \return \c true if a feasible circulation is found.
+    ///
+    /// \note Apart from the return value, c.run() is just a shortcut of
+    /// the following code.
+    /// \code
+    ///   c.greedyInit();
+    ///   c.start();
+    /// \endcode
+    bool run() {
+      greedyInit();
+      return start();
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The results of the circulation algorithm can be obtained using
+    /// these functions.\n
+    /// Either \ref run() or \ref start() should be called before
+    /// using them.
+
+    ///@{
+
+    /// \brief Returns the flow on the given arc.
+    ///
+    /// Returns the flow on the given arc.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    Value flow(const Arc& arc) const {
+      return (*_flow)[arc];
+    }
+
+    /// \brief Returns a const reference to the flow map.
+    ///
+    /// Returns a const reference to the arc map storing the found flow.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    const FlowMap& flowMap() const {
+      return *_flow;
+    }
+
+    /**
+       \brief Returns \c true if the given node is in a barrier.
+
+       Barrier is a set \e B of nodes for which
+
+       \f[ \sum_{a\in\delta_{out}(B)} upper(a) -
+           \sum_{a\in\delta_{in}(B)} lower(a) < \sum_{v\in B}delta(v) \f]
+
+       holds. The existence of a set with this property prooves that a
+       feasible circualtion cannot exist.
+
+       This function returns \c true if the given node is in the found
+       barrier. If a feasible circulation is found, the function
+       gives back \c false for every node.
+
+       \pre Either \ref run() or \ref init() must be called before
+       using this function.
+
+       \sa barrierMap()
+       \sa checkBarrier()
+    */
+    bool barrier(const Node& node) const
+    {
+      return (*_level)[node] >= _el;
+    }
+
+    /// \brief Gives back a barrier.
+    ///
+    /// This function sets \c bar to the characteristic vector of the
+    /// found barrier. \c bar should be a \ref concepts::WriteMap "writable"
+    /// node map with \c bool (or convertible) value type.
+    ///
+    /// If a feasible circulation is found, the function gives back an
+    /// empty set, so \c bar[v] will be \c false for all nodes \c v.
+    ///
+    /// \note This function calls \ref barrier() for each node,
+    /// so it runs in \f$O(n)\f$ time.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    ///
+    /// \sa barrier()
+    /// \sa checkBarrier()
+    template<class BarrierMap>
+    void barrierMap(BarrierMap &bar) const
+    {
+      for(NodeIt n(_g);n!=INVALID;++n)
+        bar.set(n, (*_level)[n] >= _el);
+    }
+
+    /// @}
+
+    /// \name Checker Functions
+    /// The feasibility of the results can be checked using
+    /// these functions.\n
+    /// Either \ref run() or \ref start() should be called before
+    /// using them.
+
+    ///@{
+
+    ///Check if the found flow is a feasible circulation
+
+    ///Check if the found flow is a feasible circulation,
+    ///
+    bool checkFlow() const {
+      for(ArcIt e(_g);e!=INVALID;++e)
+        if((*_flow)[e]<(*_lo)[e]||(*_flow)[e]>(*_up)[e]) return false;
+      for(NodeIt n(_g);n!=INVALID;++n)
+        {
+          Value dif=-(*_delta)[n];
+          for(InArcIt e(_g,n);e!=INVALID;++e) dif-=(*_flow)[e];
+          for(OutArcIt e(_g,n);e!=INVALID;++e) dif+=(*_flow)[e];
+          if(_tol.negative(dif)) return false;
+        }
+      return true;
+    }
+
+    ///Check whether or not the last execution provides a barrier
+
+    ///Check whether or not the last execution provides a barrier.
+    ///\sa barrier()
+    ///\sa barrierMap()
+    bool checkBarrier() const
+    {
+      Value delta=0;
+      for(NodeIt n(_g);n!=INVALID;++n)
+        if(barrier(n))
+          delta-=(*_delta)[n];
+      for(ArcIt e(_g);e!=INVALID;++e)
+        {
+          Node s=_g.source(e);
+          Node t=_g.target(e);
+          if(barrier(s)&&!barrier(t)) delta+=(*_up)[e];
+          else if(barrier(t)&&!barrier(s)) delta-=(*_lo)[e];
+        }
+      return _tol.negative(delta);
+    }
+
+    /// @}
+
+  };
+
+}
+
+#endif
Index: lemon/color.cc
===================================================================
--- lemon/color.cc	(revision 209)
+++ lemon/color.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/color.h
===================================================================
--- lemon/color.h	(revision 313)
+++ lemon/color.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/concept_check.h
===================================================================
--- lemon/concept_check.h	(revision 285)
+++ lemon/concept_check.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/concepts/digraph.h
===================================================================
--- lemon/concepts/digraph.h	(revision 263)
+++ lemon/concepts/digraph.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/concepts/graph.h
===================================================================
--- lemon/concepts/graph.h	(revision 263)
+++ lemon/concepts/graph.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/concepts/graph_components.h
===================================================================
--- lemon/concepts/graph_components.h	(revision 313)
+++ lemon/concepts/graph_components.h	(revision 492)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -115,5 +115,5 @@
     ///
     /// This class provides the minimal set of features needed for a
-    /// directed graph structure. All digraph concepts have to be
+    /// directed graph structure. All digraph concepts have to
     /// conform to this base directed graph. It just provides types
     /// for nodes and arcs and functions to get the source and the
@@ -180,5 +180,5 @@
     /// This class provides the minimal set of features needed for an
     /// undirected graph structure. All undirected graph concepts have
-    /// to be conform to this base graph. It just provides types for
+    /// to conform to this base graph. It just provides types for
     /// nodes, arcs and edges and functions to get the
     /// source and the target of the arcs and edges,
@@ -295,5 +295,5 @@
     /// This class provides beside the core digraph features
     /// core id functions for the digraph structure.
-    /// The most of the base digraphs should be conform to this concept.
+    /// The most of the base digraphs should conform to this concept.
     /// The id's are unique and immutable.
     template <typename _Base = BaseDigraphComponent>
@@ -373,5 +373,5 @@
     /// This class provides beside the core undirected graph features
     /// core id functions for the undirected graph structure.  The
-    /// most of the base undirected graphs should be conform to this
+    /// most of the base undirected graphs should conform to this
     /// concept.  The id's are unique and immutable.
     template <typename _Base = BaseGraphComponent>
Index: lemon/concepts/heap.h
===================================================================
--- lemon/concepts/heap.h	(revision 290)
+++ lemon/concepts/heap.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/concepts/maps.h
===================================================================
--- lemon/concepts/maps.h	(revision 314)
+++ lemon/concepts/maps.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/concepts/path.h
===================================================================
--- lemon/concepts/path.h	(revision 281)
+++ lemon/concepts/path.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: mon/config.h.cmake
===================================================================
--- lemon/config.h.cmake	(revision 485)
+++ 	(revision )
@@ -1,1 +1,0 @@
-#cmakedefine HAVE_LONG_LONG 1
Index: lemon/config.h.in
===================================================================
--- lemon/config.h.in	(revision 485)
+++ lemon/config.h.in	(revision 1)
@@ -4,5 +4,2 @@
 /* Define to 1 if you have GLPK. */
 #undef HAVE_GLPK
-
-/* Define to 1 if you have long long */
-#undef HAVE_LONG_LONG
Index: lemon/connectivity.h
===================================================================
--- lemon/connectivity.h	(revision 440)
+++ lemon/connectivity.h	(revision 440)
@@ -0,0 +1,1575 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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_CONNECTIVITY_H
+#define LEMON_CONNECTIVITY_H
+
+#include <lemon/dfs.h>
+#include <lemon/bfs.h>
+#include <lemon/core.h>
+#include <lemon/maps.h>
+#include <lemon/adaptors.h>
+
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/graph.h>
+#include <lemon/concept_check.h>
+
+#include <stack>
+#include <functional>
+
+/// \ingroup connectivity
+/// \file
+/// \brief Connectivity algorithms
+///
+/// Connectivity algorithms
+
+namespace lemon {
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Check whether the given undirected graph is connected.
+  ///
+  /// Check whether the given undirected graph is connected.
+  /// \param graph The undirected graph.
+  /// \return %True when there is path between any two nodes in the graph.
+  /// \note By definition, the empty graph is connected.
+  template <typename Graph>
+  bool connected(const Graph& graph) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::NodeIt NodeIt;
+    if (NodeIt(graph) == INVALID) return true;
+    Dfs<Graph> dfs(graph);
+    dfs.run(NodeIt(graph));
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Count the number of connected components of an undirected graph
+  ///
+  /// Count the number of connected components of an undirected graph
+  ///
+  /// \param graph The graph. It must be undirected.
+  /// \return The number of components
+  /// \note By definition, the empty graph consists
+  /// of zero connected components.
+  template <typename Graph>
+  int countConnectedComponents(const Graph &graph) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::Node Node;
+    typedef typename Graph::Arc Arc;
+
+    typedef NullMap<Node, Arc> PredMap;
+    typedef NullMap<Node, int> DistMap;
+
+    int compNum = 0;
+    typename Bfs<Graph>::
+      template SetPredMap<PredMap>::
+      template SetDistMap<DistMap>::
+      Create bfs(graph);
+
+    PredMap predMap;
+    bfs.predMap(predMap);
+
+    DistMap distMap;
+    bfs.distMap(distMap);
+
+    bfs.init();
+    for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
+      if (!bfs.reached(n)) {
+        bfs.addSource(n);
+        bfs.start();
+        ++compNum;
+      }
+    }
+    return compNum;
+  }
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Find the connected components of an undirected graph
+  ///
+  /// Find the connected components of an undirected graph.
+  ///
+  /// \param graph The graph. It must be undirected.
+  /// \retval compMap A writable node map. The values will be set from 0 to
+  /// the number of the connected components minus one. Each values of the map
+  /// will be set exactly once, the values of a certain component will be
+  /// set continuously.
+  /// \return The number of components
+  ///
+  template <class Graph, class NodeMap>
+  int connectedComponents(const Graph &graph, NodeMap &compMap) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::Node Node;
+    typedef typename Graph::Arc Arc;
+    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
+
+    typedef NullMap<Node, Arc> PredMap;
+    typedef NullMap<Node, int> DistMap;
+
+    int compNum = 0;
+    typename Bfs<Graph>::
+      template SetPredMap<PredMap>::
+      template SetDistMap<DistMap>::
+      Create bfs(graph);
+
+    PredMap predMap;
+    bfs.predMap(predMap);
+
+    DistMap distMap;
+    bfs.distMap(distMap);
+
+    bfs.init();
+    for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
+      if(!bfs.reached(n)) {
+        bfs.addSource(n);
+        while (!bfs.emptyQueue()) {
+          compMap.set(bfs.nextNode(), compNum);
+          bfs.processNextNode();
+        }
+        ++compNum;
+      }
+    }
+    return compNum;
+  }
+
+  namespace _connectivity_bits {
+
+    template <typename Digraph, typename Iterator >
+    struct LeaveOrderVisitor : public DfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Node Node;
+      LeaveOrderVisitor(Iterator it) : _it(it) {}
+
+      void leave(const Node& node) {
+        *(_it++) = node;
+      }
+
+    private:
+      Iterator _it;
+    };
+
+    template <typename Digraph, typename Map>
+    struct FillMapVisitor : public DfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Node Node;
+      typedef typename Map::Value Value;
+
+      FillMapVisitor(Map& map, Value& value)
+        : _map(map), _value(value) {}
+
+      void reach(const Node& node) {
+        _map.set(node, _value);
+      }
+    private:
+      Map& _map;
+      Value& _value;
+    };
+
+    template <typename Digraph, typename ArcMap>
+    struct StronglyConnectedCutArcsVisitor : public DfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Node Node;
+      typedef typename Digraph::Arc Arc;
+
+      StronglyConnectedCutArcsVisitor(const Digraph& digraph,
+                                      ArcMap& cutMap,
+                                      int& cutNum)
+        : _digraph(digraph), _cutMap(cutMap), _cutNum(cutNum),
+          _compMap(digraph, -1), _num(-1) {
+      }
+
+      void start(const Node&) {
+        ++_num;
+      }
+
+      void reach(const Node& node) {
+        _compMap.set(node, _num);
+      }
+
+      void examine(const Arc& arc) {
+         if (_compMap[_digraph.source(arc)] !=
+             _compMap[_digraph.target(arc)]) {
+           _cutMap.set(arc, true);
+           ++_cutNum;
+         }
+      }
+    private:
+      const Digraph& _digraph;
+      ArcMap& _cutMap;
+      int& _cutNum;
+
+      typename Digraph::template NodeMap<int> _compMap;
+      int _num;
+    };
+
+  }
+
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Check whether the given directed graph is strongly connected.
+  ///
+  /// Check whether the given directed graph is strongly connected. The
+  /// graph is strongly connected when any two nodes of the graph are
+  /// connected with directed paths in both direction.
+  /// \return %False when the graph is not strongly connected.
+  /// \see connected
+  ///
+  /// \note By definition, the empty graph is strongly connected.
+  template <typename Digraph>
+  bool stronglyConnected(const Digraph& digraph) {
+    checkConcept<concepts::Digraph, Digraph>();
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+
+    typename Digraph::Node source = NodeIt(digraph);
+    if (source == INVALID) return true;
+
+    using namespace _connectivity_bits;
+
+    typedef DfsVisitor<Digraph> Visitor;
+    Visitor visitor;
+
+    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
+    dfs.init();
+    dfs.addSource(source);
+    dfs.start();
+
+    for (NodeIt it(digraph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        return false;
+      }
+    }
+
+    typedef ReverseDigraph<const Digraph> RDigraph;
+    typedef typename RDigraph::NodeIt RNodeIt;
+    RDigraph rdigraph(digraph);
+
+    typedef DfsVisitor<Digraph> RVisitor;
+    RVisitor rvisitor;
+
+    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
+    rdfs.init();
+    rdfs.addSource(source);
+    rdfs.start();
+
+    for (RNodeIt it(rdigraph); it != INVALID; ++it) {
+      if (!rdfs.reached(it)) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Count the strongly connected components of a directed graph
+  ///
+  /// Count the strongly connected components of a directed graph.
+  /// The strongly connected components are the classes of an
+  /// equivalence relation on the nodes of the graph. Two nodes are in
+  /// the same class if they are connected with directed paths in both
+  /// direction.
+  ///
+  /// \param digraph The graph.
+  /// \return The number of components
+  /// \note By definition, the empty graph has zero
+  /// strongly connected components.
+  template <typename Digraph>
+  int countStronglyConnectedComponents(const Digraph& digraph) {
+    checkConcept<concepts::Digraph, Digraph>();
+
+    using namespace _connectivity_bits;
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::ArcIt ArcIt;
+
+    typedef std::vector<Node> Container;
+    typedef typename Container::iterator Iterator;
+
+    Container nodes(countNodes(digraph));
+    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
+    Visitor visitor(nodes.begin());
+
+    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
+    dfs.init();
+    for (NodeIt it(digraph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        dfs.start();
+      }
+    }
+
+    typedef typename Container::reverse_iterator RIterator;
+    typedef ReverseDigraph<const Digraph> RDigraph;
+
+    RDigraph rdigraph(digraph);
+
+    typedef DfsVisitor<Digraph> RVisitor;
+    RVisitor rvisitor;
+
+    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
+
+    int compNum = 0;
+
+    rdfs.init();
+    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
+      if (!rdfs.reached(*it)) {
+        rdfs.addSource(*it);
+        rdfs.start();
+        ++compNum;
+      }
+    }
+    return compNum;
+  }
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Find the strongly connected components of a directed graph
+  ///
+  /// Find the strongly connected components of a directed graph.  The
+  /// strongly connected components are the classes of an equivalence
+  /// relation on the nodes of the graph. Two nodes are in
+  /// relationship when there are directed paths between them in both
+  /// direction. In addition, the numbering of components will satisfy
+  /// that there is no arc going from a higher numbered component to
+  /// a lower.
+  ///
+  /// \param digraph The digraph.
+  /// \retval compMap A writable node map. The values will be set from 0 to
+  /// the number of the strongly connected components minus one. Each value
+  /// of the map will be set exactly once, the values of a certain component
+  /// will be set continuously.
+  /// \return The number of components
+  ///
+  template <typename Digraph, typename NodeMap>
+  int stronglyConnectedComponents(const Digraph& digraph, NodeMap& compMap) {
+    checkConcept<concepts::Digraph, Digraph>();
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
+
+    using namespace _connectivity_bits;
+
+    typedef std::vector<Node> Container;
+    typedef typename Container::iterator Iterator;
+
+    Container nodes(countNodes(digraph));
+    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
+    Visitor visitor(nodes.begin());
+
+    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
+    dfs.init();
+    for (NodeIt it(digraph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        dfs.start();
+      }
+    }
+
+    typedef typename Container::reverse_iterator RIterator;
+    typedef ReverseDigraph<const Digraph> RDigraph;
+
+    RDigraph rdigraph(digraph);
+
+    int compNum = 0;
+
+    typedef FillMapVisitor<RDigraph, NodeMap> RVisitor;
+    RVisitor rvisitor(compMap, compNum);
+
+    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
+
+    rdfs.init();
+    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
+      if (!rdfs.reached(*it)) {
+        rdfs.addSource(*it);
+        rdfs.start();
+        ++compNum;
+      }
+    }
+    return compNum;
+  }
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Find the cut arcs of the strongly connected components.
+  ///
+  /// Find the cut arcs of the strongly connected components.
+  /// The strongly connected components are the classes of an equivalence
+  /// relation on the nodes of the graph. Two nodes are in relationship
+  /// when there are directed paths between them in both direction.
+  /// The strongly connected components are separated by the cut arcs.
+  ///
+  /// \param graph The graph.
+  /// \retval cutMap A writable node map. The values will be set true when the
+  /// arc is a cut arc.
+  ///
+  /// \return The number of cut arcs
+  template <typename Digraph, typename ArcMap>
+  int stronglyConnectedCutArcs(const Digraph& graph, ArcMap& cutMap) {
+    checkConcept<concepts::Digraph, Digraph>();
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::NodeIt NodeIt;
+    checkConcept<concepts::WriteMap<Arc, bool>, ArcMap>();
+
+    using namespace _connectivity_bits;
+
+    typedef std::vector<Node> Container;
+    typedef typename Container::iterator Iterator;
+
+    Container nodes(countNodes(graph));
+    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
+    Visitor visitor(nodes.begin());
+
+    DfsVisit<Digraph, Visitor> dfs(graph, visitor);
+    dfs.init();
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        dfs.start();
+      }
+    }
+
+    typedef typename Container::reverse_iterator RIterator;
+    typedef ReverseDigraph<const Digraph> RDigraph;
+
+    RDigraph rgraph(graph);
+
+    int cutNum = 0;
+
+    typedef StronglyConnectedCutArcsVisitor<RDigraph, ArcMap> RVisitor;
+    RVisitor rvisitor(rgraph, cutMap, cutNum);
+
+    DfsVisit<RDigraph, RVisitor> rdfs(rgraph, rvisitor);
+
+    rdfs.init();
+    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
+      if (!rdfs.reached(*it)) {
+        rdfs.addSource(*it);
+        rdfs.start();
+      }
+    }
+    return cutNum;
+  }
+
+  namespace _connectivity_bits {
+
+    template <typename Digraph>
+    class CountBiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Node Node;
+      typedef typename Digraph::Arc Arc;
+      typedef typename Digraph::Edge Edge;
+
+      CountBiNodeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
+        : _graph(graph), _compNum(compNum),
+          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
+
+      void start(const Node& node) {
+        _predMap.set(node, INVALID);
+      }
+
+      void reach(const Node& node) {
+        _numMap.set(node, _num);
+        _retMap.set(node, _num);
+        ++_num;
+      }
+
+      void discover(const Arc& edge) {
+        _predMap.set(_graph.target(edge), _graph.source(edge));
+      }
+
+      void examine(const Arc& edge) {
+        if (_graph.source(edge) == _graph.target(edge) &&
+            _graph.direction(edge)) {
+          ++_compNum;
+          return;
+        }
+        if (_predMap[_graph.source(edge)] == _graph.target(edge)) {
+          return;
+        }
+        if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
+          _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
+        }
+      }
+
+      void backtrack(const Arc& edge) {
+        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
+          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
+        }
+        if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
+          ++_compNum;
+        }
+      }
+
+    private:
+      const Digraph& _graph;
+      int& _compNum;
+
+      typename Digraph::template NodeMap<int> _numMap;
+      typename Digraph::template NodeMap<int> _retMap;
+      typename Digraph::template NodeMap<Node> _predMap;
+      int _num;
+    };
+
+    template <typename Digraph, typename ArcMap>
+    class BiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Node Node;
+      typedef typename Digraph::Arc Arc;
+      typedef typename Digraph::Edge Edge;
+
+      BiNodeConnectedComponentsVisitor(const Digraph& graph,
+                                       ArcMap& compMap, int &compNum)
+        : _graph(graph), _compMap(compMap), _compNum(compNum),
+          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
+
+      void start(const Node& node) {
+        _predMap.set(node, INVALID);
+      }
+
+      void reach(const Node& node) {
+        _numMap.set(node, _num);
+        _retMap.set(node, _num);
+        ++_num;
+      }
+
+      void discover(const Arc& edge) {
+        Node target = _graph.target(edge);
+        _predMap.set(target, edge);
+        _edgeStack.push(edge);
+      }
+
+      void examine(const Arc& edge) {
+        Node source = _graph.source(edge);
+        Node target = _graph.target(edge);
+        if (source == target && _graph.direction(edge)) {
+          _compMap.set(edge, _compNum);
+          ++_compNum;
+          return;
+        }
+        if (_numMap[target] < _numMap[source]) {
+          if (_predMap[source] != _graph.oppositeArc(edge)) {
+            _edgeStack.push(edge);
+          }
+        }
+        if (_predMap[source] != INVALID &&
+            target == _graph.source(_predMap[source])) {
+          return;
+        }
+        if (_retMap[source] > _numMap[target]) {
+          _retMap.set(source, _numMap[target]);
+        }
+      }
+
+      void backtrack(const Arc& edge) {
+        Node source = _graph.source(edge);
+        Node target = _graph.target(edge);
+        if (_retMap[source] > _retMap[target]) {
+          _retMap.set(source, _retMap[target]);
+        }
+        if (_numMap[source] <= _retMap[target]) {
+          while (_edgeStack.top() != edge) {
+            _compMap.set(_edgeStack.top(), _compNum);
+            _edgeStack.pop();
+          }
+          _compMap.set(edge, _compNum);
+          _edgeStack.pop();
+          ++_compNum;
+        }
+      }
+
+    private:
+      const Digraph& _graph;
+      ArcMap& _compMap;
+      int& _compNum;
+
+      typename Digraph::template NodeMap<int> _numMap;
+      typename Digraph::template NodeMap<int> _retMap;
+      typename Digraph::template NodeMap<Arc> _predMap;
+      std::stack<Edge> _edgeStack;
+      int _num;
+    };
+
+
+    template <typename Digraph, typename NodeMap>
+    class BiNodeConnectedCutNodesVisitor : public DfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Node Node;
+      typedef typename Digraph::Arc Arc;
+      typedef typename Digraph::Edge Edge;
+
+      BiNodeConnectedCutNodesVisitor(const Digraph& graph, NodeMap& cutMap,
+                                     int& cutNum)
+        : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
+          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
+
+      void start(const Node& node) {
+        _predMap.set(node, INVALID);
+        rootCut = false;
+      }
+
+      void reach(const Node& node) {
+        _numMap.set(node, _num);
+        _retMap.set(node, _num);
+        ++_num;
+      }
+
+      void discover(const Arc& edge) {
+        _predMap.set(_graph.target(edge), _graph.source(edge));
+      }
+
+      void examine(const Arc& edge) {
+        if (_graph.source(edge) == _graph.target(edge) &&
+            _graph.direction(edge)) {
+          if (!_cutMap[_graph.source(edge)]) {
+            _cutMap.set(_graph.source(edge), true);
+            ++_cutNum;
+          }
+          return;
+        }
+        if (_predMap[_graph.source(edge)] == _graph.target(edge)) return;
+        if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
+          _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
+        }
+      }
+
+      void backtrack(const Arc& edge) {
+        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
+          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
+        }
+        if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
+          if (_predMap[_graph.source(edge)] != INVALID) {
+            if (!_cutMap[_graph.source(edge)]) {
+              _cutMap.set(_graph.source(edge), true);
+              ++_cutNum;
+            }
+          } else if (rootCut) {
+            if (!_cutMap[_graph.source(edge)]) {
+              _cutMap.set(_graph.source(edge), true);
+              ++_cutNum;
+            }
+          } else {
+            rootCut = true;
+          }
+        }
+      }
+
+    private:
+      const Digraph& _graph;
+      NodeMap& _cutMap;
+      int& _cutNum;
+
+      typename Digraph::template NodeMap<int> _numMap;
+      typename Digraph::template NodeMap<int> _retMap;
+      typename Digraph::template NodeMap<Node> _predMap;
+      std::stack<Edge> _edgeStack;
+      int _num;
+      bool rootCut;
+    };
+
+  }
+
+  template <typename Graph>
+  int countBiNodeConnectedComponents(const Graph& graph);
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Checks the graph is bi-node-connected.
+  ///
+  /// This function checks that the undirected graph is bi-node-connected
+  /// graph. The graph is bi-node-connected if any two undirected edge is
+  /// on same circle.
+  ///
+  /// \param graph The graph.
+  /// \return %True when the graph bi-node-connected.
+  template <typename Graph>
+  bool biNodeConnected(const Graph& graph) {
+    return countBiNodeConnectedComponents(graph) <= 1;
+  }
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Count the biconnected components.
+  ///
+  /// This function finds the bi-node-connected components in an undirected
+  /// graph. The biconnected components are the classes of an equivalence
+  /// relation on the undirected edges. Two undirected edge is in relationship
+  /// when they are on same circle.
+  ///
+  /// \param graph The graph.
+  /// \return The number of components.
+  template <typename Graph>
+  int countBiNodeConnectedComponents(const Graph& graph) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::NodeIt NodeIt;
+
+    using namespace _connectivity_bits;
+
+    typedef CountBiNodeConnectedComponentsVisitor<Graph> Visitor;
+
+    int compNum = 0;
+    Visitor visitor(graph, compNum);
+
+    DfsVisit<Graph, Visitor> dfs(graph, visitor);
+    dfs.init();
+
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        dfs.start();
+      }
+    }
+    return compNum;
+  }
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Find the bi-node-connected components.
+  ///
+  /// This function finds the bi-node-connected components in an undirected
+  /// graph. The bi-node-connected components are the classes of an equivalence
+  /// relation on the undirected edges. Two undirected edge are in relationship
+  /// when they are on same circle.
+  ///
+  /// \param graph The graph.
+  /// \retval compMap A writable uedge map. The values will be set from 0
+  /// to the number of the biconnected components minus one. Each values
+  /// of the map will be set exactly once, the values of a certain component
+  /// will be set continuously.
+  /// \return The number of components.
+  ///
+  template <typename Graph, typename EdgeMap>
+  int biNodeConnectedComponents(const Graph& graph,
+                                EdgeMap& compMap) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::NodeIt NodeIt;
+    typedef typename Graph::Edge Edge;
+    checkConcept<concepts::WriteMap<Edge, int>, EdgeMap>();
+
+    using namespace _connectivity_bits;
+
+    typedef BiNodeConnectedComponentsVisitor<Graph, EdgeMap> Visitor;
+
+    int compNum = 0;
+    Visitor visitor(graph, compMap, compNum);
+
+    DfsVisit<Graph, Visitor> dfs(graph, visitor);
+    dfs.init();
+
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        dfs.start();
+      }
+    }
+    return compNum;
+  }
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Find the bi-node-connected cut nodes.
+  ///
+  /// This function finds the bi-node-connected cut nodes in an undirected
+  /// graph. The bi-node-connected components are the classes of an equivalence
+  /// relation on the undirected edges. Two undirected edges are in
+  /// relationship when they are on same circle. The biconnected components
+  /// are separted by nodes which are the cut nodes of the components.
+  ///
+  /// \param graph The graph.
+  /// \retval cutMap A writable edge map. The values will be set true when
+  /// the node separate two or more components.
+  /// \return The number of the cut nodes.
+  template <typename Graph, typename NodeMap>
+  int biNodeConnectedCutNodes(const Graph& graph, NodeMap& cutMap) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::Node Node;
+    typedef typename Graph::NodeIt NodeIt;
+    checkConcept<concepts::WriteMap<Node, bool>, NodeMap>();
+
+    using namespace _connectivity_bits;
+
+    typedef BiNodeConnectedCutNodesVisitor<Graph, NodeMap> Visitor;
+
+    int cutNum = 0;
+    Visitor visitor(graph, cutMap, cutNum);
+
+    DfsVisit<Graph, Visitor> dfs(graph, visitor);
+    dfs.init();
+
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        dfs.start();
+      }
+    }
+    return cutNum;
+  }
+
+  namespace _connectivity_bits {
+
+    template <typename Digraph>
+    class CountBiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Node Node;
+      typedef typename Digraph::Arc Arc;
+      typedef typename Digraph::Edge Edge;
+
+      CountBiEdgeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
+        : _graph(graph), _compNum(compNum),
+          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
+
+      void start(const Node& node) {
+        _predMap.set(node, INVALID);
+      }
+
+      void reach(const Node& node) {
+        _numMap.set(node, _num);
+        _retMap.set(node, _num);
+        ++_num;
+      }
+
+      void leave(const Node& node) {
+        if (_numMap[node] <= _retMap[node]) {
+          ++_compNum;
+        }
+      }
+
+      void discover(const Arc& edge) {
+        _predMap.set(_graph.target(edge), edge);
+      }
+
+      void examine(const Arc& edge) {
+        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
+          return;
+        }
+        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
+          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
+        }
+      }
+
+      void backtrack(const Arc& edge) {
+        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
+          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
+        }
+      }
+
+    private:
+      const Digraph& _graph;
+      int& _compNum;
+
+      typename Digraph::template NodeMap<int> _numMap;
+      typename Digraph::template NodeMap<int> _retMap;
+      typename Digraph::template NodeMap<Arc> _predMap;
+      int _num;
+    };
+
+    template <typename Digraph, typename NodeMap>
+    class BiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Node Node;
+      typedef typename Digraph::Arc Arc;
+      typedef typename Digraph::Edge Edge;
+
+      BiEdgeConnectedComponentsVisitor(const Digraph& graph,
+                                       NodeMap& compMap, int &compNum)
+        : _graph(graph), _compMap(compMap), _compNum(compNum),
+          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
+
+      void start(const Node& node) {
+        _predMap.set(node, INVALID);
+      }
+
+      void reach(const Node& node) {
+        _numMap.set(node, _num);
+        _retMap.set(node, _num);
+        _nodeStack.push(node);
+        ++_num;
+      }
+
+      void leave(const Node& node) {
+        if (_numMap[node] <= _retMap[node]) {
+          while (_nodeStack.top() != node) {
+            _compMap.set(_nodeStack.top(), _compNum);
+            _nodeStack.pop();
+          }
+          _compMap.set(node, _compNum);
+          _nodeStack.pop();
+          ++_compNum;
+        }
+      }
+
+      void discover(const Arc& edge) {
+        _predMap.set(_graph.target(edge), edge);
+      }
+
+      void examine(const Arc& edge) {
+        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
+          return;
+        }
+        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
+          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
+        }
+      }
+
+      void backtrack(const Arc& edge) {
+        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
+          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
+        }
+      }
+
+    private:
+      const Digraph& _graph;
+      NodeMap& _compMap;
+      int& _compNum;
+
+      typename Digraph::template NodeMap<int> _numMap;
+      typename Digraph::template NodeMap<int> _retMap;
+      typename Digraph::template NodeMap<Arc> _predMap;
+      std::stack<Node> _nodeStack;
+      int _num;
+    };
+
+
+    template <typename Digraph, typename ArcMap>
+    class BiEdgeConnectedCutEdgesVisitor : public DfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Node Node;
+      typedef typename Digraph::Arc Arc;
+      typedef typename Digraph::Edge Edge;
+
+      BiEdgeConnectedCutEdgesVisitor(const Digraph& graph,
+                                     ArcMap& cutMap, int &cutNum)
+        : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
+          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
+
+      void start(const Node& node) {
+        _predMap[node] = INVALID;
+      }
+
+      void reach(const Node& node) {
+        _numMap.set(node, _num);
+        _retMap.set(node, _num);
+        ++_num;
+      }
+
+      void leave(const Node& node) {
+        if (_numMap[node] <= _retMap[node]) {
+          if (_predMap[node] != INVALID) {
+            _cutMap.set(_predMap[node], true);
+            ++_cutNum;
+          }
+        }
+      }
+
+      void discover(const Arc& edge) {
+        _predMap.set(_graph.target(edge), edge);
+      }
+
+      void examine(const Arc& edge) {
+        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
+          return;
+        }
+        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
+          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
+        }
+      }
+
+      void backtrack(const Arc& edge) {
+        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
+          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
+        }
+      }
+
+    private:
+      const Digraph& _graph;
+      ArcMap& _cutMap;
+      int& _cutNum;
+
+      typename Digraph::template NodeMap<int> _numMap;
+      typename Digraph::template NodeMap<int> _retMap;
+      typename Digraph::template NodeMap<Arc> _predMap;
+      int _num;
+    };
+  }
+
+  template <typename Graph>
+  int countBiEdgeConnectedComponents(const Graph& graph);
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Checks that the graph is bi-edge-connected.
+  ///
+  /// This function checks that the graph is bi-edge-connected. The undirected
+  /// graph is bi-edge-connected when any two nodes are connected with two
+  /// edge-disjoint paths.
+  ///
+  /// \param graph The undirected graph.
+  /// \return The number of components.
+  template <typename Graph>
+  bool biEdgeConnected(const Graph& graph) {
+    return countBiEdgeConnectedComponents(graph) <= 1;
+  }
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Count the bi-edge-connected components.
+  ///
+  /// This function count the bi-edge-connected components in an undirected
+  /// graph. The bi-edge-connected components are the classes of an equivalence
+  /// relation on the nodes. Two nodes are in relationship when they are
+  /// connected with at least two edge-disjoint paths.
+  ///
+  /// \param graph The undirected graph.
+  /// \return The number of components.
+  template <typename Graph>
+  int countBiEdgeConnectedComponents(const Graph& graph) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::NodeIt NodeIt;
+
+    using namespace _connectivity_bits;
+
+    typedef CountBiEdgeConnectedComponentsVisitor<Graph> Visitor;
+
+    int compNum = 0;
+    Visitor visitor(graph, compNum);
+
+    DfsVisit<Graph, Visitor> dfs(graph, visitor);
+    dfs.init();
+
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        dfs.start();
+      }
+    }
+    return compNum;
+  }
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Find the bi-edge-connected components.
+  ///
+  /// This function finds the bi-edge-connected components in an undirected
+  /// graph. The bi-edge-connected components are the classes of an equivalence
+  /// relation on the nodes. Two nodes are in relationship when they are
+  /// connected at least two edge-disjoint paths.
+  ///
+  /// \param graph The graph.
+  /// \retval compMap A writable node map. The values will be set from 0 to
+  /// the number of the biconnected components minus one. Each values
+  /// of the map will be set exactly once, the values of a certain component
+  /// will be set continuously.
+  /// \return The number of components.
+  ///
+  template <typename Graph, typename NodeMap>
+  int biEdgeConnectedComponents(const Graph& graph, NodeMap& compMap) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::NodeIt NodeIt;
+    typedef typename Graph::Node Node;
+    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
+
+    using namespace _connectivity_bits;
+
+    typedef BiEdgeConnectedComponentsVisitor<Graph, NodeMap> Visitor;
+
+    int compNum = 0;
+    Visitor visitor(graph, compMap, compNum);
+
+    DfsVisit<Graph, Visitor> dfs(graph, visitor);
+    dfs.init();
+
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        dfs.start();
+      }
+    }
+    return compNum;
+  }
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Find the bi-edge-connected cut edges.
+  ///
+  /// This function finds the bi-edge-connected components in an undirected
+  /// graph. The bi-edge-connected components are the classes of an equivalence
+  /// relation on the nodes. Two nodes are in relationship when they are
+  /// connected with at least two edge-disjoint paths. The bi-edge-connected
+  /// components are separted by edges which are the cut edges of the
+  /// components.
+  ///
+  /// \param graph The graph.
+  /// \retval cutMap A writable node map. The values will be set true when the
+  /// edge is a cut edge.
+  /// \return The number of cut edges.
+  template <typename Graph, typename EdgeMap>
+  int biEdgeConnectedCutEdges(const Graph& graph, EdgeMap& cutMap) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::NodeIt NodeIt;
+    typedef typename Graph::Edge Edge;
+    checkConcept<concepts::WriteMap<Edge, bool>, EdgeMap>();
+
+    using namespace _connectivity_bits;
+
+    typedef BiEdgeConnectedCutEdgesVisitor<Graph, EdgeMap> Visitor;
+
+    int cutNum = 0;
+    Visitor visitor(graph, cutMap, cutNum);
+
+    DfsVisit<Graph, Visitor> dfs(graph, visitor);
+    dfs.init();
+
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        dfs.start();
+      }
+    }
+    return cutNum;
+  }
+
+
+  namespace _connectivity_bits {
+
+    template <typename Digraph, typename IntNodeMap>
+    class TopologicalSortVisitor : public DfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Node Node;
+      typedef typename Digraph::Arc edge;
+
+      TopologicalSortVisitor(IntNodeMap& order, int num)
+        : _order(order), _num(num) {}
+
+      void leave(const Node& node) {
+        _order.set(node, --_num);
+      }
+
+    private:
+      IntNodeMap& _order;
+      int _num;
+    };
+
+  }
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Sort the nodes of a DAG into topolgical order.
+  ///
+  /// Sort the nodes of a DAG into topolgical order.
+  ///
+  /// \param graph The graph. It must be directed and acyclic.
+  /// \retval order A writable node map. The values will be set from 0 to
+  /// the number of the nodes in the graph minus one. Each values of the map
+  /// will be set exactly once, the values  will be set descending order.
+  ///
+  /// \see checkedTopologicalSort
+  /// \see dag
+  template <typename Digraph, typename NodeMap>
+  void topologicalSort(const Digraph& graph, NodeMap& order) {
+    using namespace _connectivity_bits;
+
+    checkConcept<concepts::Digraph, Digraph>();
+    checkConcept<concepts::WriteMap<typename Digraph::Node, int>, NodeMap>();
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+
+    TopologicalSortVisitor<Digraph, NodeMap>
+      visitor(order, countNodes(graph));
+
+    DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
+      dfs(graph, visitor);
+
+    dfs.init();
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        dfs.start();
+      }
+    }
+  }
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Sort the nodes of a DAG into topolgical order.
+  ///
+  /// Sort the nodes of a DAG into topolgical order. It also checks
+  /// that the given graph is DAG.
+  ///
+  /// \param digraph The graph. It must be directed and acyclic.
+  /// \retval order A readable - writable node map. The values will be set
+  /// from 0 to the number of the nodes in the graph minus one. Each values
+  /// of the map will be set exactly once, the values will be set descending
+  /// order.
+  /// \return %False when the graph is not DAG.
+  ///
+  /// \see topologicalSort
+  /// \see dag
+  template <typename Digraph, typename NodeMap>
+  bool checkedTopologicalSort(const Digraph& digraph, NodeMap& order) {
+    using namespace _connectivity_bits;
+
+    checkConcept<concepts::Digraph, Digraph>();
+    checkConcept<concepts::ReadWriteMap<typename Digraph::Node, int>,
+      NodeMap>();
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+
+    for (NodeIt it(digraph); it != INVALID; ++it) {
+      order.set(it, -1);
+    }
+
+    TopologicalSortVisitor<Digraph, NodeMap>
+      visitor(order, countNodes(digraph));
+
+    DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
+      dfs(digraph, visitor);
+
+    dfs.init();
+    for (NodeIt it(digraph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        while (!dfs.emptyQueue()) {
+           Arc arc = dfs.nextArc();
+           Node target = digraph.target(arc);
+           if (dfs.reached(target) && order[target] == -1) {
+             return false;
+           }
+           dfs.processNextArc();
+         }
+      }
+    }
+    return true;
+  }
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Check that the given directed graph is a DAG.
+  ///
+  /// Check that the given directed graph is a DAG. The DAG is
+  /// an Directed Acyclic Digraph.
+  /// \return %False when the graph is not DAG.
+  /// \see acyclic
+  template <typename Digraph>
+  bool dag(const Digraph& digraph) {
+
+    checkConcept<concepts::Digraph, Digraph>();
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+
+    typedef typename Digraph::template NodeMap<bool> ProcessedMap;
+
+    typename Dfs<Digraph>::template SetProcessedMap<ProcessedMap>::
+      Create dfs(digraph);
+
+    ProcessedMap processed(digraph);
+    dfs.processedMap(processed);
+
+    dfs.init();
+    for (NodeIt it(digraph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        while (!dfs.emptyQueue()) {
+          Arc edge = dfs.nextArc();
+          Node target = digraph.target(edge);
+          if (dfs.reached(target) && !processed[target]) {
+            return false;
+          }
+          dfs.processNextArc();
+        }
+      }
+    }
+    return true;
+  }
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Check that the given undirected graph is acyclic.
+  ///
+  /// Check that the given undirected graph acyclic.
+  /// \param graph The undirected graph.
+  /// \return %True when there is no circle in the graph.
+  /// \see dag
+  template <typename Graph>
+  bool acyclic(const Graph& graph) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::Node Node;
+    typedef typename Graph::NodeIt NodeIt;
+    typedef typename Graph::Arc Arc;
+    Dfs<Graph> dfs(graph);
+    dfs.init();
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        dfs.addSource(it);
+        while (!dfs.emptyQueue()) {
+          Arc edge = dfs.nextArc();
+          Node source = graph.source(edge);
+          Node target = graph.target(edge);
+          if (dfs.reached(target) &&
+              dfs.predArc(source) != graph.oppositeArc(edge)) {
+            return false;
+          }
+          dfs.processNextArc();
+        }
+      }
+    }
+    return true;
+  }
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Check that the given undirected graph is tree.
+  ///
+  /// Check that the given undirected graph is tree.
+  /// \param graph The undirected graph.
+  /// \return %True when the graph is acyclic and connected.
+  template <typename Graph>
+  bool tree(const Graph& graph) {
+    checkConcept<concepts::Graph, Graph>();
+    typedef typename Graph::Node Node;
+    typedef typename Graph::NodeIt NodeIt;
+    typedef typename Graph::Arc Arc;
+    Dfs<Graph> dfs(graph);
+    dfs.init();
+    dfs.addSource(NodeIt(graph));
+    while (!dfs.emptyQueue()) {
+      Arc edge = dfs.nextArc();
+      Node source = graph.source(edge);
+      Node target = graph.target(edge);
+      if (dfs.reached(target) &&
+          dfs.predArc(source) != graph.oppositeArc(edge)) {
+        return false;
+      }
+      dfs.processNextArc();
+    }
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  namespace _connectivity_bits {
+
+    template <typename Digraph>
+    class BipartiteVisitor : public BfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Arc Arc;
+      typedef typename Digraph::Node Node;
+
+      BipartiteVisitor(const Digraph& graph, bool& bipartite)
+        : _graph(graph), _part(graph), _bipartite(bipartite) {}
+
+      void start(const Node& node) {
+        _part[node] = true;
+      }
+      void discover(const Arc& edge) {
+        _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
+      }
+      void examine(const Arc& edge) {
+        _bipartite = _bipartite &&
+          _part[_graph.target(edge)] != _part[_graph.source(edge)];
+      }
+
+    private:
+
+      const Digraph& _graph;
+      typename Digraph::template NodeMap<bool> _part;
+      bool& _bipartite;
+    };
+
+    template <typename Digraph, typename PartMap>
+    class BipartitePartitionsVisitor : public BfsVisitor<Digraph> {
+    public:
+      typedef typename Digraph::Arc Arc;
+      typedef typename Digraph::Node Node;
+
+      BipartitePartitionsVisitor(const Digraph& graph,
+                                 PartMap& part, bool& bipartite)
+        : _graph(graph), _part(part), _bipartite(bipartite) {}
+
+      void start(const Node& node) {
+        _part.set(node, true);
+      }
+      void discover(const Arc& edge) {
+        _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
+      }
+      void examine(const Arc& edge) {
+        _bipartite = _bipartite &&
+          _part[_graph.target(edge)] != _part[_graph.source(edge)];
+      }
+
+    private:
+
+      const Digraph& _graph;
+      PartMap& _part;
+      bool& _bipartite;
+    };
+  }
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Check if the given undirected graph is bipartite or not
+  ///
+  /// The function checks if the given undirected \c graph graph is bipartite
+  /// or not. The \ref Bfs algorithm is used to calculate the result.
+  /// \param graph The undirected graph.
+  /// \return %True if \c graph is bipartite, %false otherwise.
+  /// \sa bipartitePartitions
+  template<typename Graph>
+  inline bool bipartite(const Graph &graph){
+    using namespace _connectivity_bits;
+
+    checkConcept<concepts::Graph, Graph>();
+
+    typedef typename Graph::NodeIt NodeIt;
+    typedef typename Graph::ArcIt ArcIt;
+
+    bool bipartite = true;
+
+    BipartiteVisitor<Graph>
+      visitor(graph, bipartite);
+    BfsVisit<Graph, BipartiteVisitor<Graph> >
+      bfs(graph, visitor);
+    bfs.init();
+    for(NodeIt it(graph); it != INVALID; ++it) {
+      if(!bfs.reached(it)){
+        bfs.addSource(it);
+        while (!bfs.emptyQueue()) {
+          bfs.processNextNode();
+          if (!bipartite) return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  /// \ingroup connectivity
+  ///
+  /// \brief Check if the given undirected graph is bipartite or not
+  ///
+  /// The function checks if the given undirected graph is bipartite
+  /// or not. The  \ref  Bfs  algorithm  is   used  to  calculate the result.
+  /// During the execution, the \c partMap will be set as the two
+  /// partitions of the graph.
+  /// \param graph The undirected graph.
+  /// \retval partMap A writable bool map of nodes. It will be set as the
+  /// two partitions of the graph.
+  /// \return %True if \c graph is bipartite, %false otherwise.
+  template<typename Graph, typename NodeMap>
+  inline bool bipartitePartitions(const Graph &graph, NodeMap &partMap){
+    using namespace _connectivity_bits;
+
+    checkConcept<concepts::Graph, Graph>();
+
+    typedef typename Graph::Node Node;
+    typedef typename Graph::NodeIt NodeIt;
+    typedef typename Graph::ArcIt ArcIt;
+
+    bool bipartite = true;
+
+    BipartitePartitionsVisitor<Graph, NodeMap>
+      visitor(graph, partMap, bipartite);
+    BfsVisit<Graph, BipartitePartitionsVisitor<Graph, NodeMap> >
+      bfs(graph, visitor);
+    bfs.init();
+    for(NodeIt it(graph); it != INVALID; ++it) {
+      if(!bfs.reached(it)){
+        bfs.addSource(it);
+        while (!bfs.emptyQueue()) {
+          bfs.processNextNode();
+          if (!bipartite) return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  /// \brief Returns true when there are not loop edges in the graph.
+  ///
+  /// Returns true when there are not loop edges in the graph.
+  template <typename Digraph>
+  bool loopFree(const Digraph& digraph) {
+    for (typename Digraph::ArcIt it(digraph); it != INVALID; ++it) {
+      if (digraph.source(it) == digraph.target(it)) return false;
+    }
+    return true;
+  }
+
+  /// \brief Returns true when there are not parallel edges in the graph.
+  ///
+  /// Returns true when there are not parallel edges in the graph.
+  template <typename Digraph>
+  bool parallelFree(const Digraph& digraph) {
+    typename Digraph::template NodeMap<bool> reached(digraph, false);
+    for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
+      for (typename Digraph::OutArcIt a(digraph, n); a != INVALID; ++a) {
+        if (reached[digraph.target(a)]) return false;
+        reached.set(digraph.target(a), true);
+      }
+      for (typename Digraph::OutArcIt a(digraph, n); a != INVALID; ++a) {
+        reached.set(digraph.target(a), false);
+      }
+    }
+    return true;
+  }
+
+  /// \brief Returns true when there are not loop edges and parallel
+  /// edges in the graph.
+  ///
+  /// Returns true when there are not loop edges and parallel edges in
+  /// the graph.
+  template <typename Digraph>
+  bool simpleDigraph(const Digraph& digraph) {
+    typename Digraph::template NodeMap<bool> reached(digraph, false);
+    for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
+      reached.set(n, true);
+      for (typename Digraph::OutArcIt a(digraph, n); a != INVALID; ++a) {
+        if (reached[digraph.target(a)]) return false;
+        reached.set(digraph.target(a), true);
+      }
+      for (typename Digraph::OutArcIt a(digraph, n); a != INVALID; ++a) {
+        reached.set(digraph.target(a), false);
+      }
+      reached.set(n, false);
+    }
+    return true;
+  }
+
+} //namespace lemon
+
+#endif //LEMON_CONNECTIVITY_H
Index: lemon/core.h
===================================================================
--- lemon/core.h	(revision 491)
+++ lemon/core.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -23,5 +23,4 @@
 #include <algorithm>
 
-#include <lemon/core.h>
 #include <lemon/bits/enable_if.h>
 #include <lemon/bits/traits.h>
Index: lemon/counter.h
===================================================================
--- lemon/counter.h	(revision 209)
+++ lemon/counter.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/dfs.h
===================================================================
--- lemon/dfs.h	(revision 319)
+++ lemon/dfs.h	(revision 492)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -50,9 +50,9 @@
     ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
-    ///Instantiates a PredMap.
-
-    ///This function instantiates a PredMap.
+    ///Instantiates a \c PredMap.
+
+    ///This function instantiates a \ref PredMap.
     ///\param g is the digraph, to which we would like to define the
-    ///PredMap.
+    ///\ref PredMap.
     static PredMap *createPredMap(const Digraph &g)
     {
@@ -65,9 +65,9 @@
     ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
-    ///Instantiates a ProcessedMap.
-
-    ///This function instantiates a ProcessedMap.
+    ///Instantiates a \c ProcessedMap.
+
+    ///This function instantiates a \ref ProcessedMap.
     ///\param g is the digraph, to which
-    ///we would like to define the ProcessedMap
+    ///we would like to define the \ref ProcessedMap.
 #ifdef DOXYGEN
     static ProcessedMap *createProcessedMap(const Digraph &g)
@@ -84,9 +84,9 @@
     ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     typedef typename Digraph::template NodeMap<bool> ReachedMap;
-    ///Instantiates a ReachedMap.
-
-    ///This function instantiates a ReachedMap.
+    ///Instantiates a \c ReachedMap.
+
+    ///This function instantiates a \ref ReachedMap.
     ///\param g is the digraph, to which
-    ///we would like to define the ReachedMap.
+    ///we would like to define the \ref ReachedMap.
     static ReachedMap *createReachedMap(const Digraph &g)
     {
@@ -99,9 +99,9 @@
     ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     typedef typename Digraph::template NodeMap<int> DistMap;
-    ///Instantiates a DistMap.
-
-    ///This function instantiates a DistMap.
+    ///Instantiates a \c DistMap.
+
+    ///This function instantiates a \ref DistMap.
     ///\param g is the digraph, to which we would like to define the
-    ///DistMap.
+    ///\ref DistMap.
     static DistMap *createDistMap(const Digraph &g)
     {
@@ -120,11 +120,5 @@
   ///
   ///\tparam GR The type of the digraph the algorithm runs on.
-  ///The default value is \ref ListDigraph. The value of GR is not used
-  ///directly by \ref Dfs, it is only passed to \ref DfsDefaultTraits.
-  ///\tparam TR Traits class to set various data types used by the algorithm.
-  ///The default traits class is
-  ///\ref DfsDefaultTraits "DfsDefaultTraits<GR>".
-  ///See \ref DfsDefaultTraits for the documentation of
-  ///a Dfs traits class.
+  ///The default type is \ref ListDigraph.
 #ifdef DOXYGEN
   template <typename GR,
@@ -152,5 +146,5 @@
     typedef PredMapPath<Digraph, PredMap> Path;
 
-    ///The traits class.
+    ///The \ref DfsDefaultTraits "traits class" of the algorithm.
     typedef TR Traits;
 
@@ -227,8 +221,9 @@
     };
     ///\brief \ref named-templ-param "Named parameter" for setting
-    ///PredMap type.
+    ///\c PredMap type.
     ///
     ///\ref named-templ-param "Named parameter" for setting
-    ///PredMap type.
+    ///\c PredMap type.
+    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetPredMap : public Dfs<Digraph, SetPredMapTraits<T> > {
@@ -246,8 +241,9 @@
     };
     ///\brief \ref named-templ-param "Named parameter" for setting
-    ///DistMap type.
+    ///\c DistMap type.
     ///
     ///\ref named-templ-param "Named parameter" for setting
-    ///DistMap type.
+    ///\c DistMap type.
+    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetDistMap : public Dfs< Digraph, SetDistMapTraits<T> > {
@@ -265,8 +261,9 @@
     };
     ///\brief \ref named-templ-param "Named parameter" for setting
-    ///ReachedMap type.
+    ///\c ReachedMap type.
     ///
     ///\ref named-templ-param "Named parameter" for setting
-    ///ReachedMap type.
+    ///\c ReachedMap type.
+    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     template <class T>
     struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits<T> > {
@@ -284,8 +281,9 @@
     };
     ///\brief \ref named-templ-param "Named parameter" for setting
-    ///ProcessedMap type.
+    ///\c ProcessedMap type.
     ///
     ///\ref named-templ-param "Named parameter" for setting
-    ///ProcessedMap type.
+    ///\c ProcessedMap type.
+    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetProcessedMap : public Dfs< Digraph, SetProcessedMapTraits<T> > {
@@ -301,8 +299,8 @@
     };
     ///\brief \ref named-templ-param "Named parameter" for setting
-    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
+    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
     ///
     ///\ref named-templ-param "Named parameter" for setting
-    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
+    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
     ///If you don't set it explicitly, it will be automatically allocated.
     struct SetStandardProcessedMap :
@@ -339,7 +337,8 @@
 
     ///Sets the map that stores the predecessor arcs.
-    ///If you don't use this function before calling \ref run(),
-    ///it will allocate one. The destructor deallocates this
-    ///automatically allocated map, of course.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
     ///\return <tt> (*this) </tt>
     Dfs &predMap(PredMap &m)
@@ -356,7 +355,8 @@
 
     ///Sets the map that indicates which nodes are reached.
-    ///If you don't use this function before calling \ref run(),
-    ///it will allocate one. The destructor deallocates this
-    ///automatically allocated map, of course.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
     ///\return <tt> (*this) </tt>
     Dfs &reachedMap(ReachedMap &m)
@@ -373,7 +373,8 @@
 
     ///Sets the map that indicates which nodes are processed.
-    ///If you don't use this function before calling \ref run(),
-    ///it will allocate one. The destructor deallocates this
-    ///automatically allocated map, of course.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
     ///\return <tt> (*this) </tt>
     Dfs &processedMap(ProcessedMap &m)
@@ -391,7 +392,8 @@
     ///Sets the map that stores the distances of the nodes calculated by
     ///the algorithm.
-    ///If you don't use this function before calling \ref run(),
-    ///it will allocate one. The destructor deallocates this
-    ///automatically allocated map, of course.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
     ///\return <tt> (*this) </tt>
     Dfs &distMap(DistMap &m)
@@ -407,20 +409,18 @@
   public:
 
-    ///\name Execution control
-    ///The simplest way to execute the algorithm is to use
-    ///one of the member functions called \ref lemon::Dfs::run() "run()".
-    ///\n
-    ///If you need more control on the execution, first you must call
-    ///\ref lemon::Dfs::init() "init()", then you can add a source node
-    ///with \ref lemon::Dfs::addSource() "addSource()".
-    ///Finally \ref lemon::Dfs::start() "start()" will perform the
-    ///actual path computation.
+    ///\name Execution Control
+    ///The simplest way to execute the DFS algorithm is to use one of the
+    ///member functions called \ref run(Node) "run()".\n
+    ///If you need more control on the execution, first you have to call
+    ///\ref init(), then you can add a source node with \ref addSource()
+    ///and perform the actual computation with \ref start().
+    ///This procedure can be repeated if there are nodes that have not
+    ///been reached.
 
     ///@{
 
+    ///\brief Initializes the internal data structures.
+    ///
     ///Initializes the internal data structures.
-
-    ///Initializes the internal data structures.
-    ///
     void init()
     {
@@ -439,9 +439,8 @@
     ///Adds a new source node to the set of nodes to be processed.
     ///
-    ///\pre The stack must be empty. (Otherwise the algorithm gives
-    ///false results.)
-    ///
-    ///\warning Distances will be wrong (or at least strange) in case of
-    ///multiple sources.
+    ///\pre The stack must be empty. Otherwise the algorithm gives
+    ///wrong results. (One of the outgoing arcs of all the source nodes
+    ///except for the last one will not be visited and distances will
+    ///also be wrong.)
     void addSource(Node s)
     {
@@ -507,14 +506,14 @@
     }
 
-    ///\brief Returns \c false if there are nodes
-    ///to be processed.
-    ///
-    ///Returns \c false if there are nodes
-    ///to be processed in the queue (stack).
+    ///Returns \c false if there are nodes to be processed.
+
+    ///Returns \c false if there are nodes to be processed
+    ///in the queue (stack).
     bool emptyQueue() const { return _stack_head<0; }
 
     ///Returns the number of the nodes to be processed.
 
-    ///Returns the number of the nodes to be processed in the queue (stack).
+    ///Returns the number of the nodes to be processed
+    ///in the queue (stack).
     int queueSize() const { return _stack_head+1; }
 
@@ -638,6 +637,6 @@
     ///
     ///The algorithm computes
-    ///- the %DFS tree,
-    ///- the distance of each node from the root in the %DFS tree.
+    ///- the %DFS tree (forest),
+    ///- the distance of each node from the root(s) in the %DFS tree.
     ///
     ///\note <tt>d.run()</tt> is just a shortcut of the following code.
@@ -664,8 +663,8 @@
 
     ///\name Query Functions
-    ///The result of the %DFS algorithm can be obtained using these
+    ///The results of the DFS algorithm can be obtained using these
     ///functions.\n
-    ///Either \ref lemon::Dfs::run() "run()" or \ref lemon::Dfs::start()
-    ///"start()" must be called before using them.
+    ///Either \ref run(Node) "run()" or \ref start() should be called
+    ///before using them.
 
     ///@{
@@ -675,19 +674,19 @@
     ///Returns the DFS path to a node.
     ///
-    ///\warning \c t should be reachable from the root.
-    ///
-    ///\pre Either \ref run() or \ref start() must be called before
-    ///using this function.
+    ///\warning \c t should be reached from the root(s).
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
     Path path(Node t) const { return Path(*G, *_pred, t); }
 
-    ///The distance of a node from the root.
-
-    ///Returns the distance of a node from the root.
-    ///
-    ///\warning If node \c v is not reachable from the root, then
+    ///The distance of a node from the root(s).
+
+    ///Returns the distance of a node from the root(s).
+    ///
+    ///\warning If node \c v is not reached from the root(s), then
     ///the return value of this function is undefined.
     ///
-    ///\pre Either \ref run() or \ref start() must be called before
-    ///using this function.
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
     int dist(Node v) const { return (*_dist)[v]; }
 
@@ -695,13 +694,13 @@
 
     ///This function returns the 'previous arc' of the %DFS tree for the
-    ///node \c v, i.e. it returns the last arc of a %DFS path from the
-    ///root to \c v. It is \c INVALID
-    ///if \c v is not reachable from the root(s) or if \c v is a root.
+    ///node \c v, i.e. it returns the last arc of a %DFS path from a
+    ///root to \c v. It is \c INVALID if \c v is not reached from the
+    ///root(s) or if \c v is a root.
     ///
     ///The %DFS tree used here is equal to the %DFS tree used in
     ///\ref predNode().
     ///
-    ///\pre Either \ref run() or \ref start() must be called before using
-    ///this function.
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
     Arc predArc(Node v) const { return (*_pred)[v];}
 
@@ -710,12 +709,12 @@
     ///This function returns the 'previous node' of the %DFS
     ///tree for the node \c v, i.e. it returns the last but one node
-    ///from a %DFS path from the root to \c v. It is \c INVALID
-    ///if \c v is not reachable from the root(s) or if \c v is a root.
+    ///from a %DFS path from a root to \c v. It is \c INVALID
+    ///if \c v is not reached from the root(s) or if \c v is a root.
     ///
     ///The %DFS tree used here is equal to the %DFS tree used in
     ///\ref predArc().
     ///
-    ///\pre Either \ref run() or \ref start() must be called before
-    ///using this function.
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
     Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
                                   G->source((*_pred)[v]); }
@@ -727,5 +726,5 @@
     ///distances of the nodes calculated by the algorithm.
     ///
-    ///\pre Either \ref run() or \ref init()
+    ///\pre Either \ref run(Node) "run()" or \ref init()
     ///must be called before using this function.
     const DistMap &distMap() const { return *_dist;}
@@ -737,12 +736,13 @@
     ///arcs, which form the DFS tree.
     ///
-    ///\pre Either \ref run() or \ref init()
+    ///\pre Either \ref run(Node) "run()" or \ref init()
     ///must be called before using this function.
     const PredMap &predMap() const { return *_pred;}
 
-    ///Checks if a node is reachable from the root(s).
-
-    ///Returns \c true if \c v is reachable from the root(s).
-    ///\pre Either \ref run() or \ref start()
+    ///Checks if a node is reached from the root(s).
+
+    ///Returns \c true if \c v is reached from the root(s).
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
     ///must be called before using this function.
     bool reached(Node v) const { return (*_reached)[v]; }
@@ -890,6 +890,6 @@
   /// This auxiliary class is created to implement the
   /// \ref dfs() "function-type interface" of \ref Dfs algorithm.
-  /// It does not have own \ref run() method, it uses the functions
-  /// and features of the plain \ref Dfs.
+  /// It does not have own \ref run(Node) "run()" method, it uses the
+  /// functions and features of the plain \ref Dfs.
   ///
   /// This class should only be used through the \ref dfs() function,
@@ -1111,6 +1111,5 @@
   ///  bool reached = dfs(g).path(p).dist(d).run(s,t);
   ///\endcode
-
-  ///\warning Don't forget to put the \ref DfsWizard::run() "run()"
+  ///\warning Don't forget to put the \ref DfsWizard::run(Node) "run()"
   ///to the end of the parameter list.
   ///\sa DfsWizard
@@ -1128,7 +1127,7 @@
   /// This class defines the interface of the DfsVisit events, and
   /// it could be the base of a real visitor class.
-  template <typename _Digraph>
+  template <typename GR>
   struct DfsVisitor {
-    typedef _Digraph Digraph;
+    typedef GR Digraph;
     typedef typename Digraph::Arc Arc;
     typedef typename Digraph::Node Node;
@@ -1166,7 +1165,7 @@
   };
 #else
-  template <typename _Digraph>
+  template <typename GR>
   struct DfsVisitor {
-    typedef _Digraph Digraph;
+    typedef GR Digraph;
     typedef typename Digraph::Arc Arc;
     typedef typename Digraph::Node Node;
@@ -1201,9 +1200,9 @@
   /// Default traits class of DfsVisit class.
   /// \tparam _Digraph The type of the digraph the algorithm runs on.
-  template<class _Digraph>
+  template<class GR>
   struct DfsVisitDefaultTraits {
 
     /// \brief The type of the digraph the algorithm runs on.
-    typedef _Digraph Digraph;
+    typedef GR Digraph;
 
     /// \brief The type of the map that indicates which nodes are reached.
@@ -1226,10 +1225,10 @@
   /// \ingroup search
   ///
-  /// \brief %DFS algorithm class with visitor interface.
+  /// \brief DFS algorithm class with visitor interface.
   ///
-  /// This class provides an efficient implementation of the %DFS algorithm
+  /// This class provides an efficient implementation of the DFS algorithm
   /// with visitor interface.
   ///
-  /// The %DfsVisit class provides an alternative interface to the Dfs
+  /// The DfsVisit class provides an alternative interface to the Dfs
   /// class. It works with callback mechanism, the DfsVisit object calls
   /// the member functions of the \c Visitor class on every DFS event.
@@ -1240,23 +1239,23 @@
   /// instead.
   ///
-  /// \tparam _Digraph The type of the digraph the algorithm runs on.
-  /// The default value is
-  /// \ref ListDigraph. The value of _Digraph is not used directly by
-  /// \ref DfsVisit, it is only passed to \ref DfsVisitDefaultTraits.
-  /// \tparam _Visitor The Visitor type that is used by the algorithm.
-  /// \ref DfsVisitor "DfsVisitor<_Digraph>" is an empty visitor, which
+  /// \tparam GR The type of the digraph the algorithm runs on.
+  /// The default type is \ref ListDigraph.
+  /// The value of GR is not used directly by \ref DfsVisit,
+  /// it is only passed to \ref DfsVisitDefaultTraits.
+  /// \tparam VS The Visitor type that is used by the algorithm.
+  /// \ref DfsVisitor "DfsVisitor<GR>" is an empty visitor, which
   /// does not observe the DFS events. If you want to observe the DFS
   /// events, you should implement your own visitor class.
-  /// \tparam _Traits Traits class to set various data types used by the
+  /// \tparam TR Traits class to set various data types used by the
   /// algorithm. The default traits class is
-  /// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<_Digraph>".
+  /// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<GR>".
   /// See \ref DfsVisitDefaultTraits for the documentation of
   /// a DFS visit traits class.
 #ifdef DOXYGEN
-  template <typename _Digraph, typename _Visitor, typename _Traits>
+  template <typename GR, typename VS, typename TR>
 #else
-  template <typename _Digraph = ListDigraph,
-            typename _Visitor = DfsVisitor<_Digraph>,
-            typename _Traits = DfsVisitDefaultTraits<_Digraph> >
+  template <typename GR = ListDigraph,
+            typename VS = DfsVisitor<GR>,
+            typename TR = DfsVisitDefaultTraits<GR> >
 #endif
   class DfsVisit {
@@ -1264,5 +1263,5 @@
 
     ///The traits class.
-    typedef _Traits Traits;
+    typedef TR Traits;
 
     ///The type of the digraph the algorithm runs on.
@@ -1270,5 +1269,5 @@
 
     ///The visitor type used by the algorithm.
-    typedef _Visitor Visitor;
+    typedef VS Visitor;
 
     ///The type of the map that indicates which nodes are reached.
@@ -1310,5 +1309,5 @@
     typedef DfsVisit Create;
 
-    /// \name Named template parameters
+    /// \name Named Template Parameters
 
     ///@{
@@ -1352,7 +1351,8 @@
     ///
     /// Sets the map that indicates which nodes are reached.
-    /// If you don't use this function before calling \ref run(),
-    /// it will allocate one. The destructor deallocates this
-    /// automatically allocated map, of course.
+    /// If you don't use this function before calling \ref run(Node) "run()"
+    /// or \ref init(), an instance will be allocated automatically.
+    /// The destructor deallocates this automatically allocated map,
+    /// of course.
     /// \return <tt> (*this) </tt>
     DfsVisit &reachedMap(ReachedMap &m) {
@@ -1367,14 +1367,12 @@
   public:
 
-    /// \name Execution control
-    /// The simplest way to execute the algorithm is to use
-    /// one of the member functions called \ref lemon::DfsVisit::run()
-    /// "run()".
-    /// \n
-    /// If you need more control on the execution, first you must call
-    /// \ref lemon::DfsVisit::init() "init()", then you can add several
-    /// source nodes with \ref lemon::DfsVisit::addSource() "addSource()".
-    /// Finally \ref lemon::DfsVisit::start() "start()" will perform the
-    /// actual path computation.
+    /// \name Execution Control
+    /// The simplest way to execute the DFS algorithm is to use one of the
+    /// member functions called \ref run(Node) "run()".\n
+    /// If you need more control on the execution, first you have to call
+    /// \ref init(), then you can add a source node with \ref addSource()
+    /// and perform the actual computation with \ref start().
+    /// This procedure can be repeated if there are nodes that have not
+    /// been reached.
 
     /// @{
@@ -1392,13 +1390,12 @@
     }
 
-    ///Adds a new source node.
-
-    ///Adds a new source node to the set of nodes to be processed.
-    ///
-    ///\pre The stack must be empty. (Otherwise the algorithm gives
-    ///false results.)
-    ///
-    ///\warning Distances will be wrong (or at least strange) in case of
-    ///multiple sources.
+    /// \brief Adds a new source node.
+    ///
+    /// Adds a new source node to the set of nodes to be processed.
+    ///
+    /// \pre The stack must be empty. Otherwise the algorithm gives
+    /// wrong results. (One of the outgoing arcs of all the source nodes
+    /// except for the last one will not be visited and distances will
+    /// also be wrong.)
     void addSource(Node s)
     {
@@ -1414,4 +1411,5 @@
           } else {
             _visitor->leave(s);
+            _visitor->stop(s);
           }
         }
@@ -1590,6 +1588,6 @@
     ///
     /// The algorithm computes
-    /// - the %DFS tree,
-    /// - the distance of each node from the root in the %DFS tree.
+    /// - the %DFS tree (forest),
+    /// - the distance of each node from the root(s) in the %DFS tree.
     ///
     /// \note <tt>d.run()</tt> is just a shortcut of the following code.
@@ -1616,17 +1614,18 @@
 
     /// \name Query Functions
-    /// The result of the %DFS algorithm can be obtained using these
+    /// The results of the DFS algorithm can be obtained using these
     /// functions.\n
-    /// Either \ref lemon::DfsVisit::run() "run()" or
-    /// \ref lemon::DfsVisit::start() "start()" must be called before
-    /// using them.
+    /// Either \ref run(Node) "run()" or \ref start() should be called
+    /// before using them.
+
     ///@{
 
-    /// \brief Checks if a node is reachable from the root(s).
-    ///
-    /// Returns \c true if \c v is reachable from the root(s).
-    /// \pre Either \ref run() or \ref start()
+    /// \brief Checks if a node is reached from the root(s).
+    ///
+    /// Returns \c true if \c v is reached from the root(s).
+    ///
+    /// \pre Either \ref run(Node) "run()" or \ref init()
     /// must be called before using this function.
-    bool reached(Node v) { return (*_reached)[v]; }
+    bool reached(Node v) const { return (*_reached)[v]; }
 
     ///@}
Index: lemon/dijkstra.h
===================================================================
--- lemon/dijkstra.h	(revision 397)
+++ lemon/dijkstra.h	(revision 492)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -74,5 +74,5 @@
     typedef typename LM::Value Value;
 
-    /// Operation traits for Dijkstra algorithm.
+    /// Operation traits for %Dijkstra algorithm.
 
     /// This class defines the operations that are used in the algorithm.
@@ -85,5 +85,5 @@
     /// Usually it is \c Digraph::NodeMap<int>.
     typedef typename Digraph::template NodeMap<int> HeapCrossRef;
-    ///Instantiates a \ref HeapCrossRef.
+    ///Instantiates a \c HeapCrossRef.
 
     ///This function instantiates a \ref HeapCrossRef.
@@ -95,5 +95,5 @@
     }
 
-    ///The heap type used by the Dijkstra algorithm.
+    ///The heap type used by the %Dijkstra algorithm.
 
     ///The heap type used by the Dijkstra algorithm.
@@ -102,5 +102,5 @@
     ///\sa Dijkstra
     typedef BinHeap<typename LM::Value, HeapCrossRef, std::less<Value> > Heap;
-    ///Instantiates a \ref Heap.
+    ///Instantiates a \c Heap.
 
     ///This function instantiates a \ref Heap.
@@ -117,9 +117,9 @@
     ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
-    ///Instantiates a PredMap.
-
-    ///This function instantiates a PredMap.
+    ///Instantiates a \c PredMap.
+
+    ///This function instantiates a \ref PredMap.
     ///\param g is the digraph, to which we would like to define the
-    ///PredMap.
+    ///\ref PredMap.
     static PredMap *createPredMap(const Digraph &g)
     {
@@ -133,9 +133,9 @@
     ///By default it is a NullMap.
     typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
-    ///Instantiates a ProcessedMap.
-
-    ///This function instantiates a ProcessedMap.
+    ///Instantiates a \c ProcessedMap.
+
+    ///This function instantiates a \ref ProcessedMap.
     ///\param g is the digraph, to which
-    ///we would like to define the ProcessedMap
+    ///we would like to define the \ref ProcessedMap.
 #ifdef DOXYGEN
     static ProcessedMap *createProcessedMap(const Digraph &g)
@@ -152,9 +152,9 @@
     ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     typedef typename Digraph::template NodeMap<typename LM::Value> DistMap;
-    ///Instantiates a DistMap.
-
-    ///This function instantiates a DistMap.
+    ///Instantiates a \c DistMap.
+
+    ///This function instantiates a \ref DistMap.
     ///\param g is the digraph, to which we would like to define
-    ///the DistMap
+    ///the \ref DistMap.
     static DistMap *createDistMap(const Digraph &g)
     {
@@ -180,18 +180,11 @@
   ///
   ///\tparam GR The type of the digraph the algorithm runs on.
-  ///The default value is \ref ListDigraph.
-  ///The value of GR is not used directly by \ref Dijkstra, it is only
-  ///passed to \ref DijkstraDefaultTraits.
-  ///\tparam LM A readable arc map that determines the lengths of the
-  ///arcs. It is read once for each arc, so the map may involve in
+  ///The default type is \ref ListDigraph.
+  ///\tparam LM A \ref concepts::ReadMap "readable" arc map that specifies
+  ///the lengths of the arcs.
+  ///It is read once for each arc, so the map may involve in
   ///relatively time consuming process to compute the arc lengths if
   ///it is necessary. The default map type is \ref
-  ///concepts::Digraph::ArcMap "Digraph::ArcMap<int>".
-  ///The value of LM is not used directly by \ref Dijkstra, it is only
-  ///passed to \ref DijkstraDefaultTraits.
-  ///\tparam TR Traits class to set various data types used by the algorithm.
-  ///The default traits class is \ref DijkstraDefaultTraits
-  ///"DijkstraDefaultTraits<GR,LM>". See \ref DijkstraDefaultTraits
-  ///for the documentation of a Dijkstra traits class.
+  ///concepts::Digraph::ArcMap "GR::ArcMap<int>".
 #ifdef DOXYGEN
   template <typename GR, typename LM, typename TR>
@@ -224,8 +217,9 @@
     ///The heap type used by the algorithm.
     typedef typename TR::Heap Heap;
-    ///The operation traits class.
+    ///\brief The \ref DijkstraDefaultOperationTraits "operation traits class"
+    ///of the algorithm.
     typedef typename TR::OperationTraits OperationTraits;
 
-    ///The traits class.
+    ///The \ref DijkstraDefaultTraits "traits class" of the algorithm.
     typedef TR Traits;
 
@@ -240,5 +234,5 @@
     const Digraph *G;
     //Pointer to the length map.
-    const LengthMap *length;
+    const LengthMap *_length;
     //Pointer to the map of predecessors arcs.
     PredMap *_pred;
@@ -305,8 +299,9 @@
     };
     ///\brief \ref named-templ-param "Named parameter" for setting
-    ///PredMap type.
+    ///\c PredMap type.
     ///
     ///\ref named-templ-param "Named parameter" for setting
-    ///PredMap type.
+    ///\c PredMap type.
+    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetPredMap
@@ -325,8 +320,9 @@
     };
     ///\brief \ref named-templ-param "Named parameter" for setting
-    ///DistMap type.
+    ///\c DistMap type.
     ///
     ///\ref named-templ-param "Named parameter" for setting
-    ///DistMap type.
+    ///\c DistMap type.
+    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetDistMap
@@ -345,8 +341,9 @@
     };
     ///\brief \ref named-templ-param "Named parameter" for setting
-    ///ProcessedMap type.
+    ///\c ProcessedMap type.
     ///
     ///\ref named-templ-param "Named parameter" for setting
-    ///ProcessedMap type.
+    ///\c ProcessedMap type.
+    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetProcessedMap
@@ -363,8 +360,8 @@
     };
     ///\brief \ref named-templ-param "Named parameter" for setting
-    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
+    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
     ///
     ///\ref named-templ-param "Named parameter" for setting
-    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
+    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
     ///If you don't set it explicitly, it will be automatically allocated.
     struct SetStandardProcessedMap
@@ -389,8 +386,12 @@
     };
     ///\brief \ref named-templ-param "Named parameter" for setting
-    ///heap and cross reference type
+    ///heap and cross reference types
     ///
     ///\ref named-templ-param "Named parameter" for setting heap and cross
-    ///reference type.
+    ///reference types. If this named parameter is used, then external
+    ///heap and cross reference objects must be passed to the algorithm
+    ///using the \ref heap() function before calling \ref run(Node) "run()"
+    ///or \ref init().
+    ///\sa SetStandardHeap
     template <class H, class CR = typename Digraph::template NodeMap<int> >
     struct SetHeap
@@ -412,10 +413,16 @@
     };
     ///\brief \ref named-templ-param "Named parameter" for setting
-    ///heap and cross reference type with automatic allocation
+    ///heap and cross reference types with automatic allocation
     ///
     ///\ref named-templ-param "Named parameter" for setting heap and cross
-    ///reference type. It can allocate the heap and the cross reference
-    ///object if the cross reference's constructor waits for the digraph as
-    ///parameter and the heap's constructor waits for the cross reference.
+    ///reference types with automatic allocation.
+    ///They should have standard constructor interfaces to be able to
+    ///automatically created by the algorithm (i.e. the digraph should be
+    ///passed to the constructor of the cross reference and the cross
+    ///reference should be passed to the constructor of the heap).
+    ///However external heap and cross reference objects could also be
+    ///passed to the algorithm using the \ref heap() function before
+    ///calling \ref run(Node) "run()" or \ref init().
+    ///\sa SetHeap
     template <class H, class CR = typename Digraph::template NodeMap<int> >
     struct SetStandardHeap
@@ -434,5 +441,5 @@
     ///
     ///\ref named-templ-param "Named parameter" for setting
-    ///\ref OperationTraits type.
+    ///\c OperationTraits type.
     template <class T>
     struct SetOperationTraits
@@ -453,8 +460,8 @@
 
     ///Constructor.
-    ///\param _g The digraph the algorithm runs on.
-    ///\param _length The length map used by the algorithm.
-    Dijkstra(const Digraph& _g, const LengthMap& _length) :
-      G(&_g), length(&_length),
+    ///\param g The digraph the algorithm runs on.
+    ///\param length The length map used by the algorithm.
+    Dijkstra(const Digraph& g, const LengthMap& length) :
+      G(&g), _length(&length),
       _pred(NULL), local_pred(false),
       _dist(NULL), local_dist(false),
@@ -480,5 +487,5 @@
     Dijkstra &lengthMap(const LengthMap &m)
     {
-      length = &m;
+      _length = &m;
       return *this;
     }
@@ -487,7 +494,8 @@
 
     ///Sets the map that stores the predecessor arcs.
-    ///If you don't use this function before calling \ref run(),
-    ///it will allocate one. The destructor deallocates this
-    ///automatically allocated map, of course.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
     ///\return <tt> (*this) </tt>
     Dijkstra &predMap(PredMap &m)
@@ -504,7 +512,8 @@
 
     ///Sets the map that indicates which nodes are processed.
-    ///If you don't use this function before calling \ref run(),
-    ///it will allocate one. The destructor deallocates this
-    ///automatically allocated map, of course.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
     ///\return <tt> (*this) </tt>
     Dijkstra &processedMap(ProcessedMap &m)
@@ -522,7 +531,8 @@
     ///Sets the map that stores the distances of the nodes calculated by the
     ///algorithm.
-    ///If you don't use this function before calling \ref run(),
-    ///it will allocate one. The destructor deallocates this
-    ///automatically allocated map, of course.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), an instance will be allocated automatically.
+    ///The destructor deallocates this automatically allocated map,
+    ///of course.
     ///\return <tt> (*this) </tt>
     Dijkstra &distMap(DistMap &m)
@@ -539,7 +549,9 @@
 
     ///Sets the heap and the cross reference used by algorithm.
-    ///If you don't use this function before calling \ref run(),
-    ///it will allocate one. The destructor deallocates this
-    ///automatically allocated heap and cross reference, of course.
+    ///If you don't use this function before calling \ref run(Node) "run()"
+    ///or \ref init(), heap and cross reference instances will be
+    ///allocated automatically.
+    ///The destructor deallocates these automatically allocated objects,
+    ///of course.
     ///\return <tt> (*this) </tt>
     Dijkstra &heap(Heap& hp, HeapCrossRef &cr)
@@ -568,20 +580,17 @@
   public:
 
-    ///\name Execution control
-    ///The simplest way to execute the algorithm is to use one of the
-    ///member functions called \ref lemon::Dijkstra::run() "run()".
-    ///\n
-    ///If you need more control on the execution, first you must call
-    ///\ref lemon::Dijkstra::init() "init()", then you can add several
-    ///source nodes with \ref lemon::Dijkstra::addSource() "addSource()".
-    ///Finally \ref lemon::Dijkstra::start() "start()" will perform the
-    ///actual path computation.
+    ///\name Execution Control
+    ///The simplest way to execute the %Dijkstra algorithm is to use
+    ///one of the member functions called \ref run(Node) "run()".\n
+    ///If you need more control on the execution, first you have to call
+    ///\ref init(), then you can add several source nodes with
+    ///\ref addSource(). Finally the actual path computation can be
+    ///performed with one of the \ref start() functions.
 
     ///@{
 
+    ///\brief Initializes the internal data structures.
+    ///
     ///Initializes the internal data structures.
-
-    ///Initializes the internal data structures.
-    ///
     void init()
     {
@@ -631,10 +640,10 @@
         switch(_heap->state(w)) {
         case Heap::PRE_HEAP:
-          _heap->push(w,OperationTraits::plus(oldvalue, (*length)[e]));
+          _heap->push(w,OperationTraits::plus(oldvalue, (*_length)[e]));
           _pred->set(w,e);
           break;
         case Heap::IN_HEAP:
           {
-            Value newvalue = OperationTraits::plus(oldvalue, (*length)[e]);
+            Value newvalue = OperationTraits::plus(oldvalue, (*_length)[e]);
             if ( OperationTraits::less(newvalue, (*_heap)[w]) ) {
               _heap->decrease(w, newvalue);
@@ -659,15 +668,14 @@
     }
 
-    ///\brief Returns \c false if there are nodes
-    ///to be processed.
-    ///
-    ///Returns \c false if there are nodes
-    ///to be processed in the priority heap.
+    ///Returns \c false if there are nodes to be processed.
+
+    ///Returns \c false if there are nodes to be processed
+    ///in the priority heap.
     bool emptyQueue() const { return _heap->empty(); }
 
-    ///Returns the number of the nodes to be processed in the priority heap
-
-    ///Returns the number of the nodes to be processed in the priority heap.
-    ///
+    ///Returns the number of the nodes to be processed.
+
+    ///Returns the number of the nodes to be processed
+    ///in the priority heap.
     int queueSize() const { return _heap->size(); }
 
@@ -790,9 +798,8 @@
 
     ///\name Query Functions
-    ///The result of the %Dijkstra algorithm can be obtained using these
+    ///The results of the %Dijkstra algorithm can be obtained using these
     ///functions.\n
-    ///Either \ref lemon::Dijkstra::run() "run()" or
-    ///\ref lemon::Dijkstra::start() "start()" must be called before
-    ///using them.
+    ///Either \ref run(Node) "run()" or \ref start() should be called
+    ///before using them.
 
     ///@{
@@ -802,8 +809,8 @@
     ///Returns the shortest path to a node.
     ///
-    ///\warning \c t should be reachable from the root(s).
-    ///
-    ///\pre Either \ref run() or \ref start() must be called before
-    ///using this function.
+    ///\warning \c t should be reached from the root(s).
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
     Path path(Node t) const { return Path(*G, *_pred, t); }
 
@@ -812,9 +819,9 @@
     ///Returns the distance of a node from the root(s).
     ///
-    ///\warning If node \c v is not reachable from the root(s), then
+    ///\warning If node \c v is not reached from the root(s), then
     ///the return value of this function is undefined.
     ///
-    ///\pre Either \ref run() or \ref start() must be called before
-    ///using this function.
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
     Value dist(Node v) const { return (*_dist)[v]; }
 
@@ -823,12 +830,12 @@
     ///This function returns the 'previous arc' of the shortest path
     ///tree for the node \c v, i.e. it returns the last arc of a
-    ///shortest path from the root(s) to \c v. It is \c INVALID if \c v
-    ///is not reachable from the root(s) or if \c v is a root.
+    ///shortest path from a root to \c v. It is \c INVALID if \c v
+    ///is not reached from the root(s) or if \c v is a root.
     ///
     ///The shortest path tree used here is equal to the shortest path
     ///tree used in \ref predNode().
     ///
-    ///\pre Either \ref run() or \ref start() must be called before
-    ///using this function.
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
     Arc predArc(Node v) const { return (*_pred)[v]; }
 
@@ -837,12 +844,12 @@
     ///This function returns the 'previous node' of the shortest path
     ///tree for the node \c v, i.e. it returns the last but one node
-    ///from a shortest path from the root(s) to \c v. It is \c INVALID
-    ///if \c v is not reachable from the root(s) or if \c v is a root.
+    ///from a shortest path from a root to \c v. It is \c INVALID
+    ///if \c v is not reached from the root(s) or if \c v is a root.
     ///
     ///The shortest path tree used here is equal to the shortest path
     ///tree used in \ref predArc().
     ///
-    ///\pre Either \ref run() or \ref start() must be called before
-    ///using this function.
+    ///\pre Either \ref run(Node) "run()" or \ref init()
+    ///must be called before using this function.
     Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
                                   G->source((*_pred)[v]); }
@@ -854,5 +861,5 @@
     ///of the nodes calculated by the algorithm.
     ///
-    ///\pre Either \ref run() or \ref init()
+    ///\pre Either \ref run(Node) "run()" or \ref init()
     ///must be called before using this function.
     const DistMap &distMap() const { return *_dist;}
@@ -864,12 +871,13 @@
     ///arcs, which form the shortest path tree.
     ///
-    ///\pre Either \ref run() or \ref init()
+    ///\pre Either \ref run(Node) "run()" or \ref init()
     ///must be called before using this function.
     const PredMap &predMap() const { return *_pred;}
 
-    ///Checks if a node is reachable from the root(s).
-
-    ///Returns \c true if \c v is reachable from the root(s).
-    ///\pre Either \ref run() or \ref start()
+    ///Checks if a node is reached from the root(s).
+
+    ///Returns \c true if \c v is reached from the root(s).
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
     ///must be called before using this function.
     bool reached(Node v) const { return (*_heap_cross_ref)[v] !=
@@ -880,5 +888,6 @@
     ///Returns \c true if \c v is processed, i.e. the shortest
     ///path to \c v has already found.
-    ///\pre Either \ref run() or \ref init()
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
     ///must be called before using this function.
     bool processed(Node v) const { return (*_heap_cross_ref)[v] ==
@@ -889,5 +898,6 @@
     ///Returns the current distance of a node from the root(s).
     ///It may be decreased in the following processes.
-    ///\pre Either \ref run() or \ref init()
+    ///
+    ///\pre Either \ref run(Node) "run()" or \ref init()
     ///must be called before using this function and
     ///node \c v must be reached but not necessarily processed.
@@ -1072,6 +1082,6 @@
   /// This auxiliary class is created to implement the
   /// \ref dijkstra() "function-type interface" of \ref Dijkstra algorithm.
-  /// It does not have own \ref run() method, it uses the functions
-  /// and features of the plain \ref Dijkstra.
+  /// It does not have own \ref run(Node) "run()" method, it uses the
+  /// functions and features of the plain \ref Dijkstra.
   ///
   /// This class should only be used through the \ref dijkstra() function,
@@ -1268,5 +1278,5 @@
   ///  bool reached = dijkstra(g,length).path(p).dist(d).run(s,t);
   ///\endcode
-  ///\warning Don't forget to put the \ref DijkstraWizard::run() "run()"
+  ///\warning Don't forget to put the \ref DijkstraWizard::run(Node) "run()"
   ///to the end of the parameter list.
   ///\sa DijkstraWizard
Index: lemon/dim2.h
===================================================================
--- lemon/dim2.h	(revision 314)
+++ lemon/dim2.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/dimacs.h
===================================================================
--- lemon/dimacs.h	(revision 440)
+++ lemon/dimacs.h	(revision 440)
@@ -0,0 +1,357 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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_DIMACS_H
+#define LEMON_DIMACS_H
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <lemon/maps.h>
+#include <lemon/error.h>
+
+/// \ingroup dimacs_group
+/// \file
+/// \brief DIMACS file format reader.
+
+namespace lemon {
+
+  /// \addtogroup dimacs_group
+  /// @{
+
+  /// DIMACS file type descriptor.
+  struct DimacsDescriptor
+  {
+    ///File type enum
+    enum Type
+      {
+        NONE, MIN, MAX, SP, MAT
+      };
+    ///The file type
+    Type type;
+    ///The number of nodes in the graph
+    int nodeNum;
+    ///The number of edges in the graph
+    int edgeNum;
+    int lineShift;
+    /// Constructor. Sets the type to NONE.
+    DimacsDescriptor() : type(NONE) {}
+  };
+
+  ///Discover the type of a DIMACS file
+
+  ///It starts seeking the begining of the file for the problem type
+  ///and size info. The found data is returned in a special struct
+  ///that can be evaluated and passed to the appropriate reader
+  ///function.
+  DimacsDescriptor dimacsType(std::istream& is)
+  {
+    DimacsDescriptor r;
+    std::string problem,str;
+    char c;
+    r.lineShift=0;
+    while (is >> c)
+      switch(c)
+        {
+        case 'p':
+          if(is >> problem >> r.nodeNum >> r.edgeNum)
+            {
+              getline(is, str);
+              r.lineShift++;
+              if(problem=="min") r.type=DimacsDescriptor::MIN;
+              else if(problem=="max") r.type=DimacsDescriptor::MAX;
+              else if(problem=="sp") r.type=DimacsDescriptor::SP;
+              else if(problem=="mat") r.type=DimacsDescriptor::MAT;
+              else throw FormatError("Unknown problem type");
+              return r;
+            }
+          else
+            {
+              throw FormatError("Missing or wrong problem type declaration.");
+            }
+          break;
+        case 'c':
+          getline(is, str);
+          r.lineShift++;
+          break;
+        default:
+          throw FormatError("Unknown DIMACS declaration.");
+        }
+    throw FormatError("Missing problem type declaration.");
+  }
+
+
+
+  /// DIMACS minimum cost flow reader function.
+  ///
+  /// This function reads a minimum cost flow instance from DIMACS format,
+  /// i.e. from a DIMACS file having a line starting with
+  /// \code
+  ///   p min
+  /// \endcode
+  /// At the beginning, \c g is cleared by \c g.clear(). The supply
+  /// amount of the nodes are written to \c supply (signed). The
+  /// lower bounds, capacities and costs of the arcs are written to
+  /// \c lower, \c capacity and \c cost.
+  ///
+  /// If the file type was previously evaluated by dimacsType(), then
+  /// the descriptor struct should be given by the \c dest parameter.
+  template <typename Digraph, typename LowerMap,
+            typename CapacityMap, typename CostMap,
+            typename SupplyMap>
+  void readDimacsMin(std::istream& is,
+                     Digraph &g,
+                     LowerMap& lower,
+                     CapacityMap& capacity,
+                     CostMap& cost,
+                     SupplyMap& supply,
+                     DimacsDescriptor desc=DimacsDescriptor())
+  {
+    g.clear();
+    std::vector<typename Digraph::Node> nodes;
+    typename Digraph::Arc e;
+    std::string problem, str;
+    char c;
+    int i, j;
+    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
+    if(desc.type!=DimacsDescriptor::MIN)
+      throw FormatError("Problem type mismatch");
+
+    nodes.resize(desc.nodeNum + 1);
+    for (int k = 1; k <= desc.nodeNum; ++k) {
+      nodes[k] = g.addNode();
+      supply.set(nodes[k], 0);
+    }
+
+    typename SupplyMap::Value sup;
+    typename CapacityMap::Value low;
+    typename CapacityMap::Value cap;
+    typename CostMap::Value co;
+    while (is >> c) {
+      switch (c) {
+      case 'c': // comment line
+        getline(is, str);
+        break;
+      case 'n': // node definition line
+        is >> i >> sup;
+        getline(is, str);
+        supply.set(nodes[i], sup);
+        break;
+      case 'a': // arc (arc) definition line
+        is >> i >> j >> low >> cap >> co;
+        getline(is, str);
+        e = g.addArc(nodes[i], nodes[j]);
+        lower.set(e, low);
+        if (cap >= 0)
+          capacity.set(e, cap);
+        else
+          capacity.set(e, -1);
+        cost.set(e, co);
+        break;
+      }
+    }
+  }
+
+  template<typename Digraph, typename CapacityMap>
+  void _readDimacs(std::istream& is,
+                   Digraph &g,
+                   CapacityMap& capacity,
+                   typename Digraph::Node &s,
+                   typename Digraph::Node &t,
+                   DimacsDescriptor desc=DimacsDescriptor()) {
+    g.clear();
+    s=t=INVALID;
+    std::vector<typename Digraph::Node> nodes;
+    typename Digraph::Arc e;
+    char c, d;
+    int i, j;
+    typename CapacityMap::Value _cap;
+    std::string str;
+    nodes.resize(desc.nodeNum + 1);
+    for (int k = 1; k <= desc.nodeNum; ++k) {
+      nodes[k] = g.addNode();
+    }
+
+    while (is >> c) {
+      switch (c) {
+      case 'c': // comment line
+        getline(is, str);
+        break;
+      case 'n': // node definition line
+        if (desc.type==DimacsDescriptor::SP) { // shortest path problem
+          is >> i;
+          getline(is, str);
+          s = nodes[i];
+        }
+        if (desc.type==DimacsDescriptor::MAX) { // max flow problem
+          is >> i >> d;
+          getline(is, str);
+          if (d == 's') s = nodes[i];
+          if (d == 't') t = nodes[i];
+        }
+        break;
+      case 'a': // arc (arc) definition line
+        if (desc.type==DimacsDescriptor::SP ||
+            desc.type==DimacsDescriptor::MAX) {
+          is >> i >> j >> _cap;
+          getline(is, str);
+          e = g.addArc(nodes[i], nodes[j]);
+          capacity.set(e, _cap);
+        } else {
+          is >> i >> j;
+          getline(is, str);
+          g.addArc(nodes[i], nodes[j]);
+        }
+        break;
+      }
+    }
+  }
+
+  /// DIMACS maximum flow reader function.
+  ///
+  /// This function reads a maximum flow instance from DIMACS format,
+  /// i.e. from a DIMACS file having a line starting with
+  /// \code
+  ///   p max
+  /// \endcode
+  /// At the beginning, \c g is cleared by \c g.clear(). The arc
+  /// capacities are written to \c capacity and \c s and \c t are
+  /// set to the source and the target nodes.
+  ///
+  /// If the file type was previously evaluated by dimacsType(), then
+  /// the descriptor struct should be given by the \c dest parameter.
+  template<typename Digraph, typename CapacityMap>
+  void readDimacsMax(std::istream& is,
+                     Digraph &g,
+                     CapacityMap& capacity,
+                     typename Digraph::Node &s,
+                     typename Digraph::Node &t,
+                     DimacsDescriptor desc=DimacsDescriptor()) {
+    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
+    if(desc.type!=DimacsDescriptor::MAX)
+      throw FormatError("Problem type mismatch");
+    _readDimacs(is,g,capacity,s,t,desc);
+  }
+
+  /// DIMACS shortest path reader function.
+  ///
+  /// This function reads a shortest path instance from DIMACS format,
+  /// i.e. from a DIMACS file having a line starting with
+  /// \code
+  ///   p sp
+  /// \endcode
+  /// At the beginning, \c g is cleared by \c g.clear(). The arc
+  /// lengths are written to \c length and \c s is set to the
+  /// source node.
+  ///
+  /// If the file type was previously evaluated by dimacsType(), then
+  /// the descriptor struct should be given by the \c dest parameter.
+  template<typename Digraph, typename LengthMap>
+  void readDimacsSp(std::istream& is,
+                    Digraph &g,
+                    LengthMap& length,
+                    typename Digraph::Node &s,
+                    DimacsDescriptor desc=DimacsDescriptor()) {
+    typename Digraph::Node t;
+    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
+    if(desc.type!=DimacsDescriptor::SP)
+      throw FormatError("Problem type mismatch");
+    _readDimacs(is, g, length, s, t,desc);
+  }
+
+  /// DIMACS capacitated digraph reader function.
+  ///
+  /// This function reads an arc capacitated digraph instance from
+  /// DIMACS 'mat' or 'sp' format.
+  /// At the beginning, \c g is cleared by \c g.clear()
+  /// and the arc capacities/lengths are written to \c capacity.
+  ///
+  /// If the file type was previously evaluated by dimacsType(), then
+  /// the descriptor struct should be given by the \c dest parameter.
+  template<typename Digraph, typename CapacityMap>
+  void readDimacsCap(std::istream& is,
+                     Digraph &g,
+                     CapacityMap& capacity,
+                     DimacsDescriptor desc=DimacsDescriptor()) {
+    typename Digraph::Node u,v;
+    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
+    if(desc.type!=DimacsDescriptor::MAX || desc.type!=DimacsDescriptor::SP)
+      throw FormatError("Problem type mismatch");
+    _readDimacs(is, g, capacity, u, v, desc);
+  }
+
+  /// DIMACS plain digraph reader function.
+  ///
+  /// This function reads a digraph without any designated nodes and
+  /// maps from DIMACS format, i.e. from DIMACS files having a line
+  /// starting with
+  /// \code
+  ///   p mat
+  /// \endcode
+  /// At the beginning, \c g is cleared by \c g.clear().
+  ///
+  /// If the file type was previously evaluated by dimacsType(), then
+  /// the descriptor struct should be given by the \c dest parameter.
+  template<typename Digraph>
+  void readDimacsMat(std::istream& is, Digraph &g,
+                     DimacsDescriptor desc=DimacsDescriptor()) {
+    typename Digraph::Node u,v;
+    NullMap<typename Digraph::Arc, int> n;
+    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
+    if(desc.type!=DimacsDescriptor::MAT)
+      throw FormatError("Problem type mismatch");
+    _readDimacs(is, g, n, u, v, desc);
+  }
+
+  /// DIMACS plain digraph writer function.
+  ///
+  /// This function writes a digraph without any designated nodes and
+  /// maps into DIMACS format, i.e. into DIMACS file having a line
+  /// starting with
+  /// \code
+  ///   p mat
+  /// \endcode
+  /// If \c comment is not empty, then it will be printed in the first line
+  /// prefixed by 'c'.
+  template<typename Digraph>
+  void writeDimacsMat(std::ostream& os, const Digraph &g,
+                      std::string comment="") {
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::ArcIt ArcIt;
+
+    if(!comment.empty())
+      os << "c " << comment << std::endl;
+    os << "p mat " << g.nodeNum() << " " << g.arcNum() << std::endl;
+
+    typename Digraph::template NodeMap<int> nodes(g);
+    int i = 1;
+    for(NodeIt v(g); v != INVALID; ++v) {
+      nodes.set(v, i);
+      ++i;
+    }
+    for(ArcIt e(g); e != INVALID; ++e) {
+      os << "a " << nodes[g.source(e)] << " " << nodes[g.target(e)]
+         << std::endl;
+    }
+  }
+
+  /// @}
+
+} //namespace lemon
+
+#endif //LEMON_DIMACS_H
Index: lemon/elevator.h
===================================================================
--- lemon/elevator.h	(revision 440)
+++ lemon/elevator.h	(revision 440)
@@ -0,0 +1,981 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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_ELEVATOR_H
+#define LEMON_ELEVATOR_H
+
+///\ingroup auxdat
+///\file
+///\brief Elevator class
+///
+///Elevator class implements an efficient data structure
+///for labeling items in push-relabel type algorithms.
+///
+
+#include <lemon/bits/traits.h>
+
+namespace lemon {
+
+  ///Class for handling "labels" in push-relabel type algorithms.
+
+  ///A class for handling "labels" in push-relabel type algorithms.
+  ///
+  ///\ingroup auxdat
+  ///Using this class you can assign "labels" (nonnegative integer numbers)
+  ///to the edges or nodes of a graph, manipulate and query them through
+  ///operations typically arising in "push-relabel" type algorithms.
+  ///
+  ///Each item is either \em active or not, and you can also choose a
+  ///highest level active item.
+  ///
+  ///\sa LinkedElevator
+  ///
+  ///\param Graph Type of the underlying graph.
+  ///\param Item Type of the items the data is assigned to (Graph::Node,
+  ///Graph::Arc, Graph::Edge).
+  template<class Graph, class Item>
+  class Elevator
+  {
+  public:
+
+    typedef Item Key;
+    typedef int Value;
+
+  private:
+
+    typedef Item *Vit;
+    typedef typename ItemSetTraits<Graph,Item>::template Map<Vit>::Type VitMap;
+    typedef typename ItemSetTraits<Graph,Item>::template Map<int>::Type IntMap;
+
+    const Graph &_g;
+    int _max_level;
+    int _item_num;
+    VitMap _where;
+    IntMap _level;
+    std::vector<Item> _items;
+    std::vector<Vit> _first;
+    std::vector<Vit> _last_active;
+
+    int _highest_active;
+
+    void copy(Item i, Vit p)
+    {
+      _where.set(*p=i,p);
+    }
+    void copy(Vit s, Vit p)
+    {
+      if(s!=p)
+        {
+          Item i=*s;
+          *p=i;
+          _where.set(i,p);
+        }
+    }
+    void swap(Vit i, Vit j)
+    {
+      Item ti=*i;
+      Vit ct = _where[ti];
+      _where.set(ti,_where[*i=*j]);
+      _where.set(*j,ct);
+      *j=ti;
+    }
+
+  public:
+
+    ///Constructor with given maximum level.
+
+    ///Constructor with given maximum level.
+    ///
+    ///\param graph The underlying graph.
+    ///\param max_level The maximum allowed level.
+    ///Set the range of the possible labels to <tt>[0..max_level]</tt>.
+    Elevator(const Graph &graph,int max_level) :
+      _g(graph),
+      _max_level(max_level),
+      _item_num(_max_level),
+      _where(graph),
+      _level(graph,0),
+      _items(_max_level),
+      _first(_max_level+2),
+      _last_active(_max_level+2),
+      _highest_active(-1) {}
+    ///Constructor.
+
+    ///Constructor.
+    ///
+    ///\param graph The underlying graph.
+    ///Set the range of the possible labels to <tt>[0..max_level]</tt>,
+    ///where \c max_level is equal to the number of labeled items in the graph.
+    Elevator(const Graph &graph) :
+      _g(graph),
+      _max_level(countItems<Graph, Item>(graph)),
+      _item_num(_max_level),
+      _where(graph),
+      _level(graph,0),
+      _items(_max_level),
+      _first(_max_level+2),
+      _last_active(_max_level+2),
+      _highest_active(-1)
+    {
+    }
+
+    ///Activate item \c i.
+
+    ///Activate item \c i.
+    ///\pre Item \c i shouldn't be active before.
+    void activate(Item i)
+    {
+      const int l=_level[i];
+      swap(_where[i],++_last_active[l]);
+      if(l>_highest_active) _highest_active=l;
+    }
+
+    ///Deactivate item \c i.
+
+    ///Deactivate item \c i.
+    ///\pre Item \c i must be active before.
+    void deactivate(Item i)
+    {
+      swap(_where[i],_last_active[_level[i]]--);
+      while(_highest_active>=0 &&
+            _last_active[_highest_active]<_first[_highest_active])
+        _highest_active--;
+    }
+
+    ///Query whether item \c i is active
+    bool active(Item i) const { return _where[i]<=_last_active[_level[i]]; }
+
+    ///Return the level of item \c i.
+    int operator[](Item i) const { return _level[i]; }
+
+    ///Return the number of items on level \c l.
+    int onLevel(int l) const
+    {
+      return _first[l+1]-_first[l];
+    }
+    ///Return true if level \c l is empty.
+    bool emptyLevel(int l) const
+    {
+      return _first[l+1]-_first[l]==0;
+    }
+    ///Return the number of items above level \c l.
+    int aboveLevel(int l) const
+    {
+      return _first[_max_level+1]-_first[l+1];
+    }
+    ///Return the number of active items on level \c l.
+    int activesOnLevel(int l) const
+    {
+      return _last_active[l]-_first[l]+1;
+    }
+    ///Return true if there is no active item on level \c l.
+    bool activeFree(int l) const
+    {
+      return _last_active[l]<_first[l];
+    }
+    ///Return the maximum allowed level.
+    int maxLevel() const
+    {
+      return _max_level;
+    }
+
+    ///\name Highest Active Item
+    ///Functions for working with the highest level
+    ///active item.
+
+    ///@{
+
+    ///Return a highest level active item.
+
+    ///Return a highest level active item or INVALID if there is no active
+    ///item.
+    Item highestActive() const
+    {
+      return _highest_active>=0?*_last_active[_highest_active]:INVALID;
+    }
+
+    ///Return the highest active level.
+
+    ///Return the level of the highest active item or -1 if there is no active
+    ///item.
+    int highestActiveLevel() const
+    {
+      return _highest_active;
+    }
+
+    ///Lift the highest active item by one.
+
+    ///Lift the item returned by highestActive() by one.
+    ///
+    void liftHighestActive()
+    {
+      Item it = *_last_active[_highest_active];
+      _level.set(it,_level[it]+1);
+      swap(_last_active[_highest_active]--,_last_active[_highest_active+1]);
+      --_first[++_highest_active];
+    }
+
+    ///Lift the highest active item to the given level.
+
+    ///Lift the item returned by highestActive() to level \c new_level.
+    ///
+    ///\warning \c new_level must be strictly higher
+    ///than the current level.
+    ///
+    void liftHighestActive(int new_level)
+    {
+      const Item li = *_last_active[_highest_active];
+
+      copy(--_first[_highest_active+1],_last_active[_highest_active]--);
+      for(int l=_highest_active+1;l<new_level;l++)
+        {
+          copy(--_first[l+1],_first[l]);
+          --_last_active[l];
+        }
+      copy(li,_first[new_level]);
+      _level.set(li,new_level);
+      _highest_active=new_level;
+    }
+
+    ///Lift the highest active item to the top level.
+
+    ///Lift the item returned by highestActive() to the top level and
+    ///deactivate it.
+    void liftHighestActiveToTop()
+    {
+      const Item li = *_last_active[_highest_active];
+
+      copy(--_first[_highest_active+1],_last_active[_highest_active]--);
+      for(int l=_highest_active+1;l<_max_level;l++)
+        {
+          copy(--_first[l+1],_first[l]);
+          --_last_active[l];
+        }
+      copy(li,_first[_max_level]);
+      --_last_active[_max_level];
+      _level.set(li,_max_level);
+
+      while(_highest_active>=0 &&
+            _last_active[_highest_active]<_first[_highest_active])
+        _highest_active--;
+    }
+
+    ///@}
+
+    ///\name Active Item on Certain Level
+    ///Functions for working with the active items.
+
+    ///@{
+
+    ///Return an active item on level \c l.
+
+    ///Return an active item on level \c l or \ref INVALID if there is no such
+    ///an item. (\c l must be from the range [0...\c max_level].
+    Item activeOn(int l) const
+    {
+      return _last_active[l]>=_first[l]?*_last_active[l]:INVALID;
+    }
+
+    ///Lift the active item returned by \c activeOn(level) by one.
+
+    ///Lift the active item returned by \ref activeOn() "activeOn(level)"
+    ///by one.
+    Item liftActiveOn(int level)
+    {
+      Item it =*_last_active[level];
+      _level.set(it,_level[it]+1);
+      swap(_last_active[level]--, --_first[level+1]);
+      if (level+1>_highest_active) ++_highest_active;
+    }
+
+    ///Lift the active item returned by \c activeOn(level) to the given level.
+
+    ///Lift the active item returned by \ref activeOn() "activeOn(level)"
+    ///to the given level.
+    void liftActiveOn(int level, int new_level)
+    {
+      const Item ai = *_last_active[level];
+
+      copy(--_first[level+1], _last_active[level]--);
+      for(int l=level+1;l<new_level;l++)
+        {
+          copy(_last_active[l],_first[l]);
+          copy(--_first[l+1], _last_active[l]--);
+        }
+      copy(ai,_first[new_level]);
+      _level.set(ai,new_level);
+      if (new_level>_highest_active) _highest_active=new_level;
+    }
+
+    ///Lift the active item returned by \c activeOn(level) to the top level.
+
+    ///Lift the active item returned by \ref activeOn() "activeOn(level)"
+    ///to the top level and deactivate it.
+    void liftActiveToTop(int level)
+    {
+      const Item ai = *_last_active[level];
+
+      copy(--_first[level+1],_last_active[level]--);
+      for(int l=level+1;l<_max_level;l++)
+        {
+          copy(_last_active[l],_first[l]);
+          copy(--_first[l+1], _last_active[l]--);
+        }
+      copy(ai,_first[_max_level]);
+      --_last_active[_max_level];
+      _level.set(ai,_max_level);
+
+      if (_highest_active==level) {
+        while(_highest_active>=0 &&
+              _last_active[_highest_active]<_first[_highest_active])
+          _highest_active--;
+      }
+    }
+
+    ///@}
+
+    ///Lift an active item to a higher level.
+
+    ///Lift an active item to a higher level.
+    ///\param i The item to be lifted. It must be active.
+    ///\param new_level The new level of \c i. It must be strictly higher
+    ///than the current level.
+    ///
+    void lift(Item i, int new_level)
+    {
+      const int lo = _level[i];
+      const Vit w = _where[i];
+
+      copy(_last_active[lo],w);
+      copy(--_first[lo+1],_last_active[lo]--);
+      for(int l=lo+1;l<new_level;l++)
+        {
+          copy(_last_active[l],_first[l]);
+          copy(--_first[l+1],_last_active[l]--);
+        }
+      copy(i,_first[new_level]);
+      _level.set(i,new_level);
+      if(new_level>_highest_active) _highest_active=new_level;
+    }
+
+    ///Move an inactive item to the top but one level (in a dirty way).
+
+    ///This function moves an inactive item from the top level to the top
+    ///but one level (in a dirty way).
+    ///\warning It makes the underlying datastructure corrupt, so use it
+    ///only if you really know what it is for.
+    ///\pre The item is on the top level.
+    void dirtyTopButOne(Item i) {
+      _level.set(i,_max_level - 1);
+    }
+
+    ///Lift all items on and above the given level to the top level.
+
+    ///This function lifts all items on and above level \c l to the top
+    ///level and deactivates them.
+    void liftToTop(int l)
+    {
+      const Vit f=_first[l];
+      const Vit tl=_first[_max_level];
+      for(Vit i=f;i!=tl;++i)
+        _level.set(*i,_max_level);
+      for(int i=l;i<=_max_level;i++)
+        {
+          _first[i]=f;
+          _last_active[i]=f-1;
+        }
+      for(_highest_active=l-1;
+          _highest_active>=0 &&
+            _last_active[_highest_active]<_first[_highest_active];
+          _highest_active--) ;
+    }
+
+  private:
+    int _init_lev;
+    Vit _init_num;
+
+  public:
+
+    ///\name Initialization
+    ///Using these functions you can initialize the levels of the items.
+    ///\n
+    ///The initialization must be started with calling \c initStart().
+    ///Then the items should be listed level by level starting with the
+    ///lowest one (level 0) using \c initAddItem() and \c initNewLevel().
+    ///Finally \c initFinish() must be called.
+    ///The items not listed are put on the highest level.
+    ///@{
+
+    ///Start the initialization process.
+    void initStart()
+    {
+      _init_lev=0;
+      _init_num=&_items[0];
+      _first[0]=&_items[0];
+      _last_active[0]=&_items[0]-1;
+      Vit n=&_items[0];
+      for(typename ItemSetTraits<Graph,Item>::ItemIt i(_g);i!=INVALID;++i)
+        {
+          *n=i;
+          _where.set(i,n);
+          _level.set(i,_max_level);
+          ++n;
+        }
+    }
+
+    ///Add an item to the current level.
+    void initAddItem(Item i)
+    {
+      swap(_where[i],_init_num);
+      _level.set(i,_init_lev);
+      ++_init_num;
+    }
+
+    ///Start a new level.
+
+    ///Start a new level.
+    ///It shouldn't be used before the items on level 0 are listed.
+    void initNewLevel()
+    {
+      _init_lev++;
+      _first[_init_lev]=_init_num;
+      _last_active[_init_lev]=_init_num-1;
+    }
+
+    ///Finalize the initialization process.
+    void initFinish()
+    {
+      for(_init_lev++;_init_lev<=_max_level;_init_lev++)
+        {
+          _first[_init_lev]=_init_num;
+          _last_active[_init_lev]=_init_num-1;
+        }
+      _first[_max_level+1]=&_items[0]+_item_num;
+      _last_active[_max_level+1]=&_items[0]+_item_num-1;
+      _highest_active = -1;
+    }
+
+    ///@}
+
+  };
+
+  ///Class for handling "labels" in push-relabel type algorithms.
+
+  ///A class for handling "labels" in push-relabel type algorithms.
+  ///
+  ///\ingroup auxdat
+  ///Using this class you can assign "labels" (nonnegative integer numbers)
+  ///to the edges or nodes of a graph, manipulate and query them through
+  ///operations typically arising in "push-relabel" type algorithms.
+  ///
+  ///Each item is either \em active or not, and you can also choose a
+  ///highest level active item.
+  ///
+  ///\sa Elevator
+  ///
+  ///\param Graph Type of the underlying graph.
+  ///\param Item Type of the items the data is assigned to (Graph::Node,
+  ///Graph::Arc, Graph::Edge).
+  template <class Graph, class Item>
+  class LinkedElevator {
+  public:
+
+    typedef Item Key;
+    typedef int Value;
+
+  private:
+
+    typedef typename ItemSetTraits<Graph,Item>::
+    template Map<Item>::Type ItemMap;
+    typedef typename ItemSetTraits<Graph,Item>::
+    template Map<int>::Type IntMap;
+    typedef typename ItemSetTraits<Graph,Item>::
+    template Map<bool>::Type BoolMap;
+
+    const Graph &_graph;
+    int _max_level;
+    int _item_num;
+    std::vector<Item> _first, _last;
+    ItemMap _prev, _next;
+    int _highest_active;
+    IntMap _level;
+    BoolMap _active;
+
+  public:
+    ///Constructor with given maximum level.
+
+    ///Constructor with given maximum level.
+    ///
+    ///\param graph The underlying graph.
+    ///\param max_level The maximum allowed level.
+    ///Set the range of the possible labels to <tt>[0..max_level]</tt>.
+    LinkedElevator(const Graph& graph, int max_level)
+      : _graph(graph), _max_level(max_level), _item_num(_max_level),
+        _first(_max_level + 1), _last(_max_level + 1),
+        _prev(graph), _next(graph),
+        _highest_active(-1), _level(graph), _active(graph) {}
+
+    ///Constructor.
+
+    ///Constructor.
+    ///
+    ///\param graph The underlying graph.
+    ///Set the range of the possible labels to <tt>[0..max_level]</tt>,
+    ///where \c max_level is equal to the number of labeled items in the graph.
+    LinkedElevator(const Graph& graph)
+      : _graph(graph), _max_level(countItems<Graph, Item>(graph)),
+        _item_num(_max_level),
+        _first(_max_level + 1), _last(_max_level + 1),
+        _prev(graph, INVALID), _next(graph, INVALID),
+        _highest_active(-1), _level(graph), _active(graph) {}
+
+
+    ///Activate item \c i.
+
+    ///Activate item \c i.
+    ///\pre Item \c i shouldn't be active before.
+    void activate(Item i) {
+      _active.set(i, true);
+
+      int level = _level[i];
+      if (level > _highest_active) {
+        _highest_active = level;
+      }
+
+      if (_prev[i] == INVALID || _active[_prev[i]]) return;
+      //unlace
+      _next.set(_prev[i], _next[i]);
+      if (_next[i] != INVALID) {
+        _prev.set(_next[i], _prev[i]);
+      } else {
+        _last[level] = _prev[i];
+      }
+      //lace
+      _next.set(i, _first[level]);
+      _prev.set(_first[level], i);
+      _prev.set(i, INVALID);
+      _first[level] = i;
+
+    }
+
+    ///Deactivate item \c i.
+
+    ///Deactivate item \c i.
+    ///\pre Item \c i must be active before.
+    void deactivate(Item i) {
+      _active.set(i, false);
+      int level = _level[i];
+
+      if (_next[i] == INVALID || !_active[_next[i]])
+        goto find_highest_level;
+
+      //unlace
+      _prev.set(_next[i], _prev[i]);
+      if (_prev[i] != INVALID) {
+        _next.set(_prev[i], _next[i]);
+      } else {
+        _first[_level[i]] = _next[i];
+      }
+      //lace
+      _prev.set(i, _last[level]);
+      _next.set(_last[level], i);
+      _next.set(i, INVALID);
+      _last[level] = i;
+
+    find_highest_level:
+      if (level == _highest_active) {
+        while (_highest_active >= 0 && activeFree(_highest_active))
+          --_highest_active;
+      }
+    }
+
+    ///Query whether item \c i is active
+    bool active(Item i) const { return _active[i]; }
+
+    ///Return the level of item \c i.
+    int operator[](Item i) const { return _level[i]; }
+
+    ///Return the number of items on level \c l.
+    int onLevel(int l) const {
+      int num = 0;
+      Item n = _first[l];
+      while (n != INVALID) {
+        ++num;
+        n = _next[n];
+      }
+      return num;
+    }
+
+    ///Return true if the level is empty.
+    bool emptyLevel(int l) const {
+      return _first[l] == INVALID;
+    }
+
+    ///Return the number of items above level \c l.
+    int aboveLevel(int l) const {
+      int num = 0;
+      for (int level = l + 1; level < _max_level; ++level)
+        num += onLevel(level);
+      return num;
+    }
+
+    ///Return the number of active items on level \c l.
+    int activesOnLevel(int l) const {
+      int num = 0;
+      Item n = _first[l];
+      while (n != INVALID && _active[n]) {
+        ++num;
+        n = _next[n];
+      }
+      return num;
+    }
+
+    ///Return true if there is no active item on level \c l.
+    bool activeFree(int l) const {
+      return _first[l] == INVALID || !_active[_first[l]];
+    }
+
+    ///Return the maximum allowed level.
+    int maxLevel() const {
+      return _max_level;
+    }
+
+    ///\name Highest Active Item
+    ///Functions for working with the highest level
+    ///active item.
+
+    ///@{
+
+    ///Return a highest level active item.
+
+    ///Return a highest level active item or INVALID if there is no active
+    ///item.
+    Item highestActive() const {
+      return _highest_active >= 0 ? _first[_highest_active] : INVALID;
+    }
+
+    ///Return the highest active level.
+
+    ///Return the level of the highest active item or -1 if there is no active
+    ///item.
+    int highestActiveLevel() const {
+      return _highest_active;
+    }
+
+    ///Lift the highest active item by one.
+
+    ///Lift the item returned by highestActive() by one.
+    ///
+    void liftHighestActive() {
+      Item i = _first[_highest_active];
+      if (_next[i] != INVALID) {
+        _prev.set(_next[i], INVALID);
+        _first[_highest_active] = _next[i];
+      } else {
+        _first[_highest_active] = INVALID;
+        _last[_highest_active] = INVALID;
+      }
+      _level.set(i, ++_highest_active);
+      if (_first[_highest_active] == INVALID) {
+        _first[_highest_active] = i;
+        _last[_highest_active] = i;
+        _prev.set(i, INVALID);
+        _next.set(i, INVALID);
+      } else {
+        _prev.set(_first[_highest_active], i);
+        _next.set(i, _first[_highest_active]);
+        _first[_highest_active] = i;
+      }
+    }
+
+    ///Lift the highest active item to the given level.
+
+    ///Lift the item returned by highestActive() to level \c new_level.
+    ///
+    ///\warning \c new_level must be strictly higher
+    ///than the current level.
+    ///
+    void liftHighestActive(int new_level) {
+      Item i = _first[_highest_active];
+      if (_next[i] != INVALID) {
+        _prev.set(_next[i], INVALID);
+        _first[_highest_active] = _next[i];
+      } else {
+        _first[_highest_active] = INVALID;
+        _last[_highest_active] = INVALID;
+      }
+      _level.set(i, _highest_active = new_level);
+      if (_first[_highest_active] == INVALID) {
+        _first[_highest_active] = _last[_highest_active] = i;
+        _prev.set(i, INVALID);
+        _next.set(i, INVALID);
+      } else {
+        _prev.set(_first[_highest_active], i);
+        _next.set(i, _first[_highest_active]);
+        _first[_highest_active] = i;
+      }
+    }
+
+    ///Lift the highest active item to the top level.
+
+    ///Lift the item returned by highestActive() to the top level and
+    ///deactivate it.
+    void liftHighestActiveToTop() {
+      Item i = _first[_highest_active];
+      _level.set(i, _max_level);
+      if (_next[i] != INVALID) {
+        _prev.set(_next[i], INVALID);
+        _first[_highest_active] = _next[i];
+      } else {
+        _first[_highest_active] = INVALID;
+        _last[_highest_active] = INVALID;
+      }
+      while (_highest_active >= 0 && activeFree(_highest_active))
+        --_highest_active;
+    }
+
+    ///@}
+
+    ///\name Active Item on Certain Level
+    ///Functions for working with the active items.
+
+    ///@{
+
+    ///Return an active item on level \c l.
+
+    ///Return an active item on level \c l or \ref INVALID if there is no such
+    ///an item. (\c l must be from the range [0...\c max_level].
+    Item activeOn(int l) const
+    {
+      return _active[_first[l]] ? _first[l] : INVALID;
+    }
+
+    ///Lift the active item returned by \c activeOn(l) by one.
+
+    ///Lift the active item returned by \ref activeOn() "activeOn(l)"
+    ///by one.
+    Item liftActiveOn(int l)
+    {
+      Item i = _first[l];
+      if (_next[i] != INVALID) {
+        _prev.set(_next[i], INVALID);
+        _first[l] = _next[i];
+      } else {
+        _first[l] = INVALID;
+        _last[l] = INVALID;
+      }
+      _level.set(i, ++l);
+      if (_first[l] == INVALID) {
+        _first[l] = _last[l] = i;
+        _prev.set(i, INVALID);
+        _next.set(i, INVALID);
+      } else {
+        _prev.set(_first[l], i);
+        _next.set(i, _first[l]);
+        _first[l] = i;
+      }
+      if (_highest_active < l) {
+        _highest_active = l;
+      }
+    }
+
+    ///Lift the active item returned by \c activeOn(l) to the given level.
+
+    ///Lift the active item returned by \ref activeOn() "activeOn(l)"
+    ///to the given level.
+    void liftActiveOn(int l, int new_level)
+    {
+      Item i = _first[l];
+      if (_next[i] != INVALID) {
+        _prev.set(_next[i], INVALID);
+        _first[l] = _next[i];
+      } else {
+        _first[l] = INVALID;
+        _last[l] = INVALID;
+      }
+      _level.set(i, l = new_level);
+      if (_first[l] == INVALID) {
+        _first[l] = _last[l] = i;
+        _prev.set(i, INVALID);
+        _next.set(i, INVALID);
+      } else {
+        _prev.set(_first[l], i);
+        _next.set(i, _first[l]);
+        _first[l] = i;
+      }
+      if (_highest_active < l) {
+        _highest_active = l;
+      }
+    }
+
+    ///Lift the active item returned by \c activeOn(l) to the top level.
+
+    ///Lift the active item returned by \ref activeOn() "activeOn(l)"
+    ///to the top level and deactivate it.
+    void liftActiveToTop(int l)
+    {
+      Item i = _first[l];
+      if (_next[i] != INVALID) {
+        _prev.set(_next[i], INVALID);
+        _first[l] = _next[i];
+      } else {
+        _first[l] = INVALID;
+        _last[l] = INVALID;
+      }
+      _level.set(i, _max_level);
+      if (l == _highest_active) {
+        while (_highest_active >= 0 && activeFree(_highest_active))
+          --_highest_active;
+      }
+    }
+
+    ///@}
+
+    /// \brief Lift an active item to a higher level.
+    ///
+    /// Lift an active item to a higher level.
+    /// \param i The item to be lifted. It must be active.
+    /// \param new_level The new level of \c i. It must be strictly higher
+    /// than the current level.
+    ///
+    void lift(Item i, int new_level) {
+      if (_next[i] != INVALID) {
+        _prev.set(_next[i], _prev[i]);
+      } else {
+        _last[new_level] = _prev[i];
+      }
+      if (_prev[i] != INVALID) {
+        _next.set(_prev[i], _next[i]);
+      } else {
+        _first[new_level] = _next[i];
+      }
+      _level.set(i, new_level);
+      if (_first[new_level] == INVALID) {
+        _first[new_level] = _last[new_level] = i;
+        _prev.set(i, INVALID);
+        _next.set(i, INVALID);
+      } else {
+        _prev.set(_first[new_level], i);
+        _next.set(i, _first[new_level]);
+        _first[new_level] = i;
+      }
+      if (_highest_active < new_level) {
+        _highest_active = new_level;
+      }
+    }
+
+    ///Move an inactive item to the top but one level (in a dirty way).
+
+    ///This function moves an inactive item from the top level to the top
+    ///but one level (in a dirty way).
+    ///\warning It makes the underlying datastructure corrupt, so use it
+    ///only if you really know what it is for.
+    ///\pre The item is on the top level.
+    void dirtyTopButOne(Item i) {
+      _level.set(i, _max_level - 1);
+    }
+
+    ///Lift all items on and above the given level to the top level.
+
+    ///This function lifts all items on and above level \c l to the top
+    ///level and deactivates them.
+    void liftToTop(int l)  {
+      for (int i = l + 1; _first[i] != INVALID; ++i) {
+        Item n = _first[i];
+        while (n != INVALID) {
+          _level.set(n, _max_level);
+          n = _next[n];
+        }
+        _first[i] = INVALID;
+        _last[i] = INVALID;
+      }
+      if (_highest_active > l - 1) {
+        _highest_active = l - 1;
+        while (_highest_active >= 0 && activeFree(_highest_active))
+          --_highest_active;
+      }
+    }
+
+  private:
+
+    int _init_level;
+
+  public:
+
+    ///\name Initialization
+    ///Using these functions you can initialize the levels of the items.
+    ///\n
+    ///The initialization must be started with calling \c initStart().
+    ///Then the items should be listed level by level starting with the
+    ///lowest one (level 0) using \c initAddItem() and \c initNewLevel().
+    ///Finally \c initFinish() must be called.
+    ///The items not listed are put on the highest level.
+    ///@{
+
+    ///Start the initialization process.
+    void initStart() {
+
+      for (int i = 0; i <= _max_level; ++i) {
+        _first[i] = _last[i] = INVALID;
+      }
+      _init_level = 0;
+      for(typename ItemSetTraits<Graph,Item>::ItemIt i(_graph);
+          i != INVALID; ++i) {
+        _level.set(i, _max_level);
+        _active.set(i, false);
+      }
+    }
+
+    ///Add an item to the current level.
+    void initAddItem(Item i) {
+      _level.set(i, _init_level);
+      if (_last[_init_level] == INVALID) {
+        _first[_init_level] = i;
+        _last[_init_level] = i;
+        _prev.set(i, INVALID);
+        _next.set(i, INVALID);
+      } else {
+        _prev.set(i, _last[_init_level]);
+        _next.set(i, INVALID);
+        _next.set(_last[_init_level], i);
+        _last[_init_level] = i;
+      }
+    }
+
+    ///Start a new level.
+
+    ///Start a new level.
+    ///It shouldn't be used before the items on level 0 are listed.
+    void initNewLevel() {
+      ++_init_level;
+    }
+
+    ///Finalize the initialization process.
+    void initFinish() {
+      _highest_active = -1;
+    }
+
+    ///@}
+
+  };
+
+
+} //END OF NAMESPACE LEMON
+
+#endif
+
Index: lemon/error.h
===================================================================
--- lemon/error.h	(revision 291)
+++ lemon/error.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/full_graph.h
===================================================================
--- lemon/full_graph.h	(revision 440)
+++ lemon/full_graph.h	(revision 440)
@@ -0,0 +1,614 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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_FULL_GRAPH_H
+#define LEMON_FULL_GRAPH_H
+
+#include <lemon/core.h>
+#include <lemon/bits/graph_extender.h>
+
+///\ingroup graphs
+///\file
+///\brief FullGraph and FullDigraph classes.
+
+namespace lemon {
+
+  class FullDigraphBase {
+  public:
+
+    typedef FullDigraphBase Graph;
+
+    class Node;
+    class Arc;
+
+  protected:
+
+    int _node_num;
+    int _arc_num;
+
+    FullDigraphBase() {}
+
+    void construct(int n) { _node_num = n; _arc_num = n * n; }
+
+  public:
+
+    typedef True NodeNumTag;
+    typedef True ArcNumTag;
+
+    Node operator()(int ix) const { return Node(ix); }
+    int index(const Node& node) const { return node._id; }
+
+    Arc arc(const Node& s, const Node& t) const {
+      return Arc(s._id * _node_num + t._id);
+    }
+
+    int nodeNum() const { return _node_num; }
+    int arcNum() const { return _arc_num; }
+
+    int maxNodeId() const { return _node_num - 1; }
+    int maxArcId() const { return _arc_num - 1; }
+
+    Node source(Arc arc) const { return arc._id / _node_num; }
+    Node target(Arc arc) const { return arc._id % _node_num; }
+
+    static int id(Node node) { return node._id; }
+    static int id(Arc arc) { return arc._id; }
+
+    static Node nodeFromId(int id) { return Node(id);}
+    static Arc arcFromId(int id) { return Arc(id);}
+
+    typedef True FindArcTag;
+
+    Arc findArc(Node s, Node t, Arc prev = INVALID) const {
+      return prev == INVALID ? arc(s, t) : INVALID;
+    }
+
+    class Node {
+      friend class FullDigraphBase;
+
+    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 FullDigraphBase;
+
+    protected:
+      int _id;  // _node_num * source + target;
+
+      Arc(int id) : _id(id) {}
+
+    public:
+      Arc() { }
+      Arc (Invalid) { _id = -1; }
+      bool operator==(const Arc arc) const {return _id == arc._id;}
+      bool operator!=(const Arc arc) const {return _id != arc._id;}
+      bool operator<(const Arc arc) const {return _id < arc._id;}
+    };
+
+    void first(Node& node) const {
+      node._id = _node_num - 1;
+    }
+
+    static void next(Node& node) {
+      --node._id;
+    }
+
+    void first(Arc& arc) const {
+      arc._id = _arc_num - 1;
+    }
+
+    static void next(Arc& arc) {
+      --arc._id;
+    }
+
+    void firstOut(Arc& arc, const Node& node) const {
+      arc._id = (node._id + 1) * _node_num - 1;
+    }
+
+    void nextOut(Arc& arc) const {
+      if (arc._id % _node_num == 0) arc._id = 0;
+      --arc._id;
+    }
+
+    void firstIn(Arc& arc, const Node& node) const {
+      arc._id = _arc_num + node._id - _node_num;
+    }
+
+    void nextIn(Arc& arc) const {
+      arc._id -= _node_num;
+      if (arc._id < 0) arc._id = -1;
+    }
+
+  };
+
+  typedef DigraphExtender<FullDigraphBase> ExtendedFullDigraphBase;
+
+  /// \ingroup graphs
+  ///
+  /// \brief A full digraph class.
+  ///
+  /// This is a simple and fast directed full graph implementation.
+  /// From each node go arcs to each node (including the source node),
+  /// therefore the number of the arcs in the digraph is the square of
+  /// the node number. This digraph type is completely static, so you
+  /// can neither add nor delete either arcs or nodes, and it needs
+  /// constant space in memory.
+  ///
+  /// This class conforms to the \ref concepts::Digraph "Digraph" concept
+  /// and it also has an important extra feature that its maps are
+  /// real \ref concepts::ReferenceMap "reference map"s.
+  ///
+  /// The \c FullDigraph and \c FullGraph classes are very similar,
+  /// but there are two differences. While this class conforms only
+  /// to the \ref concepts::Digraph "Digraph" concept, the \c FullGraph
+  /// class conforms to the \ref concepts::Graph "Graph" concept,
+  /// moreover \c FullGraph does not contain a loop arc for each
+  /// node as \c FullDigraph does.
+  ///
+  /// \sa FullGraph
+  class FullDigraph : public ExtendedFullDigraphBase {
+  public:
+
+    typedef ExtendedFullDigraphBase Parent;
+
+    /// \brief Constructor
+    FullDigraph() { construct(0); }
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    /// \param n The number of the nodes.
+    FullDigraph(int n) { construct(n); }
+
+    /// \brief Resizes the digraph
+    ///
+    /// Resizes the digraph. The function will fully destroy and
+    /// rebuild the digraph. This cause that the maps of the digraph will
+    /// reallocated automatically and the previous values will be lost.
+    void resize(int n) {
+      Parent::notifier(Arc()).clear();
+      Parent::notifier(Node()).clear();
+      construct(n);
+      Parent::notifier(Node()).build();
+      Parent::notifier(Arc()).build();
+    }
+
+    /// \brief Returns the node with the given index.
+    ///
+    /// Returns the node with the given index. Since it is a static
+    /// digraph its nodes can be indexed with integers from the range
+    /// <tt>[0..nodeNum()-1]</tt>.
+    /// \sa index()
+    Node operator()(int ix) const { return Parent::operator()(ix); }
+
+    /// \brief Returns the index of the given node.
+    ///
+    /// Returns the index of the given node. Since it is a static
+    /// digraph its nodes can be indexed with integers from the range
+    /// <tt>[0..nodeNum()-1]</tt>.
+    /// \sa operator()
+    int index(const Node& node) const { return Parent::index(node); }
+
+    /// \brief Returns the arc connecting the given nodes.
+    ///
+    /// Returns the arc connecting the given nodes.
+    Arc arc(const Node& u, const Node& v) const {
+      return Parent::arc(u, v);
+    }
+
+    /// \brief Number of nodes.
+    int nodeNum() const { return Parent::nodeNum(); }
+    /// \brief Number of arcs.
+    int arcNum() const { return Parent::arcNum(); }
+  };
+
+
+  class FullGraphBase {
+    int _node_num;
+    int _edge_num;
+  public:
+
+    typedef FullGraphBase Graph;
+
+    class Node;
+    class Arc;
+    class Edge;
+
+  protected:
+
+    FullGraphBase() {}
+
+    void construct(int n) { _node_num = n; _edge_num = n * (n - 1) / 2; }
+
+    int _uid(int e) const {
+      int u = e / _node_num;
+      int v = e % _node_num;
+      return u < v ? u : _node_num - 2 - u;
+    }
+
+    int _vid(int e) const {
+      int u = e / _node_num;
+      int v = e % _node_num;
+      return u < v ? v : _node_num - 1 - v;
+    }
+
+    void _uvid(int e, int& u, int& v) const {
+      u = e / _node_num;
+      v = e % _node_num;
+      if  (u >= v) {
+        u = _node_num - 2 - u;
+        v = _node_num - 1 - v;
+      }
+    }
+
+    void _stid(int a, int& s, int& t) const {
+      if ((a & 1) == 1) {
+        _uvid(a >> 1, s, t);
+      } else {
+        _uvid(a >> 1, t, s);
+      }
+    }
+
+    int _eid(int u, int v) const {
+      if (u < (_node_num - 1) / 2) {
+        return u * _node_num + v;
+      } else {
+        return (_node_num - 1 - u) * _node_num - v - 1;
+      }
+    }
+
+  public:
+
+    Node operator()(int ix) const { return Node(ix); }
+    int index(const Node& node) const { return node._id; }
+
+    Edge edge(const Node& u, const Node& v) const {
+      if (u._id < v._id) {
+        return Edge(_eid(u._id, v._id));
+      } else if (u._id != v._id) {
+        return Edge(_eid(v._id, u._id));
+      } else {
+        return INVALID;
+      }
+    }
+
+    Arc arc(const Node& s, const Node& t) const {
+      if (s._id < t._id) {
+        return Arc((_eid(s._id, t._id) << 1) | 1);
+      } else if (s._id != t._id) {
+        return Arc(_eid(t._id, s._id) << 1);
+      } else {
+        return INVALID;
+      }
+    }
+
+    typedef True NodeNumTag;
+    typedef True ArcNumTag;
+    typedef True EdgeNumTag;
+
+    int nodeNum() const { return _node_num; }
+    int arcNum() const { return 2 * _edge_num; }
+    int edgeNum() const { return _edge_num; }
+
+    static int id(Node node) { return node._id; }
+    static int id(Arc arc) { return arc._id; }
+    static int id(Edge edge) { return edge._id; }
+
+    int maxNodeId() const { return _node_num-1; }
+    int maxArcId() const { return 2 * _edge_num-1; }
+    int maxEdgeId() const { return _edge_num-1; }
+
+    static Node nodeFromId(int id) { return Node(id);}
+    static Arc arcFromId(int id) { return Arc(id);}
+    static Edge edgeFromId(int id) { return Edge(id);}
+
+    Node u(Edge edge) const {
+      return Node(_uid(edge._id));
+    }
+
+    Node v(Edge edge) const {
+      return Node(_vid(edge._id));
+    }
+
+    Node source(Arc arc) const {
+      return Node((arc._id & 1) == 1 ?
+                  _uid(arc._id >> 1) : _vid(arc._id >> 1));
+    }
+
+    Node target(Arc arc) const {
+      return Node((arc._id & 1) == 1 ?
+                  _vid(arc._id >> 1) : _uid(arc._id >> 1));
+    }
+
+    typedef True FindEdgeTag;
+    typedef True FindArcTag;
+
+    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
+      return prev != INVALID ? INVALID : edge(u, v);
+    }
+
+    Arc findArc(Node s, Node t, Arc prev = INVALID) const {
+      return prev != INVALID ? INVALID : arc(s, t);
+    }
+
+    class Node {
+      friend class FullGraphBase;
+
+    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 Edge {
+      friend class FullGraphBase;
+      friend class Arc;
+
+    protected:
+      int _id;
+
+      Edge(int id) : _id(id) {}
+
+    public:
+      Edge() { }
+      Edge (Invalid) { _id = -1; }
+
+      bool operator==(const Edge edge) const {return _id == edge._id;}
+      bool operator!=(const Edge edge) const {return _id != edge._id;}
+      bool operator<(const Edge edge) const {return _id < edge._id;}
+    };
+
+    class Arc {
+      friend class FullGraphBase;
+
+    protected:
+      int _id;
+
+      Arc(int id) : _id(id) {}
+
+    public:
+      Arc() { }
+      Arc (Invalid) { _id = -1; }
+
+      operator Edge() const { return Edge(_id != -1 ? (_id >> 1) : -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;}
+    };
+
+    static bool direction(Arc arc) {
+      return (arc._id & 1) == 1;
+    }
+
+    static Arc direct(Edge edge, bool dir) {
+      return Arc((edge._id << 1) | (dir ? 1 : 0));
+    }
+
+    void first(Node& node) const {
+      node._id = _node_num - 1;
+    }
+
+    static void next(Node& node) {
+      --node._id;
+    }
+
+    void first(Arc& arc) const {
+      arc._id = (_edge_num << 1) - 1;
+    }
+
+    static void next(Arc& arc) {
+      --arc._id;
+    }
+
+    void first(Edge& edge) const {
+      edge._id = _edge_num - 1;
+    }
+
+    static void next(Edge& edge) {
+      --edge._id;
+    }
+
+    void firstOut(Arc& arc, const Node& node) const {
+      int s = node._id, t = _node_num - 1;
+      if (s < t) {
+        arc._id = (_eid(s, t) << 1) | 1;
+      } else {
+        --t;
+        arc._id = (t != -1 ? (_eid(t, s) << 1) : -1);
+      }
+    }
+
+    void nextOut(Arc& arc) const {
+      int s, t;
+      _stid(arc._id, s, t);
+      --t;
+      if (s < t) {
+        arc._id = (_eid(s, t) << 1) | 1;
+      } else {
+        if (s == t) --t;
+        arc._id = (t != -1 ? (_eid(t, s) << 1) : -1);
+      }
+    }
+
+    void firstIn(Arc& arc, const Node& node) const {
+      int s = _node_num - 1, t = node._id;
+      if (s > t) {
+        arc._id = (_eid(t, s) << 1);
+      } else {
+        --s;
+        arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1);
+      }
+    }
+
+    void nextIn(Arc& arc) const {
+      int s, t;
+      _stid(arc._id, s, t);
+      --s;
+      if (s > t) {
+        arc._id = (_eid(t, s) << 1);
+      } else {
+        if (s == t) --s;
+        arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1);
+      }
+    }
+
+    void firstInc(Edge& edge, bool& dir, const Node& node) const {
+      int u = node._id, v = _node_num - 1;
+      if (u < v) {
+        edge._id = _eid(u, v);
+        dir = true;
+      } else {
+        --v;
+        edge._id = (v != -1 ? _eid(v, u) : -1);
+        dir = false;
+      }
+    }
+
+    void nextInc(Edge& edge, bool& dir) const {
+      int u, v;
+      if (dir) {
+        _uvid(edge._id, u, v);
+        --v;
+        if (u < v) {
+          edge._id = _eid(u, v);
+        } else {
+          --v;
+          edge._id = (v != -1 ? _eid(v, u) : -1);
+          dir = false;
+        }
+      } else {
+        _uvid(edge._id, v, u);
+        --v;
+        edge._id = (v != -1 ? _eid(v, u) : -1);
+      }
+    }
+
+  };
+
+  typedef GraphExtender<FullGraphBase> ExtendedFullGraphBase;
+
+  /// \ingroup graphs
+  ///
+  /// \brief An undirected full graph class.
+  ///
+  /// This is a simple and fast undirected full graph
+  /// implementation. From each node go edge to each other node,
+  /// therefore the number of edges in the graph is \f$n(n-1)/2\f$.
+  /// This graph type is completely static, so you can neither
+  /// add nor delete either edges or nodes, and it needs constant
+  /// space in memory.
+  ///
+  /// This class conforms to the \ref concepts::Graph "Graph" concept
+  /// and it also has an important extra feature that its maps are
+  /// real \ref concepts::ReferenceMap "reference map"s.
+  ///
+  /// The \c FullGraph and \c FullDigraph classes are very similar,
+  /// but there are two differences. While the \c FullDigraph class
+  /// conforms only to the \ref concepts::Digraph "Digraph" concept,
+  /// this class conforms to the \ref concepts::Graph "Graph" concept,
+  /// moreover \c FullGraph does not contain a loop arc for each
+  /// node as \c FullDigraph does.
+  ///
+  /// \sa FullDigraph
+  class FullGraph : public ExtendedFullGraphBase {
+  public:
+
+    typedef ExtendedFullGraphBase Parent;
+
+    /// \brief Constructor
+    FullGraph() { construct(0); }
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    /// \param n The number of the nodes.
+    FullGraph(int n) { construct(n); }
+
+    /// \brief Resizes the graph
+    ///
+    /// Resizes the graph. The function will fully destroy and
+    /// rebuild the graph. This cause that the maps of the graph will
+    /// reallocated automatically and the previous values will be lost.
+    void resize(int n) {
+      Parent::notifier(Arc()).clear();
+      Parent::notifier(Edge()).clear();
+      Parent::notifier(Node()).clear();
+      construct(n);
+      Parent::notifier(Node()).build();
+      Parent::notifier(Edge()).build();
+      Parent::notifier(Arc()).build();
+    }
+
+    /// \brief Returns the node with the given index.
+    ///
+    /// Returns the node with the given index. Since it is a static
+    /// graph its nodes can be indexed with integers from the range
+    /// <tt>[0..nodeNum()-1]</tt>.
+    /// \sa index()
+    Node operator()(int ix) const { return Parent::operator()(ix); }
+
+    /// \brief Returns the index of the given node.
+    ///
+    /// Returns the index of the given node. Since it is a static
+    /// graph its nodes can be indexed with integers from the range
+    /// <tt>[0..nodeNum()-1]</tt>.
+    /// \sa operator()
+    int index(const Node& node) const { return Parent::index(node); }
+
+    /// \brief Returns the arc connecting the given nodes.
+    ///
+    /// Returns the arc connecting the given nodes.
+    Arc arc(const Node& s, const Node& t) const {
+      return Parent::arc(s, t);
+    }
+
+    /// \brief Returns the edge connects the given nodes.
+    ///
+    /// Returns the edge connects the given nodes.
+    Edge edge(const Node& u, const Node& v) const {
+      return Parent::edge(u, v);
+    }
+
+    /// \brief Number of nodes.
+    int nodeNum() const { return Parent::nodeNum(); }
+    /// \brief Number of arcs.
+    int arcNum() const { return Parent::arcNum(); }
+    /// \brief Number of edges.
+    int edgeNum() const { return Parent::edgeNum(); }
+
+  };
+
+
+} //namespace lemon
+
+
+#endif //LEMON_FULL_GRAPH_H
Index: lemon/graph_to_eps.h
===================================================================
--- lemon/graph_to_eps.h	(revision 482)
+++ lemon/graph_to_eps.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -30,5 +30,7 @@
 #include<ctime>
 #else
-#include<lemon/bits/windows.h>
+#define WIN32_LEAN_AND_MEAN
+#define NOMINMAX
+#include<windows.h>
 #endif
 
@@ -678,5 +680,4 @@
 
     {
-      os << "%%CreationDate: ";
 #ifndef WIN32
       timeval tv;
@@ -685,10 +686,21 @@
       char cbuf[26];
       ctime_r(&tv.tv_sec,cbuf);
-      os << cbuf;
+      os << "%%CreationDate: " << cbuf;
 #else
-      os << bits::getWinFormattedDate();
+      SYSTEMTIME time;
+      char buf1[11], buf2[9], buf3[5];
+
+      GetSystemTime(&time);
+      if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &time,
+                        "ddd MMM dd", buf1, 11) &&
+          GetTimeFormat(LOCALE_USER_DEFAULT, 0, &time,
+                        "HH':'mm':'ss", buf2, 9) &&
+          GetDateFormat(LOCALE_USER_DEFAULT, 0, &time,
+                                "yyyy", buf3, 5)) {
+        os << "%%CreationDate: " << buf1 << ' '
+           << buf2 << ' ' << buf3 << std::endl;
+      }
 #endif
     }
-    os << std::endl;
 
     if (_autoArcWidthScale) {
Index: lemon/grid_graph.h
===================================================================
--- lemon/grid_graph.h	(revision 440)
+++ lemon/grid_graph.h	(revision 440)
@@ -0,0 +1,705 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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 GRID_GRAPH_H
+#define GRID_GRAPH_H
+
+#include <lemon/core.h>
+#include <lemon/bits/graph_extender.h>
+#include <lemon/dim2.h>
+#include <lemon/assert.h>
+
+///\ingroup graphs
+///\file
+///\brief GridGraph class.
+
+namespace lemon {
+
+  class GridGraphBase {
+
+  public:
+
+    typedef GridGraphBase Graph;
+
+    class Node;
+    class Edge;
+    class Arc;
+
+  public:
+
+    GridGraphBase() {}
+
+  protected:
+
+    void construct(int width, int height) {
+       _width = width; _height = height;
+      _node_num = width * height;
+      _edge_num = 2 * _node_num - width - height;
+      _edge_limit = _node_num - _width;
+    }
+
+  public:
+
+    Node operator()(int i, int j) const {
+      LEMON_DEBUG(0 <= i && i < _width &&
+                  0 <= j  && j < _height, "Index out of range");
+      return Node(i + j * _width);
+    }
+
+    int col(Node n) const {
+      return n._id % _width;
+    }
+
+    int row(Node n) const {
+      return n._id / _width;
+    }
+
+    dim2::Point<int> pos(Node n) const {
+      return dim2::Point<int>(col(n), row(n));
+    }
+
+    int width() const {
+      return _width;
+    }
+
+    int height() const {
+      return _height;
+    }
+
+    typedef True NodeNumTag;
+    typedef True EdgeNumTag;
+    typedef True ArcNumTag;
+
+    int nodeNum() const { return _node_num; }
+    int edgeNum() const { return _edge_num; }
+    int arcNum() const { return 2 * _edge_num; }
+
+    Node u(Edge edge) const {
+      if (edge._id < _edge_limit) {
+        return edge._id;
+      } else {
+        return (edge._id - _edge_limit) % (_width - 1) +
+          (edge._id - _edge_limit) / (_width - 1) * _width;
+      }
+    }
+
+    Node v(Edge edge) const {
+      if (edge._id < _edge_limit) {
+        return edge._id + _width;
+      } else {
+        return (edge._id - _edge_limit) % (_width - 1) +
+          (edge._id - _edge_limit) / (_width - 1) * _width + 1;
+      }
+    }
+
+    Node source(Arc arc) const {
+      return (arc._id & 1) == 1 ? u(arc) : v(arc);
+    }
+
+    Node target(Arc arc) const {
+      return (arc._id & 1) == 1 ? v(arc) : u(arc);
+    }
+
+    static int id(Node node) { return node._id; }
+    static int id(Edge edge) { return edge._id; }
+    static int id(Arc arc) { return arc._id; }
+
+    int maxNodeId() const { return _node_num - 1; }
+    int maxEdgeId() const { return _edge_num - 1; }
+    int maxArcId() const { return 2 * _edge_num - 1; }
+
+    static Node nodeFromId(int id) { return Node(id);}
+    static Edge edgeFromId(int id) { return Edge(id);}
+    static Arc arcFromId(int id) { return Arc(id);}
+
+    typedef True FindEdgeTag;
+    typedef True FindArcTag;
+
+    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
+      if (prev != INVALID) return INVALID;
+      if (v._id > u._id) {
+        if (v._id - u._id == _width)
+          return Edge(u._id);
+        if (v._id - u._id == 1 && u._id % _width < _width - 1) {
+          return Edge(u._id / _width * (_width - 1) +
+                      u._id % _width + _edge_limit);
+        }
+      } else {
+        if (u._id - v._id == _width)
+          return Edge(v._id);
+        if (u._id - v._id == 1 && v._id % _width < _width - 1) {
+          return Edge(v._id / _width * (_width - 1) +
+                      v._id % _width + _edge_limit);
+        }
+      }
+      return INVALID;
+    }
+
+    Arc findArc(Node u, Node v, Arc prev = INVALID) const {
+      if (prev != INVALID) return INVALID;
+      if (v._id > u._id) {
+        if (v._id - u._id == _width)
+          return Arc((u._id << 1) | 1);
+        if (v._id - u._id == 1 && u._id % _width < _width - 1) {
+          return Arc(((u._id / _width * (_width - 1) +
+                       u._id % _width + _edge_limit) << 1) | 1);
+        }
+      } else {
+        if (u._id - v._id == _width)
+          return Arc(v._id << 1);
+        if (u._id - v._id == 1 && v._id % _width < _width - 1) {
+          return Arc((v._id / _width * (_width - 1) +
+                       v._id % _width + _edge_limit) << 1);
+        }
+      }
+      return INVALID;
+    }
+
+    class Node {
+      friend class GridGraphBase;
+
+    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 Edge {
+      friend class GridGraphBase;
+      friend class Arc;
+
+    protected:
+      int _id;
+
+      Edge(int id) : _id(id) {}
+
+    public:
+      Edge() {}
+      Edge (Invalid) : _id(-1) {}
+      bool operator==(const Edge edge) const {return _id == edge._id;}
+      bool operator!=(const Edge edge) const {return _id != edge._id;}
+      bool operator<(const Edge edge) const {return _id < edge._id;}
+    };
+
+    class Arc {
+      friend class GridGraphBase;
+
+    protected:
+      int _id;
+
+      Arc(int id) : _id(id) {}
+
+    public:
+      Arc() {}
+      Arc (Invalid) : _id(-1) {}
+      operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; }
+      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;}
+    };
+
+    static bool direction(Arc arc) {
+      return (arc._id & 1) == 1;
+    }
+
+    static Arc direct(Edge edge, bool dir) {
+      return Arc((edge._id << 1) | (dir ? 1 : 0));
+    }
+
+    void first(Node& node) const {
+      node._id = _node_num - 1;
+    }
+
+    static void next(Node& node) {
+      --node._id;
+    }
+
+    void first(Edge& edge) const {
+      edge._id = _edge_num - 1;
+    }
+
+    static void next(Edge& edge) {
+      --edge._id;
+    }
+
+    void first(Arc& arc) const {
+      arc._id = 2 * _edge_num - 1;
+    }
+
+    static void next(Arc& arc) {
+      --arc._id;
+    }
+
+    void firstOut(Arc& arc, const Node& node) const {
+      if (node._id % _width < _width - 1) {
+        arc._id = (_edge_limit + node._id % _width +
+                   (node._id / _width) * (_width - 1)) << 1 | 1;
+        return;
+      }
+      if (node._id < _node_num - _width) {
+        arc._id = node._id << 1 | 1;
+        return;
+      }
+      if (node._id % _width > 0) {
+        arc._id = (_edge_limit + node._id % _width +
+                   (node._id / _width) * (_width - 1) - 1) << 1;
+        return;
+      }
+      if (node._id >= _width) {
+        arc._id = (node._id - _width) << 1;
+        return;
+      }
+      arc._id = -1;
+    }
+
+    void nextOut(Arc& arc) const {
+      int nid = arc._id >> 1;
+      if ((arc._id & 1) == 1) {
+        if (nid >= _edge_limit) {
+          nid = (nid - _edge_limit) % (_width - 1) +
+            (nid - _edge_limit) / (_width - 1) * _width;
+          if (nid < _node_num - _width) {
+            arc._id = nid << 1 | 1;
+            return;
+          }
+        }
+        if (nid % _width > 0) {
+          arc._id = (_edge_limit + nid % _width +
+                     (nid / _width) * (_width - 1) - 1) << 1;
+          return;
+        }
+        if (nid >= _width) {
+          arc._id = (nid - _width) << 1;
+          return;
+        }
+      } else {
+        if (nid >= _edge_limit) {
+          nid = (nid - _edge_limit) % (_width - 1) +
+            (nid - _edge_limit) / (_width - 1) * _width + 1;
+          if (nid >= _width) {
+            arc._id = (nid - _width) << 1;
+            return;
+          }
+        }
+      }
+      arc._id = -1;
+    }
+
+    void firstIn(Arc& arc, const Node& node) const {
+      if (node._id % _width < _width - 1) {
+        arc._id = (_edge_limit + node._id % _width +
+                   (node._id / _width) * (_width - 1)) << 1;
+        return;
+      }
+      if (node._id < _node_num - _width) {
+        arc._id = node._id << 1;
+        return;
+      }
+      if (node._id % _width > 0) {
+        arc._id = (_edge_limit + node._id % _width +
+                   (node._id / _width) * (_width - 1) - 1) << 1 | 1;
+        return;
+      }
+      if (node._id >= _width) {
+        arc._id = (node._id - _width) << 1 | 1;
+        return;
+      }
+      arc._id = -1;
+    }
+
+    void nextIn(Arc& arc) const {
+      int nid = arc._id >> 1;
+      if ((arc._id & 1) == 0) {
+        if (nid >= _edge_limit) {
+          nid = (nid - _edge_limit) % (_width - 1) +
+            (nid - _edge_limit) / (_width - 1) * _width;
+          if (nid < _node_num - _width) {
+            arc._id = nid << 1;
+            return;
+          }
+        }
+        if (nid % _width > 0) {
+          arc._id = (_edge_limit + nid % _width +
+                     (nid / _width) * (_width - 1) - 1) << 1 | 1;
+          return;
+        }
+        if (nid >= _width) {
+          arc._id = (nid - _width) << 1 | 1;
+          return;
+        }
+      } else {
+        if (nid >= _edge_limit) {
+          nid = (nid - _edge_limit) % (_width - 1) +
+            (nid - _edge_limit) / (_width - 1) * _width + 1;
+          if (nid >= _width) {
+            arc._id = (nid - _width) << 1 | 1;
+            return;
+          }
+        }
+      }
+      arc._id = -1;
+    }
+
+    void firstInc(Edge& edge, bool& dir, const Node& node) const {
+      if (node._id % _width < _width - 1) {
+        edge._id = _edge_limit + node._id % _width +
+          (node._id / _width) * (_width - 1);
+        dir = true;
+        return;
+      }
+      if (node._id < _node_num - _width) {
+        edge._id = node._id;
+        dir = true;
+        return;
+      }
+      if (node._id % _width > 0) {
+        edge._id = _edge_limit + node._id % _width +
+          (node._id / _width) * (_width - 1) - 1;
+        dir = false;
+        return;
+      }
+      if (node._id >= _width) {
+        edge._id = node._id - _width;
+        dir = false;
+        return;
+      }
+      edge._id = -1;
+      dir = true;
+    }
+
+    void nextInc(Edge& edge, bool& dir) const {
+      int nid = edge._id;
+      if (dir) {
+        if (nid >= _edge_limit) {
+          nid = (nid - _edge_limit) % (_width - 1) +
+            (nid - _edge_limit) / (_width - 1) * _width;
+          if (nid < _node_num - _width) {
+            edge._id = nid;
+            return;
+          }
+        }
+        if (nid % _width > 0) {
+          edge._id = _edge_limit + nid % _width +
+            (nid / _width) * (_width - 1) - 1;
+          dir = false;
+          return;
+        }
+        if (nid >= _width) {
+          edge._id = nid - _width;
+          dir = false;
+          return;
+        }
+      } else {
+        if (nid >= _edge_limit) {
+          nid = (nid - _edge_limit) % (_width - 1) +
+            (nid - _edge_limit) / (_width - 1) * _width + 1;
+          if (nid >= _width) {
+            edge._id = nid - _width;
+            return;
+          }
+        }
+      }
+      edge._id = -1;
+      dir = true;
+    }
+
+    Arc right(Node n) const {
+      if (n._id % _width < _width - 1) {
+        return Arc(((_edge_limit + n._id % _width +
+                    (n._id / _width) * (_width - 1)) << 1) | 1);
+      } else {
+        return INVALID;
+      }
+    }
+
+    Arc left(Node n) const {
+      if (n._id % _width > 0) {
+        return Arc((_edge_limit + n._id % _width +
+                     (n._id / _width) * (_width - 1) - 1) << 1);
+      } else {
+        return INVALID;
+      }
+    }
+
+    Arc up(Node n) const {
+      if (n._id < _edge_limit) {
+        return Arc((n._id << 1) | 1);
+      } else {
+        return INVALID;
+      }
+    }
+
+    Arc down(Node n) const {
+      if (n._id >= _width) {
+        return Arc((n._id - _width) << 1);
+      } else {
+        return INVALID;
+      }
+    }
+
+  private:
+    int _width, _height;
+    int _node_num, _edge_num;
+    int _edge_limit;
+  };
+
+
+  typedef GraphExtender<GridGraphBase> ExtendedGridGraphBase;
+
+  /// \ingroup graphs
+  ///
+  /// \brief Grid graph class
+  ///
+  /// This class implements a special graph type. The nodes of the
+  /// graph can be indexed by two integer \c (i,j) value where \c i is
+  /// in the \c [0..width()-1] range and j is in the \c
+  /// [0..height()-1] range.  Two nodes are connected in the graph if
+  /// the indexes differ exactly on one position and exactly one is
+  /// the difference. The nodes of the graph can be indexed by position
+  /// with the \c operator()() function. The positions of the nodes can be
+  /// get with \c pos(), \c col() and \c row() members. The outgoing
+  /// arcs can be retrieved with the \c right(), \c up(), \c left()
+  /// and \c down() functions, where the bottom-left corner is the
+  /// origin.
+  ///
+  /// \image html grid_graph.png
+  /// \image latex grid_graph.eps "Grid graph" width=\textwidth
+  ///
+  /// A short example about the basic usage:
+  ///\code
+  /// GridGraph graph(rows, cols);
+  /// GridGraph::NodeMap<int> val(graph);
+  /// for (int i = 0; i < graph.width(); ++i) {
+  ///   for (int j = 0; j < graph.height(); ++j) {
+  ///     val[graph(i, j)] = i + j;
+  ///   }
+  /// }
+  ///\endcode
+  ///
+  /// This graph type is fully conform to the \ref concepts::Graph
+  /// "Graph" concept, and it also has an important extra feature
+  /// that its maps are real \ref concepts::ReferenceMap
+  /// "reference map"s.
+  class GridGraph : public ExtendedGridGraphBase {
+  public:
+
+    typedef ExtendedGridGraphBase Parent;
+
+    /// \brief Map to get the indices of the nodes as dim2::Point<int>.
+    ///
+    /// Map to get the indices of the nodes as dim2::Point<int>.
+    class IndexMap {
+    public:
+      /// \brief The key type of the map
+      typedef GridGraph::Node Key;
+      /// \brief The value type of the map
+      typedef dim2::Point<int> Value;
+
+      /// \brief Constructor
+      ///
+      /// Constructor
+      IndexMap(const GridGraph& graph) : _graph(graph) {}
+
+      /// \brief The subscript operator
+      ///
+      /// The subscript operator.
+      Value operator[](Key key) const {
+        return _graph.pos(key);
+      }
+
+    private:
+      const GridGraph& _graph;
+    };
+
+    /// \brief Map to get the column of the nodes.
+    ///
+    /// Map to get the column of the nodes.
+    class ColMap {
+    public:
+      /// \brief The key type of the map
+      typedef GridGraph::Node Key;
+      /// \brief The value type of the map
+      typedef int Value;
+
+      /// \brief Constructor
+      ///
+      /// Constructor
+      ColMap(const GridGraph& graph) : _graph(graph) {}
+
+      /// \brief The subscript operator
+      ///
+      /// The subscript operator.
+      Value operator[](Key key) const {
+        return _graph.col(key);
+      }
+
+    private:
+      const GridGraph& _graph;
+    };
+
+    /// \brief Map to get the row of the nodes.
+    ///
+    /// Map to get the row of the nodes.
+    class RowMap {
+    public:
+      /// \brief The key type of the map
+      typedef GridGraph::Node Key;
+      /// \brief The value type of the map
+      typedef int Value;
+
+      /// \brief Constructor
+      ///
+      /// Constructor
+      RowMap(const GridGraph& graph) : _graph(graph) {}
+
+      /// \brief The subscript operator
+      ///
+      /// The subscript operator.
+      Value operator[](Key key) const {
+        return _graph.row(key);
+      }
+
+    private:
+      const GridGraph& _graph;
+    };
+
+    /// \brief Constructor
+    ///
+    /// Construct a grid graph with given size.
+    GridGraph(int width, int height) { construct(width, height); }
+
+    /// \brief Resize the graph
+    ///
+    /// Resize the graph. The function will fully destroy and rebuild
+    /// the graph.  This cause that the maps of the graph will
+    /// reallocated automatically and the previous values will be
+    /// lost.
+    void resize(int width, int height) {
+      Parent::notifier(Arc()).clear();
+      Parent::notifier(Edge()).clear();
+      Parent::notifier(Node()).clear();
+      construct(width, height);
+      Parent::notifier(Node()).build();
+      Parent::notifier(Edge()).build();
+      Parent::notifier(Arc()).build();
+    }
+
+    /// \brief The node on the given position.
+    ///
+    /// Gives back the node on the given position.
+    Node operator()(int i, int j) const {
+      return Parent::operator()(i, j);
+    }
+
+    /// \brief Gives back the column index of the node.
+    ///
+    /// Gives back the column index of the node.
+    int col(Node n) const {
+      return Parent::col(n);
+    }
+
+    /// \brief Gives back the row index of the node.
+    ///
+    /// Gives back the row index of the node.
+    int row(Node n) const {
+      return Parent::row(n);
+    }
+
+    /// \brief Gives back the position of the node.
+    ///
+    /// Gives back the position of the node, ie. the <tt>(col,row)</tt> pair.
+    dim2::Point<int> pos(Node n) const {
+      return Parent::pos(n);
+    }
+
+    /// \brief Gives back the number of the columns.
+    ///
+    /// Gives back the number of the columns.
+    int width() const {
+      return Parent::width();
+    }
+
+    /// \brief Gives back the number of the rows.
+    ///
+    /// Gives back the number of the rows.
+    int height() const {
+      return Parent::height();
+    }
+
+    /// \brief Gives back the arc goes right from the node.
+    ///
+    /// Gives back the arc goes right from the node. If there is not
+    /// outgoing arc then it gives back INVALID.
+    Arc right(Node n) const {
+      return Parent::right(n);
+    }
+
+    /// \brief Gives back the arc goes left from the node.
+    ///
+    /// Gives back the arc goes left from the node. If there is not
+    /// outgoing arc then it gives back INVALID.
+    Arc left(Node n) const {
+      return Parent::left(n);
+    }
+
+    /// \brief Gives back the arc goes up from the node.
+    ///
+    /// Gives back the arc goes up from the node. If there is not
+    /// outgoing arc then it gives back INVALID.
+    Arc up(Node n) const {
+      return Parent::up(n);
+    }
+
+    /// \brief Gives back the arc goes down from the node.
+    ///
+    /// Gives back the arc goes down from the node. If there is not
+    /// outgoing arc then it gives back INVALID.
+    Arc down(Node n) const {
+      return Parent::down(n);
+    }
+
+    /// \brief Index map of the grid graph
+    ///
+    /// Just returns an IndexMap for the grid graph.
+    IndexMap indexMap() const {
+      return IndexMap(*this);
+    }
+
+    /// \brief Row map of the grid graph
+    ///
+    /// Just returns a RowMap for the grid graph.
+    RowMap rowMap() const {
+      return RowMap(*this);
+    }
+
+    /// \brief Column map of the grid graph
+    ///
+    /// Just returns a ColMap for the grid graph.
+    ColMap colMap() const {
+      return ColMap(*this);
+    }
+
+  };
+
+}
+#endif
Index: lemon/hao_orlin.h
===================================================================
--- lemon/hao_orlin.h	(revision 440)
+++ lemon/hao_orlin.h	(revision 440)
@@ -0,0 +1,966 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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_HAO_ORLIN_H
+#define LEMON_HAO_ORLIN_H
+
+#include <vector>
+#include <list>
+#include <limits>
+
+#include <lemon/maps.h>
+#include <lemon/core.h>
+#include <lemon/tolerance.h>
+
+/// \file
+/// \ingroup min_cut
+/// \brief Implementation of the Hao-Orlin algorithm.
+///
+/// Implementation of the Hao-Orlin algorithm class for testing network
+/// reliability.
+
+namespace lemon {
+
+  /// \ingroup min_cut
+  ///
+  /// \brief %Hao-Orlin algorithm to find a minimum cut in directed graphs.
+  ///
+  /// Hao-Orlin calculates a minimum cut in a directed graph
+  /// \f$D=(V,A)\f$. It takes a fixed node \f$ source \in V \f$ and
+  /// consists of two phases: in the first phase it determines a
+  /// minimum cut with \f$ source \f$ on the source-side (i.e. a set
+  /// \f$ X\subsetneq V \f$ with \f$ source \in X \f$ and minimal
+  /// out-degree) and in the second phase it determines a minimum cut
+  /// with \f$ source \f$ on the sink-side (i.e. a set
+  /// \f$ X\subsetneq V \f$ with \f$ source \notin X \f$ and minimal
+  /// out-degree). Obviously, the smaller of these two cuts will be a
+  /// minimum cut of \f$ D \f$. The algorithm is a modified
+  /// push-relabel preflow algorithm and our implementation calculates
+  /// the minimum cut in \f$ O(n^2\sqrt{m}) \f$ time (we use the
+  /// highest-label rule), or in \f$O(nm)\f$ for unit capacities. The
+  /// purpose of such algorithm is testing network reliability. For an
+  /// undirected graph you can run just the first phase of the
+  /// algorithm or you can use the algorithm of Nagamochi and Ibaraki
+  /// which solves the undirected problem in
+  /// \f$ O(nm + n^2 \log(n)) \f$ time: it is implemented in the
+  /// NagamochiIbaraki algorithm class.
+  ///
+  /// \param _Digraph is the graph type of the algorithm.
+  /// \param _CapacityMap is an edge map of capacities which should
+  /// be any numreric type. The default type is _Digraph::ArcMap<int>.
+  /// \param _Tolerance is the handler of the inexact computation. The
+  /// default type for this is Tolerance<CapacityMap::Value>.
+#ifdef DOXYGEN
+  template <typename _Digraph, typename _CapacityMap, typename _Tolerance>
+#else
+  template <typename _Digraph,
+            typename _CapacityMap = typename _Digraph::template ArcMap<int>,
+            typename _Tolerance = Tolerance<typename _CapacityMap::Value> >
+#endif
+  class HaoOrlin {
+  private:
+
+    typedef _Digraph Digraph;
+    typedef _CapacityMap CapacityMap;
+    typedef _Tolerance Tolerance;
+
+    typedef typename CapacityMap::Value Value;
+
+    TEMPLATE_GRAPH_TYPEDEFS(Digraph);
+
+    const Digraph& _graph;
+    const CapacityMap* _capacity;
+
+    typedef typename Digraph::template ArcMap<Value> FlowMap;
+    FlowMap* _flow;
+
+    Node _source;
+
+    int _node_num;
+
+    // Bucketing structure
+    std::vector<Node> _first, _last;
+    typename Digraph::template NodeMap<Node>* _next;
+    typename Digraph::template NodeMap<Node>* _prev;
+    typename Digraph::template NodeMap<bool>* _active;
+    typename Digraph::template NodeMap<int>* _bucket;
+
+    std::vector<bool> _dormant;
+
+    std::list<std::list<int> > _sets;
+    std::list<int>::iterator _highest;
+
+    typedef typename Digraph::template NodeMap<Value> ExcessMap;
+    ExcessMap* _excess;
+
+    typedef typename Digraph::template NodeMap<bool> SourceSetMap;
+    SourceSetMap* _source_set;
+
+    Value _min_cut;
+
+    typedef typename Digraph::template NodeMap<bool> MinCutMap;
+    MinCutMap* _min_cut_map;
+
+    Tolerance _tolerance;
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor of the algorithm class.
+    HaoOrlin(const Digraph& graph, const CapacityMap& capacity,
+             const Tolerance& tolerance = Tolerance()) :
+      _graph(graph), _capacity(&capacity), _flow(0), _source(),
+      _node_num(), _first(), _last(), _next(0), _prev(0),
+      _active(0), _bucket(0), _dormant(), _sets(), _highest(),
+      _excess(0), _source_set(0), _min_cut(), _min_cut_map(0),
+      _tolerance(tolerance) {}
+
+    ~HaoOrlin() {
+      if (_min_cut_map) {
+        delete _min_cut_map;
+      }
+      if (_source_set) {
+        delete _source_set;
+      }
+      if (_excess) {
+        delete _excess;
+      }
+      if (_next) {
+        delete _next;
+      }
+      if (_prev) {
+        delete _prev;
+      }
+      if (_active) {
+        delete _active;
+      }
+      if (_bucket) {
+        delete _bucket;
+      }
+      if (_flow) {
+        delete _flow;
+      }
+    }
+
+  private:
+
+    void activate(const Node& i) {
+      _active->set(i, true);
+
+      int bucket = (*_bucket)[i];
+
+      if ((*_prev)[i] == INVALID || (*_active)[(*_prev)[i]]) return;
+      //unlace
+      _next->set((*_prev)[i], (*_next)[i]);
+      if ((*_next)[i] != INVALID) {
+        _prev->set((*_next)[i], (*_prev)[i]);
+      } else {
+        _last[bucket] = (*_prev)[i];
+      }
+      //lace
+      _next->set(i, _first[bucket]);
+      _prev->set(_first[bucket], i);
+      _prev->set(i, INVALID);
+      _first[bucket] = i;
+    }
+
+    void deactivate(const Node& i) {
+      _active->set(i, false);
+      int bucket = (*_bucket)[i];
+
+      if ((*_next)[i] == INVALID || !(*_active)[(*_next)[i]]) return;
+
+      //unlace
+      _prev->set((*_next)[i], (*_prev)[i]);
+      if ((*_prev)[i] != INVALID) {
+        _next->set((*_prev)[i], (*_next)[i]);
+      } else {
+        _first[bucket] = (*_next)[i];
+      }
+      //lace
+      _prev->set(i, _last[bucket]);
+      _next->set(_last[bucket], i);
+      _next->set(i, INVALID);
+      _last[bucket] = i;
+    }
+
+    void addItem(const Node& i, int bucket) {
+      (*_bucket)[i] = bucket;
+      if (_last[bucket] != INVALID) {
+        _prev->set(i, _last[bucket]);
+        _next->set(_last[bucket], i);
+        _next->set(i, INVALID);
+        _last[bucket] = i;
+      } else {
+        _prev->set(i, INVALID);
+        _first[bucket] = i;
+        _next->set(i, INVALID);
+        _last[bucket] = i;
+      }
+    }
+
+    void findMinCutOut() {
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _excess->set(n, 0);
+      }
+
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        _flow->set(a, 0);
+      }
+
+      int bucket_num = 0;
+      std::vector<Node> queue(_node_num);
+      int qfirst = 0, qlast = 0, qsep = 0;
+
+      {
+        typename Digraph::template NodeMap<bool> reached(_graph, false);
+
+        reached.set(_source, true);
+        bool first_set = true;
+
+        for (NodeIt t(_graph); t != INVALID; ++t) {
+          if (reached[t]) continue;
+          _sets.push_front(std::list<int>());
+
+          queue[qlast++] = t;
+          reached.set(t, true);
+
+          while (qfirst != qlast) {
+            if (qsep == qfirst) {
+              ++bucket_num;
+              _sets.front().push_front(bucket_num);
+              _dormant[bucket_num] = !first_set;
+              _first[bucket_num] = _last[bucket_num] = INVALID;
+              qsep = qlast;
+            }
+
+            Node n = queue[qfirst++];
+            addItem(n, bucket_num);
+
+            for (InArcIt a(_graph, n); a != INVALID; ++a) {
+              Node u = _graph.source(a);
+              if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
+                reached.set(u, true);
+                queue[qlast++] = u;
+              }
+            }
+          }
+          first_set = false;
+        }
+
+        ++bucket_num;
+        _bucket->set(_source, 0);
+        _dormant[0] = true;
+      }
+      _source_set->set(_source, true);
+
+      Node target = _last[_sets.back().back()];
+      {
+        for (OutArcIt a(_graph, _source); a != INVALID; ++a) {
+          if (_tolerance.positive((*_capacity)[a])) {
+            Node u = _graph.target(a);
+            _flow->set(a, (*_capacity)[a]);
+            _excess->set(u, (*_excess)[u] + (*_capacity)[a]);
+            if (!(*_active)[u] && u != _source) {
+              activate(u);
+            }
+          }
+        }
+
+        if ((*_active)[target]) {
+          deactivate(target);
+        }
+
+        _highest = _sets.back().begin();
+        while (_highest != _sets.back().end() &&
+               !(*_active)[_first[*_highest]]) {
+          ++_highest;
+        }
+      }
+
+      while (true) {
+        while (_highest != _sets.back().end()) {
+          Node n = _first[*_highest];
+          Value excess = (*_excess)[n];
+          int next_bucket = _node_num;
+
+          int under_bucket;
+          if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
+            under_bucket = -1;
+          } else {
+            under_bucket = *(++std::list<int>::iterator(_highest));
+          }
+
+          for (OutArcIt a(_graph, n); a != INVALID; ++a) {
+            Node v = _graph.target(a);
+            if (_dormant[(*_bucket)[v]]) continue;
+            Value rem = (*_capacity)[a] - (*_flow)[a];
+            if (!_tolerance.positive(rem)) continue;
+            if ((*_bucket)[v] == under_bucket) {
+              if (!(*_active)[v] && v != target) {
+                activate(v);
+              }
+              if (!_tolerance.less(rem, excess)) {
+                _flow->set(a, (*_flow)[a] + excess);
+                _excess->set(v, (*_excess)[v] + excess);
+                excess = 0;
+                goto no_more_push;
+              } else {
+                excess -= rem;
+                _excess->set(v, (*_excess)[v] + rem);
+                _flow->set(a, (*_capacity)[a]);
+              }
+            } else if (next_bucket > (*_bucket)[v]) {
+              next_bucket = (*_bucket)[v];
+            }
+          }
+
+          for (InArcIt a(_graph, n); a != INVALID; ++a) {
+            Node v = _graph.source(a);
+            if (_dormant[(*_bucket)[v]]) continue;
+            Value rem = (*_flow)[a];
+            if (!_tolerance.positive(rem)) continue;
+            if ((*_bucket)[v] == under_bucket) {
+              if (!(*_active)[v] && v != target) {
+                activate(v);
+              }
+              if (!_tolerance.less(rem, excess)) {
+                _flow->set(a, (*_flow)[a] - excess);
+                _excess->set(v, (*_excess)[v] + excess);
+                excess = 0;
+                goto no_more_push;
+              } else {
+                excess -= rem;
+                _excess->set(v, (*_excess)[v] + rem);
+                _flow->set(a, 0);
+              }
+            } else if (next_bucket > (*_bucket)[v]) {
+              next_bucket = (*_bucket)[v];
+            }
+          }
+
+        no_more_push:
+
+          _excess->set(n, excess);
+
+          if (excess != 0) {
+            if ((*_next)[n] == INVALID) {
+              typename std::list<std::list<int> >::iterator new_set =
+                _sets.insert(--_sets.end(), std::list<int>());
+              new_set->splice(new_set->end(), _sets.back(),
+                              _sets.back().begin(), ++_highest);
+              for (std::list<int>::iterator it = new_set->begin();
+                   it != new_set->end(); ++it) {
+                _dormant[*it] = true;
+              }
+              while (_highest != _sets.back().end() &&
+                     !(*_active)[_first[*_highest]]) {
+                ++_highest;
+              }
+            } else if (next_bucket == _node_num) {
+              _first[(*_bucket)[n]] = (*_next)[n];
+              _prev->set((*_next)[n], INVALID);
+
+              std::list<std::list<int> >::iterator new_set =
+                _sets.insert(--_sets.end(), std::list<int>());
+
+              new_set->push_front(bucket_num);
+              _bucket->set(n, bucket_num);
+              _first[bucket_num] = _last[bucket_num] = n;
+              _next->set(n, INVALID);
+              _prev->set(n, INVALID);
+              _dormant[bucket_num] = true;
+              ++bucket_num;
+
+              while (_highest != _sets.back().end() &&
+                     !(*_active)[_first[*_highest]]) {
+                ++_highest;
+              }
+            } else {
+              _first[*_highest] = (*_next)[n];
+              _prev->set((*_next)[n], INVALID);
+
+              while (next_bucket != *_highest) {
+                --_highest;
+              }
+
+              if (_highest == _sets.back().begin()) {
+                _sets.back().push_front(bucket_num);
+                _dormant[bucket_num] = false;
+                _first[bucket_num] = _last[bucket_num] = INVALID;
+                ++bucket_num;
+              }
+              --_highest;
+
+              _bucket->set(n, *_highest);
+              _next->set(n, _first[*_highest]);
+              if (_first[*_highest] != INVALID) {
+                _prev->set(_first[*_highest], n);
+              } else {
+                _last[*_highest] = n;
+              }
+              _first[*_highest] = n;
+            }
+          } else {
+
+            deactivate(n);
+            if (!(*_active)[_first[*_highest]]) {
+              ++_highest;
+              if (_highest != _sets.back().end() &&
+                  !(*_active)[_first[*_highest]]) {
+                _highest = _sets.back().end();
+              }
+            }
+          }
+        }
+
+        if ((*_excess)[target] < _min_cut) {
+          _min_cut = (*_excess)[target];
+          for (NodeIt i(_graph); i != INVALID; ++i) {
+            _min_cut_map->set(i, true);
+          }
+          for (std::list<int>::iterator it = _sets.back().begin();
+               it != _sets.back().end(); ++it) {
+            Node n = _first[*it];
+            while (n != INVALID) {
+              _min_cut_map->set(n, false);
+              n = (*_next)[n];
+            }
+          }
+        }
+
+        {
+          Node new_target;
+          if ((*_prev)[target] != INVALID || (*_next)[target] != INVALID) {
+            if ((*_next)[target] == INVALID) {
+              _last[(*_bucket)[target]] = (*_prev)[target];
+              new_target = (*_prev)[target];
+            } else {
+              _prev->set((*_next)[target], (*_prev)[target]);
+              new_target = (*_next)[target];
+            }
+            if ((*_prev)[target] == INVALID) {
+              _first[(*_bucket)[target]] = (*_next)[target];
+            } else {
+              _next->set((*_prev)[target], (*_next)[target]);
+            }
+          } else {
+            _sets.back().pop_back();
+            if (_sets.back().empty()) {
+              _sets.pop_back();
+              if (_sets.empty())
+                break;
+              for (std::list<int>::iterator it = _sets.back().begin();
+                   it != _sets.back().end(); ++it) {
+                _dormant[*it] = false;
+              }
+            }
+            new_target = _last[_sets.back().back()];
+          }
+
+          _bucket->set(target, 0);
+
+          _source_set->set(target, true);
+          for (OutArcIt a(_graph, target); a != INVALID; ++a) {
+            Value rem = (*_capacity)[a] - (*_flow)[a];
+            if (!_tolerance.positive(rem)) continue;
+            Node v = _graph.target(a);
+            if (!(*_active)[v] && !(*_source_set)[v]) {
+              activate(v);
+            }
+            _excess->set(v, (*_excess)[v] + rem);
+            _flow->set(a, (*_capacity)[a]);
+          }
+
+          for (InArcIt a(_graph, target); a != INVALID; ++a) {
+            Value rem = (*_flow)[a];
+            if (!_tolerance.positive(rem)) continue;
+            Node v = _graph.source(a);
+            if (!(*_active)[v] && !(*_source_set)[v]) {
+              activate(v);
+            }
+            _excess->set(v, (*_excess)[v] + rem);
+            _flow->set(a, 0);
+          }
+
+          target = new_target;
+          if ((*_active)[target]) {
+            deactivate(target);
+          }
+
+          _highest = _sets.back().begin();
+          while (_highest != _sets.back().end() &&
+                 !(*_active)[_first[*_highest]]) {
+            ++_highest;
+          }
+        }
+      }
+    }
+
+    void findMinCutIn() {
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _excess->set(n, 0);
+      }
+
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        _flow->set(a, 0);
+      }
+
+      int bucket_num = 0;
+      std::vector<Node> queue(_node_num);
+      int qfirst = 0, qlast = 0, qsep = 0;
+
+      {
+        typename Digraph::template NodeMap<bool> reached(_graph, false);
+
+        reached.set(_source, true);
+
+        bool first_set = true;
+
+        for (NodeIt t(_graph); t != INVALID; ++t) {
+          if (reached[t]) continue;
+          _sets.push_front(std::list<int>());
+
+          queue[qlast++] = t;
+          reached.set(t, true);
+
+          while (qfirst != qlast) {
+            if (qsep == qfirst) {
+              ++bucket_num;
+              _sets.front().push_front(bucket_num);
+              _dormant[bucket_num] = !first_set;
+              _first[bucket_num] = _last[bucket_num] = INVALID;
+              qsep = qlast;
+            }
+
+            Node n = queue[qfirst++];
+            addItem(n, bucket_num);
+
+            for (OutArcIt a(_graph, n); a != INVALID; ++a) {
+              Node u = _graph.target(a);
+              if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
+                reached.set(u, true);
+                queue[qlast++] = u;
+              }
+            }
+          }
+          first_set = false;
+        }
+
+        ++bucket_num;
+        _bucket->set(_source, 0);
+        _dormant[0] = true;
+      }
+      _source_set->set(_source, true);
+
+      Node target = _last[_sets.back().back()];
+      {
+        for (InArcIt a(_graph, _source); a != INVALID; ++a) {
+          if (_tolerance.positive((*_capacity)[a])) {
+            Node u = _graph.source(a);
+            _flow->set(a, (*_capacity)[a]);
+            _excess->set(u, (*_excess)[u] + (*_capacity)[a]);
+            if (!(*_active)[u] && u != _source) {
+              activate(u);
+            }
+          }
+        }
+        if ((*_active)[target]) {
+          deactivate(target);
+        }
+
+        _highest = _sets.back().begin();
+        while (_highest != _sets.back().end() &&
+               !(*_active)[_first[*_highest]]) {
+          ++_highest;
+        }
+      }
+
+
+      while (true) {
+        while (_highest != _sets.back().end()) {
+          Node n = _first[*_highest];
+          Value excess = (*_excess)[n];
+          int next_bucket = _node_num;
+
+          int under_bucket;
+          if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
+            under_bucket = -1;
+          } else {
+            under_bucket = *(++std::list<int>::iterator(_highest));
+          }
+
+          for (InArcIt a(_graph, n); a != INVALID; ++a) {
+            Node v = _graph.source(a);
+            if (_dormant[(*_bucket)[v]]) continue;
+            Value rem = (*_capacity)[a] - (*_flow)[a];
+            if (!_tolerance.positive(rem)) continue;
+            if ((*_bucket)[v] == under_bucket) {
+              if (!(*_active)[v] && v != target) {
+                activate(v);
+              }
+              if (!_tolerance.less(rem, excess)) {
+                _flow->set(a, (*_flow)[a] + excess);
+                _excess->set(v, (*_excess)[v] + excess);
+                excess = 0;
+                goto no_more_push;
+              } else {
+                excess -= rem;
+                _excess->set(v, (*_excess)[v] + rem);
+                _flow->set(a, (*_capacity)[a]);
+              }
+            } else if (next_bucket > (*_bucket)[v]) {
+              next_bucket = (*_bucket)[v];
+            }
+          }
+
+          for (OutArcIt a(_graph, n); a != INVALID; ++a) {
+            Node v = _graph.target(a);
+            if (_dormant[(*_bucket)[v]]) continue;
+            Value rem = (*_flow)[a];
+            if (!_tolerance.positive(rem)) continue;
+            if ((*_bucket)[v] == under_bucket) {
+              if (!(*_active)[v] && v != target) {
+                activate(v);
+              }
+              if (!_tolerance.less(rem, excess)) {
+                _flow->set(a, (*_flow)[a] - excess);
+                _excess->set(v, (*_excess)[v] + excess);
+                excess = 0;
+                goto no_more_push;
+              } else {
+                excess -= rem;
+                _excess->set(v, (*_excess)[v] + rem);
+                _flow->set(a, 0);
+              }
+            } else if (next_bucket > (*_bucket)[v]) {
+              next_bucket = (*_bucket)[v];
+            }
+          }
+
+        no_more_push:
+
+          _excess->set(n, excess);
+
+          if (excess != 0) {
+            if ((*_next)[n] == INVALID) {
+              typename std::list<std::list<int> >::iterator new_set =
+                _sets.insert(--_sets.end(), std::list<int>());
+              new_set->splice(new_set->end(), _sets.back(),
+                              _sets.back().begin(), ++_highest);
+              for (std::list<int>::iterator it = new_set->begin();
+                   it != new_set->end(); ++it) {
+                _dormant[*it] = true;
+              }
+              while (_highest != _sets.back().end() &&
+                     !(*_active)[_first[*_highest]]) {
+                ++_highest;
+              }
+            } else if (next_bucket == _node_num) {
+              _first[(*_bucket)[n]] = (*_next)[n];
+              _prev->set((*_next)[n], INVALID);
+
+              std::list<std::list<int> >::iterator new_set =
+                _sets.insert(--_sets.end(), std::list<int>());
+
+              new_set->push_front(bucket_num);
+              _bucket->set(n, bucket_num);
+              _first[bucket_num] = _last[bucket_num] = n;
+              _next->set(n, INVALID);
+              _prev->set(n, INVALID);
+              _dormant[bucket_num] = true;
+              ++bucket_num;
+
+              while (_highest != _sets.back().end() &&
+                     !(*_active)[_first[*_highest]]) {
+                ++_highest;
+              }
+            } else {
+              _first[*_highest] = (*_next)[n];
+              _prev->set((*_next)[n], INVALID);
+
+              while (next_bucket != *_highest) {
+                --_highest;
+              }
+              if (_highest == _sets.back().begin()) {
+                _sets.back().push_front(bucket_num);
+                _dormant[bucket_num] = false;
+                _first[bucket_num] = _last[bucket_num] = INVALID;
+                ++bucket_num;
+              }
+              --_highest;
+
+              _bucket->set(n, *_highest);
+              _next->set(n, _first[*_highest]);
+              if (_first[*_highest] != INVALID) {
+                _prev->set(_first[*_highest], n);
+              } else {
+                _last[*_highest] = n;
+              }
+              _first[*_highest] = n;
+            }
+          } else {
+
+            deactivate(n);
+            if (!(*_active)[_first[*_highest]]) {
+              ++_highest;
+              if (_highest != _sets.back().end() &&
+                  !(*_active)[_first[*_highest]]) {
+                _highest = _sets.back().end();
+              }
+            }
+          }
+        }
+
+        if ((*_excess)[target] < _min_cut) {
+          _min_cut = (*_excess)[target];
+          for (NodeIt i(_graph); i != INVALID; ++i) {
+            _min_cut_map->set(i, false);
+          }
+          for (std::list<int>::iterator it = _sets.back().begin();
+               it != _sets.back().end(); ++it) {
+            Node n = _first[*it];
+            while (n != INVALID) {
+              _min_cut_map->set(n, true);
+              n = (*_next)[n];
+            }
+          }
+        }
+
+        {
+          Node new_target;
+          if ((*_prev)[target] != INVALID || (*_next)[target] != INVALID) {
+            if ((*_next)[target] == INVALID) {
+              _last[(*_bucket)[target]] = (*_prev)[target];
+              new_target = (*_prev)[target];
+            } else {
+              _prev->set((*_next)[target], (*_prev)[target]);
+              new_target = (*_next)[target];
+            }
+            if ((*_prev)[target] == INVALID) {
+              _first[(*_bucket)[target]] = (*_next)[target];
+            } else {
+              _next->set((*_prev)[target], (*_next)[target]);
+            }
+          } else {
+            _sets.back().pop_back();
+            if (_sets.back().empty()) {
+              _sets.pop_back();
+              if (_sets.empty())
+                break;
+              for (std::list<int>::iterator it = _sets.back().begin();
+                   it != _sets.back().end(); ++it) {
+                _dormant[*it] = false;
+              }
+            }
+            new_target = _last[_sets.back().back()];
+          }
+
+          _bucket->set(target, 0);
+
+          _source_set->set(target, true);
+          for (InArcIt a(_graph, target); a != INVALID; ++a) {
+            Value rem = (*_capacity)[a] - (*_flow)[a];
+            if (!_tolerance.positive(rem)) continue;
+            Node v = _graph.source(a);
+            if (!(*_active)[v] && !(*_source_set)[v]) {
+              activate(v);
+            }
+            _excess->set(v, (*_excess)[v] + rem);
+            _flow->set(a, (*_capacity)[a]);
+          }
+
+          for (OutArcIt a(_graph, target); a != INVALID; ++a) {
+            Value rem = (*_flow)[a];
+            if (!_tolerance.positive(rem)) continue;
+            Node v = _graph.target(a);
+            if (!(*_active)[v] && !(*_source_set)[v]) {
+              activate(v);
+            }
+            _excess->set(v, (*_excess)[v] + rem);
+            _flow->set(a, 0);
+          }
+
+          target = new_target;
+          if ((*_active)[target]) {
+            deactivate(target);
+          }
+
+          _highest = _sets.back().begin();
+          while (_highest != _sets.back().end() &&
+                 !(*_active)[_first[*_highest]]) {
+            ++_highest;
+          }
+        }
+      }
+    }
+
+  public:
+
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to use
+    /// one of the member functions called \c run(...).
+    /// \n
+    /// If you need more control on the execution,
+    /// first you must call \ref init(), then the \ref calculateIn() or
+    /// \ref calculateOut() functions.
+
+    /// @{
+
+    /// \brief Initializes the internal data structures.
+    ///
+    /// Initializes the internal data structures. It creates
+    /// the maps, residual graph adaptors and some bucket structures
+    /// for the algorithm.
+    void init() {
+      init(NodeIt(_graph));
+    }
+
+    /// \brief Initializes the internal data structures.
+    ///
+    /// Initializes the internal data structures. It creates
+    /// the maps, residual graph adaptor and some bucket structures
+    /// for the algorithm. Node \c source  is used as the push-relabel
+    /// algorithm's source.
+    void init(const Node& source) {
+      _source = source;
+
+      _node_num = countNodes(_graph);
+
+      _first.resize(_node_num);
+      _last.resize(_node_num);
+
+      _dormant.resize(_node_num);
+
+      if (!_flow) {
+        _flow = new FlowMap(_graph);
+      }
+      if (!_next) {
+        _next = new typename Digraph::template NodeMap<Node>(_graph);
+      }
+      if (!_prev) {
+        _prev = new typename Digraph::template NodeMap<Node>(_graph);
+      }
+      if (!_active) {
+        _active = new typename Digraph::template NodeMap<bool>(_graph);
+      }
+      if (!_bucket) {
+        _bucket = new typename Digraph::template NodeMap<int>(_graph);
+      }
+      if (!_excess) {
+        _excess = new ExcessMap(_graph);
+      }
+      if (!_source_set) {
+        _source_set = new SourceSetMap(_graph);
+      }
+      if (!_min_cut_map) {
+        _min_cut_map = new MinCutMap(_graph);
+      }
+
+      _min_cut = std::numeric_limits<Value>::max();
+    }
+
+
+    /// \brief Calculates a minimum cut with \f$ source \f$ on the
+    /// source-side.
+    ///
+    /// Calculates a minimum cut with \f$ source \f$ on the
+    /// source-side (i.e. a set \f$ X\subsetneq V \f$ with
+    /// \f$ source \in X \f$ and minimal out-degree).
+    void calculateOut() {
+      findMinCutOut();
+    }
+
+    /// \brief Calculates a minimum cut with \f$ source \f$ on the
+    /// target-side.
+    ///
+    /// Calculates a minimum cut with \f$ source \f$ on the
+    /// target-side (i.e. a set \f$ X\subsetneq V \f$ with
+    /// \f$ source \in X \f$ and minimal out-degree).
+    void calculateIn() {
+      findMinCutIn();
+    }
+
+
+    /// \brief Runs the algorithm.
+    ///
+    /// Runs the algorithm. It finds nodes \c source and \c target
+    /// arbitrarily and then calls \ref init(), \ref calculateOut()
+    /// and \ref calculateIn().
+    void run() {
+      init();
+      calculateOut();
+      calculateIn();
+    }
+
+    /// \brief Runs the algorithm.
+    ///
+    /// Runs the algorithm. It uses the given \c source node, finds a
+    /// proper \c target and then calls the \ref init(), \ref
+    /// calculateOut() and \ref calculateIn().
+    void run(const Node& s) {
+      init(s);
+      calculateOut();
+      calculateIn();
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The result of the %HaoOrlin algorithm
+    /// can be obtained using these functions.
+    /// \n
+    /// Before using these functions, either \ref run(), \ref
+    /// calculateOut() or \ref calculateIn() must be called.
+
+    /// @{
+
+    /// \brief Returns the value of the minimum value cut.
+    ///
+    /// Returns the value of the minimum value cut.
+    Value minCutValue() const {
+      return _min_cut;
+    }
+
+
+    /// \brief Returns a minimum cut.
+    ///
+    /// Sets \c nodeMap to the characteristic vector of a minimum
+    /// value cut: it will give a nonempty set \f$ X\subsetneq V \f$
+    /// with minimal out-degree (i.e. \c nodeMap will be true exactly
+    /// for the nodes of \f$ X \f$).  \pre nodeMap should be a
+    /// bool-valued node-map.
+    template <typename NodeMap>
+    Value minCutMap(NodeMap& nodeMap) const {
+      for (NodeIt it(_graph); it != INVALID; ++it) {
+        nodeMap.set(it, (*_min_cut_map)[it]);
+      }
+      return _min_cut;
+    }
+
+    /// @}
+
+  }; //class HaoOrlin
+
+
+} //namespace lemon
+
+#endif //LEMON_HAO_ORLIN_H
Index: lemon/hypercube_graph.h
===================================================================
--- lemon/hypercube_graph.h	(revision 440)
+++ lemon/hypercube_graph.h	(revision 440)
@@ -0,0 +1,440 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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 HYPERCUBE_GRAPH_H
+#define HYPERCUBE_GRAPH_H
+
+#include <vector>
+#include <lemon/core.h>
+#include <lemon/assert.h>
+#include <lemon/bits/graph_extender.h>
+
+///\ingroup graphs
+///\file
+///\brief HypercubeGraph class.
+
+namespace lemon {
+
+  class HypercubeGraphBase {
+
+  public:
+
+    typedef HypercubeGraphBase Graph;
+
+    class Node;
+    class Edge;
+    class Arc;
+
+  public:
+
+    HypercubeGraphBase() {}
+
+  protected:
+
+    void construct(int dim) {
+      LEMON_ASSERT(dim >= 1, "The number of dimensions must be at least 1.");
+      _dim = dim;
+      _node_num = 1 << dim;
+      _edge_num = dim * (1 << (dim-1));
+    }
+
+  public:
+
+    typedef True NodeNumTag;
+    typedef True EdgeNumTag;
+    typedef True ArcNumTag;
+
+    int nodeNum() const { return _node_num; }
+    int edgeNum() const { return _edge_num; }
+    int arcNum() const { return 2 * _edge_num; }
+
+    int maxNodeId() const { return _node_num - 1; }
+    int maxEdgeId() const { return _edge_num - 1; }
+    int maxArcId() const { return 2 * _edge_num - 1; }
+
+    static Node nodeFromId(int id) { return Node(id); }
+    static Edge edgeFromId(int id) { return Edge(id); }
+    static Arc arcFromId(int id) { return Arc(id); }
+
+    static int id(Node node) { return node._id; }
+    static int id(Edge edge) { return edge._id; }
+    static int id(Arc arc) { return arc._id; }
+
+    Node u(Edge edge) const {
+      int base = edge._id & ((1 << (_dim-1)) - 1);
+      int k = edge._id >> (_dim-1);
+      return ((base >> k) << (k+1)) | (base & ((1 << k) - 1));
+    }
+
+    Node v(Edge edge) const {
+      int base = edge._id & ((1 << (_dim-1)) - 1);
+      int k = edge._id >> (_dim-1);
+      return ((base >> k) << (k+1)) | (base & ((1 << k) - 1)) | (1 << k);
+    }
+
+    Node source(Arc arc) const {
+      return (arc._id & 1) == 1 ? u(arc) : v(arc);
+    }
+
+    Node target(Arc arc) const {
+      return (arc._id & 1) == 1 ? v(arc) : u(arc);
+    }
+
+    typedef True FindEdgeTag;
+    typedef True FindArcTag;
+
+    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
+      if (prev != INVALID) return INVALID;
+      int d = u._id ^ v._id;
+      int k = 0;
+      if (d == 0) return INVALID;
+      for ( ; (d & 1) == 0; d >>= 1) ++k;
+      if (d >> 1 != 0) return INVALID;
+      return (k << (_dim-1)) | ((u._id >> (k+1)) << k) |
+        (u._id & ((1 << k) - 1));
+    }
+
+    Arc findArc(Node u, Node v, Arc prev = INVALID) const {
+      Edge edge = findEdge(u, v, prev);
+      if (edge == INVALID) return INVALID;
+      int k = edge._id >> (_dim-1);
+      return ((u._id >> k) & 1) == 1 ? edge._id << 1 : (edge._id << 1) | 1;
+    }
+
+    class Node {
+      friend class HypercubeGraphBase;
+
+    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 Edge {
+      friend class HypercubeGraphBase;
+      friend class Arc;
+
+    protected:
+      int _id;
+
+      Edge(int id) : _id(id) {}
+
+    public:
+      Edge() {}
+      Edge (Invalid) : _id(-1) {}
+      bool operator==(const Edge edge) const {return _id == edge._id;}
+      bool operator!=(const Edge edge) const {return _id != edge._id;}
+      bool operator<(const Edge edge) const {return _id < edge._id;}
+    };
+
+    class Arc {
+      friend class HypercubeGraphBase;
+
+    protected:
+      int _id;
+
+      Arc(int id) : _id(id) {}
+
+    public:
+      Arc() {}
+      Arc (Invalid) : _id(-1) {}
+      operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; }
+      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;}
+    };
+
+    void first(Node& node) const {
+      node._id = _node_num - 1;
+    }
+
+    static void next(Node& node) {
+      --node._id;
+    }
+
+    void first(Edge& edge) const {
+      edge._id = _edge_num - 1;
+    }
+
+    static void next(Edge& edge) {
+      --edge._id;
+    }
+
+    void first(Arc& arc) const {
+      arc._id = 2 * _edge_num - 1;
+    }
+
+    static void next(Arc& arc) {
+      --arc._id;
+    }
+
+    void firstInc(Edge& edge, bool& dir, const Node& node) const {
+      edge._id = node._id >> 1;
+      dir = (node._id & 1) == 0;
+    }
+
+    void nextInc(Edge& edge, bool& dir) const {
+      Node n = dir ? u(edge) : v(edge);
+      int k = (edge._id >> (_dim-1)) + 1;
+      if (k < _dim) {
+        edge._id = (k << (_dim-1)) |
+          ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
+        dir = ((n._id >> k) & 1) == 0;
+      } else {
+        edge._id = -1;
+        dir = true;
+      }
+    }
+
+    void firstOut(Arc& arc, const Node& node) const {
+      arc._id = ((node._id >> 1) << 1) | (~node._id & 1);
+    }
+
+    void nextOut(Arc& arc) const {
+      Node n = (arc._id & 1) == 1 ? u(arc) : v(arc);
+      int k = (arc._id >> _dim) + 1;
+      if (k < _dim) {
+        arc._id = (k << (_dim-1)) |
+          ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
+        arc._id = (arc._id << 1) | (~(n._id >> k) & 1);
+      } else {
+        arc._id = -1;
+      }
+    }
+
+    void firstIn(Arc& arc, const Node& node) const {
+      arc._id = ((node._id >> 1) << 1) | (node._id & 1);
+    }
+
+    void nextIn(Arc& arc) const {
+      Node n = (arc._id & 1) == 1 ? v(arc) : u(arc);
+      int k = (arc._id >> _dim) + 1;
+      if (k < _dim) {
+        arc._id = (k << (_dim-1)) |
+          ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
+        arc._id = (arc._id << 1) | ((n._id >> k) & 1);
+      } else {
+        arc._id = -1;
+      }
+    }
+
+    static bool direction(Arc arc) {
+      return (arc._id & 1) == 1;
+    }
+
+    static Arc direct(Edge edge, bool dir) {
+      return Arc((edge._id << 1) | (dir ? 1 : 0));
+    }
+
+    int dimension() const {
+      return _dim;
+    }
+
+    bool projection(Node node, int n) const {
+      return static_cast<bool>(node._id & (1 << n));
+    }
+
+    int dimension(Edge edge) const {
+      return edge._id >> (_dim-1);
+    }
+
+    int dimension(Arc arc) const {
+      return arc._id >> _dim;
+    }
+
+    int index(Node node) const {
+      return node._id;
+    }
+
+    Node operator()(int ix) const {
+      return Node(ix);
+    }
+
+  private:
+    int _dim;
+    int _node_num, _edge_num;
+  };
+
+
+  typedef GraphExtender<HypercubeGraphBase> ExtendedHypercubeGraphBase;
+
+  /// \ingroup graphs
+  ///
+  /// \brief Hypercube graph class
+  ///
+  /// This class implements a special graph type. The nodes of the graph
+  /// are indiced with integers with at most \c dim binary digits.
+  /// Two nodes are connected in the graph if and only if their indices
+  /// differ only on one position in the binary form.
+  ///
+  /// \note The type of the indices is chosen to \c int for efficiency
+  /// reasons. Thus the maximum dimension of this implementation is 26
+  /// (assuming that the size of \c int is 32 bit).
+  ///
+  /// This graph type is fully conform to the \ref concepts::Graph
+  /// "Graph" concept, and it also has an important extra feature
+  /// that its maps are real \ref concepts::ReferenceMap
+  /// "reference map"s.
+  class HypercubeGraph : public ExtendedHypercubeGraphBase {
+  public:
+
+    typedef ExtendedHypercubeGraphBase Parent;
+
+    /// \brief Constructs a hypercube graph with \c dim dimensions.
+    ///
+    /// Constructs a hypercube graph with \c dim dimensions.
+    HypercubeGraph(int dim) { construct(dim); }
+
+    /// \brief The number of dimensions.
+    ///
+    /// Gives back the number of dimensions.
+    int dimension() const {
+      return Parent::dimension();
+    }
+
+    /// \brief Returns \c true if the n'th bit of the node is one.
+    ///
+    /// Returns \c true if the n'th bit of the node is one.
+    bool projection(Node node, int n) const {
+      return Parent::projection(node, n);
+    }
+
+    /// \brief The dimension id of an edge.
+    ///
+    /// Gives back the dimension id of the given edge.
+    /// It is in the [0..dim-1] range.
+    int dimension(Edge edge) const {
+      return Parent::dimension(edge);
+    }
+
+    /// \brief The dimension id of an arc.
+    ///
+    /// Gives back the dimension id of the given arc.
+    /// It is in the [0..dim-1] range.
+    int dimension(Arc arc) const {
+      return Parent::dimension(arc);
+    }
+
+    /// \brief The index of a node.
+    ///
+    /// Gives back the index of the given node.
+    /// The lower bits of the integer describes the node.
+    int index(Node node) const {
+      return Parent::index(node);
+    }
+
+    /// \brief Gives back a node by its index.
+    ///
+    /// Gives back a node by its index.
+    Node operator()(int ix) const {
+      return Parent::operator()(ix);
+    }
+
+    /// \brief Number of nodes.
+    int nodeNum() const { return Parent::nodeNum(); }
+    /// \brief Number of edges.
+    int edgeNum() const { return Parent::edgeNum(); }
+    /// \brief Number of arcs.
+    int arcNum() const { return Parent::arcNum(); }
+
+    /// \brief Linear combination map.
+    ///
+    /// This map makes possible to give back a linear combination
+    /// for each node. It works like the \c std::accumulate function,
+    /// so it accumulates the \c bf binary function with the \c fv first
+    /// value. The map accumulates only on that positions (dimensions)
+    /// where the index of the node is one. The values that have to be
+    /// accumulated should be given by the \c begin and \c end iterators
+    /// and the length of this range should be equal to the dimension
+    /// number of the graph.
+    ///
+    ///\code
+    /// const int DIM = 3;
+    /// HypercubeGraph graph(DIM);
+    /// dim2::Point<double> base[DIM];
+    /// for (int k = 0; k < DIM; ++k) {
+    ///   base[k].x = rnd();
+    ///   base[k].y = rnd();
+    /// }
+    /// HypercubeGraph::HyperMap<dim2::Point<double> >
+    ///   pos(graph, base, base + DIM, dim2::Point<double>(0.0, 0.0));
+    ///\endcode
+    ///
+    /// \see HypercubeGraph
+    template <typename T, typename BF = std::plus<T> >
+    class HyperMap {
+    public:
+
+      /// \brief The key type of the map
+      typedef Node Key;
+      /// \brief The value type of the map
+      typedef T Value;
+
+      /// \brief Constructor for HyperMap.
+      ///
+      /// Construct a HyperMap for the given graph. The values that have
+      /// to be accumulated should be given by the \c begin and \c end
+      /// iterators and the length of this range should be equal to the
+      /// dimension number of the graph.
+      ///
+      /// This map accumulates the \c bf binary function with the \c fv
+      /// first value on that positions (dimensions) where the index of
+      /// the node is one.
+      template <typename It>
+      HyperMap(const Graph& graph, It begin, It end,
+               T fv = 0, const BF& bf = BF())
+        : _graph(graph), _values(begin, end), _first_value(fv), _bin_func(bf)
+      {
+        LEMON_ASSERT(_values.size() == graph.dimension(),
+                     "Wrong size of range");
+      }
+
+      /// \brief The partial accumulated value.
+      ///
+      /// Gives back the partial accumulated value.
+      Value operator[](const Key& k) const {
+        Value val = _first_value;
+        int id = _graph.index(k);
+        int n = 0;
+        while (id != 0) {
+          if (id & 1) {
+            val = _bin_func(val, _values[n]);
+          }
+          id >>= 1;
+          ++n;
+        }
+        return val;
+      }
+
+    private:
+      const Graph& _graph;
+      std::vector<T> _values;
+      T _first_value;
+      BF _bin_func;
+    };
+
+  };
+
+}
+
+#endif
Index: lemon/kruskal.h
===================================================================
--- lemon/kruskal.h	(revision 220)
+++ lemon/kruskal.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/lgf_reader.h
===================================================================
--- lemon/lgf_reader.h	(revision 487)
+++ lemon/lgf_reader.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -391,11 +391,35 @@
   class DigraphReader;
 
+  /// \brief Return a \ref DigraphReader class
+  ///
+  /// This function just returns a \ref DigraphReader class.
+  /// \relates DigraphReader
   template <typename Digraph>
-  DigraphReader<Digraph> digraphReader(Digraph& digraph, 
-                                       std::istream& is = std::cin);
+  DigraphReader<Digraph> digraphReader(Digraph& digraph,
+                                       std::istream& is = std::cin) {
+    DigraphReader<Digraph> tmp(digraph, is);
+    return tmp;
+  }
+
+  /// \brief Return a \ref DigraphReader class
+  ///
+  /// This function just returns a \ref DigraphReader class.
+  /// \relates DigraphReader
   template <typename Digraph>
-  DigraphReader<Digraph> digraphReader(Digraph& digraph, const std::string& fn);
+  DigraphReader<Digraph> digraphReader(Digraph& digraph,
+                                       const std::string& fn) {
+    DigraphReader<Digraph> tmp(digraph, fn);
+    return tmp;
+  }
+
+  /// \brief Return a \ref DigraphReader class
+  ///
+  /// This function just returns a \ref DigraphReader class.
+  /// \relates DigraphReader
   template <typename Digraph>
-  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char *fn);
+  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char* fn) {
+    DigraphReader<Digraph> tmp(digraph, fn);
+    return tmp;
+  }
 
   /// \ingroup lemon_io
@@ -561,11 +585,10 @@
   private:
 
-    template <typename DGR>
-    friend DigraphReader<DGR> digraphReader(DGR& digraph, std::istream& is);
-    template <typename DGR>
-    friend DigraphReader<DGR> digraphReader(DGR& digraph, 
-                                            const std::string& fn);
-    template <typename DGR>
-    friend DigraphReader<DGR> digraphReader(DGR& digraph, const char *fn);
+    friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
+                                                  std::istream& is);
+    friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
+                                                  const std::string& fn);
+    friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
+                                                  const char *fn);
 
     DigraphReader(DigraphReader& other)
@@ -848,5 +871,7 @@
         readLine();
       }
-      line.putback(c);
+      if (readSuccess()) {
+        line.putback(c);
+      }
     }
 
@@ -1188,45 +1213,36 @@
   };
 
-  /// \brief Return a \ref DigraphReader class
+  template <typename Graph>
+  class GraphReader;
+
+  /// \brief Return a \ref GraphReader class
   ///
-  /// This function just returns a \ref DigraphReader class.
-  /// \relates DigraphReader
-  template <typename Digraph>
-  DigraphReader<Digraph> digraphReader(Digraph& digraph, std::istream& is) {
-    DigraphReader<Digraph> tmp(digraph, is);
+  /// This function just returns a \ref GraphReader class.
+  /// \relates GraphReader
+  template <typename Graph>
+  GraphReader<Graph> graphReader(Graph& graph, std::istream& is = std::cin) {
+    GraphReader<Graph> tmp(graph, is);
     return tmp;
   }
 
-  /// \brief Return a \ref DigraphReader class
+  /// \brief Return a \ref GraphReader class
   ///
-  /// This function just returns a \ref DigraphReader class.
-  /// \relates DigraphReader
-  template <typename Digraph>
-  DigraphReader<Digraph> digraphReader(Digraph& digraph,
-                                       const std::string& fn) {
-    DigraphReader<Digraph> tmp(digraph, fn);
+  /// This function just returns a \ref GraphReader class.
+  /// \relates GraphReader
+  template <typename Graph>
+  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn) {
+    GraphReader<Graph> tmp(graph, fn);
     return tmp;
   }
 
-  /// \brief Return a \ref DigraphReader class
+  /// \brief Return a \ref GraphReader class
   ///
-  /// This function just returns a \ref DigraphReader class.
-  /// \relates DigraphReader
-  template <typename Digraph>
-  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char* fn) {
-    DigraphReader<Digraph> tmp(digraph, fn);
+  /// This function just returns a \ref GraphReader class.
+  /// \relates GraphReader
+  template <typename Graph>
+  GraphReader<Graph> graphReader(Graph& graph, const char* fn) {
+    GraphReader<Graph> tmp(graph, fn);
     return tmp;
   }
-
-  template <typename Graph>
-  class GraphReader;
- 
-  template <typename Graph>
-  GraphReader<Graph> graphReader(Graph& graph, 
-                                 std::istream& is = std::cin);
-  template <typename Graph>
-  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn);
-  template <typename Graph>
-  GraphReader<Graph> graphReader(Graph& graph, const char *fn);
 
   /// \ingroup lemon_io
@@ -1355,10 +1371,8 @@
 
   private:
-    template <typename GR>
-    friend GraphReader<GR> graphReader(GR& graph, std::istream& is);
-    template <typename GR>
-    friend GraphReader<GR> graphReader(GR& graph, const std::string& fn); 
-    template <typename GR>
-    friend GraphReader<GR> graphReader(GR& graph, const char *fn);
+    friend GraphReader<Graph> graphReader<>(Graph& graph, std::istream& is);
+    friend GraphReader<Graph> graphReader<>(Graph& graph,
+                                            const std::string& fn);
+    friend GraphReader<Graph> graphReader<>(Graph& graph, const char *fn);
 
     GraphReader(GraphReader& other)
@@ -1688,5 +1702,7 @@
         readLine();
       }
-      line.putback(c);
+      if (readSuccess()) {
+        line.putback(c);
+      }
     }
 
@@ -2029,34 +2045,4 @@
   };
 
-  /// \brief Return a \ref GraphReader class
-  ///
-  /// This function just returns a \ref GraphReader class.
-  /// \relates GraphReader
-  template <typename Graph>
-  GraphReader<Graph> graphReader(Graph& graph, std::istream& is) {
-    GraphReader<Graph> tmp(graph, is);
-    return tmp;
-  }
-
-  /// \brief Return a \ref GraphReader class
-  ///
-  /// This function just returns a \ref GraphReader class.
-  /// \relates GraphReader
-  template <typename Graph>
-  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn) {
-    GraphReader<Graph> tmp(graph, fn);
-    return tmp;
-  }
-
-  /// \brief Return a \ref GraphReader class
-  ///
-  /// This function just returns a \ref GraphReader class.
-  /// \relates GraphReader
-  template <typename Graph>
-  GraphReader<Graph> graphReader(Graph& graph, const char* fn) {
-    GraphReader<Graph> tmp(graph, fn);
-    return tmp;
-  }
-
   class SectionReader;
 
@@ -2245,5 +2231,7 @@
         readLine();
       }
-      line.putback(c);
+      if (readSuccess()) {
+        line.putback(c);
+      }
     }
 
@@ -2586,5 +2574,7 @@
         readLine();
       }
-      line.putback(c);
+      if (readSuccess()) {
+        line.putback(c);
+      }
     }
 
Index: lemon/lgf_writer.h
===================================================================
--- lemon/lgf_writer.h	(revision 487)
+++ lemon/lgf_writer.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -351,15 +351,36 @@
   class DigraphWriter;
 
+  /// \brief Return a \ref DigraphWriter class
+  ///
+  /// This function just returns a \ref DigraphWriter class.
+  /// \relates DigraphWriter
   template <typename Digraph>
   DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
-                                       std::ostream& os = std::cout);
+                                       std::ostream& os = std::cout) {
+    DigraphWriter<Digraph> tmp(digraph, os);
+    return tmp;
+  }
+
+  /// \brief Return a \ref DigraphWriter class
+  ///
+  /// This function just returns a \ref DigraphWriter class.
+  /// \relates DigraphWriter
   template <typename Digraph>
   DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
-                                       const std::string& fn);
-
+                                       const std::string& fn) {
+    DigraphWriter<Digraph> tmp(digraph, fn);
+    return tmp;
+  }
+
+  /// \brief Return a \ref DigraphWriter class
+  ///
+  /// This function just returns a \ref DigraphWriter class.
+  /// \relates DigraphWriter
   template <typename Digraph>
   DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
-                                       const char* fn);
-
+                                       const char* fn) {
+    DigraphWriter<Digraph> tmp(digraph, fn);
+    return tmp;
+  }
 
   /// \ingroup lemon_io
@@ -506,13 +527,10 @@
   private:
 
-    template <typename DGR>
-    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph, 
-                                            std::ostream& os);
-    template <typename DGR>
-    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
-                                            const std::string& fn);
-    template <typename DGR>
-    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
-                                            const char *fn);
+    friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
+                                                  std::ostream& os);
+    friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
+                                                  const std::string& fn);
+    friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
+                                                  const char *fn);
 
     DigraphWriter(DigraphWriter& other)
@@ -916,47 +934,37 @@
   };
 
-  /// \brief Return a \ref DigraphWriter class
-  ///
-  /// This function just returns a \ref DigraphWriter class.
-  /// \relates DigraphWriter
-  template <typename Digraph>
-  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
-                                       std::ostream& os) {
-    DigraphWriter<Digraph> tmp(digraph, os);
+  template <typename Graph>
+  class GraphWriter;
+
+  /// \brief Return a \ref GraphWriter class
+  ///
+  /// This function just returns a \ref GraphWriter class.
+  /// \relates GraphWriter
+  template <typename Graph>
+  GraphWriter<Graph> graphWriter(const Graph& graph,
+                                 std::ostream& os = std::cout) {
+    GraphWriter<Graph> tmp(graph, os);
     return tmp;
   }
 
-  /// \brief Return a \ref DigraphWriter class
-  ///
-  /// This function just returns a \ref DigraphWriter class.
-  /// \relates DigraphWriter
-  template <typename Digraph>
-  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
-                                       const std::string& fn) {
-    DigraphWriter<Digraph> tmp(digraph, fn);
+  /// \brief Return a \ref GraphWriter class
+  ///
+  /// This function just returns a \ref GraphWriter class.
+  /// \relates GraphWriter
+  template <typename Graph>
+  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn) {
+    GraphWriter<Graph> tmp(graph, fn);
     return tmp;
   }
 
-  /// \brief Return a \ref DigraphWriter class
-  ///
-  /// This function just returns a \ref DigraphWriter class.
-  /// \relates DigraphWriter
-  template <typename Digraph>
-  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
-                                       const char* fn) {
-    DigraphWriter<Digraph> tmp(digraph, fn);
+  /// \brief Return a \ref GraphWriter class
+  ///
+  /// This function just returns a \ref GraphWriter class.
+  /// \relates GraphWriter
+  template <typename Graph>
+  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn) {
+    GraphWriter<Graph> tmp(graph, fn);
     return tmp;
   }
-
-  template <typename Graph>
-  class GraphWriter;
-
-  template <typename Graph>
-  GraphWriter<Graph> graphWriter(const Graph& graph,
-                                 std::ostream& os = std::cout);
-  template <typename Graph>
-  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn);
-  template <typename Graph>
-  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn);
 
   /// \ingroup lemon_io
@@ -1074,14 +1082,11 @@
   private:
 
-    template <typename GR>
-    friend GraphWriter<GR> graphWriter(const GR& graph,
-                                       std::ostream& os);
-    template <typename GR>
-    friend GraphWriter<GR> graphWriter(const GR& graph,
-                                       const std::string& fn);
-    template <typename GR>
-    friend GraphWriter<GR> graphWriter(const GR& graph,
-                                       const char *fn);
-    
+    friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
+                                            std::ostream& os);
+    friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
+                                            const std::string& fn);
+    friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
+                                            const char *fn);
+
     GraphWriter(GraphWriter& other)
       : _os(other._os), local_os(other.local_os), _graph(other._graph),
@@ -1529,35 +1534,4 @@
     /// @}
   };
-
-  /// \brief Return a \ref GraphWriter class
-  ///
-  /// This function just returns a \ref GraphWriter class.
-  /// \relates GraphWriter
-  template <typename Graph>
-  GraphWriter<Graph> graphWriter(const Graph& graph,
-                                 std::ostream& os) {
-    GraphWriter<Graph> tmp(graph, os);
-    return tmp;
-  }
-
-  /// \brief Return a \ref GraphWriter class
-  ///
-  /// This function just returns a \ref GraphWriter class.
-  /// \relates GraphWriter
-  template <typename Graph>
-  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn) {
-    GraphWriter<Graph> tmp(graph, fn);
-    return tmp;
-  }
-
-  /// \brief Return a \ref GraphWriter class
-  ///
-  /// This function just returns a \ref GraphWriter class.
-  /// \relates GraphWriter
-  template <typename Graph>
-  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn) {
-    GraphWriter<Graph> tmp(graph, fn);
-    return tmp;
-  }
 
   class SectionWriter;
Index: lemon/list_graph.h
===================================================================
--- lemon/list_graph.h	(revision 313)
+++ lemon/list_graph.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -841,6 +841,6 @@
 
     public:
-      operator Edge() const { 
-        return id != -1 ? edgeFromId(id / 2) : INVALID; 
+      operator Edge() const {
+        return id != -1 ? edgeFromId(id / 2) : INVALID;
       }
 
Index: lemon/maps.h
===================================================================
--- lemon/maps.h	(revision 314)
+++ lemon/maps.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/math.h
===================================================================
--- lemon/math.h	(revision 209)
+++ lemon/math.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/max_matching.h
===================================================================
--- lemon/max_matching.h	(revision 440)
+++ lemon/max_matching.h	(revision 440)
@@ -0,0 +1,3104 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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_MAX_MATCHING_H
+#define LEMON_MAX_MATCHING_H
+
+#include <vector>
+#include <queue>
+#include <set>
+#include <limits>
+
+#include <lemon/core.h>
+#include <lemon/unionfind.h>
+#include <lemon/bin_heap.h>
+#include <lemon/maps.h>
+
+///\ingroup matching
+///\file
+///\brief Maximum matching algorithms in general graphs.
+
+namespace lemon {
+
+  /// \ingroup matching
+  ///
+  /// \brief Edmonds' alternating forest maximum matching algorithm.
+  ///
+  /// This class implements Edmonds' alternating forest matching
+  /// algorithm. The algorithm can be started from an arbitrary initial
+  /// matching (the default is the empty one)
+  ///
+  /// The dual solution of the problem is a map of the nodes to
+  /// MaxMatching::Status, having values \c EVEN/D, \c ODD/A and \c
+  /// MATCHED/C showing the Gallai-Edmonds decomposition of the
+  /// graph. The nodes in \c EVEN/D induce a graph with
+  /// factor-critical components, the nodes in \c ODD/A form the
+  /// barrier, and the nodes in \c MATCHED/C induce a graph having a
+  /// perfect matching. The number of the factor-critical components
+  /// minus the number of barrier nodes is a lower bound on the
+  /// unmatched nodes, and the matching is optimal if and only if this bound is
+  /// tight. This decomposition can be attained by calling \c
+  /// decomposition() after running the algorithm.
+  ///
+  /// \param _Graph The graph type the algorithm runs on.
+  template <typename _Graph>
+  class MaxMatching {
+  public:
+
+    typedef _Graph Graph;
+    typedef typename Graph::template NodeMap<typename Graph::Arc>
+    MatchingMap;
+
+    ///\brief Indicates the Gallai-Edmonds decomposition of the graph.
+    ///
+    ///Indicates the Gallai-Edmonds decomposition of the graph. The
+    ///nodes with Status \c EVEN/D induce a graph with factor-critical
+    ///components, the nodes in \c ODD/A form the canonical barrier,
+    ///and the nodes in \c MATCHED/C induce a graph having a perfect
+    ///matching.
+    enum Status {
+      EVEN = 1, D = 1, MATCHED = 0, C = 0, ODD = -1, A = -1, UNMATCHED = -2
+    };
+
+    typedef typename Graph::template NodeMap<Status> StatusMap;
+
+  private:
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    typedef UnionFindEnum<IntNodeMap> BlossomSet;
+    typedef ExtendFindEnum<IntNodeMap> TreeSet;
+    typedef RangeMap<Node> NodeIntMap;
+    typedef MatchingMap EarMap;
+    typedef std::vector<Node> NodeQueue;
+
+    const Graph& _graph;
+    MatchingMap* _matching;
+    StatusMap* _status;
+
+    EarMap* _ear;
+
+    IntNodeMap* _blossom_set_index;
+    BlossomSet* _blossom_set;
+    NodeIntMap* _blossom_rep;
+
+    IntNodeMap* _tree_set_index;
+    TreeSet* _tree_set;
+
+    NodeQueue _node_queue;
+    int _process, _postpone, _last;
+
+    int _node_num;
+
+  private:
+
+    void createStructures() {
+      _node_num = countNodes(_graph);
+      if (!_matching) {
+        _matching = new MatchingMap(_graph);
+      }
+      if (!_status) {
+        _status = new StatusMap(_graph);
+      }
+      if (!_ear) {
+        _ear = new EarMap(_graph);
+      }
+      if (!_blossom_set) {
+        _blossom_set_index = new IntNodeMap(_graph);
+        _blossom_set = new BlossomSet(*_blossom_set_index);
+      }
+      if (!_blossom_rep) {
+        _blossom_rep = new NodeIntMap(_node_num);
+      }
+      if (!_tree_set) {
+        _tree_set_index = new IntNodeMap(_graph);
+        _tree_set = new TreeSet(*_tree_set_index);
+      }
+      _node_queue.resize(_node_num);
+    }
+
+    void destroyStructures() {
+      if (_matching) {
+        delete _matching;
+      }
+      if (_status) {
+        delete _status;
+      }
+      if (_ear) {
+        delete _ear;
+      }
+      if (_blossom_set) {
+        delete _blossom_set;
+        delete _blossom_set_index;
+      }
+      if (_blossom_rep) {
+        delete _blossom_rep;
+      }
+      if (_tree_set) {
+        delete _tree_set_index;
+        delete _tree_set;
+      }
+    }
+
+    void processDense(const Node& n) {
+      _process = _postpone = _last = 0;
+      _node_queue[_last++] = n;
+
+      while (_process != _last) {
+        Node u = _node_queue[_process++];
+        for (OutArcIt a(_graph, u); a != INVALID; ++a) {
+          Node v = _graph.target(a);
+          if ((*_status)[v] == MATCHED) {
+            extendOnArc(a);
+          } else if ((*_status)[v] == UNMATCHED) {
+            augmentOnArc(a);
+            return;
+          }
+        }
+      }
+
+      while (_postpone != _last) {
+        Node u = _node_queue[_postpone++];
+
+        for (OutArcIt a(_graph, u); a != INVALID ; ++a) {
+          Node v = _graph.target(a);
+
+          if ((*_status)[v] == EVEN) {
+            if (_blossom_set->find(u) != _blossom_set->find(v)) {
+              shrinkOnEdge(a);
+            }
+          }
+
+          while (_process != _last) {
+            Node w = _node_queue[_process++];
+            for (OutArcIt b(_graph, w); b != INVALID; ++b) {
+              Node x = _graph.target(b);
+              if ((*_status)[x] == MATCHED) {
+                extendOnArc(b);
+              } else if ((*_status)[x] == UNMATCHED) {
+                augmentOnArc(b);
+                return;
+              }
+            }
+          }
+        }
+      }
+    }
+
+    void processSparse(const Node& n) {
+      _process = _last = 0;
+      _node_queue[_last++] = n;
+      while (_process != _last) {
+        Node u = _node_queue[_process++];
+        for (OutArcIt a(_graph, u); a != INVALID; ++a) {
+          Node v = _graph.target(a);
+
+          if ((*_status)[v] == EVEN) {
+            if (_blossom_set->find(u) != _blossom_set->find(v)) {
+              shrinkOnEdge(a);
+            }
+          } else if ((*_status)[v] == MATCHED) {
+            extendOnArc(a);
+          } else if ((*_status)[v] == UNMATCHED) {
+            augmentOnArc(a);
+            return;
+          }
+        }
+      }
+    }
+
+    void shrinkOnEdge(const Edge& e) {
+      Node nca = INVALID;
+
+      {
+        std::set<Node> left_set, right_set;
+
+        Node left = (*_blossom_rep)[_blossom_set->find(_graph.u(e))];
+        left_set.insert(left);
+
+        Node right = (*_blossom_rep)[_blossom_set->find(_graph.v(e))];
+        right_set.insert(right);
+
+        while (true) {
+          if ((*_matching)[left] == INVALID) break;
+          left = _graph.target((*_matching)[left]);
+          left = (*_blossom_rep)[_blossom_set->
+                                 find(_graph.target((*_ear)[left]))];
+          if (right_set.find(left) != right_set.end()) {
+            nca = left;
+            break;
+          }
+          left_set.insert(left);
+
+          if ((*_matching)[right] == INVALID) break;
+          right = _graph.target((*_matching)[right]);
+          right = (*_blossom_rep)[_blossom_set->
+                                  find(_graph.target((*_ear)[right]))];
+          if (left_set.find(right) != left_set.end()) {
+            nca = right;
+            break;
+          }
+          right_set.insert(right);
+        }
+
+        if (nca == INVALID) {
+          if ((*_matching)[left] == INVALID) {
+            nca = right;
+            while (left_set.find(nca) == left_set.end()) {
+              nca = _graph.target((*_matching)[nca]);
+              nca =(*_blossom_rep)[_blossom_set->
+                                   find(_graph.target((*_ear)[nca]))];
+            }
+          } else {
+            nca = left;
+            while (right_set.find(nca) == right_set.end()) {
+              nca = _graph.target((*_matching)[nca]);
+              nca = (*_blossom_rep)[_blossom_set->
+                                   find(_graph.target((*_ear)[nca]))];
+            }
+          }
+        }
+      }
+
+      {
+
+        Node node = _graph.u(e);
+        Arc arc = _graph.direct(e, true);
+        Node base = (*_blossom_rep)[_blossom_set->find(node)];
+
+        while (base != nca) {
+          _ear->set(node, arc);
+
+          Node n = node;
+          while (n != base) {
+            n = _graph.target((*_matching)[n]);
+            Arc a = (*_ear)[n];
+            n = _graph.target(a);
+            _ear->set(n, _graph.oppositeArc(a));
+          }
+          node = _graph.target((*_matching)[base]);
+          _tree_set->erase(base);
+          _tree_set->erase(node);
+          _blossom_set->insert(node, _blossom_set->find(base));
+          _status->set(node, EVEN);
+          _node_queue[_last++] = node;
+          arc = _graph.oppositeArc((*_ear)[node]);
+          node = _graph.target((*_ear)[node]);
+          base = (*_blossom_rep)[_blossom_set->find(node)];
+          _blossom_set->join(_graph.target(arc), base);
+        }
+      }
+
+      _blossom_rep->set(_blossom_set->find(nca), nca);
+
+      {
+
+        Node node = _graph.v(e);
+        Arc arc = _graph.direct(e, false);
+        Node base = (*_blossom_rep)[_blossom_set->find(node)];
+
+        while (base != nca) {
+          _ear->set(node, arc);
+
+          Node n = node;
+          while (n != base) {
+            n = _graph.target((*_matching)[n]);
+            Arc a = (*_ear)[n];
+            n = _graph.target(a);
+            _ear->set(n, _graph.oppositeArc(a));
+          }
+          node = _graph.target((*_matching)[base]);
+          _tree_set->erase(base);
+          _tree_set->erase(node);
+          _blossom_set->insert(node, _blossom_set->find(base));
+          _status->set(node, EVEN);
+          _node_queue[_last++] = node;
+          arc = _graph.oppositeArc((*_ear)[node]);
+          node = _graph.target((*_ear)[node]);
+          base = (*_blossom_rep)[_blossom_set->find(node)];
+          _blossom_set->join(_graph.target(arc), base);
+        }
+      }
+
+      _blossom_rep->set(_blossom_set->find(nca), nca);
+    }
+
+
+
+    void extendOnArc(const Arc& a) {
+      Node base = _graph.source(a);
+      Node odd = _graph.target(a);
+
+      _ear->set(odd, _graph.oppositeArc(a));
+      Node even = _graph.target((*_matching)[odd]);
+      _blossom_rep->set(_blossom_set->insert(even), even);
+      _status->set(odd, ODD);
+      _status->set(even, EVEN);
+      int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(base)]);
+      _tree_set->insert(odd, tree);
+      _tree_set->insert(even, tree);
+      _node_queue[_last++] = even;
+
+    }
+
+    void augmentOnArc(const Arc& a) {
+      Node even = _graph.source(a);
+      Node odd = _graph.target(a);
+
+      int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(even)]);
+
+      _matching->set(odd, _graph.oppositeArc(a));
+      _status->set(odd, MATCHED);
+
+      Arc arc = (*_matching)[even];
+      _matching->set(even, a);
+
+      while (arc != INVALID) {
+        odd = _graph.target(arc);
+        arc = (*_ear)[odd];
+        even = _graph.target(arc);
+        _matching->set(odd, arc);
+        arc = (*_matching)[even];
+        _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
+      }
+
+      for (typename TreeSet::ItemIt it(*_tree_set, tree);
+           it != INVALID; ++it) {
+        if ((*_status)[it] == ODD) {
+          _status->set(it, MATCHED);
+        } else {
+          int blossom = _blossom_set->find(it);
+          for (typename BlossomSet::ItemIt jt(*_blossom_set, blossom);
+               jt != INVALID; ++jt) {
+            _status->set(jt, MATCHED);
+          }
+          _blossom_set->eraseClass(blossom);
+        }
+      }
+      _tree_set->eraseClass(tree);
+
+    }
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    MaxMatching(const Graph& graph)
+      : _graph(graph), _matching(0), _status(0), _ear(0),
+        _blossom_set_index(0), _blossom_set(0), _blossom_rep(0),
+        _tree_set_index(0), _tree_set(0) {}
+
+    ~MaxMatching() {
+      destroyStructures();
+    }
+
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to use the
+    /// \c run() member function.
+    /// \n
+
+    /// If you need better control on the execution, you must call
+    /// \ref init(), \ref greedyInit() or \ref matchingInit()
+    /// functions first, then you can start the algorithm with the \ref
+    /// startSparse() or startDense() functions.
+
+    ///@{
+
+    /// \brief Sets the actual matching to the empty matching.
+    ///
+    /// Sets the actual matching to the empty matching.
+    ///
+    void init() {
+      createStructures();
+      for(NodeIt n(_graph); n != INVALID; ++n) {
+        _matching->set(n, INVALID);
+        _status->set(n, UNMATCHED);
+      }
+    }
+
+    ///\brief Finds an initial matching in a greedy way
+    ///
+    ///It finds an initial matching in a greedy way.
+    void greedyInit() {
+      createStructures();
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _matching->set(n, INVALID);
+        _status->set(n, UNMATCHED);
+      }
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] == INVALID) {
+          for (OutArcIt a(_graph, n); a != INVALID ; ++a) {
+            Node v = _graph.target(a);
+            if ((*_matching)[v] == INVALID && v != n) {
+              _matching->set(n, a);
+              _status->set(n, MATCHED);
+              _matching->set(v, _graph.oppositeArc(a));
+              _status->set(v, MATCHED);
+              break;
+            }
+          }
+        }
+      }
+    }
+
+
+    /// \brief Initialize the matching from a map containing.
+    ///
+    /// Initialize the matching from a \c bool valued \c Edge map. This
+    /// map must have the property that there are no two incident edges
+    /// with true value, ie. it contains a matching.
+    /// \return %True if the map contains a matching.
+    template <typename MatchingMap>
+    bool matchingInit(const MatchingMap& matching) {
+      createStructures();
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _matching->set(n, INVALID);
+        _status->set(n, UNMATCHED);
+      }
+      for(EdgeIt e(_graph); e!=INVALID; ++e) {
+        if (matching[e]) {
+
+          Node u = _graph.u(e);
+          if ((*_matching)[u] != INVALID) return false;
+          _matching->set(u, _graph.direct(e, true));
+          _status->set(u, MATCHED);
+
+          Node v = _graph.v(e);
+          if ((*_matching)[v] != INVALID) return false;
+          _matching->set(v, _graph.direct(e, false));
+          _status->set(v, MATCHED);
+        }
+      }
+      return true;
+    }
+
+    /// \brief Starts Edmonds' algorithm
+    ///
+    /// If runs the original Edmonds' algorithm.
+    void startSparse() {
+      for(NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_status)[n] == UNMATCHED) {
+          (*_blossom_rep)[_blossom_set->insert(n)] = n;
+          _tree_set->insert(n);
+          _status->set(n, EVEN);
+          processSparse(n);
+        }
+      }
+    }
+
+    /// \brief Starts Edmonds' algorithm.
+    ///
+    /// It runs Edmonds' algorithm with a heuristic of postponing
+    /// shrinks, therefore resulting in a faster algorithm for dense graphs.
+    void startDense() {
+      for(NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_status)[n] == UNMATCHED) {
+          (*_blossom_rep)[_blossom_set->insert(n)] = n;
+          _tree_set->insert(n);
+          _status->set(n, EVEN);
+          processDense(n);
+        }
+      }
+    }
+
+
+    /// \brief Runs Edmonds' algorithm
+    ///
+    /// Runs Edmonds' algorithm for sparse graphs (<tt>m<2*n</tt>)
+    /// or Edmonds' algorithm with a heuristic of
+    /// postponing shrinks for dense graphs.
+    void run() {
+      if (countEdges(_graph) < 2 * countNodes(_graph)) {
+        greedyInit();
+        startSparse();
+      } else {
+        init();
+        startDense();
+      }
+    }
+
+    /// @}
+
+    /// \name Primal solution
+    /// Functions to get the primal solution, ie. the matching.
+
+    /// @{
+
+    ///\brief Returns the size of the current matching.
+    ///
+    ///Returns the size of the current matching. After \ref
+    ///run() it returns the size of the maximum matching in the graph.
+    int matchingSize() const {
+      int size = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          ++size;
+        }
+      }
+      return size / 2;
+    }
+
+    /// \brief Returns true when the edge is in the matching.
+    ///
+    /// Returns true when the edge is in the matching.
+    bool matching(const Edge& edge) const {
+      return edge == (*_matching)[_graph.u(edge)];
+    }
+
+    /// \brief Returns the matching edge incident to the given node.
+    ///
+    /// Returns the matching edge of a \c node in the actual matching or
+    /// INVALID if the \c node is not covered by the actual matching.
+    Arc matching(const Node& n) const {
+      return (*_matching)[n];
+    }
+
+    ///\brief Returns the mate of a node in the actual matching.
+    ///
+    ///Returns the mate of a \c node in the actual matching or
+    ///INVALID if the \c node is not covered by the actual matching.
+    Node mate(const Node& n) const {
+      return (*_matching)[n] != INVALID ?
+        _graph.target((*_matching)[n]) : INVALID;
+    }
+
+    /// @}
+
+    /// \name Dual solution
+    /// Functions to get the dual solution, ie. the decomposition.
+
+    /// @{
+
+    /// \brief Returns the class of the node in the Edmonds-Gallai
+    /// decomposition.
+    ///
+    /// Returns the class of the node in the Edmonds-Gallai
+    /// decomposition.
+    Status decomposition(const Node& n) const {
+      return (*_status)[n];
+    }
+
+    /// \brief Returns true when the node is in the barrier.
+    ///
+    /// Returns true when the node is in the barrier.
+    bool barrier(const Node& n) const {
+      return (*_status)[n] == ODD;
+    }
+
+    /// @}
+
+  };
+
+  /// \ingroup matching
+  ///
+  /// \brief Weighted matching in general graphs
+  ///
+  /// This class provides an efficient implementation of Edmond's
+  /// maximum weighted matching algorithm. The implementation is based
+  /// on extensive use of priority queues and provides
+  /// \f$O(nm\log(n))\f$ time complexity.
+  ///
+  /// The maximum weighted matching problem is to find undirected
+  /// edges in the graph with maximum overall weight and no two of
+  /// them shares their ends. The problem can be formulated with the
+  /// following linear program.
+  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
+  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
+      \quad \forall B\in\mathcal{O}\f] */
+  /// \f[x_e \ge 0\quad \forall e\in E\f]
+  /// \f[\max \sum_{e\in E}x_ew_e\f]
+  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
+  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
+  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
+  /// subsets of the nodes.
+  ///
+  /// The algorithm calculates an optimal matching and a proof of the
+  /// optimality. The solution of the dual problem can be used to check
+  /// the result of the algorithm. The dual linear problem is the
+  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}
+      z_B \ge w_{uv} \quad \forall uv\in E\f] */
+  /// \f[y_u \ge 0 \quad \forall u \in V\f]
+  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
+  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
+      \frac{\vert B \vert - 1}{2}z_B\f] */
+  ///
+  /// The algorithm can be executed with \c run() or the \c init() and
+  /// then the \c start() member functions. After it the matching can
+  /// be asked with \c matching() or mate() functions. The dual
+  /// solution can be get with \c nodeValue(), \c blossomNum() and \c
+  /// blossomValue() members and \ref MaxWeightedMatching::BlossomIt
+  /// "BlossomIt" nested class, which is able to iterate on the nodes
+  /// of a blossom. If the value type is integral then the dual
+  /// solution is multiplied by \ref MaxWeightedMatching::dualScale "4".
+  template <typename _Graph,
+            typename _WeightMap = typename _Graph::template EdgeMap<int> >
+  class MaxWeightedMatching {
+  public:
+
+    typedef _Graph Graph;
+    typedef _WeightMap WeightMap;
+    typedef typename WeightMap::Value Value;
+
+    /// \brief Scaling factor for dual solution
+    ///
+    /// Scaling factor for dual solution, it is equal to 4 or 1
+    /// according to the value type.
+    static const int dualScale =
+      std::numeric_limits<Value>::is_integer ? 4 : 1;
+
+    typedef typename Graph::template NodeMap<typename Graph::Arc>
+    MatchingMap;
+
+  private:
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    typedef typename Graph::template NodeMap<Value> NodePotential;
+    typedef std::vector<Node> BlossomNodeList;
+
+    struct BlossomVariable {
+      int begin, end;
+      Value value;
+
+      BlossomVariable(int _begin, int _end, Value _value)
+        : begin(_begin), end(_end), value(_value) {}
+
+    };
+
+    typedef std::vector<BlossomVariable> BlossomPotential;
+
+    const Graph& _graph;
+    const WeightMap& _weight;
+
+    MatchingMap* _matching;
+
+    NodePotential* _node_potential;
+
+    BlossomPotential _blossom_potential;
+    BlossomNodeList _blossom_node_list;
+
+    int _node_num;
+    int _blossom_num;
+
+    typedef RangeMap<int> IntIntMap;
+
+    enum Status {
+      EVEN = -1, MATCHED = 0, ODD = 1, UNMATCHED = -2
+    };
+
+    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
+    struct BlossomData {
+      int tree;
+      Status status;
+      Arc pred, next;
+      Value pot, offset;
+      Node base;
+    };
+
+    IntNodeMap *_blossom_index;
+    BlossomSet *_blossom_set;
+    RangeMap<BlossomData>* _blossom_data;
+
+    IntNodeMap *_node_index;
+    IntArcMap *_node_heap_index;
+
+    struct NodeData {
+
+      NodeData(IntArcMap& node_heap_index)
+        : heap(node_heap_index) {}
+
+      int blossom;
+      Value pot;
+      BinHeap<Value, IntArcMap> heap;
+      std::map<int, Arc> heap_index;
+
+      int tree;
+    };
+
+    RangeMap<NodeData>* _node_data;
+
+    typedef ExtendFindEnum<IntIntMap> TreeSet;
+
+    IntIntMap *_tree_set_index;
+    TreeSet *_tree_set;
+
+    IntNodeMap *_delta1_index;
+    BinHeap<Value, IntNodeMap> *_delta1;
+
+    IntIntMap *_delta2_index;
+    BinHeap<Value, IntIntMap> *_delta2;
+
+    IntEdgeMap *_delta3_index;
+    BinHeap<Value, IntEdgeMap> *_delta3;
+
+    IntIntMap *_delta4_index;
+    BinHeap<Value, IntIntMap> *_delta4;
+
+    Value _delta_sum;
+
+    void createStructures() {
+      _node_num = countNodes(_graph);
+      _blossom_num = _node_num * 3 / 2;
+
+      if (!_matching) {
+        _matching = new MatchingMap(_graph);
+      }
+      if (!_node_potential) {
+        _node_potential = new NodePotential(_graph);
+      }
+      if (!_blossom_set) {
+        _blossom_index = new IntNodeMap(_graph);
+        _blossom_set = new BlossomSet(*_blossom_index);
+        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
+      }
+
+      if (!_node_index) {
+        _node_index = new IntNodeMap(_graph);
+        _node_heap_index = new IntArcMap(_graph);
+        _node_data = new RangeMap<NodeData>(_node_num,
+                                              NodeData(*_node_heap_index));
+      }
+
+      if (!_tree_set) {
+        _tree_set_index = new IntIntMap(_blossom_num);
+        _tree_set = new TreeSet(*_tree_set_index);
+      }
+      if (!_delta1) {
+        _delta1_index = new IntNodeMap(_graph);
+        _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
+      }
+      if (!_delta2) {
+        _delta2_index = new IntIntMap(_blossom_num);
+        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
+      }
+      if (!_delta3) {
+        _delta3_index = new IntEdgeMap(_graph);
+        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
+      }
+      if (!_delta4) {
+        _delta4_index = new IntIntMap(_blossom_num);
+        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
+      }
+    }
+
+    void destroyStructures() {
+      _node_num = countNodes(_graph);
+      _blossom_num = _node_num * 3 / 2;
+
+      if (_matching) {
+        delete _matching;
+      }
+      if (_node_potential) {
+        delete _node_potential;
+      }
+      if (_blossom_set) {
+        delete _blossom_index;
+        delete _blossom_set;
+        delete _blossom_data;
+      }
+
+      if (_node_index) {
+        delete _node_index;
+        delete _node_heap_index;
+        delete _node_data;
+      }
+
+      if (_tree_set) {
+        delete _tree_set_index;
+        delete _tree_set;
+      }
+      if (_delta1) {
+        delete _delta1_index;
+        delete _delta1;
+      }
+      if (_delta2) {
+        delete _delta2_index;
+        delete _delta2;
+      }
+      if (_delta3) {
+        delete _delta3_index;
+        delete _delta3;
+      }
+      if (_delta4) {
+        delete _delta4_index;
+        delete _delta4;
+      }
+    }
+
+    void matchedToEven(int blossom, int tree) {
+      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
+        _delta2->erase(blossom);
+      }
+
+      if (!_blossom_set->trivial(blossom)) {
+        (*_blossom_data)[blossom].pot -=
+          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
+      }
+
+      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
+           n != INVALID; ++n) {
+
+        _blossom_set->increase(n, std::numeric_limits<Value>::max());
+        int ni = (*_node_index)[n];
+
+        (*_node_data)[ni].heap.clear();
+        (*_node_data)[ni].heap_index.clear();
+
+        (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
+
+        _delta1->push(n, (*_node_data)[ni].pot);
+
+        for (InArcIt e(_graph, n); e != INVALID; ++e) {
+          Node v = _graph.source(e);
+          int vb = _blossom_set->find(v);
+          int vi = (*_node_index)[v];
+
+          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
+            dualScale * _weight[e];
+
+          if ((*_blossom_data)[vb].status == EVEN) {
+            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
+              _delta3->push(e, rw / 2);
+            }
+          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
+            if (_delta3->state(e) != _delta3->IN_HEAP) {
+              _delta3->push(e, rw);
+            }
+          } else {
+            typename std::map<int, Arc>::iterator it =
+              (*_node_data)[vi].heap_index.find(tree);
+
+            if (it != (*_node_data)[vi].heap_index.end()) {
+              if ((*_node_data)[vi].heap[it->second] > rw) {
+                (*_node_data)[vi].heap.replace(it->second, e);
+                (*_node_data)[vi].heap.decrease(e, rw);
+                it->second = e;
+              }
+            } else {
+              (*_node_data)[vi].heap.push(e, rw);
+              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
+            }
+
+            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
+              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
+
+              if ((*_blossom_data)[vb].status == MATCHED) {
+                if (_delta2->state(vb) != _delta2->IN_HEAP) {
+                  _delta2->push(vb, _blossom_set->classPrio(vb) -
+                               (*_blossom_data)[vb].offset);
+                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
+                           (*_blossom_data)[vb].offset){
+                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
+                                   (*_blossom_data)[vb].offset);
+                }
+              }
+            }
+          }
+        }
+      }
+      (*_blossom_data)[blossom].offset = 0;
+    }
+
+    void matchedToOdd(int blossom) {
+      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
+        _delta2->erase(blossom);
+      }
+      (*_blossom_data)[blossom].offset += _delta_sum;
+      if (!_blossom_set->trivial(blossom)) {
+        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
+                     (*_blossom_data)[blossom].offset);
+      }
+    }
+
+    void evenToMatched(int blossom, int tree) {
+      if (!_blossom_set->trivial(blossom)) {
+        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
+      }
+
+      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
+           n != INVALID; ++n) {
+        int ni = (*_node_index)[n];
+        (*_node_data)[ni].pot -= _delta_sum;
+
+        _delta1->erase(n);
+
+        for (InArcIt e(_graph, n); e != INVALID; ++e) {
+          Node v = _graph.source(e);
+          int vb = _blossom_set->find(v);
+          int vi = (*_node_index)[v];
+
+          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
+            dualScale * _weight[e];
+
+          if (vb == blossom) {
+            if (_delta3->state(e) == _delta3->IN_HEAP) {
+              _delta3->erase(e);
+            }
+          } else if ((*_blossom_data)[vb].status == EVEN) {
+
+            if (_delta3->state(e) == _delta3->IN_HEAP) {
+              _delta3->erase(e);
+            }
+
+            int vt = _tree_set->find(vb);
+
+            if (vt != tree) {
+
+              Arc r = _graph.oppositeArc(e);
+
+              typename std::map<int, Arc>::iterator it =
+                (*_node_data)[ni].heap_index.find(vt);
+
+              if (it != (*_node_data)[ni].heap_index.end()) {
+                if ((*_node_data)[ni].heap[it->second] > rw) {
+                  (*_node_data)[ni].heap.replace(it->second, r);
+                  (*_node_data)[ni].heap.decrease(r, rw);
+                  it->second = r;
+                }
+              } else {
+                (*_node_data)[ni].heap.push(r, rw);
+                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
+              }
+
+              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
+                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
+
+                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
+                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
+                               (*_blossom_data)[blossom].offset);
+                } else if ((*_delta2)[blossom] >
+                           _blossom_set->classPrio(blossom) -
+                           (*_blossom_data)[blossom].offset){
+                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
+                                   (*_blossom_data)[blossom].offset);
+                }
+              }
+            }
+
+          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
+            if (_delta3->state(e) == _delta3->IN_HEAP) {
+              _delta3->erase(e);
+            }
+          } else {
+
+            typename std::map<int, Arc>::iterator it =
+              (*_node_data)[vi].heap_index.find(tree);
+
+            if (it != (*_node_data)[vi].heap_index.end()) {
+              (*_node_data)[vi].heap.erase(it->second);
+              (*_node_data)[vi].heap_index.erase(it);
+              if ((*_node_data)[vi].heap.empty()) {
+                _blossom_set->increase(v, std::numeric_limits<Value>::max());
+              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
+                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
+              }
+
+              if ((*_blossom_data)[vb].status == MATCHED) {
+                if (_blossom_set->classPrio(vb) ==
+                    std::numeric_limits<Value>::max()) {
+                  _delta2->erase(vb);
+                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
+                           (*_blossom_data)[vb].offset) {
+                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
+                                   (*_blossom_data)[vb].offset);
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+
+    void oddToMatched(int blossom) {
+      (*_blossom_data)[blossom].offset -= _delta_sum;
+
+      if (_blossom_set->classPrio(blossom) !=
+          std::numeric_limits<Value>::max()) {
+        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
+                       (*_blossom_data)[blossom].offset);
+      }
+
+      if (!_blossom_set->trivial(blossom)) {
+        _delta4->erase(blossom);
+      }
+    }
+
+    void oddToEven(int blossom, int tree) {
+      if (!_blossom_set->trivial(blossom)) {
+        _delta4->erase(blossom);
+        (*_blossom_data)[blossom].pot -=
+          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
+      }
+
+      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
+           n != INVALID; ++n) {
+        int ni = (*_node_index)[n];
+
+        _blossom_set->increase(n, std::numeric_limits<Value>::max());
+
+        (*_node_data)[ni].heap.clear();
+        (*_node_data)[ni].heap_index.clear();
+        (*_node_data)[ni].pot +=
+          2 * _delta_sum - (*_blossom_data)[blossom].offset;
+
+        _delta1->push(n, (*_node_data)[ni].pot);
+
+        for (InArcIt e(_graph, n); e != INVALID; ++e) {
+          Node v = _graph.source(e);
+          int vb = _blossom_set->find(v);
+          int vi = (*_node_index)[v];
+
+          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
+            dualScale * _weight[e];
+
+          if ((*_blossom_data)[vb].status == EVEN) {
+            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
+              _delta3->push(e, rw / 2);
+            }
+          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
+            if (_delta3->state(e) != _delta3->IN_HEAP) {
+              _delta3->push(e, rw);
+            }
+          } else {
+
+            typename std::map<int, Arc>::iterator it =
+              (*_node_data)[vi].heap_index.find(tree);
+
+            if (it != (*_node_data)[vi].heap_index.end()) {
+              if ((*_node_data)[vi].heap[it->second] > rw) {
+                (*_node_data)[vi].heap.replace(it->second, e);
+                (*_node_data)[vi].heap.decrease(e, rw);
+                it->second = e;
+              }
+            } else {
+              (*_node_data)[vi].heap.push(e, rw);
+              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
+            }
+
+            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
+              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
+
+              if ((*_blossom_data)[vb].status == MATCHED) {
+                if (_delta2->state(vb) != _delta2->IN_HEAP) {
+                  _delta2->push(vb, _blossom_set->classPrio(vb) -
+                               (*_blossom_data)[vb].offset);
+                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
+                           (*_blossom_data)[vb].offset) {
+                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
+                                   (*_blossom_data)[vb].offset);
+                }
+              }
+            }
+          }
+        }
+      }
+      (*_blossom_data)[blossom].offset = 0;
+    }
+
+
+    void matchedToUnmatched(int blossom) {
+      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
+        _delta2->erase(blossom);
+      }
+
+      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
+           n != INVALID; ++n) {
+        int ni = (*_node_index)[n];
+
+        _blossom_set->increase(n, std::numeric_limits<Value>::max());
+
+        (*_node_data)[ni].heap.clear();
+        (*_node_data)[ni].heap_index.clear();
+
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          Node v = _graph.target(e);
+          int vb = _blossom_set->find(v);
+          int vi = (*_node_index)[v];
+
+          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
+            dualScale * _weight[e];
+
+          if ((*_blossom_data)[vb].status == EVEN) {
+            if (_delta3->state(e) != _delta3->IN_HEAP) {
+              _delta3->push(e, rw);
+            }
+          }
+        }
+      }
+    }
+
+    void unmatchedToMatched(int blossom) {
+      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
+           n != INVALID; ++n) {
+        int ni = (*_node_index)[n];
+
+        for (InArcIt e(_graph, n); e != INVALID; ++e) {
+          Node v = _graph.source(e);
+          int vb = _blossom_set->find(v);
+          int vi = (*_node_index)[v];
+
+          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
+            dualScale * _weight[e];
+
+          if (vb == blossom) {
+            if (_delta3->state(e) == _delta3->IN_HEAP) {
+              _delta3->erase(e);
+            }
+          } else if ((*_blossom_data)[vb].status == EVEN) {
+
+            if (_delta3->state(e) == _delta3->IN_HEAP) {
+              _delta3->erase(e);
+            }
+
+            int vt = _tree_set->find(vb);
+
+            Arc r = _graph.oppositeArc(e);
+
+            typename std::map<int, Arc>::iterator it =
+              (*_node_data)[ni].heap_index.find(vt);
+
+            if (it != (*_node_data)[ni].heap_index.end()) {
+              if ((*_node_data)[ni].heap[it->second] > rw) {
+                (*_node_data)[ni].heap.replace(it->second, r);
+                (*_node_data)[ni].heap.decrease(r, rw);
+                it->second = r;
+              }
+            } else {
+              (*_node_data)[ni].heap.push(r, rw);
+              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
+            }
+
+            if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
+              _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
+
+              if (_delta2->state(blossom) != _delta2->IN_HEAP) {
+                _delta2->push(blossom, _blossom_set->classPrio(blossom) -
+                             (*_blossom_data)[blossom].offset);
+              } else if ((*_delta2)[blossom] > _blossom_set->classPrio(blossom)-
+                         (*_blossom_data)[blossom].offset){
+                _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
+                                 (*_blossom_data)[blossom].offset);
+              }
+            }
+
+          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
+            if (_delta3->state(e) == _delta3->IN_HEAP) {
+              _delta3->erase(e);
+            }
+          }
+        }
+      }
+    }
+
+    void alternatePath(int even, int tree) {
+      int odd;
+
+      evenToMatched(even, tree);
+      (*_blossom_data)[even].status = MATCHED;
+
+      while ((*_blossom_data)[even].pred != INVALID) {
+        odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
+        (*_blossom_data)[odd].status = MATCHED;
+        oddToMatched(odd);
+        (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
+
+        even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
+        (*_blossom_data)[even].status = MATCHED;
+        evenToMatched(even, tree);
+        (*_blossom_data)[even].next =
+          _graph.oppositeArc((*_blossom_data)[odd].pred);
+      }
+
+    }
+
+    void destroyTree(int tree) {
+      for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
+        if ((*_blossom_data)[b].status == EVEN) {
+          (*_blossom_data)[b].status = MATCHED;
+          evenToMatched(b, tree);
+        } else if ((*_blossom_data)[b].status == ODD) {
+          (*_blossom_data)[b].status = MATCHED;
+          oddToMatched(b);
+        }
+      }
+      _tree_set->eraseClass(tree);
+    }
+
+
+    void unmatchNode(const Node& node) {
+      int blossom = _blossom_set->find(node);
+      int tree = _tree_set->find(blossom);
+
+      alternatePath(blossom, tree);
+      destroyTree(tree);
+
+      (*_blossom_data)[blossom].status = UNMATCHED;
+      (*_blossom_data)[blossom].base = node;
+      matchedToUnmatched(blossom);
+    }
+
+
+    void augmentOnEdge(const Edge& edge) {
+
+      int left = _blossom_set->find(_graph.u(edge));
+      int right = _blossom_set->find(_graph.v(edge));
+
+      if ((*_blossom_data)[left].status == EVEN) {
+        int left_tree = _tree_set->find(left);
+        alternatePath(left, left_tree);
+        destroyTree(left_tree);
+      } else {
+        (*_blossom_data)[left].status = MATCHED;
+        unmatchedToMatched(left);
+      }
+
+      if ((*_blossom_data)[right].status == EVEN) {
+        int right_tree = _tree_set->find(right);
+        alternatePath(right, right_tree);
+        destroyTree(right_tree);
+      } else {
+        (*_blossom_data)[right].status = MATCHED;
+        unmatchedToMatched(right);
+      }
+
+      (*_blossom_data)[left].next = _graph.direct(edge, true);
+      (*_blossom_data)[right].next = _graph.direct(edge, false);
+    }
+
+    void extendOnArc(const Arc& arc) {
+      int base = _blossom_set->find(_graph.target(arc));
+      int tree = _tree_set->find(base);
+
+      int odd = _blossom_set->find(_graph.source(arc));
+      _tree_set->insert(odd, tree);
+      (*_blossom_data)[odd].status = ODD;
+      matchedToOdd(odd);
+      (*_blossom_data)[odd].pred = arc;
+
+      int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
+      (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
+      _tree_set->insert(even, tree);
+      (*_blossom_data)[even].status = EVEN;
+      matchedToEven(even, tree);
+    }
+
+    void shrinkOnEdge(const Edge& edge, int tree) {
+      int nca = -1;
+      std::vector<int> left_path, right_path;
+
+      {
+        std::set<int> left_set, right_set;
+        int left = _blossom_set->find(_graph.u(edge));
+        left_path.push_back(left);
+        left_set.insert(left);
+
+        int right = _blossom_set->find(_graph.v(edge));
+        right_path.push_back(right);
+        right_set.insert(right);
+
+        while (true) {
+
+          if ((*_blossom_data)[left].pred == INVALID) break;
+
+          left =
+            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
+          left_path.push_back(left);
+          left =
+            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
+          left_path.push_back(left);
+
+          left_set.insert(left);
+
+          if (right_set.find(left) != right_set.end()) {
+            nca = left;
+            break;
+          }
+
+          if ((*_blossom_data)[right].pred == INVALID) break;
+
+          right =
+            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
+          right_path.push_back(right);
+          right =
+            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
+          right_path.push_back(right);
+
+          right_set.insert(right);
+
+          if (left_set.find(right) != left_set.end()) {
+            nca = right;
+            break;
+          }
+
+        }
+
+        if (nca == -1) {
+          if ((*_blossom_data)[left].pred == INVALID) {
+            nca = right;
+            while (left_set.find(nca) == left_set.end()) {
+              nca =
+                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
+              right_path.push_back(nca);
+              nca =
+                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
+              right_path.push_back(nca);
+            }
+          } else {
+            nca = left;
+            while (right_set.find(nca) == right_set.end()) {
+              nca =
+                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
+              left_path.push_back(nca);
+              nca =
+                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
+              left_path.push_back(nca);
+            }
+          }
+        }
+      }
+
+      std::vector<int> subblossoms;
+      Arc prev;
+
+      prev = _graph.direct(edge, true);
+      for (int i = 0; left_path[i] != nca; i += 2) {
+        subblossoms.push_back(left_path[i]);
+        (*_blossom_data)[left_path[i]].next = prev;
+        _tree_set->erase(left_path[i]);
+
+        subblossoms.push_back(left_path[i + 1]);
+        (*_blossom_data)[left_path[i + 1]].status = EVEN;
+        oddToEven(left_path[i + 1], tree);
+        _tree_set->erase(left_path[i + 1]);
+        prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
+      }
+
+      int k = 0;
+      while (right_path[k] != nca) ++k;
+
+      subblossoms.push_back(nca);
+      (*_blossom_data)[nca].next = prev;
+
+      for (int i = k - 2; i >= 0; i -= 2) {
+        subblossoms.push_back(right_path[i + 1]);
+        (*_blossom_data)[right_path[i + 1]].status = EVEN;
+        oddToEven(right_path[i + 1], tree);
+        _tree_set->erase(right_path[i + 1]);
+
+        (*_blossom_data)[right_path[i + 1]].next =
+          (*_blossom_data)[right_path[i + 1]].pred;
+
+        subblossoms.push_back(right_path[i]);
+        _tree_set->erase(right_path[i]);
+      }
+
+      int surface =
+        _blossom_set->join(subblossoms.begin(), subblossoms.end());
+
+      for (int i = 0; i < int(subblossoms.size()); ++i) {
+        if (!_blossom_set->trivial(subblossoms[i])) {
+          (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
+        }
+        (*_blossom_data)[subblossoms[i]].status = MATCHED;
+      }
+
+      (*_blossom_data)[surface].pot = -2 * _delta_sum;
+      (*_blossom_data)[surface].offset = 0;
+      (*_blossom_data)[surface].status = EVEN;
+      (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
+      (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
+
+      _tree_set->insert(surface, tree);
+      _tree_set->erase(nca);
+    }
+
+    void splitBlossom(int blossom) {
+      Arc next = (*_blossom_data)[blossom].next;
+      Arc pred = (*_blossom_data)[blossom].pred;
+
+      int tree = _tree_set->find(blossom);
+
+      (*_blossom_data)[blossom].status = MATCHED;
+      oddToMatched(blossom);
+      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
+        _delta2->erase(blossom);
+      }
+
+      std::vector<int> subblossoms;
+      _blossom_set->split(blossom, std::back_inserter(subblossoms));
+
+      Value offset = (*_blossom_data)[blossom].offset;
+      int b = _blossom_set->find(_graph.source(pred));
+      int d = _blossom_set->find(_graph.source(next));
+
+      int ib = -1, id = -1;
+      for (int i = 0; i < int(subblossoms.size()); ++i) {
+        if (subblossoms[i] == b) ib = i;
+        if (subblossoms[i] == d) id = i;
+
+        (*_blossom_data)[subblossoms[i]].offset = offset;
+        if (!_blossom_set->trivial(subblossoms[i])) {
+          (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
+        }
+        if (_blossom_set->classPrio(subblossoms[i]) !=
+            std::numeric_limits<Value>::max()) {
+          _delta2->push(subblossoms[i],
+                        _blossom_set->classPrio(subblossoms[i]) -
+                        (*_blossom_data)[subblossoms[i]].offset);
+        }
+      }
+
+      if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
+        for (int i = (id + 1) % subblossoms.size();
+             i != ib; i = (i + 2) % subblossoms.size()) {
+          int sb = subblossoms[i];
+          int tb = subblossoms[(i + 1) % subblossoms.size()];
+          (*_blossom_data)[sb].next =
+            _graph.oppositeArc((*_blossom_data)[tb].next);
+        }
+
+        for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
+          int sb = subblossoms[i];
+          int tb = subblossoms[(i + 1) % subblossoms.size()];
+          int ub = subblossoms[(i + 2) % subblossoms.size()];
+
+          (*_blossom_data)[sb].status = ODD;
+          matchedToOdd(sb);
+          _tree_set->insert(sb, tree);
+          (*_blossom_data)[sb].pred = pred;
+          (*_blossom_data)[sb].next =
+                           _graph.oppositeArc((*_blossom_data)[tb].next);
+
+          pred = (*_blossom_data)[ub].next;
+
+          (*_blossom_data)[tb].status = EVEN;
+          matchedToEven(tb, tree);
+          _tree_set->insert(tb, tree);
+          (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
+        }
+
+        (*_blossom_data)[subblossoms[id]].status = ODD;
+        matchedToOdd(subblossoms[id]);
+        _tree_set->insert(subblossoms[id], tree);
+        (*_blossom_data)[subblossoms[id]].next = next;
+        (*_blossom_data)[subblossoms[id]].pred = pred;
+
+      } else {
+
+        for (int i = (ib + 1) % subblossoms.size();
+             i != id; i = (i + 2) % subblossoms.size()) {
+          int sb = subblossoms[i];
+          int tb = subblossoms[(i + 1) % subblossoms.size()];
+          (*_blossom_data)[sb].next =
+            _graph.oppositeArc((*_blossom_data)[tb].next);
+        }
+
+        for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
+          int sb = subblossoms[i];
+          int tb = subblossoms[(i + 1) % subblossoms.size()];
+          int ub = subblossoms[(i + 2) % subblossoms.size()];
+
+          (*_blossom_data)[sb].status = ODD;
+          matchedToOdd(sb);
+          _tree_set->insert(sb, tree);
+          (*_blossom_data)[sb].next = next;
+          (*_blossom_data)[sb].pred =
+            _graph.oppositeArc((*_blossom_data)[tb].next);
+
+          (*_blossom_data)[tb].status = EVEN;
+          matchedToEven(tb, tree);
+          _tree_set->insert(tb, tree);
+          (*_blossom_data)[tb].pred =
+            (*_blossom_data)[tb].next =
+            _graph.oppositeArc((*_blossom_data)[ub].next);
+          next = (*_blossom_data)[ub].next;
+        }
+
+        (*_blossom_data)[subblossoms[ib]].status = ODD;
+        matchedToOdd(subblossoms[ib]);
+        _tree_set->insert(subblossoms[ib], tree);
+        (*_blossom_data)[subblossoms[ib]].next = next;
+        (*_blossom_data)[subblossoms[ib]].pred = pred;
+      }
+      _tree_set->erase(blossom);
+    }
+
+    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
+      if (_blossom_set->trivial(blossom)) {
+        int bi = (*_node_index)[base];
+        Value pot = (*_node_data)[bi].pot;
+
+        _matching->set(base, matching);
+        _blossom_node_list.push_back(base);
+        _node_potential->set(base, pot);
+      } else {
+
+        Value pot = (*_blossom_data)[blossom].pot;
+        int bn = _blossom_node_list.size();
+
+        std::vector<int> subblossoms;
+        _blossom_set->split(blossom, std::back_inserter(subblossoms));
+        int b = _blossom_set->find(base);
+        int ib = -1;
+        for (int i = 0; i < int(subblossoms.size()); ++i) {
+          if (subblossoms[i] == b) { ib = i; break; }
+        }
+
+        for (int i = 1; i < int(subblossoms.size()); i += 2) {
+          int sb = subblossoms[(ib + i) % subblossoms.size()];
+          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
+
+          Arc m = (*_blossom_data)[tb].next;
+          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
+          extractBlossom(tb, _graph.source(m), m);
+        }
+        extractBlossom(subblossoms[ib], base, matching);
+
+        int en = _blossom_node_list.size();
+
+        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
+      }
+    }
+
+    void extractMatching() {
+      std::vector<int> blossoms;
+      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
+        blossoms.push_back(c);
+      }
+
+      for (int i = 0; i < int(blossoms.size()); ++i) {
+        if ((*_blossom_data)[blossoms[i]].status == MATCHED) {
+
+          Value offset = (*_blossom_data)[blossoms[i]].offset;
+          (*_blossom_data)[blossoms[i]].pot += 2 * offset;
+          for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
+               n != INVALID; ++n) {
+            (*_node_data)[(*_node_index)[n]].pot -= offset;
+          }
+
+          Arc matching = (*_blossom_data)[blossoms[i]].next;
+          Node base = _graph.source(matching);
+          extractBlossom(blossoms[i], base, matching);
+        } else {
+          Node base = (*_blossom_data)[blossoms[i]].base;
+          extractBlossom(blossoms[i], base, INVALID);
+        }
+      }
+    }
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    MaxWeightedMatching(const Graph& graph, const WeightMap& weight)
+      : _graph(graph), _weight(weight), _matching(0),
+        _node_potential(0), _blossom_potential(), _blossom_node_list(),
+        _node_num(0), _blossom_num(0),
+
+        _blossom_index(0), _blossom_set(0), _blossom_data(0),
+        _node_index(0), _node_heap_index(0), _node_data(0),
+        _tree_set_index(0), _tree_set(0),
+
+        _delta1_index(0), _delta1(0),
+        _delta2_index(0), _delta2(0),
+        _delta3_index(0), _delta3(0),
+        _delta4_index(0), _delta4(0),
+
+        _delta_sum() {}
+
+    ~MaxWeightedMatching() {
+      destroyStructures();
+    }
+
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to use the
+    /// \c run() member function.
+
+    ///@{
+
+    /// \brief Initialize the algorithm
+    ///
+    /// Initialize the algorithm
+    void init() {
+      createStructures();
+
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        _node_heap_index->set(e, BinHeap<Value, IntArcMap>::PRE_HEAP);
+      }
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _delta1_index->set(n, _delta1->PRE_HEAP);
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        _delta3_index->set(e, _delta3->PRE_HEAP);
+      }
+      for (int i = 0; i < _blossom_num; ++i) {
+        _delta2_index->set(i, _delta2->PRE_HEAP);
+        _delta4_index->set(i, _delta4->PRE_HEAP);
+      }
+
+      int index = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        Value max = 0;
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          if (_graph.target(e) == n) continue;
+          if ((dualScale * _weight[e]) / 2 > max) {
+            max = (dualScale * _weight[e]) / 2;
+          }
+        }
+        _node_index->set(n, index);
+        (*_node_data)[index].pot = max;
+        _delta1->push(n, max);
+        int blossom =
+          _blossom_set->insert(n, std::numeric_limits<Value>::max());
+
+        _tree_set->insert(blossom);
+
+        (*_blossom_data)[blossom].status = EVEN;
+        (*_blossom_data)[blossom].pred = INVALID;
+        (*_blossom_data)[blossom].next = INVALID;
+        (*_blossom_data)[blossom].pot = 0;
+        (*_blossom_data)[blossom].offset = 0;
+        ++index;
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        int si = (*_node_index)[_graph.u(e)];
+        int ti = (*_node_index)[_graph.v(e)];
+        if (_graph.u(e) != _graph.v(e)) {
+          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
+                            dualScale * _weight[e]) / 2);
+        }
+      }
+    }
+
+    /// \brief Starts the algorithm
+    ///
+    /// Starts the algorithm
+    void start() {
+      enum OpType {
+        D1, D2, D3, D4
+      };
+
+      int unmatched = _node_num;
+      while (unmatched > 0) {
+        Value d1 = !_delta1->empty() ?
+          _delta1->prio() : std::numeric_limits<Value>::max();
+
+        Value d2 = !_delta2->empty() ?
+          _delta2->prio() : std::numeric_limits<Value>::max();
+
+        Value d3 = !_delta3->empty() ?
+          _delta3->prio() : std::numeric_limits<Value>::max();
+
+        Value d4 = !_delta4->empty() ?
+          _delta4->prio() : std::numeric_limits<Value>::max();
+
+        _delta_sum = d1; OpType ot = D1;
+        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
+        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
+        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
+
+
+        switch (ot) {
+        case D1:
+          {
+            Node n = _delta1->top();
+            unmatchNode(n);
+            --unmatched;
+          }
+          break;
+        case D2:
+          {
+            int blossom = _delta2->top();
+            Node n = _blossom_set->classTop(blossom);
+            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
+            extendOnArc(e);
+          }
+          break;
+        case D3:
+          {
+            Edge e = _delta3->top();
+
+            int left_blossom = _blossom_set->find(_graph.u(e));
+            int right_blossom = _blossom_set->find(_graph.v(e));
+
+            if (left_blossom == right_blossom) {
+              _delta3->pop();
+            } else {
+              int left_tree;
+              if ((*_blossom_data)[left_blossom].status == EVEN) {
+                left_tree = _tree_set->find(left_blossom);
+              } else {
+                left_tree = -1;
+                ++unmatched;
+              }
+              int right_tree;
+              if ((*_blossom_data)[right_blossom].status == EVEN) {
+                right_tree = _tree_set->find(right_blossom);
+              } else {
+                right_tree = -1;
+                ++unmatched;
+              }
+
+              if (left_tree == right_tree) {
+                shrinkOnEdge(e, left_tree);
+              } else {
+                augmentOnEdge(e);
+                unmatched -= 2;
+              }
+            }
+          } break;
+        case D4:
+          splitBlossom(_delta4->top());
+          break;
+        }
+      }
+      extractMatching();
+    }
+
+    /// \brief Runs %MaxWeightedMatching algorithm.
+    ///
+    /// This method runs the %MaxWeightedMatching algorithm.
+    ///
+    /// \note mwm.run() is just a shortcut of the following code.
+    /// \code
+    ///   mwm.init();
+    ///   mwm.start();
+    /// \endcode
+    void run() {
+      init();
+      start();
+    }
+
+    /// @}
+
+    /// \name Primal solution
+    /// Functions to get the primal solution, ie. the matching.
+
+    /// @{
+
+    /// \brief Returns the weight of the matching.
+    ///
+    /// Returns the weight of the matching.
+    Value matchingValue() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          sum += _weight[(*_matching)[n]];
+        }
+      }
+      return sum /= 2;
+    }
+
+    /// \brief Returns the cardinality of the matching.
+    ///
+    /// Returns the cardinality of the matching.
+    int matchingSize() const {
+      int num = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          ++num;
+        }
+      }
+      return num /= 2;
+    }
+
+    /// \brief Returns true when the edge is in the matching.
+    ///
+    /// Returns true when the edge is in the matching.
+    bool matching(const Edge& edge) const {
+      return edge == (*_matching)[_graph.u(edge)];
+    }
+
+    /// \brief Returns the incident matching arc.
+    ///
+    /// Returns the incident matching arc from given node. If the
+    /// node is not matched then it gives back \c INVALID.
+    Arc matching(const Node& node) const {
+      return (*_matching)[node];
+    }
+
+    /// \brief Returns the mate of the node.
+    ///
+    /// Returns the adjancent node in a mathcing arc. If the node is
+    /// not matched then it gives back \c INVALID.
+    Node mate(const Node& node) const {
+      return (*_matching)[node] != INVALID ?
+        _graph.target((*_matching)[node]) : INVALID;
+    }
+
+    /// @}
+
+    /// \name Dual solution
+    /// Functions to get the dual solution.
+
+    /// @{
+
+    /// \brief Returns the value of the dual solution.
+    ///
+    /// Returns the value of the dual solution. It should be equal to
+    /// the primal value scaled by \ref dualScale "dual scale".
+    Value dualValue() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        sum += nodeValue(n);
+      }
+      for (int i = 0; i < blossomNum(); ++i) {
+        sum += blossomValue(i) * (blossomSize(i) / 2);
+      }
+      return sum;
+    }
+
+    /// \brief Returns the value of the node.
+    ///
+    /// Returns the the value of the node.
+    Value nodeValue(const Node& n) const {
+      return (*_node_potential)[n];
+    }
+
+    /// \brief Returns the number of the blossoms in the basis.
+    ///
+    /// Returns the number of the blossoms in the basis.
+    /// \see BlossomIt
+    int blossomNum() const {
+      return _blossom_potential.size();
+    }
+
+
+    /// \brief Returns the number of the nodes in the blossom.
+    ///
+    /// Returns the number of the nodes in the blossom.
+    int blossomSize(int k) const {
+      return _blossom_potential[k].end - _blossom_potential[k].begin;
+    }
+
+    /// \brief Returns the value of the blossom.
+    ///
+    /// Returns the the value of the blossom.
+    /// \see BlossomIt
+    Value blossomValue(int k) const {
+      return _blossom_potential[k].value;
+    }
+
+    /// \brief Iterator for obtaining the nodes of the blossom.
+    ///
+    /// Iterator for obtaining the nodes of the blossom. This class
+    /// provides a common lemon style iterator for listing a
+    /// subset of the nodes.
+    class BlossomIt {
+    public:
+
+      /// \brief Constructor.
+      ///
+      /// Constructor to get the nodes of the variable.
+      BlossomIt(const MaxWeightedMatching& algorithm, int variable)
+        : _algorithm(&algorithm)
+      {
+        _index = _algorithm->_blossom_potential[variable].begin;
+        _last = _algorithm->_blossom_potential[variable].end;
+      }
+
+      /// \brief Conversion to node.
+      ///
+      /// Conversion to node.
+      operator Node() const {
+        return _algorithm->_blossom_node_list[_index];
+      }
+
+      /// \brief Increment operator.
+      ///
+      /// Increment operator.
+      BlossomIt& operator++() {
+        ++_index;
+        return *this;
+      }
+
+      /// \brief Validity checking
+      ///
+      /// Checks whether the iterator is invalid.
+      bool operator==(Invalid) const { return _index == _last; }
+
+      /// \brief Validity checking
+      ///
+      /// Checks whether the iterator is valid.
+      bool operator!=(Invalid) const { return _index != _last; }
+
+    private:
+      const MaxWeightedMatching* _algorithm;
+      int _last;
+      int _index;
+    };
+
+    /// @}
+
+  };
+
+  /// \ingroup matching
+  ///
+  /// \brief Weighted perfect matching in general graphs
+  ///
+  /// This class provides an efficient implementation of Edmond's
+  /// maximum weighted perfect matching algorithm. The implementation
+  /// is based on extensive use of priority queues and provides
+  /// \f$O(nm\log(n))\f$ time complexity.
+  ///
+  /// The maximum weighted matching problem is to find undirected
+  /// edges in the graph with maximum overall weight and no two of
+  /// them shares their ends and covers all nodes. The problem can be
+  /// formulated with the following linear program.
+  /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
+  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
+      \quad \forall B\in\mathcal{O}\f] */
+  /// \f[x_e \ge 0\quad \forall e\in E\f]
+  /// \f[\max \sum_{e\in E}x_ew_e\f]
+  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
+  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
+  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
+  /// subsets of the nodes.
+  ///
+  /// The algorithm calculates an optimal matching and a proof of the
+  /// optimality. The solution of the dual problem can be used to check
+  /// the result of the algorithm. The dual linear problem is the
+  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}z_B \ge
+      w_{uv} \quad \forall uv\in E\f] */
+  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
+  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
+      \frac{\vert B \vert - 1}{2}z_B\f] */
+  ///
+  /// The algorithm can be executed with \c run() or the \c init() and
+  /// then the \c start() member functions. After it the matching can
+  /// be asked with \c matching() or mate() functions. The dual
+  /// solution can be get with \c nodeValue(), \c blossomNum() and \c
+  /// blossomValue() members and \ref MaxWeightedMatching::BlossomIt
+  /// "BlossomIt" nested class which is able to iterate on the nodes
+  /// of a blossom. If the value type is integral then the dual
+  /// solution is multiplied by \ref MaxWeightedMatching::dualScale "4".
+  template <typename _Graph,
+            typename _WeightMap = typename _Graph::template EdgeMap<int> >
+  class MaxWeightedPerfectMatching {
+  public:
+
+    typedef _Graph Graph;
+    typedef _WeightMap WeightMap;
+    typedef typename WeightMap::Value Value;
+
+    /// \brief Scaling factor for dual solution
+    ///
+    /// Scaling factor for dual solution, it is equal to 4 or 1
+    /// according to the value type.
+    static const int dualScale =
+      std::numeric_limits<Value>::is_integer ? 4 : 1;
+
+    typedef typename Graph::template NodeMap<typename Graph::Arc>
+    MatchingMap;
+
+  private:
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    typedef typename Graph::template NodeMap<Value> NodePotential;
+    typedef std::vector<Node> BlossomNodeList;
+
+    struct BlossomVariable {
+      int begin, end;
+      Value value;
+
+      BlossomVariable(int _begin, int _end, Value _value)
+        : begin(_begin), end(_end), value(_value) {}
+
+    };
+
+    typedef std::vector<BlossomVariable> BlossomPotential;
+
+    const Graph& _graph;
+    const WeightMap& _weight;
+
+    MatchingMap* _matching;
+
+    NodePotential* _node_potential;
+
+    BlossomPotential _blossom_potential;
+    BlossomNodeList _blossom_node_list;
+
+    int _node_num;
+    int _blossom_num;
+
+    typedef RangeMap<int> IntIntMap;
+
+    enum Status {
+      EVEN = -1, MATCHED = 0, ODD = 1
+    };
+
+    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
+    struct BlossomData {
+      int tree;
+      Status status;
+      Arc pred, next;
+      Value pot, offset;
+    };
+
+    IntNodeMap *_blossom_index;
+    BlossomSet *_blossom_set;
+    RangeMap<BlossomData>* _blossom_data;
+
+    IntNodeMap *_node_index;
+    IntArcMap *_node_heap_index;
+
+    struct NodeData {
+
+      NodeData(IntArcMap& node_heap_index)
+        : heap(node_heap_index) {}
+
+      int blossom;
+      Value pot;
+      BinHeap<Value, IntArcMap> heap;
+      std::map<int, Arc> heap_index;
+
+      int tree;
+    };
+
+    RangeMap<NodeData>* _node_data;
+
+    typedef ExtendFindEnum<IntIntMap> TreeSet;
+
+    IntIntMap *_tree_set_index;
+    TreeSet *_tree_set;
+
+    IntIntMap *_delta2_index;
+    BinHeap<Value, IntIntMap> *_delta2;
+
+    IntEdgeMap *_delta3_index;
+    BinHeap<Value, IntEdgeMap> *_delta3;
+
+    IntIntMap *_delta4_index;
+    BinHeap<Value, IntIntMap> *_delta4;
+
+    Value _delta_sum;
+
+    void createStructures() {
+      _node_num = countNodes(_graph);
+      _blossom_num = _node_num * 3 / 2;
+
+      if (!_matching) {
+        _matching = new MatchingMap(_graph);
+      }
+      if (!_node_potential) {
+        _node_potential = new NodePotential(_graph);
+      }
+      if (!_blossom_set) {
+        _blossom_index = new IntNodeMap(_graph);
+        _blossom_set = new BlossomSet(*_blossom_index);
+        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
+      }
+
+      if (!_node_index) {
+        _node_index = new IntNodeMap(_graph);
+        _node_heap_index = new IntArcMap(_graph);
+        _node_data = new RangeMap<NodeData>(_node_num,
+                                            NodeData(*_node_heap_index));
+      }
+
+      if (!_tree_set) {
+        _tree_set_index = new IntIntMap(_blossom_num);
+        _tree_set = new TreeSet(*_tree_set_index);
+      }
+      if (!_delta2) {
+        _delta2_index = new IntIntMap(_blossom_num);
+        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
+      }
+      if (!_delta3) {
+        _delta3_index = new IntEdgeMap(_graph);
+        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
+      }
+      if (!_delta4) {
+        _delta4_index = new IntIntMap(_blossom_num);
+        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
+      }
+    }
+
+    void destroyStructures() {
+      _node_num = countNodes(_graph);
+      _blossom_num = _node_num * 3 / 2;
+
+      if (_matching) {
+        delete _matching;
+      }
+      if (_node_potential) {
+        delete _node_potential;
+      }
+      if (_blossom_set) {
+        delete _blossom_index;
+        delete _blossom_set;
+        delete _blossom_data;
+      }
+
+      if (_node_index) {
+        delete _node_index;
+        delete _node_heap_index;
+        delete _node_data;
+      }
+
+      if (_tree_set) {
+        delete _tree_set_index;
+        delete _tree_set;
+      }
+      if (_delta2) {
+        delete _delta2_index;
+        delete _delta2;
+      }
+      if (_delta3) {
+        delete _delta3_index;
+        delete _delta3;
+      }
+      if (_delta4) {
+        delete _delta4_index;
+        delete _delta4;
+      }
+    }
+
+    void matchedToEven(int blossom, int tree) {
+      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
+        _delta2->erase(blossom);
+      }
+
+      if (!_blossom_set->trivial(blossom)) {
+        (*_blossom_data)[blossom].pot -=
+          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
+      }
+
+      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
+           n != INVALID; ++n) {
+
+        _blossom_set->increase(n, std::numeric_limits<Value>::max());
+        int ni = (*_node_index)[n];
+
+        (*_node_data)[ni].heap.clear();
+        (*_node_data)[ni].heap_index.clear();
+
+        (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
+
+        for (InArcIt e(_graph, n); e != INVALID; ++e) {
+          Node v = _graph.source(e);
+          int vb = _blossom_set->find(v);
+          int vi = (*_node_index)[v];
+
+          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
+            dualScale * _weight[e];
+
+          if ((*_blossom_data)[vb].status == EVEN) {
+            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
+              _delta3->push(e, rw / 2);
+            }
+          } else {
+            typename std::map<int, Arc>::iterator it =
+              (*_node_data)[vi].heap_index.find(tree);
+
+            if (it != (*_node_data)[vi].heap_index.end()) {
+              if ((*_node_data)[vi].heap[it->second] > rw) {
+                (*_node_data)[vi].heap.replace(it->second, e);
+                (*_node_data)[vi].heap.decrease(e, rw);
+                it->second = e;
+              }
+            } else {
+              (*_node_data)[vi].heap.push(e, rw);
+              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
+            }
+
+            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
+              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
+
+              if ((*_blossom_data)[vb].status == MATCHED) {
+                if (_delta2->state(vb) != _delta2->IN_HEAP) {
+                  _delta2->push(vb, _blossom_set->classPrio(vb) -
+                               (*_blossom_data)[vb].offset);
+                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
+                           (*_blossom_data)[vb].offset){
+                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
+                                   (*_blossom_data)[vb].offset);
+                }
+              }
+            }
+          }
+        }
+      }
+      (*_blossom_data)[blossom].offset = 0;
+    }
+
+    void matchedToOdd(int blossom) {
+      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
+        _delta2->erase(blossom);
+      }
+      (*_blossom_data)[blossom].offset += _delta_sum;
+      if (!_blossom_set->trivial(blossom)) {
+        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
+                     (*_blossom_data)[blossom].offset);
+      }
+    }
+
+    void evenToMatched(int blossom, int tree) {
+      if (!_blossom_set->trivial(blossom)) {
+        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
+      }
+
+      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
+           n != INVALID; ++n) {
+        int ni = (*_node_index)[n];
+        (*_node_data)[ni].pot -= _delta_sum;
+
+        for (InArcIt e(_graph, n); e != INVALID; ++e) {
+          Node v = _graph.source(e);
+          int vb = _blossom_set->find(v);
+          int vi = (*_node_index)[v];
+
+          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
+            dualScale * _weight[e];
+
+          if (vb == blossom) {
+            if (_delta3->state(e) == _delta3->IN_HEAP) {
+              _delta3->erase(e);
+            }
+          } else if ((*_blossom_data)[vb].status == EVEN) {
+
+            if (_delta3->state(e) == _delta3->IN_HEAP) {
+              _delta3->erase(e);
+            }
+
+            int vt = _tree_set->find(vb);
+
+            if (vt != tree) {
+
+              Arc r = _graph.oppositeArc(e);
+
+              typename std::map<int, Arc>::iterator it =
+                (*_node_data)[ni].heap_index.find(vt);
+
+              if (it != (*_node_data)[ni].heap_index.end()) {
+                if ((*_node_data)[ni].heap[it->second] > rw) {
+                  (*_node_data)[ni].heap.replace(it->second, r);
+                  (*_node_data)[ni].heap.decrease(r, rw);
+                  it->second = r;
+                }
+              } else {
+                (*_node_data)[ni].heap.push(r, rw);
+                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
+              }
+
+              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
+                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
+
+                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
+                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
+                               (*_blossom_data)[blossom].offset);
+                } else if ((*_delta2)[blossom] >
+                           _blossom_set->classPrio(blossom) -
+                           (*_blossom_data)[blossom].offset){
+                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
+                                   (*_blossom_data)[blossom].offset);
+                }
+              }
+            }
+          } else {
+
+            typename std::map<int, Arc>::iterator it =
+              (*_node_data)[vi].heap_index.find(tree);
+
+            if (it != (*_node_data)[vi].heap_index.end()) {
+              (*_node_data)[vi].heap.erase(it->second);
+              (*_node_data)[vi].heap_index.erase(it);
+              if ((*_node_data)[vi].heap.empty()) {
+                _blossom_set->increase(v, std::numeric_limits<Value>::max());
+              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
+                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
+              }
+
+              if ((*_blossom_data)[vb].status == MATCHED) {
+                if (_blossom_set->classPrio(vb) ==
+                    std::numeric_limits<Value>::max()) {
+                  _delta2->erase(vb);
+                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
+                           (*_blossom_data)[vb].offset) {
+                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
+                                   (*_blossom_data)[vb].offset);
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+
+    void oddToMatched(int blossom) {
+      (*_blossom_data)[blossom].offset -= _delta_sum;
+
+      if (_blossom_set->classPrio(blossom) !=
+          std::numeric_limits<Value>::max()) {
+        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
+                       (*_blossom_data)[blossom].offset);
+      }
+
+      if (!_blossom_set->trivial(blossom)) {
+        _delta4->erase(blossom);
+      }
+    }
+
+    void oddToEven(int blossom, int tree) {
+      if (!_blossom_set->trivial(blossom)) {
+        _delta4->erase(blossom);
+        (*_blossom_data)[blossom].pot -=
+          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
+      }
+
+      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
+           n != INVALID; ++n) {
+        int ni = (*_node_index)[n];
+
+        _blossom_set->increase(n, std::numeric_limits<Value>::max());
+
+        (*_node_data)[ni].heap.clear();
+        (*_node_data)[ni].heap_index.clear();
+        (*_node_data)[ni].pot +=
+          2 * _delta_sum - (*_blossom_data)[blossom].offset;
+
+        for (InArcIt e(_graph, n); e != INVALID; ++e) {
+          Node v = _graph.source(e);
+          int vb = _blossom_set->find(v);
+          int vi = (*_node_index)[v];
+
+          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
+            dualScale * _weight[e];
+
+          if ((*_blossom_data)[vb].status == EVEN) {
+            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
+              _delta3->push(e, rw / 2);
+            }
+          } else {
+
+            typename std::map<int, Arc>::iterator it =
+              (*_node_data)[vi].heap_index.find(tree);
+
+            if (it != (*_node_data)[vi].heap_index.end()) {
+              if ((*_node_data)[vi].heap[it->second] > rw) {
+                (*_node_data)[vi].heap.replace(it->second, e);
+                (*_node_data)[vi].heap.decrease(e, rw);
+                it->second = e;
+              }
+            } else {
+              (*_node_data)[vi].heap.push(e, rw);
+              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
+            }
+
+            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
+              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
+
+              if ((*_blossom_data)[vb].status == MATCHED) {
+                if (_delta2->state(vb) != _delta2->IN_HEAP) {
+                  _delta2->push(vb, _blossom_set->classPrio(vb) -
+                               (*_blossom_data)[vb].offset);
+                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
+                           (*_blossom_data)[vb].offset) {
+                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
+                                   (*_blossom_data)[vb].offset);
+                }
+              }
+            }
+          }
+        }
+      }
+      (*_blossom_data)[blossom].offset = 0;
+    }
+
+    void alternatePath(int even, int tree) {
+      int odd;
+
+      evenToMatched(even, tree);
+      (*_blossom_data)[even].status = MATCHED;
+
+      while ((*_blossom_data)[even].pred != INVALID) {
+        odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
+        (*_blossom_data)[odd].status = MATCHED;
+        oddToMatched(odd);
+        (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
+
+        even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
+        (*_blossom_data)[even].status = MATCHED;
+        evenToMatched(even, tree);
+        (*_blossom_data)[even].next =
+          _graph.oppositeArc((*_blossom_data)[odd].pred);
+      }
+
+    }
+
+    void destroyTree(int tree) {
+      for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
+        if ((*_blossom_data)[b].status == EVEN) {
+          (*_blossom_data)[b].status = MATCHED;
+          evenToMatched(b, tree);
+        } else if ((*_blossom_data)[b].status == ODD) {
+          (*_blossom_data)[b].status = MATCHED;
+          oddToMatched(b);
+        }
+      }
+      _tree_set->eraseClass(tree);
+    }
+
+    void augmentOnEdge(const Edge& edge) {
+
+      int left = _blossom_set->find(_graph.u(edge));
+      int right = _blossom_set->find(_graph.v(edge));
+
+      int left_tree = _tree_set->find(left);
+      alternatePath(left, left_tree);
+      destroyTree(left_tree);
+
+      int right_tree = _tree_set->find(right);
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+
+      (*_blossom_data)[left].next = _graph.direct(edge, true);
+      (*_blossom_data)[right].next = _graph.direct(edge, false);
+    }
+
+    void extendOnArc(const Arc& arc) {
+      int base = _blossom_set->find(_graph.target(arc));
+      int tree = _tree_set->find(base);
+
+      int odd = _blossom_set->find(_graph.source(arc));
+      _tree_set->insert(odd, tree);
+      (*_blossom_data)[odd].status = ODD;
+      matchedToOdd(odd);
+      (*_blossom_data)[odd].pred = arc;
+
+      int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
+      (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
+      _tree_set->insert(even, tree);
+      (*_blossom_data)[even].status = EVEN;
+      matchedToEven(even, tree);
+    }
+
+    void shrinkOnEdge(const Edge& edge, int tree) {
+      int nca = -1;
+      std::vector<int> left_path, right_path;
+
+      {
+        std::set<int> left_set, right_set;
+        int left = _blossom_set->find(_graph.u(edge));
+        left_path.push_back(left);
+        left_set.insert(left);
+
+        int right = _blossom_set->find(_graph.v(edge));
+        right_path.push_back(right);
+        right_set.insert(right);
+
+        while (true) {
+
+          if ((*_blossom_data)[left].pred == INVALID) break;
+
+          left =
+            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
+          left_path.push_back(left);
+          left =
+            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
+          left_path.push_back(left);
+
+          left_set.insert(left);
+
+          if (right_set.find(left) != right_set.end()) {
+            nca = left;
+            break;
+          }
+
+          if ((*_blossom_data)[right].pred == INVALID) break;
+
+          right =
+            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
+          right_path.push_back(right);
+          right =
+            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
+          right_path.push_back(right);
+
+          right_set.insert(right);
+
+          if (left_set.find(right) != left_set.end()) {
+            nca = right;
+            break;
+          }
+
+        }
+
+        if (nca == -1) {
+          if ((*_blossom_data)[left].pred == INVALID) {
+            nca = right;
+            while (left_set.find(nca) == left_set.end()) {
+              nca =
+                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
+              right_path.push_back(nca);
+              nca =
+                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
+              right_path.push_back(nca);
+            }
+          } else {
+            nca = left;
+            while (right_set.find(nca) == right_set.end()) {
+              nca =
+                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
+              left_path.push_back(nca);
+              nca =
+                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
+              left_path.push_back(nca);
+            }
+          }
+        }
+      }
+
+      std::vector<int> subblossoms;
+      Arc prev;
+
+      prev = _graph.direct(edge, true);
+      for (int i = 0; left_path[i] != nca; i += 2) {
+        subblossoms.push_back(left_path[i]);
+        (*_blossom_data)[left_path[i]].next = prev;
+        _tree_set->erase(left_path[i]);
+
+        subblossoms.push_back(left_path[i + 1]);
+        (*_blossom_data)[left_path[i + 1]].status = EVEN;
+        oddToEven(left_path[i + 1], tree);
+        _tree_set->erase(left_path[i + 1]);
+        prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
+      }
+
+      int k = 0;
+      while (right_path[k] != nca) ++k;
+
+      subblossoms.push_back(nca);
+      (*_blossom_data)[nca].next = prev;
+
+      for (int i = k - 2; i >= 0; i -= 2) {
+        subblossoms.push_back(right_path[i + 1]);
+        (*_blossom_data)[right_path[i + 1]].status = EVEN;
+        oddToEven(right_path[i + 1], tree);
+        _tree_set->erase(right_path[i + 1]);
+
+        (*_blossom_data)[right_path[i + 1]].next =
+          (*_blossom_data)[right_path[i + 1]].pred;
+
+        subblossoms.push_back(right_path[i]);
+        _tree_set->erase(right_path[i]);
+      }
+
+      int surface =
+        _blossom_set->join(subblossoms.begin(), subblossoms.end());
+
+      for (int i = 0; i < int(subblossoms.size()); ++i) {
+        if (!_blossom_set->trivial(subblossoms[i])) {
+          (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
+        }
+        (*_blossom_data)[subblossoms[i]].status = MATCHED;
+      }
+
+      (*_blossom_data)[surface].pot = -2 * _delta_sum;
+      (*_blossom_data)[surface].offset = 0;
+      (*_blossom_data)[surface].status = EVEN;
+      (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
+      (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
+
+      _tree_set->insert(surface, tree);
+      _tree_set->erase(nca);
+    }
+
+    void splitBlossom(int blossom) {
+      Arc next = (*_blossom_data)[blossom].next;
+      Arc pred = (*_blossom_data)[blossom].pred;
+
+      int tree = _tree_set->find(blossom);
+
+      (*_blossom_data)[blossom].status = MATCHED;
+      oddToMatched(blossom);
+      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
+        _delta2->erase(blossom);
+      }
+
+      std::vector<int> subblossoms;
+      _blossom_set->split(blossom, std::back_inserter(subblossoms));
+
+      Value offset = (*_blossom_data)[blossom].offset;
+      int b = _blossom_set->find(_graph.source(pred));
+      int d = _blossom_set->find(_graph.source(next));
+
+      int ib = -1, id = -1;
+      for (int i = 0; i < int(subblossoms.size()); ++i) {
+        if (subblossoms[i] == b) ib = i;
+        if (subblossoms[i] == d) id = i;
+
+        (*_blossom_data)[subblossoms[i]].offset = offset;
+        if (!_blossom_set->trivial(subblossoms[i])) {
+          (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
+        }
+        if (_blossom_set->classPrio(subblossoms[i]) !=
+            std::numeric_limits<Value>::max()) {
+          _delta2->push(subblossoms[i],
+                        _blossom_set->classPrio(subblossoms[i]) -
+                        (*_blossom_data)[subblossoms[i]].offset);
+        }
+      }
+
+      if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
+        for (int i = (id + 1) % subblossoms.size();
+             i != ib; i = (i + 2) % subblossoms.size()) {
+          int sb = subblossoms[i];
+          int tb = subblossoms[(i + 1) % subblossoms.size()];
+          (*_blossom_data)[sb].next =
+            _graph.oppositeArc((*_blossom_data)[tb].next);
+        }
+
+        for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
+          int sb = subblossoms[i];
+          int tb = subblossoms[(i + 1) % subblossoms.size()];
+          int ub = subblossoms[(i + 2) % subblossoms.size()];
+
+          (*_blossom_data)[sb].status = ODD;
+          matchedToOdd(sb);
+          _tree_set->insert(sb, tree);
+          (*_blossom_data)[sb].pred = pred;
+          (*_blossom_data)[sb].next =
+                           _graph.oppositeArc((*_blossom_data)[tb].next);
+
+          pred = (*_blossom_data)[ub].next;
+
+          (*_blossom_data)[tb].status = EVEN;
+          matchedToEven(tb, tree);
+          _tree_set->insert(tb, tree);
+          (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
+        }
+
+        (*_blossom_data)[subblossoms[id]].status = ODD;
+        matchedToOdd(subblossoms[id]);
+        _tree_set->insert(subblossoms[id], tree);
+        (*_blossom_data)[subblossoms[id]].next = next;
+        (*_blossom_data)[subblossoms[id]].pred = pred;
+
+      } else {
+
+        for (int i = (ib + 1) % subblossoms.size();
+             i != id; i = (i + 2) % subblossoms.size()) {
+          int sb = subblossoms[i];
+          int tb = subblossoms[(i + 1) % subblossoms.size()];
+          (*_blossom_data)[sb].next =
+            _graph.oppositeArc((*_blossom_data)[tb].next);
+        }
+
+        for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
+          int sb = subblossoms[i];
+          int tb = subblossoms[(i + 1) % subblossoms.size()];
+          int ub = subblossoms[(i + 2) % subblossoms.size()];
+
+          (*_blossom_data)[sb].status = ODD;
+          matchedToOdd(sb);
+          _tree_set->insert(sb, tree);
+          (*_blossom_data)[sb].next = next;
+          (*_blossom_data)[sb].pred =
+            _graph.oppositeArc((*_blossom_data)[tb].next);
+
+          (*_blossom_data)[tb].status = EVEN;
+          matchedToEven(tb, tree);
+          _tree_set->insert(tb, tree);
+          (*_blossom_data)[tb].pred =
+            (*_blossom_data)[tb].next =
+            _graph.oppositeArc((*_blossom_data)[ub].next);
+          next = (*_blossom_data)[ub].next;
+        }
+
+        (*_blossom_data)[subblossoms[ib]].status = ODD;
+        matchedToOdd(subblossoms[ib]);
+        _tree_set->insert(subblossoms[ib], tree);
+        (*_blossom_data)[subblossoms[ib]].next = next;
+        (*_blossom_data)[subblossoms[ib]].pred = pred;
+      }
+      _tree_set->erase(blossom);
+    }
+
+    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
+      if (_blossom_set->trivial(blossom)) {
+        int bi = (*_node_index)[base];
+        Value pot = (*_node_data)[bi].pot;
+
+        _matching->set(base, matching);
+        _blossom_node_list.push_back(base);
+        _node_potential->set(base, pot);
+      } else {
+
+        Value pot = (*_blossom_data)[blossom].pot;
+        int bn = _blossom_node_list.size();
+
+        std::vector<int> subblossoms;
+        _blossom_set->split(blossom, std::back_inserter(subblossoms));
+        int b = _blossom_set->find(base);
+        int ib = -1;
+        for (int i = 0; i < int(subblossoms.size()); ++i) {
+          if (subblossoms[i] == b) { ib = i; break; }
+        }
+
+        for (int i = 1; i < int(subblossoms.size()); i += 2) {
+          int sb = subblossoms[(ib + i) % subblossoms.size()];
+          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
+
+          Arc m = (*_blossom_data)[tb].next;
+          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
+          extractBlossom(tb, _graph.source(m), m);
+        }
+        extractBlossom(subblossoms[ib], base, matching);
+
+        int en = _blossom_node_list.size();
+
+        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
+      }
+    }
+
+    void extractMatching() {
+      std::vector<int> blossoms;
+      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
+        blossoms.push_back(c);
+      }
+
+      for (int i = 0; i < int(blossoms.size()); ++i) {
+
+        Value offset = (*_blossom_data)[blossoms[i]].offset;
+        (*_blossom_data)[blossoms[i]].pot += 2 * offset;
+        for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
+             n != INVALID; ++n) {
+          (*_node_data)[(*_node_index)[n]].pot -= offset;
+        }
+
+        Arc matching = (*_blossom_data)[blossoms[i]].next;
+        Node base = _graph.source(matching);
+        extractBlossom(blossoms[i], base, matching);
+      }
+    }
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    MaxWeightedPerfectMatching(const Graph& graph, const WeightMap& weight)
+      : _graph(graph), _weight(weight), _matching(0),
+        _node_potential(0), _blossom_potential(), _blossom_node_list(),
+        _node_num(0), _blossom_num(0),
+
+        _blossom_index(0), _blossom_set(0), _blossom_data(0),
+        _node_index(0), _node_heap_index(0), _node_data(0),
+        _tree_set_index(0), _tree_set(0),
+
+        _delta2_index(0), _delta2(0),
+        _delta3_index(0), _delta3(0),
+        _delta4_index(0), _delta4(0),
+
+        _delta_sum() {}
+
+    ~MaxWeightedPerfectMatching() {
+      destroyStructures();
+    }
+
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to use the
+    /// \c run() member function.
+
+    ///@{
+
+    /// \brief Initialize the algorithm
+    ///
+    /// Initialize the algorithm
+    void init() {
+      createStructures();
+
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        _node_heap_index->set(e, BinHeap<Value, IntArcMap>::PRE_HEAP);
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        _delta3_index->set(e, _delta3->PRE_HEAP);
+      }
+      for (int i = 0; i < _blossom_num; ++i) {
+        _delta2_index->set(i, _delta2->PRE_HEAP);
+        _delta4_index->set(i, _delta4->PRE_HEAP);
+      }
+
+      int index = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        Value max = - std::numeric_limits<Value>::max();
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          if (_graph.target(e) == n) continue;
+          if ((dualScale * _weight[e]) / 2 > max) {
+            max = (dualScale * _weight[e]) / 2;
+          }
+        }
+        _node_index->set(n, index);
+        (*_node_data)[index].pot = max;
+        int blossom =
+          _blossom_set->insert(n, std::numeric_limits<Value>::max());
+
+        _tree_set->insert(blossom);
+
+        (*_blossom_data)[blossom].status = EVEN;
+        (*_blossom_data)[blossom].pred = INVALID;
+        (*_blossom_data)[blossom].next = INVALID;
+        (*_blossom_data)[blossom].pot = 0;
+        (*_blossom_data)[blossom].offset = 0;
+        ++index;
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        int si = (*_node_index)[_graph.u(e)];
+        int ti = (*_node_index)[_graph.v(e)];
+        if (_graph.u(e) != _graph.v(e)) {
+          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
+                            dualScale * _weight[e]) / 2);
+        }
+      }
+    }
+
+    /// \brief Starts the algorithm
+    ///
+    /// Starts the algorithm
+    bool start() {
+      enum OpType {
+        D2, D3, D4
+      };
+
+      int unmatched = _node_num;
+      while (unmatched > 0) {
+        Value d2 = !_delta2->empty() ?
+          _delta2->prio() : std::numeric_limits<Value>::max();
+
+        Value d3 = !_delta3->empty() ?
+          _delta3->prio() : std::numeric_limits<Value>::max();
+
+        Value d4 = !_delta4->empty() ?
+          _delta4->prio() : std::numeric_limits<Value>::max();
+
+        _delta_sum = d2; OpType ot = D2;
+        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
+        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
+
+        if (_delta_sum == std::numeric_limits<Value>::max()) {
+          return false;
+        }
+
+        switch (ot) {
+        case D2:
+          {
+            int blossom = _delta2->top();
+            Node n = _blossom_set->classTop(blossom);
+            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
+            extendOnArc(e);
+          }
+          break;
+        case D3:
+          {
+            Edge e = _delta3->top();
+
+            int left_blossom = _blossom_set->find(_graph.u(e));
+            int right_blossom = _blossom_set->find(_graph.v(e));
+
+            if (left_blossom == right_blossom) {
+              _delta3->pop();
+            } else {
+              int left_tree = _tree_set->find(left_blossom);
+              int right_tree = _tree_set->find(right_blossom);
+
+              if (left_tree == right_tree) {
+                shrinkOnEdge(e, left_tree);
+              } else {
+                augmentOnEdge(e);
+                unmatched -= 2;
+              }
+            }
+          } break;
+        case D4:
+          splitBlossom(_delta4->top());
+          break;
+        }
+      }
+      extractMatching();
+      return true;
+    }
+
+    /// \brief Runs %MaxWeightedPerfectMatching algorithm.
+    ///
+    /// This method runs the %MaxWeightedPerfectMatching algorithm.
+    ///
+    /// \note mwm.run() is just a shortcut of the following code.
+    /// \code
+    ///   mwm.init();
+    ///   mwm.start();
+    /// \endcode
+    bool run() {
+      init();
+      return start();
+    }
+
+    /// @}
+
+    /// \name Primal solution
+    /// Functions to get the primal solution, ie. the matching.
+
+    /// @{
+
+    /// \brief Returns the matching value.
+    ///
+    /// Returns the matching value.
+    Value matchingValue() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          sum += _weight[(*_matching)[n]];
+        }
+      }
+      return sum /= 2;
+    }
+
+    /// \brief Returns true when the edge is in the matching.
+    ///
+    /// Returns true when the edge is in the matching.
+    bool matching(const Edge& edge) const {
+      return static_cast<const Edge&>((*_matching)[_graph.u(edge)]) == edge;
+    }
+
+    /// \brief Returns the incident matching edge.
+    ///
+    /// Returns the incident matching arc from given edge.
+    Arc matching(const Node& node) const {
+      return (*_matching)[node];
+    }
+
+    /// \brief Returns the mate of the node.
+    ///
+    /// Returns the adjancent node in a mathcing arc.
+    Node mate(const Node& node) const {
+      return _graph.target((*_matching)[node]);
+    }
+
+    /// @}
+
+    /// \name Dual solution
+    /// Functions to get the dual solution.
+
+    /// @{
+
+    /// \brief Returns the value of the dual solution.
+    ///
+    /// Returns the value of the dual solution. It should be equal to
+    /// the primal value scaled by \ref dualScale "dual scale".
+    Value dualValue() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        sum += nodeValue(n);
+      }
+      for (int i = 0; i < blossomNum(); ++i) {
+        sum += blossomValue(i) * (blossomSize(i) / 2);
+      }
+      return sum;
+    }
+
+    /// \brief Returns the value of the node.
+    ///
+    /// Returns the the value of the node.
+    Value nodeValue(const Node& n) const {
+      return (*_node_potential)[n];
+    }
+
+    /// \brief Returns the number of the blossoms in the basis.
+    ///
+    /// Returns the number of the blossoms in the basis.
+    /// \see BlossomIt
+    int blossomNum() const {
+      return _blossom_potential.size();
+    }
+
+
+    /// \brief Returns the number of the nodes in the blossom.
+    ///
+    /// Returns the number of the nodes in the blossom.
+    int blossomSize(int k) const {
+      return _blossom_potential[k].end - _blossom_potential[k].begin;
+    }
+
+    /// \brief Returns the value of the blossom.
+    ///
+    /// Returns the the value of the blossom.
+    /// \see BlossomIt
+    Value blossomValue(int k) const {
+      return _blossom_potential[k].value;
+    }
+
+    /// \brief Iterator for obtaining the nodes of the blossom.
+    ///
+    /// Iterator for obtaining the nodes of the blossom. This class
+    /// provides a common lemon style iterator for listing a
+    /// subset of the nodes.
+    class BlossomIt {
+    public:
+
+      /// \brief Constructor.
+      ///
+      /// Constructor to get the nodes of the variable.
+      BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable)
+        : _algorithm(&algorithm)
+      {
+        _index = _algorithm->_blossom_potential[variable].begin;
+        _last = _algorithm->_blossom_potential[variable].end;
+      }
+
+      /// \brief Conversion to node.
+      ///
+      /// Conversion to node.
+      operator Node() const {
+        return _algorithm->_blossom_node_list[_index];
+      }
+
+      /// \brief Increment operator.
+      ///
+      /// Increment operator.
+      BlossomIt& operator++() {
+        ++_index;
+        return *this;
+      }
+
+      /// \brief Validity checking
+      ///
+      /// Checks whether the iterator is invalid.
+      bool operator==(Invalid) const { return _index == _last; }
+
+      /// \brief Validity checking
+      ///
+      /// Checks whether the iterator is valid.
+      bool operator!=(Invalid) const { return _index != _last; }
+
+    private:
+      const MaxWeightedPerfectMatching* _algorithm;
+      int _last;
+      int _index;
+    };
+
+    /// @}
+
+  };
+
+
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_MAX_MATCHING_H
Index: lemon/nauty_reader.h
===================================================================
--- lemon/nauty_reader.h	(revision 440)
+++ lemon/nauty_reader.h	(revision 440)
@@ -0,0 +1,113 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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_NAUTY_READER_H
+#define LEMON_NAUTY_READER_H
+
+#include <vector>
+#include <iostream>
+#include <string>
+
+/// \ingroup nauty_group
+/// \file
+/// \brief Nauty file reader.
+
+namespace lemon {
+
+  /// \ingroup nauty_group
+  ///
+  /// \brief Nauty file reader
+  ///
+  /// The \e geng program is in the \e gtools suite of the nauty
+  /// package. This tool can generate all non-isomorphic undirected
+  /// graphs of several classes with given node number (e.g.
+  /// general, connected, biconnected, triangle-free, 4-cycle-free,
+  /// bipartite and graphs with given edge number and degree
+  /// constraints). This function reads a \e nauty \e graph6 \e format
+  /// line from the given stream and builds it in the given graph.
+  ///
+  /// The site of nauty package: http://cs.anu.edu.au/~bdm/nauty/
+  ///
+  /// For example, the number of all non-isomorphic planar graphs
+  /// can be computed with the following code.
+  ///\code
+  /// int num = 0;
+  /// SmartGraph graph;
+  /// while (readNautyGraph(graph, std::cin)) {
+  ///   PlanarityChecking<SmartGraph> pc(graph);
+  ///   if (pc.run()) ++num;
+  /// }
+  /// std::cout << "Number of planar graphs: " << num << std::endl;
+  ///\endcode
+  ///
+  /// The nauty files are quite huge, therefore instead of the direct
+  /// file generation pipelining is recommended. For example,
+  ///\code
+  /// ./geng -c 10 | ./num_of_planar_graphs
+  ///\endcode
+  template <typename Graph>
+  std::istream& readNautyGraph(Graph& graph, std::istream& is = std::cin) {
+    graph.clear();
+
+    std::string line;
+    if (getline(is, line)) {
+      int index = 0;
+
+      int n;
+
+      if (line[index] == '>') {
+        index += 10;
+      }
+
+      char c = line[index++]; c -= 63;
+      if (c != 63) {
+        n = int(c);
+      } else {
+        c = line[index++]; c -= 63;
+        n = (int(c) << 12);
+        c = line[index++]; c -= 63;
+        n |= (int(c) << 6);
+        c = line[index++]; c -= 63;
+        n |= int(c);
+      }
+
+      std::vector<typename Graph::Node> nodes;
+      for (int i = 0; i < n; ++i) {
+        nodes.push_back(graph.addNode());
+      }
+
+      int bit = -1;
+      for (int j = 0; j < n; ++j) {
+        for (int i = 0; i < j; ++i) {
+          if (bit == -1) {
+            c = line[index++]; c -= 63;
+            bit = 5;
+          }
+          bool b = (c & (1 << (bit--))) != 0;
+
+          if (b) {
+            graph.addEdge(nodes[i], nodes[j]);
+          }
+        }
+      }
+    }
+    return is;
+  }
+}
+
+#endif
Index: lemon/path.h
===================================================================
--- lemon/path.h	(revision 487)
+++ lemon/path.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -930,6 +930,7 @@
 
     template <typename Target, typename Source,
-              bool buildEnable = BuildTagIndicator<Target>::value>
-    struct PathCopySelectorForward {
+              bool buildEnable = BuildTagIndicator<Target>::value,
+              bool revEnable = RevPathTagIndicator<Source>::value>
+    struct PathCopySelector {
       static void copy(Target& target, const Source& source) {
         target.clear();
@@ -941,14 +942,5 @@
 
     template <typename Target, typename Source>
-    struct PathCopySelectorForward<Target, Source, true> {
-      static void copy(Target& target, const Source& source) {
-        target.clear();
-        target.build(source);
-      }
-    };
-
-    template <typename Target, typename Source,
-              bool buildEnable = BuildTagIndicator<Target>::value>
-    struct PathCopySelectorBackward {
+    struct PathCopySelector<Target, Source, false, true> {
       static void copy(Target& target, const Source& source) {
         target.clear();
@@ -960,25 +952,17 @@
 
     template <typename Target, typename Source>
-    struct PathCopySelectorBackward<Target, Source, true> {
+    struct PathCopySelector<Target, Source, true, false> {
+      static void copy(Target& target, const Source& source) {
+        target.clear();
+        target.build(source);
+      }
+    };
+
+    template <typename Target, typename Source>
+    struct PathCopySelector<Target, Source, true, true> {
       static void copy(Target& target, const Source& source) {
         target.clear();
         target.buildRev(source);
       }
-    };
-
-    
-    template <typename Target, typename Source,
-              bool revEnable = RevPathTagIndicator<Source>::value>
-    struct PathCopySelector {
-      static void copy(Target& target, const Source& source) {
-        PathCopySelectorForward<Target, Source>::copy(target, source);
-      }      
-    };
-
-    template <typename Target, typename Source>
-    struct PathCopySelector<Target, Source, true> {
-      static void copy(Target& target, const Source& source) {
-        PathCopySelectorBackward<Target, Source>::copy(target, source);
-      }      
     };
 
Index: lemon/preflow.h
===================================================================
--- lemon/preflow.h	(revision 492)
+++ lemon/preflow.h	(revision 492)
@@ -0,0 +1,964 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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_PREFLOW_H
+#define LEMON_PREFLOW_H
+
+#include <lemon/tolerance.h>
+#include <lemon/elevator.h>
+
+/// \file
+/// \ingroup max_flow
+/// \brief Implementation of the preflow algorithm.
+
+namespace lemon {
+
+  /// \brief Default traits class of Preflow class.
+  ///
+  /// Default traits class of Preflow class.
+  /// \tparam GR Digraph type.
+  /// \tparam CM Capacity map type.
+  template <typename GR, typename CM>
+  struct PreflowDefaultTraits {
+
+    /// \brief The type of the digraph the algorithm runs on.
+    typedef GR Digraph;
+
+    /// \brief The type of the map that stores the arc capacities.
+    ///
+    /// The type of the map that stores the arc capacities.
+    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
+    typedef CM CapacityMap;
+
+    /// \brief The type of the flow values.
+    typedef typename CapacityMap::Value Value;
+
+    /// \brief The type of the map that stores the flow values.
+    ///
+    /// The type of the map that stores the flow values.
+    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    typedef typename Digraph::template ArcMap<Value> FlowMap;
+
+    /// \brief Instantiates a FlowMap.
+    ///
+    /// This function instantiates a \ref FlowMap.
+    /// \param digraph The digraph, to which we would like to define
+    /// the flow map.
+    static FlowMap* createFlowMap(const Digraph& digraph) {
+      return new FlowMap(digraph);
+    }
+
+    /// \brief The elevator type used by Preflow algorithm.
+    ///
+    /// The elevator type used by Preflow algorithm.
+    ///
+    /// \sa Elevator
+    /// \sa LinkedElevator
+    typedef LinkedElevator<Digraph, typename Digraph::Node> Elevator;
+
+    /// \brief Instantiates an Elevator.
+    ///
+    /// This function instantiates an \ref Elevator.
+    /// \param digraph The digraph, to which we would like to define
+    /// the elevator.
+    /// \param max_level The maximum level of the elevator.
+    static Elevator* createElevator(const Digraph& digraph, int max_level) {
+      return new Elevator(digraph, max_level);
+    }
+
+    /// \brief The tolerance used by the algorithm
+    ///
+    /// The tolerance used by the algorithm to handle inexact computation.
+    typedef lemon::Tolerance<Value> Tolerance;
+
+  };
+
+
+  /// \ingroup max_flow
+  ///
+  /// \brief %Preflow algorithm class.
+  ///
+  /// This class provides an implementation of Goldberg-Tarjan's \e preflow
+  /// \e push-relabel algorithm producing a flow of maximum value in a
+  /// digraph. The preflow algorithms are the fastest known maximum
+  /// flow algorithms. The current implementation use a mixture of the
+  /// \e "highest label" and the \e "bound decrease" heuristics.
+  /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{e})\f$.
+  ///
+  /// The algorithm consists of two phases. After the first phase
+  /// the maximum flow value and the minimum cut is obtained. The
+  /// second phase constructs a feasible maximum flow on each arc.
+  ///
+  /// \tparam GR The type of the digraph the algorithm runs on.
+  /// \tparam CM The type of the capacity map. The default map
+  /// type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+#ifdef DOXYGEN
+  template <typename GR, typename CM, typename TR>
+#else
+  template <typename GR,
+            typename CM = typename GR::template ArcMap<int>,
+            typename TR = PreflowDefaultTraits<GR, CM> >
+#endif
+  class Preflow {
+  public:
+
+    ///The \ref PreflowDefaultTraits "traits class" of the algorithm.
+    typedef TR Traits;
+    ///The type of the digraph the algorithm runs on.
+    typedef typename Traits::Digraph Digraph;
+    ///The type of the capacity map.
+    typedef typename Traits::CapacityMap CapacityMap;
+    ///The type of the flow values.
+    typedef typename Traits::Value Value;
+
+    ///The type of the flow map.
+    typedef typename Traits::FlowMap FlowMap;
+    ///The type of the elevator.
+    typedef typename Traits::Elevator Elevator;
+    ///The type of the tolerance.
+    typedef typename Traits::Tolerance Tolerance;
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+    const Digraph& _graph;
+    const CapacityMap* _capacity;
+
+    int _node_num;
+
+    Node _source, _target;
+
+    FlowMap* _flow;
+    bool _local_flow;
+
+    Elevator* _level;
+    bool _local_level;
+
+    typedef typename Digraph::template NodeMap<Value> ExcessMap;
+    ExcessMap* _excess;
+
+    Tolerance _tolerance;
+
+    bool _phase;
+
+
+    void createStructures() {
+      _node_num = countNodes(_graph);
+
+      if (!_flow) {
+        _flow = Traits::createFlowMap(_graph);
+        _local_flow = true;
+      }
+      if (!_level) {
+        _level = Traits::createElevator(_graph, _node_num);
+        _local_level = true;
+      }
+      if (!_excess) {
+        _excess = new ExcessMap(_graph);
+      }
+    }
+
+    void destroyStructures() {
+      if (_local_flow) {
+        delete _flow;
+      }
+      if (_local_level) {
+        delete _level;
+      }
+      if (_excess) {
+        delete _excess;
+      }
+    }
+
+  public:
+
+    typedef Preflow Create;
+
+    ///\name Named Template Parameters
+
+    ///@{
+
+    template <typename _FlowMap>
+    struct SetFlowMapTraits : public Traits {
+      typedef _FlowMap FlowMap;
+      static FlowMap *createFlowMap(const Digraph&) {
+        LEMON_ASSERT(false, "FlowMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// FlowMap type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting FlowMap
+    /// type.
+    template <typename _FlowMap>
+    struct SetFlowMap
+      : public Preflow<Digraph, CapacityMap, SetFlowMapTraits<_FlowMap> > {
+      typedef Preflow<Digraph, CapacityMap,
+                      SetFlowMapTraits<_FlowMap> > Create;
+    };
+
+    template <typename _Elevator>
+    struct SetElevatorTraits : public Traits {
+      typedef _Elevator Elevator;
+      static Elevator *createElevator(const Digraph&, int) {
+        LEMON_ASSERT(false, "Elevator is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// Elevator type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting Elevator
+    /// type. If this named parameter is used, then an external
+    /// elevator object must be passed to the algorithm using the
+    /// \ref elevator(Elevator&) "elevator()" function before calling
+    /// \ref run() or \ref init().
+    /// \sa SetStandardElevator
+    template <typename _Elevator>
+    struct SetElevator
+      : public Preflow<Digraph, CapacityMap, SetElevatorTraits<_Elevator> > {
+      typedef Preflow<Digraph, CapacityMap,
+                      SetElevatorTraits<_Elevator> > Create;
+    };
+
+    template <typename _Elevator>
+    struct SetStandardElevatorTraits : public Traits {
+      typedef _Elevator Elevator;
+      static Elevator *createElevator(const Digraph& digraph, int max_level) {
+        return new Elevator(digraph, max_level);
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// Elevator type with automatic allocation
+    ///
+    /// \ref named-templ-param "Named parameter" for setting Elevator
+    /// type with automatic allocation.
+    /// The Elevator should have standard constructor interface to be
+    /// able to automatically created by the algorithm (i.e. the
+    /// digraph and the maximum level should be passed to it).
+    /// However an external elevator object could also be passed to the
+    /// algorithm with the \ref elevator(Elevator&) "elevator()" function
+    /// before calling \ref run() or \ref init().
+    /// \sa SetElevator
+    template <typename _Elevator>
+    struct SetStandardElevator
+      : public Preflow<Digraph, CapacityMap,
+                       SetStandardElevatorTraits<_Elevator> > {
+      typedef Preflow<Digraph, CapacityMap,
+                      SetStandardElevatorTraits<_Elevator> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    Preflow() {}
+
+  public:
+
+
+    /// \brief The constructor of the class.
+    ///
+    /// The constructor of the class.
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param capacity The capacity of the arcs.
+    /// \param source The source node.
+    /// \param target The target node.
+    Preflow(const Digraph& digraph, const CapacityMap& capacity,
+            Node source, Node target)
+      : _graph(digraph), _capacity(&capacity),
+        _node_num(0), _source(source), _target(target),
+        _flow(0), _local_flow(false),
+        _level(0), _local_level(false),
+        _excess(0), _tolerance(), _phase() {}
+
+    /// \brief Destructor.
+    ///
+    /// Destructor.
+    ~Preflow() {
+      destroyStructures();
+    }
+
+    /// \brief Sets the capacity map.
+    ///
+    /// Sets the capacity map.
+    /// \return <tt>(*this)</tt>
+    Preflow& capacityMap(const CapacityMap& map) {
+      _capacity = &map;
+      return *this;
+    }
+
+    /// \brief Sets the flow map.
+    ///
+    /// Sets the flow map.
+    /// If you don't use this function before calling \ref run() or
+    /// \ref init(), an instance will be allocated automatically.
+    /// The destructor deallocates this automatically allocated map,
+    /// of course.
+    /// \return <tt>(*this)</tt>
+    Preflow& flowMap(FlowMap& map) {
+      if (_local_flow) {
+        delete _flow;
+        _local_flow = false;
+      }
+      _flow = &map;
+      return *this;
+    }
+
+    /// \brief Sets the source node.
+    ///
+    /// Sets the source node.
+    /// \return <tt>(*this)</tt>
+    Preflow& source(const Node& node) {
+      _source = node;
+      return *this;
+    }
+
+    /// \brief Sets the target node.
+    ///
+    /// Sets the target node.
+    /// \return <tt>(*this)</tt>
+    Preflow& target(const Node& node) {
+      _target = node;
+      return *this;
+    }
+
+    /// \brief Sets the elevator used by algorithm.
+    ///
+    /// Sets the elevator used by algorithm.
+    /// If you don't use this function before calling \ref run() or
+    /// \ref init(), an instance will be allocated automatically.
+    /// The destructor deallocates this automatically allocated elevator,
+    /// of course.
+    /// \return <tt>(*this)</tt>
+    Preflow& elevator(Elevator& elevator) {
+      if (_local_level) {
+        delete _level;
+        _local_level = false;
+      }
+      _level = &elevator;
+      return *this;
+    }
+
+    /// \brief Returns a const reference to the elevator.
+    ///
+    /// Returns a const reference to the elevator.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    const Elevator& elevator() const {
+      return *_level;
+    }
+
+    /// \brief Sets the tolerance used by algorithm.
+    ///
+    /// Sets the tolerance used by algorithm.
+    Preflow& tolerance(const Tolerance& tolerance) const {
+      _tolerance = tolerance;
+      return *this;
+    }
+
+    /// \brief Returns a const reference to the tolerance.
+    ///
+    /// Returns a const reference to the tolerance.
+    const Tolerance& tolerance() const {
+      return tolerance;
+    }
+
+    /// \name Execution Control
+    /// The simplest way to execute the preflow algorithm is to use
+    /// \ref run() or \ref runMinCut().\n
+    /// If you need more control on the initial solution or the execution,
+    /// first you have to call one of the \ref init() functions, then
+    /// \ref startFirstPhase() and if you need it \ref startSecondPhase().
+
+    ///@{
+
+    /// \brief Initializes the internal data structures.
+    ///
+    /// Initializes the internal data structures and sets the initial
+    /// flow to zero on each arc.
+    void init() {
+      createStructures();
+
+      _phase = true;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _excess->set(n, 0);
+      }
+
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        _flow->set(e, 0);
+      }
+
+      typename Digraph::template NodeMap<bool> reached(_graph, false);
+
+      _level->initStart();
+      _level->initAddItem(_target);
+
+      std::vector<Node> queue;
+      reached.set(_source, true);
+
+      queue.push_back(_target);
+      reached.set(_target, true);
+      while (!queue.empty()) {
+        _level->initNewLevel();
+        std::vector<Node> nqueue;
+        for (int i = 0; i < int(queue.size()); ++i) {
+          Node n = queue[i];
+          for (InArcIt e(_graph, n); e != INVALID; ++e) {
+            Node u = _graph.source(e);
+            if (!reached[u] && _tolerance.positive((*_capacity)[e])) {
+              reached.set(u, true);
+              _level->initAddItem(u);
+              nqueue.push_back(u);
+            }
+          }
+        }
+        queue.swap(nqueue);
+      }
+      _level->initFinish();
+
+      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
+        if (_tolerance.positive((*_capacity)[e])) {
+          Node u = _graph.target(e);
+          if ((*_level)[u] == _level->maxLevel()) continue;
+          _flow->set(e, (*_capacity)[e]);
+          _excess->set(u, (*_excess)[u] + (*_capacity)[e]);
+          if (u != _target && !_level->active(u)) {
+            _level->activate(u);
+          }
+        }
+      }
+    }
+
+    /// \brief Initializes the internal data structures using the
+    /// given flow map.
+    ///
+    /// Initializes the internal data structures and sets the initial
+    /// flow to the given \c flowMap. The \c flowMap should contain a
+    /// flow or at least a preflow, i.e. at each node excluding the
+    /// source node the incoming flow should greater or equal to the
+    /// outgoing flow.
+    /// \return \c false if the given \c flowMap is not a preflow.
+    template <typename FlowMap>
+    bool init(const FlowMap& flowMap) {
+      createStructures();
+
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        _flow->set(e, flowMap[e]);
+      }
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        Value excess = 0;
+        for (InArcIt e(_graph, n); e != INVALID; ++e) {
+          excess += (*_flow)[e];
+        }
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          excess -= (*_flow)[e];
+        }
+        if (excess < 0 && n != _source) return false;
+        _excess->set(n, excess);
+      }
+
+      typename Digraph::template NodeMap<bool> reached(_graph, false);
+
+      _level->initStart();
+      _level->initAddItem(_target);
+
+      std::vector<Node> queue;
+      reached.set(_source, true);
+
+      queue.push_back(_target);
+      reached.set(_target, true);
+      while (!queue.empty()) {
+        _level->initNewLevel();
+        std::vector<Node> nqueue;
+        for (int i = 0; i < int(queue.size()); ++i) {
+          Node n = queue[i];
+          for (InArcIt e(_graph, n); e != INVALID; ++e) {
+            Node u = _graph.source(e);
+            if (!reached[u] &&
+                _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
+              reached.set(u, true);
+              _level->initAddItem(u);
+              nqueue.push_back(u);
+            }
+          }
+          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+            Node v = _graph.target(e);
+            if (!reached[v] && _tolerance.positive((*_flow)[e])) {
+              reached.set(v, true);
+              _level->initAddItem(v);
+              nqueue.push_back(v);
+            }
+          }
+        }
+        queue.swap(nqueue);
+      }
+      _level->initFinish();
+
+      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
+        Value rem = (*_capacity)[e] - (*_flow)[e];
+        if (_tolerance.positive(rem)) {
+          Node u = _graph.target(e);
+          if ((*_level)[u] == _level->maxLevel()) continue;
+          _flow->set(e, (*_capacity)[e]);
+          _excess->set(u, (*_excess)[u] + rem);
+          if (u != _target && !_level->active(u)) {
+            _level->activate(u);
+          }
+        }
+      }
+      for (InArcIt e(_graph, _source); e != INVALID; ++e) {
+        Value rem = (*_flow)[e];
+        if (_tolerance.positive(rem)) {
+          Node v = _graph.source(e);
+          if ((*_level)[v] == _level->maxLevel()) continue;
+          _flow->set(e, 0);
+          _excess->set(v, (*_excess)[v] + rem);
+          if (v != _target && !_level->active(v)) {
+            _level->activate(v);
+          }
+        }
+      }
+      return true;
+    }
+
+    /// \brief Starts the first phase of the preflow algorithm.
+    ///
+    /// The preflow algorithm consists of two phases, this method runs
+    /// the first phase. After the first phase the maximum flow value
+    /// and a minimum value cut can already be computed, although a
+    /// maximum flow is not yet obtained. So after calling this method
+    /// \ref flowValue() returns the value of a maximum flow and \ref
+    /// minCut() returns a minimum cut.
+    /// \pre One of the \ref init() functions must be called before
+    /// using this function.
+    void startFirstPhase() {
+      _phase = true;
+
+      Node n = _level->highestActive();
+      int level = _level->highestActiveLevel();
+      while (n != INVALID) {
+        int num = _node_num;
+
+        while (num > 0 && n != INVALID) {
+          Value excess = (*_excess)[n];
+          int new_level = _level->maxLevel();
+
+          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+            Value rem = (*_capacity)[e] - (*_flow)[e];
+            if (!_tolerance.positive(rem)) continue;
+            Node v = _graph.target(e);
+            if ((*_level)[v] < level) {
+              if (!_level->active(v) && v != _target) {
+                _level->activate(v);
+              }
+              if (!_tolerance.less(rem, excess)) {
+                _flow->set(e, (*_flow)[e] + excess);
+                _excess->set(v, (*_excess)[v] + excess);
+                excess = 0;
+                goto no_more_push_1;
+              } else {
+                excess -= rem;
+                _excess->set(v, (*_excess)[v] + rem);
+                _flow->set(e, (*_capacity)[e]);
+              }
+            } else if (new_level > (*_level)[v]) {
+              new_level = (*_level)[v];
+            }
+          }
+
+          for (InArcIt e(_graph, n); e != INVALID; ++e) {
+            Value rem = (*_flow)[e];
+            if (!_tolerance.positive(rem)) continue;
+            Node v = _graph.source(e);
+            if ((*_level)[v] < level) {
+              if (!_level->active(v) && v != _target) {
+                _level->activate(v);
+              }
+              if (!_tolerance.less(rem, excess)) {
+                _flow->set(e, (*_flow)[e] - excess);
+                _excess->set(v, (*_excess)[v] + excess);
+                excess = 0;
+                goto no_more_push_1;
+              } else {
+                excess -= rem;
+                _excess->set(v, (*_excess)[v] + rem);
+                _flow->set(e, 0);
+              }
+            } else if (new_level > (*_level)[v]) {
+              new_level = (*_level)[v];
+            }
+          }
+
+        no_more_push_1:
+
+          _excess->set(n, excess);
+
+          if (excess != 0) {
+            if (new_level + 1 < _level->maxLevel()) {
+              _level->liftHighestActive(new_level + 1);
+            } else {
+              _level->liftHighestActiveToTop();
+            }
+            if (_level->emptyLevel(level)) {
+              _level->liftToTop(level);
+            }
+          } else {
+            _level->deactivate(n);
+          }
+
+          n = _level->highestActive();
+          level = _level->highestActiveLevel();
+          --num;
+        }
+
+        num = _node_num * 20;
+        while (num > 0 && n != INVALID) {
+          Value excess = (*_excess)[n];
+          int new_level = _level->maxLevel();
+
+          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+            Value rem = (*_capacity)[e] - (*_flow)[e];
+            if (!_tolerance.positive(rem)) continue;
+            Node v = _graph.target(e);
+            if ((*_level)[v] < level) {
+              if (!_level->active(v) && v != _target) {
+                _level->activate(v);
+              }
+              if (!_tolerance.less(rem, excess)) {
+                _flow->set(e, (*_flow)[e] + excess);
+                _excess->set(v, (*_excess)[v] + excess);
+                excess = 0;
+                goto no_more_push_2;
+              } else {
+                excess -= rem;
+                _excess->set(v, (*_excess)[v] + rem);
+                _flow->set(e, (*_capacity)[e]);
+              }
+            } else if (new_level > (*_level)[v]) {
+              new_level = (*_level)[v];
+            }
+          }
+
+          for (InArcIt e(_graph, n); e != INVALID; ++e) {
+            Value rem = (*_flow)[e];
+            if (!_tolerance.positive(rem)) continue;
+            Node v = _graph.source(e);
+            if ((*_level)[v] < level) {
+              if (!_level->active(v) && v != _target) {
+                _level->activate(v);
+              }
+              if (!_tolerance.less(rem, excess)) {
+                _flow->set(e, (*_flow)[e] - excess);
+                _excess->set(v, (*_excess)[v] + excess);
+                excess = 0;
+                goto no_more_push_2;
+              } else {
+                excess -= rem;
+                _excess->set(v, (*_excess)[v] + rem);
+                _flow->set(e, 0);
+              }
+            } else if (new_level > (*_level)[v]) {
+              new_level = (*_level)[v];
+            }
+          }
+
+        no_more_push_2:
+
+          _excess->set(n, excess);
+
+          if (excess != 0) {
+            if (new_level + 1 < _level->maxLevel()) {
+              _level->liftActiveOn(level, new_level + 1);
+            } else {
+              _level->liftActiveToTop(level);
+            }
+            if (_level->emptyLevel(level)) {
+              _level->liftToTop(level);
+            }
+          } else {
+            _level->deactivate(n);
+          }
+
+          while (level >= 0 && _level->activeFree(level)) {
+            --level;
+          }
+          if (level == -1) {
+            n = _level->highestActive();
+            level = _level->highestActiveLevel();
+          } else {
+            n = _level->activeOn(level);
+          }
+          --num;
+        }
+      }
+    }
+
+    /// \brief Starts the second phase of the preflow algorithm.
+    ///
+    /// The preflow algorithm consists of two phases, this method runs
+    /// the second phase. After calling one of the \ref init() functions
+    /// and \ref startFirstPhase() and then \ref startSecondPhase(),
+    /// \ref flowMap() returns a maximum flow, \ref flowValue() returns the
+    /// value of a maximum flow, \ref minCut() returns a minimum cut
+    /// \pre One of the \ref init() functions and \ref startFirstPhase()
+    /// must be called before using this function.
+    void startSecondPhase() {
+      _phase = false;
+
+      typename Digraph::template NodeMap<bool> reached(_graph);
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        reached.set(n, (*_level)[n] < _level->maxLevel());
+      }
+
+      _level->initStart();
+      _level->initAddItem(_source);
+
+      std::vector<Node> queue;
+      queue.push_back(_source);
+      reached.set(_source, true);
+
+      while (!queue.empty()) {
+        _level->initNewLevel();
+        std::vector<Node> nqueue;
+        for (int i = 0; i < int(queue.size()); ++i) {
+          Node n = queue[i];
+          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+            Node v = _graph.target(e);
+            if (!reached[v] && _tolerance.positive((*_flow)[e])) {
+              reached.set(v, true);
+              _level->initAddItem(v);
+              nqueue.push_back(v);
+            }
+          }
+          for (InArcIt e(_graph, n); e != INVALID; ++e) {
+            Node u = _graph.source(e);
+            if (!reached[u] &&
+                _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
+              reached.set(u, true);
+              _level->initAddItem(u);
+              nqueue.push_back(u);
+            }
+          }
+        }
+        queue.swap(nqueue);
+      }
+      _level->initFinish();
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if (!reached[n]) {
+          _level->dirtyTopButOne(n);
+        } else if ((*_excess)[n] > 0 && _target != n) {
+          _level->activate(n);
+        }
+      }
+
+      Node n;
+      while ((n = _level->highestActive()) != INVALID) {
+        Value excess = (*_excess)[n];
+        int level = _level->highestActiveLevel();
+        int new_level = _level->maxLevel();
+
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          Value rem = (*_capacity)[e] - (*_flow)[e];
+          if (!_tolerance.positive(rem)) continue;
+          Node v = _graph.target(e);
+          if ((*_level)[v] < level) {
+            if (!_level->active(v) && v != _source) {
+              _level->activate(v);
+            }
+            if (!_tolerance.less(rem, excess)) {
+              _flow->set(e, (*_flow)[e] + excess);
+              _excess->set(v, (*_excess)[v] + excess);
+              excess = 0;
+              goto no_more_push;
+            } else {
+              excess -= rem;
+              _excess->set(v, (*_excess)[v] + rem);
+              _flow->set(e, (*_capacity)[e]);
+            }
+          } else if (new_level > (*_level)[v]) {
+            new_level = (*_level)[v];
+          }
+        }
+
+        for (InArcIt e(_graph, n); e != INVALID; ++e) {
+          Value rem = (*_flow)[e];
+          if (!_tolerance.positive(rem)) continue;
+          Node v = _graph.source(e);
+          if ((*_level)[v] < level) {
+            if (!_level->active(v) && v != _source) {
+              _level->activate(v);
+            }
+            if (!_tolerance.less(rem, excess)) {
+              _flow->set(e, (*_flow)[e] - excess);
+              _excess->set(v, (*_excess)[v] + excess);
+              excess = 0;
+              goto no_more_push;
+            } else {
+              excess -= rem;
+              _excess->set(v, (*_excess)[v] + rem);
+              _flow->set(e, 0);
+            }
+          } else if (new_level > (*_level)[v]) {
+            new_level = (*_level)[v];
+          }
+        }
+
+      no_more_push:
+
+        _excess->set(n, excess);
+
+        if (excess != 0) {
+          if (new_level + 1 < _level->maxLevel()) {
+            _level->liftHighestActive(new_level + 1);
+          } else {
+            // Calculation error
+            _level->liftHighestActiveToTop();
+          }
+          if (_level->emptyLevel(level)) {
+            // Calculation error
+            _level->liftToTop(level);
+          }
+        } else {
+          _level->deactivate(n);
+        }
+
+      }
+    }
+
+    /// \brief Runs the preflow algorithm.
+    ///
+    /// Runs the preflow algorithm.
+    /// \note pf.run() is just a shortcut of the following code.
+    /// \code
+    ///   pf.init();
+    ///   pf.startFirstPhase();
+    ///   pf.startSecondPhase();
+    /// \endcode
+    void run() {
+      init();
+      startFirstPhase();
+      startSecondPhase();
+    }
+
+    /// \brief Runs the preflow algorithm to compute the minimum cut.
+    ///
+    /// Runs the preflow algorithm to compute the minimum cut.
+    /// \note pf.runMinCut() is just a shortcut of the following code.
+    /// \code
+    ///   pf.init();
+    ///   pf.startFirstPhase();
+    /// \endcode
+    void runMinCut() {
+      init();
+      startFirstPhase();
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The results of the preflow algorithm can be obtained using these
+    /// functions.\n
+    /// Either one of the \ref run() "run*()" functions or one of the
+    /// \ref startFirstPhase() "start*()" functions should be called
+    /// before using them.
+
+    ///@{
+
+    /// \brief Returns the value of the maximum flow.
+    ///
+    /// Returns the value of the maximum flow by returning the excess
+    /// of the target node. This value equals to the value of
+    /// the maximum flow already after the first phase of the algorithm.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    Value flowValue() const {
+      return (*_excess)[_target];
+    }
+
+    /// \brief Returns the flow on the given arc.
+    ///
+    /// Returns the flow on the given arc. This method can
+    /// be called after the second phase of the algorithm.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    Value flow(const Arc& arc) const {
+      return (*_flow)[arc];
+    }
+
+    /// \brief Returns a const reference to the flow map.
+    ///
+    /// Returns a const reference to the arc map storing the found flow.
+    /// This method can be called after the second phase of the algorithm.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    const FlowMap& flowMap() const {
+      return *_flow;
+    }
+
+    /// \brief Returns \c true when the node is on the source side of the
+    /// minimum cut.
+    ///
+    /// Returns true when the node is on the source side of the found
+    /// minimum cut. This method can be called both after running \ref
+    /// startFirstPhase() and \ref startSecondPhase().
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    bool minCut(const Node& node) const {
+      return ((*_level)[node] == _level->maxLevel()) == _phase;
+    }
+
+    /// \brief Gives back a minimum value cut.
+    ///
+    /// Sets \c cutMap to the characteristic vector of a minimum value
+    /// cut. \c cutMap should be a \ref concepts::WriteMap "writable"
+    /// node map with \c bool (or convertible) value type.
+    ///
+    /// This method can be called both after running \ref startFirstPhase()
+    /// and \ref startSecondPhase(). The result after the second phase
+    /// could be slightly different if inexact computation is used.
+    ///
+    /// \note This function calls \ref minCut() for each node, so it runs in
+    /// \f$O(n)\f$ time.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    template <typename CutMap>
+    void minCutMap(CutMap& cutMap) const {
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        cutMap.set(n, minCut(n));
+      }
+    }
+
+    /// @}
+  };
+}
+
+#endif
Index: lemon/random.cc
===================================================================
--- lemon/random.cc	(revision 209)
+++ lemon/random.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/random.h
===================================================================
--- lemon/random.h	(revision 487)
+++ lemon/random.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -78,5 +78,5 @@
 #include <unistd.h>
 #else
-#include <lemon/bits/windows.h>
+#include <windows.h>
 #endif
 
@@ -345,6 +345,16 @@
     };
 
+    template <typename Result, int exp, bool pos = (exp >= 0)>
+    struct ShiftMultiplier {
+      static const Result multiplier() {
+        Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
+        res *= res;
+        if ((exp & 1) == 1) res *= static_cast<Result>(2.0);
+        return res;
+      }
+    };
+
     template <typename Result, int exp>
-    struct ShiftMultiplier {
+    struct ShiftMultiplier<Result, exp, false> {
       static const Result multiplier() {
         Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
@@ -356,5 +366,5 @@
 
     template <typename Result>
-    struct ShiftMultiplier<Result, 0> {
+    struct ShiftMultiplier<Result, 0, true> {
       static const Result multiplier() {
         return static_cast<Result>(1.0);
@@ -363,5 +373,5 @@
 
     template <typename Result>
-    struct ShiftMultiplier<Result, 20> {
+    struct ShiftMultiplier<Result, -20, true> {
       static const Result multiplier() {
         return static_cast<Result>(1.0/1048576.0);
@@ -370,12 +380,12 @@
 
     template <typename Result>
-    struct ShiftMultiplier<Result, 32> {
+    struct ShiftMultiplier<Result, -32, true> {
       static const Result multiplier() {
-        return static_cast<Result>(1.0/4294967296.0);
+        return static_cast<Result>(1.0/424967296.0);
       }
     };
 
     template <typename Result>
-    struct ShiftMultiplier<Result, 53> {
+    struct ShiftMultiplier<Result, -53, true> {
       static const Result multiplier() {
         return static_cast<Result>(1.0/9007199254740992.0);
@@ -384,5 +394,5 @@
 
     template <typename Result>
-    struct ShiftMultiplier<Result, 64> {
+    struct ShiftMultiplier<Result, -64, true> {
       static const Result multiplier() {
         return static_cast<Result>(1.0/18446744073709551616.0);
@@ -404,5 +414,5 @@
 
       static Result convert(RandomCore<Word>& rnd) {
-        return Shifting<Result, shift + rest>::
+        return Shifting<Result, - shift - rest>::
           shift(static_cast<Result>(rnd() >> (bits - rest)));
       }
@@ -414,5 +424,5 @@
 
       static Result convert(RandomCore<Word>& rnd) {
-        return Shifting<Result, shift + bits>::
+        return Shifting<Result, - shift - bits>::
           shift(static_cast<Result>(rnd())) +
           RealConversion<Result, Word, rest-bits, shift + bits>::
@@ -531,8 +541,4 @@
     /// @{
 
-    ///\name Initialization
-    ///
-    /// @{
-
     /// \brief Default constructor
     ///
@@ -657,5 +663,7 @@
       seed(getpid() + tv.tv_sec + tv.tv_usec);
 #else
-      seed(bits::getWinRndSeed());
+      FILETIME time;
+      GetSystemTimeAsFileTime(&time);
+      seed(GetCurrentProcessId() + time.dwHighDateTime + time.dwLowDateTime);
 #endif
       return true;
@@ -680,10 +688,4 @@
       return real<double>();
     }
-
-    /// @}
-
-    ///\name Uniform distributions
-    ///
-    /// @{
 
     /// \brief Returns a random real number from the range [0, 1)
@@ -741,6 +743,4 @@
       return _random_bits::IntConversion<Number, Word>::convert(core);
     }
-
-    /// @}
 
     unsigned int uinteger() {
@@ -777,8 +777,7 @@
     ///\name Non-uniform distributions
     ///
-
     ///@{
 
-    /// \brief Returns a random bool
+    /// \brief Returns a random bool with given probability of true result.
     ///
     /// It returns a random bool with given probability of true result.
@@ -787,7 +786,7 @@
     }
 
-    /// Standard Gauss distribution
-
-    /// Standard Gauss distribution.
+    /// 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.
@@ -802,11 +801,51 @@
       return std::sqrt(-2*std::log(S)/S)*V1;
     }
-    /// Gauss distribution with given mean and standard deviation
-
-    /// Gauss distribution with given mean and standard deviation.
+    /// 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));
     }
 
@@ -914,5 +953,4 @@
     ///\name Two dimensional distributions
     ///
-
     ///@{
 
@@ -931,5 +969,5 @@
       return dim2::Point<double>(V1,V2);
     }
-    /// A kind of two dimensional Gauss distribution
+    /// A kind of two dimensional normal (Gauss) distribution
 
     /// This function provides a turning symmetric two-dimensional distribution.
Index: lemon/smart_graph.h
===================================================================
--- lemon/smart_graph.h	(revision 313)
+++ lemon/smart_graph.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -68,5 +68,5 @@
 
     typedef True NodeNumTag;
-    typedef True EdgeNumTag;
+    typedef True ArcNumTag;
 
     int nodeNum() const { return nodes.size(); }
@@ -306,5 +306,7 @@
       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].source=b._id;
+      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);
       return b;
@@ -465,6 +467,6 @@
 
     public:
-      operator Edge() const { 
-        return _id != -1 ? edgeFromId(_id / 2) : INVALID; 
+      operator Edge() const {
+        return _id != -1 ? edgeFromId(_id / 2) : INVALID;
       }
 
@@ -481,4 +483,11 @@
       : nodes(), arcs() {}
 
+    typedef True NodeNumTag;
+    typedef True EdgeNumTag;
+    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; }
@@ -729,6 +738,6 @@
         dir.push_back(arcFromId(n-1));
         Parent::notifier(Arc()).erase(dir);
-        nodes[arcs[n].target].first_out=arcs[n].next_out;
-        nodes[arcs[n-1].target].first_out=arcs[n-1].next_out;
+        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();
Index: lemon/suurballe.h
===================================================================
--- lemon/suurballe.h	(revision 440)
+++ lemon/suurballe.h	(revision 440)
@@ -0,0 +1,501 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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_SUURBALLE_H
+#define LEMON_SUURBALLE_H
+
+///\ingroup shortest_path
+///\file
+///\brief An algorithm for finding arc-disjoint paths between two
+/// nodes having minimum total length.
+
+#include <vector>
+#include <lemon/bin_heap.h>
+#include <lemon/path.h>
+
+namespace lemon {
+
+  /// \addtogroup shortest_path
+  /// @{
+
+  /// \brief Algorithm for finding arc-disjoint paths between two nodes
+  /// having minimum total length.
+  ///
+  /// \ref lemon::Suurballe "Suurballe" implements an algorithm for
+  /// finding arc-disjoint paths having minimum total length (cost)
+  /// from a given source node to a given target node in a digraph.
+  ///
+  /// In fact, this implementation is the specialization of the
+  /// \ref CapacityScaling "successive shortest path" algorithm.
+  ///
+  /// \tparam Digraph The digraph type the algorithm runs on.
+  /// The default value is \c ListDigraph.
+  /// \tparam LengthMap The type of the length (cost) map.
+  /// The default value is <tt>Digraph::ArcMap<int></tt>.
+  ///
+  /// \warning Length values should be \e non-negative \e integers.
+  ///
+  /// \note For finding node-disjoint paths this algorithm can be used
+  /// with \ref SplitNodes.
+#ifdef DOXYGEN
+  template <typename Digraph, typename LengthMap>
+#else
+  template < typename Digraph = ListDigraph,
+             typename LengthMap = typename Digraph::template ArcMap<int> >
+#endif
+  class Suurballe
+  {
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+    typedef typename LengthMap::Value Length;
+    typedef ConstMap<Arc, int> ConstArcMap;
+    typedef typename Digraph::template NodeMap<Arc> PredMap;
+
+  public:
+
+    /// The type of the flow map.
+    typedef typename Digraph::template ArcMap<int> FlowMap;
+    /// The type of the potential map.
+    typedef typename Digraph::template NodeMap<Length> PotentialMap;
+    /// The type of the path structures.
+    typedef SimplePath<Digraph> Path;
+
+  private:
+
+    /// \brief Special implementation of the Dijkstra algorithm
+    /// for finding shortest paths in the residual network.
+    ///
+    /// \ref ResidualDijkstra is a special implementation of the
+    /// \ref Dijkstra algorithm for finding shortest paths in the
+    /// residual network of the digraph with respect to the reduced arc
+    /// lengths and modifying the node potentials according to the
+    /// distance of the nodes.
+    class ResidualDijkstra
+    {
+      typedef typename Digraph::template NodeMap<int> HeapCrossRef;
+      typedef BinHeap<Length, HeapCrossRef> Heap;
+
+    private:
+
+      // The digraph the algorithm runs on
+      const Digraph &_graph;
+
+      // The main maps
+      const FlowMap &_flow;
+      const LengthMap &_length;
+      PotentialMap &_potential;
+
+      // The distance map
+      PotentialMap _dist;
+      // The pred arc map
+      PredMap &_pred;
+      // The processed (i.e. permanently labeled) nodes
+      std::vector<Node> _proc_nodes;
+
+      Node _s;
+      Node _t;
+
+    public:
+
+      /// Constructor.
+      ResidualDijkstra( const Digraph &digraph,
+                        const FlowMap &flow,
+                        const LengthMap &length,
+                        PotentialMap &potential,
+                        PredMap &pred,
+                        Node s, Node t ) :
+        _graph(digraph), _flow(flow), _length(length), _potential(potential),
+        _dist(digraph), _pred(pred), _s(s), _t(t) {}
+
+      /// \brief Run the algorithm. It returns \c true if a path is found
+      /// from the source node to the target node.
+      bool run() {
+        HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
+        Heap heap(heap_cross_ref);
+        heap.push(_s, 0);
+        _pred[_s] = INVALID;
+        _proc_nodes.clear();
+
+        // Process nodes
+        while (!heap.empty() && heap.top() != _t) {
+          Node u = heap.top(), v;
+          Length d = heap.prio() + _potential[u], nd;
+          _dist[u] = heap.prio();
+          heap.pop();
+          _proc_nodes.push_back(u);
+
+          // Traverse outgoing arcs
+          for (OutArcIt e(_graph, u); e != INVALID; ++e) {
+            if (_flow[e] == 0) {
+              v = _graph.target(e);
+              switch(heap.state(v)) {
+              case Heap::PRE_HEAP:
+                heap.push(v, d + _length[e] - _potential[v]);
+                _pred[v] = e;
+                break;
+              case Heap::IN_HEAP:
+                nd = d + _length[e] - _potential[v];
+                if (nd < heap[v]) {
+                  heap.decrease(v, nd);
+                  _pred[v] = e;
+                }
+                break;
+              case Heap::POST_HEAP:
+                break;
+              }
+            }
+          }
+
+          // Traverse incoming arcs
+          for (InArcIt e(_graph, u); e != INVALID; ++e) {
+            if (_flow[e] == 1) {
+              v = _graph.source(e);
+              switch(heap.state(v)) {
+              case Heap::PRE_HEAP:
+                heap.push(v, d - _length[e] - _potential[v]);
+                _pred[v] = e;
+                break;
+              case Heap::IN_HEAP:
+                nd = d - _length[e] - _potential[v];
+                if (nd < heap[v]) {
+                  heap.decrease(v, nd);
+                  _pred[v] = e;
+                }
+                break;
+              case Heap::POST_HEAP:
+                break;
+              }
+            }
+          }
+        }
+        if (heap.empty()) return false;
+
+        // Update potentials of processed nodes
+        Length t_dist = heap.prio();
+        for (int i = 0; i < int(_proc_nodes.size()); ++i)
+          _potential[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
+        return true;
+      }
+
+    }; //class ResidualDijkstra
+
+  private:
+
+    // The digraph the algorithm runs on
+    const Digraph &_graph;
+    // The length map
+    const LengthMap &_length;
+
+    // Arc map of the current flow
+    FlowMap *_flow;
+    bool _local_flow;
+    // Node map of the current potentials
+    PotentialMap *_potential;
+    bool _local_potential;
+
+    // The source node
+    Node _source;
+    // The target node
+    Node _target;
+
+    // Container to store the found paths
+    std::vector< SimplePath<Digraph> > paths;
+    int _path_num;
+
+    // The pred arc map
+    PredMap _pred;
+    // Implementation of the Dijkstra algorithm for finding augmenting
+    // shortest paths in the residual network
+    ResidualDijkstra *_dijkstra;
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    ///
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param length The length (cost) values of the arcs.
+    /// \param s The source node.
+    /// \param t The target node.
+    Suurballe( const Digraph &digraph,
+               const LengthMap &length,
+               Node s, Node t ) :
+      _graph(digraph), _length(length), _flow(0), _local_flow(false),
+      _potential(0), _local_potential(false), _source(s), _target(t),
+      _pred(digraph) {}
+
+    /// Destructor.
+    ~Suurballe() {
+      if (_local_flow) delete _flow;
+      if (_local_potential) delete _potential;
+      delete _dijkstra;
+    }
+
+    /// \brief Set the flow map.
+    ///
+    /// This function sets the flow map.
+    ///
+    /// The found flow contains only 0 and 1 values. It is the union of
+    /// the found arc-disjoint paths.
+    ///
+    /// \return \c (*this)
+    Suurballe& flowMap(FlowMap &map) {
+      if (_local_flow) {
+        delete _flow;
+        _local_flow = false;
+      }
+      _flow = &map;
+      return *this;
+    }
+
+    /// \brief Set the potential map.
+    ///
+    /// This function sets the potential map.
+    ///
+    /// The potentials provide the dual solution of the underlying
+    /// minimum cost flow problem.
+    ///
+    /// \return \c (*this)
+    Suurballe& potentialMap(PotentialMap &map) {
+      if (_local_potential) {
+        delete _potential;
+        _local_potential = false;
+      }
+      _potential = &map;
+      return *this;
+    }
+
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to call the run()
+    /// function.
+    /// \n
+    /// If you only need the flow that is the union of the found
+    /// arc-disjoint paths, you may call init() and findFlow().
+
+    /// @{
+
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm.
+    ///
+    /// \param k The number of paths to be found.
+    ///
+    /// \return \c k if there are at least \c k arc-disjoint paths from
+    /// \c s to \c t in the digraph. Otherwise it returns the number of
+    /// arc-disjoint paths found.
+    ///
+    /// \note Apart from the return value, <tt>s.run(k)</tt> is just a
+    /// shortcut of the following code.
+    /// \code
+    ///   s.init();
+    ///   s.findFlow(k);
+    ///   s.findPaths();
+    /// \endcode
+    int run(int k = 2) {
+      init();
+      findFlow(k);
+      findPaths();
+      return _path_num;
+    }
+
+    /// \brief Initialize the algorithm.
+    ///
+    /// This function initializes the algorithm.
+    void init() {
+      // Initialize maps
+      if (!_flow) {
+        _flow = new FlowMap(_graph);
+        _local_flow = true;
+      }
+      if (!_potential) {
+        _potential = new PotentialMap(_graph);
+        _local_potential = true;
+      }
+      for (ArcIt e(_graph); e != INVALID; ++e) (*_flow)[e] = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) (*_potential)[n] = 0;
+
+      _dijkstra = new ResidualDijkstra( _graph, *_flow, _length,
+                                        *_potential, _pred,
+                                        _source, _target );
+    }
+
+    /// \brief Execute the successive shortest path algorithm to find
+    /// an optimal flow.
+    ///
+    /// This function executes the successive shortest path algorithm to
+    /// find a minimum cost flow, which is the union of \c k or less
+    /// arc-disjoint paths.
+    ///
+    /// \return \c k if there are at least \c k arc-disjoint paths from
+    /// \c s to \c t in the digraph. Otherwise it returns the number of
+    /// arc-disjoint paths found.
+    ///
+    /// \pre \ref init() must be called before using this function.
+    int findFlow(int k = 2) {
+      // Find shortest paths
+      _path_num = 0;
+      while (_path_num < k) {
+        // Run Dijkstra
+        if (!_dijkstra->run()) break;
+        ++_path_num;
+
+        // Set the flow along the found shortest path
+        Node u = _target;
+        Arc e;
+        while ((e = _pred[u]) != INVALID) {
+          if (u == _graph.target(e)) {
+            (*_flow)[e] = 1;
+            u = _graph.source(e);
+          } else {
+            (*_flow)[e] = 0;
+            u = _graph.target(e);
+          }
+        }
+      }
+      return _path_num;
+    }
+
+    /// \brief Compute the paths from the flow.
+    ///
+    /// This function computes the paths from the flow.
+    ///
+    /// \pre \ref init() and \ref findFlow() must be called before using
+    /// this function.
+    void findPaths() {
+      // Create the residual flow map (the union of the paths not found
+      // so far)
+      FlowMap res_flow(_graph);
+      for(ArcIt a(_graph); a != INVALID; ++a) res_flow[a] = (*_flow)[a];
+
+      paths.clear();
+      paths.resize(_path_num);
+      for (int i = 0; i < _path_num; ++i) {
+        Node n = _source;
+        while (n != _target) {
+          OutArcIt e(_graph, n);
+          for ( ; res_flow[e] == 0; ++e) ;
+          n = _graph.target(e);
+          paths[i].addBack(e);
+          res_flow[e] = 0;
+        }
+      }
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The results of the algorithm can be obtained using these
+    /// functions.
+    /// \n The algorithm should be executed before using them.
+
+    /// @{
+
+    /// \brief Return a const reference to the arc map storing the
+    /// found flow.
+    ///
+    /// This function returns a const reference to the arc map storing
+    /// the flow that is the union of the found arc-disjoint paths.
+    ///
+    /// \pre \ref run() or \ref findFlow() must be called before using
+    /// this function.
+    const FlowMap& flowMap() const {
+      return *_flow;
+    }
+
+    /// \brief Return a const reference to the node map storing the
+    /// found potentials (the dual solution).
+    ///
+    /// This function returns a const reference to the node map storing
+    /// the found potentials that provide the dual solution of the
+    /// underlying minimum cost flow problem.
+    ///
+    /// \pre \ref run() or \ref findFlow() must be called before using
+    /// this function.
+    const PotentialMap& potentialMap() const {
+      return *_potential;
+    }
+
+    /// \brief Return the flow on the given arc.
+    ///
+    /// This function returns the flow on the given arc.
+    /// It is \c 1 if the arc is involved in one of the found paths,
+    /// otherwise it is \c 0.
+    ///
+    /// \pre \ref run() or \ref findFlow() must be called before using
+    /// this function.
+    int flow(const Arc& arc) const {
+      return (*_flow)[arc];
+    }
+
+    /// \brief Return the potential of the given node.
+    ///
+    /// This function returns the potential of the given node.
+    ///
+    /// \pre \ref run() or \ref findFlow() must be called before using
+    /// this function.
+    Length potential(const Node& node) const {
+      return (*_potential)[node];
+    }
+
+    /// \brief Return the total length (cost) of the found paths (flow).
+    ///
+    /// This function returns the total length (cost) of the found paths
+    /// (flow). The complexity of the function is \f$ O(e) \f$.
+    ///
+    /// \pre \ref run() or \ref findFlow() must be called before using
+    /// this function.
+    Length totalLength() const {
+      Length c = 0;
+      for (ArcIt e(_graph); e != INVALID; ++e)
+        c += (*_flow)[e] * _length[e];
+      return c;
+    }
+
+    /// \brief Return the number of the found paths.
+    ///
+    /// This function returns the number of the found paths.
+    ///
+    /// \pre \ref run() or \ref findFlow() must be called before using
+    /// this function.
+    int pathNum() const {
+      return _path_num;
+    }
+
+    /// \brief Return a const reference to the specified path.
+    ///
+    /// This function returns a const reference to the specified path.
+    ///
+    /// \param i The function returns the \c i-th path.
+    /// \c i must be between \c 0 and <tt>%pathNum()-1</tt>.
+    ///
+    /// \pre \ref run() or \ref findPaths() must be called before using
+    /// this function.
+    Path path(int i) const {
+      return paths[i];
+    }
+
+    /// @}
+
+  }; //class Suurballe
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_SUURBALLE_H
Index: lemon/time_measure.h
===================================================================
--- lemon/time_measure.h	(revision 482)
+++ lemon/time_measure.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -25,7 +25,9 @@
 
 #ifdef WIN32
-#include <lemon/bits/windows.h>
+#define WIN32_LEAN_AND_MEAN
+#define NOMINMAX
+#include <windows.h>
+#include <cmath>
 #else
-#include <unistd.h>
 #include <sys/times.h>
 #include <sys/time.h>
@@ -86,5 +88,24 @@
       cstime=ts.tms_cstime/tck;
 #else
-      bits::getWinProcTimes(rtime, utime, stime, cutime, cstime);
+      static const double ch = 4294967296.0e-7;
+      static const double cl = 1.0e-7;
+
+      FILETIME system;
+      GetSystemTimeAsFileTime(&system);
+      rtime = ch * system.dwHighDateTime + cl * system.dwLowDateTime;
+
+      FILETIME create, exit, kernel, user;
+      if (GetProcessTimes(GetCurrentProcess(),&create, &exit, &kernel, &user)) {
+        utime = ch * user.dwHighDateTime + cl * user.dwLowDateTime;
+        stime = ch * kernel.dwHighDateTime + cl * kernel.dwLowDateTime;
+        cutime = 0;
+        cstime = 0;
+      } else {
+        rtime = 0;
+        utime = 0;
+        stime = 0;
+        cutime = 0;
+        cstime = 0;
+      }
 #endif
     }
Index: lemon/tolerance.h
===================================================================
--- lemon/tolerance.h	(revision 486)
+++ lemon/tolerance.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -39,7 +39,6 @@
   ///as a result of a probably inexact computation.
   ///
-  ///The general implementation is suitable only if the data type is exact,
-  ///like the integer types, otherwise a specialized version must be
-  ///implemented. These specialized classes like
+  ///This is an abstract class, it should be specialized for all
+  ///numerical data types. These specialized classes like
   ///Tolerance<double> may offer additional tuning parameters.
   ///
@@ -47,4 +46,8 @@
   ///\sa Tolerance<double>
   ///\sa Tolerance<long double>
+  ///\sa Tolerance<int>
+  ///\sa Tolerance<long long int>
+  ///\sa Tolerance<unsigned int>
+  ///\sa Tolerance<unsigned long long int>
 
   template<class T>
@@ -62,18 +65,18 @@
 
     ///Returns \c true if \c a is \e surely strictly less than \c b
-    static bool less(Value a,Value b) {return a<b;}
-    ///Returns \c true if \c a is \e surely different from \c b
-    static bool different(Value a,Value b) {return a!=b;}
-    ///Returns \c true if \c a is \e surely positive
-    static bool positive(Value a) {return static_cast<Value>(0) < a;}
-    ///Returns \c true if \c a is \e surely negative
-    static bool negative(Value a) {return a < static_cast<Value>(0);}
-    ///Returns \c true if \c a is \e surely non-zero
-    static bool nonZero(Value a) {return a != static_cast<Value>(0);}
+    static bool less(Value a,Value b) {return false;}
+    ///Returns \c true if \c a is \e surely different from \c b
+    static bool different(Value a,Value b) {return false;}
+    ///Returns \c true if \c a is \e surely positive
+    static bool positive(Value a) {return false;}
+    ///Returns \c true if \c a is \e surely negative
+    static bool negative(Value a) {return false;}
+    ///Returns \c true if \c a is \e surely non-zero
+    static bool nonZero(Value a) {return false;}
 
     ///@}
 
     ///Returns the zero value.
-    static Value zero() {return static_cast<Value>(0);}
+    static Value zero() {return T();}
 
     //   static bool finite(Value a) {}
@@ -236,4 +239,211 @@
   };
 
+  ///Integer specialization of Tolerance.
+
+  ///Integer specialization of Tolerance.
+  ///\sa Tolerance
+  template<>
+  class Tolerance<int>
+  {
+  public:
+    ///\e
+    typedef int Value;
+
+    ///\name Comparisons
+    ///See \ref lemon::Tolerance "Tolerance" for more details.
+
+    ///@{
+
+    ///Returns \c true if \c a is \e surely strictly less than \c b
+    static bool less(Value a,Value b) { return a<b;}
+    ///Returns \c true if \c a is \e surely different from \c b
+    static bool different(Value a,Value b) { return a!=b; }
+    ///Returns \c true if \c a is \e surely positive
+    static bool positive(Value a) { return 0<a; }
+    ///Returns \c true if \c a is \e surely negative
+    static bool negative(Value a) { return 0>a; }
+    ///Returns \c true if \c a is \e surely non-zero
+    static bool nonZero(Value a) { return a!=0; }
+
+    ///@}
+
+    ///Returns zero
+    static Value zero() {return 0;}
+  };
+
+  ///Unsigned integer specialization of Tolerance.
+
+  ///Unsigned integer specialization of Tolerance.
+  ///\sa Tolerance
+  template<>
+  class Tolerance<unsigned int>
+  {
+  public:
+    ///\e
+    typedef unsigned int Value;
+
+    ///\name Comparisons
+    ///See \ref lemon::Tolerance "Tolerance" for more details.
+
+    ///@{
+
+    ///Returns \c true if \c a is \e surely strictly less than \c b
+    static bool less(Value a,Value b) { return a<b;}
+    ///Returns \c true if \c a is \e surely different from \c b
+    static bool different(Value a,Value b) { return a!=b; }
+    ///Returns \c true if \c a is \e surely positive
+    static bool positive(Value a) { return 0<a; }
+    ///Returns \c true if \c a is \e surely negative
+    static bool negative(Value) { return false; }
+    ///Returns \c true if \c a is \e surely non-zero
+    static bool nonZero(Value a) { return a!=0; }
+
+    ///@}
+
+    ///Returns zero
+    static Value zero() {return 0;}
+  };
+
+
+  ///Long integer specialization of Tolerance.
+
+  ///Long integer specialization of Tolerance.
+  ///\sa Tolerance
+  template<>
+  class Tolerance<long int>
+  {
+  public:
+    ///\e
+    typedef long int Value;
+
+    ///\name Comparisons
+    ///See \ref lemon::Tolerance "Tolerance" for more details.
+
+    ///@{
+
+    ///Returns \c true if \c a is \e surely strictly less than \c b
+    static bool less(Value a,Value b) { return a<b;}
+    ///Returns \c true if \c a is \e surely different from \c b
+    static bool different(Value a,Value b) { return a!=b; }
+    ///Returns \c true if \c a is \e surely positive
+    static bool positive(Value a) { return 0<a; }
+    ///Returns \c true if \c a is \e surely negative
+    static bool negative(Value a) { return 0>a; }
+    ///Returns \c true if \c a is \e surely non-zero
+    static bool nonZero(Value a) { return a!=0;}
+
+    ///@}
+
+    ///Returns zero
+    static Value zero() {return 0;}
+  };
+
+  ///Unsigned long integer specialization of Tolerance.
+
+  ///Unsigned long integer specialization of Tolerance.
+  ///\sa Tolerance
+  template<>
+  class Tolerance<unsigned long int>
+  {
+  public:
+    ///\e
+    typedef unsigned long int Value;
+
+    ///\name Comparisons
+    ///See \ref lemon::Tolerance "Tolerance" for more details.
+
+    ///@{
+
+    ///Returns \c true if \c a is \e surely strictly less than \c b
+    static bool less(Value a,Value b) { return a<b;}
+    ///Returns \c true if \c a is \e surely different from \c b
+    static bool different(Value a,Value b) { return a!=b; }
+    ///Returns \c true if \c a is \e surely positive
+    static bool positive(Value a) { return 0<a; }
+    ///Returns \c true if \c a is \e surely negative
+    static bool negative(Value) { return false; }
+    ///Returns \c true if \c a is \e surely non-zero
+    static bool nonZero(Value a) { return a!=0;}
+
+    ///@}
+
+    ///Returns zero
+    static Value zero() {return 0;}
+  };
+
+#if defined __GNUC__ && !defined __STRICT_ANSI__
+
+  ///Long long integer specialization of Tolerance.
+
+  ///Long long integer specialization of Tolerance.
+  ///\warning This class (more exactly, type <tt>long long</tt>)
+  ///is not ansi compatible.
+  ///\sa Tolerance
+  template<>
+  class Tolerance<long long int>
+  {
+  public:
+    ///\e
+    typedef long long int Value;
+
+    ///\name Comparisons
+    ///See \ref lemon::Tolerance "Tolerance" for more details.
+
+    ///@{
+
+    ///Returns \c true if \c a is \e surely strictly less than \c b
+    static bool less(Value a,Value b) { return a<b;}
+    ///Returns \c true if \c a is \e surely different from \c b
+    static bool different(Value a,Value b) { return a!=b; }
+    ///Returns \c true if \c a is \e surely positive
+    static bool positive(Value a) { return 0<a; }
+    ///Returns \c true if \c a is \e surely negative
+    static bool negative(Value a) { return 0>a; }
+    ///Returns \c true if \c a is \e surely non-zero
+    static bool nonZero(Value a) { return a!=0;}
+
+    ///@}
+
+    ///Returns zero
+    static Value zero() {return 0;}
+  };
+
+  ///Unsigned long long integer specialization of Tolerance.
+
+  ///Unsigned long long integer specialization of Tolerance.
+  ///\warning This class (more exactly, type <tt>unsigned long long</tt>)
+  ///is not ansi compatible.
+  ///\sa Tolerance
+  template<>
+  class Tolerance<unsigned long long int>
+  {
+  public:
+    ///\e
+    typedef unsigned long long int Value;
+
+    ///\name Comparisons
+    ///See \ref lemon::Tolerance "Tolerance" for more details.
+
+    ///@{
+
+    ///Returns \c true if \c a is \e surely strictly less than \c b
+    static bool less(Value a,Value b) { return a<b;}
+    ///Returns \c true if \c a is \e surely different from \c b
+    static bool different(Value a,Value b) { return a!=b; }
+    ///Returns \c true if \c a is \e surely positive
+    static bool positive(Value a) { return 0<a; }
+    ///Returns \c true if \c a is \e surely negative
+    static bool negative(Value) { return false; }
+    ///Returns \c true if \c a is \e surely non-zero
+    static bool nonZero(Value a) { return a!=0;}
+
+    ///@}
+
+    ///Returns zero
+    static Value zero() {return 0;}
+  };
+
+#endif
+
   /// @}
 
Index: lemon/unionfind.h
===================================================================
--- lemon/unionfind.h	(revision 438)
+++ lemon/unionfind.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -1190,5 +1190,5 @@
               popLeft(nodes[jd].next);
               pushRight(jd, ld);
-              if (less(ld, nodes[jd].left) || 
+              if (less(ld, nodes[jd].left) ||
                   nodes[ld].item == nodes[pd].item) {
                 nodes[jd].item = nodes[ld].item;
Index: scripts/chg-len.py
===================================================================
--- scripts/chg-len.py	(revision 284)
+++ scripts/chg-len.py	(revision 422)
@@ -2,5 +2,9 @@
 
 import sys
-import os
+
+from mercurial import ui, hg
+from mercurial import util
+
+util.rcpath = lambda : []
 
 if len(sys.argv)>1 and sys.argv[1] in ["-h","--help"]:
@@ -10,31 +14,19 @@
 """
     exit(0)
-plist = os.popen("HGRCPATH='' hg parents --template='{rev}\n'").readlines()
-if len(plist)>1:
-    print "You are in the process of merging"
-    exit(1)
-PAR = int(plist[0])
 
-f = os.popen("HGRCPATH='' hg log -r 0:tip --template='{rev} {parents}\n'").\
-    readlines()
-REV = -1
-lengths=[]
-for l in f:
-    REV+=1
-    s = l.split()
-    rev = int(s[0])
-    if REV != rev:
-        print "Something is seriously wrong"
-        exit(1)
-    if len(s) == 1:
-        par1 = par2 = rev - 1
-    elif len(s) == 2:
-        par1 = par2 = int(s[1].split(":")[0])
+u = ui.ui()
+r = hg.repository(u, ".")
+N = r.changectx(".").rev()
+lengths=[0]*(N+1)
+for i in range(N+1):
+    p=r.changectx(i).parents()
+    if p[0]:
+        p0=lengths[p[0].rev()]
     else:
-        par1 = int(s[1].split(":")[0])
-        par2 = int(s[2].split(":")[0])
-    if rev == 0:
-        lengths.append(0)
+        p0=-1
+    if len(p)>1 and p[1]:
+        p1=lengths[p[1].rev()]
     else:
-        lengths.append(max(lengths[par1],lengths[par2])+1)
-print lengths[PAR]
+        p1=-1
+    lengths[i]=max(p0,p1)+1
+print lengths[N]
Index: scripts/unify-sources.sh
===================================================================
--- scripts/unify-sources.sh	(revision 208)
+++ scripts/unify-sources.sh	(revision 396)
@@ -4,7 +4,182 @@
 HGROOT=`hg root`
 
-function update_header() {
+# file enumaration modes
+
+function all_files() {
+    hg status -a -m -c |
+    cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' |
+    while read file; do echo $HGROOT/$file; done
+}
+
+function modified_files() {
+    hg status -a -m |
+    cut -d ' ' -f 2 | grep -E  '(\.(cc|h|dox)$|Makefile\.am$)' |
+    while read file; do echo $HGROOT/$file; done
+}
+
+function changed_files() {
+    {
+        if [ -n "$HG_PARENT1" ]
+        then
+            hg status --rev $HG_PARENT1:$HG_NODE -a -m
+        fi
+        if [ -n "$HG_PARENT2" ]
+        then
+            hg status --rev $HG_PARENT2:$HG_NODE -a -m
+        fi
+    } | cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' | 
+    sort | uniq |
+    while read file; do echo $HGROOT/$file; done
+}
+
+function given_files() {
+    for file in $GIVEN_FILES
+    do
+	echo $file
+    done
+}
+
+# actions
+
+function update_action() {
+    if ! diff -q $1 $2 >/dev/null
+    then
+	echo -n " [$3 updated]"
+	rm $2
+	mv $1 $2
+	CHANGED=YES
+    fi
+}
+
+function update_warning() {
+    echo -n " [$2 warning]"
+    WARNED=YES
+}
+
+function update_init() {
+    echo Update source files...
+    TOTAL_FILES=0
+    CHANGED_FILES=0
+    WARNED_FILES=0
+}
+
+function update_done() {
+    echo $CHANGED_FILES out of $TOTAL_FILES files has been changed.
+    echo $WARNED_FILES out of $TOTAL_FILES files triggered warnings.
+}
+
+function update_begin() {
+    ((TOTAL_FILES++))
+    CHANGED=NO
+    WARNED=NO
+}
+
+function update_end() {
+    if [ $CHANGED == YES ]
+    then
+	((++CHANGED_FILES))
+    fi
+    if [ $WARNED == YES ]
+    then
+	((++WARNED_FILES))
+    fi
+}
+
+function check_action() {
+    if [ "$3" == 'tabs' ]
+    then
+        PATTERN=$(echo -e '\t')
+    elif [ "$3" == 'trailing spaces' ]
+    then
+        PATTERN='\ +$'
+    else
+        PATTERN='*'
+    fi
+
+    if ! diff -q $1 $2 >/dev/null
+    then
+        if [ "$PATTERN" == '*' ]
+        then
+            diff $1 $2 | grep '^[0-9]' | sed "s|^\(.*\)c.*$|$2:\1: check failed: $3|g" |
+              sed "s/:\([0-9]*\),\([0-9]*\):\(.*\)$/:\1:\3 (until line \2)/g"
+        else
+            grep -n -E "$PATTERN" $2 | sed "s|^\([0-9]*\):.*$|$2:\1: check failed: $3|g"
+        fi
+        FAILED=YES
+    fi
+}
+
+function check_warning() {
+    if [ "$2" == 'long lines' ]
+    then
+        grep -n -E '.{81,}' $1 | sed "s|^\([0-9]*\):.*$|$1:\1: warning: $2|g"
+    else
+        echo "$1: warning: $2"
+    fi
+    WARNED=YES
+}
+
+function check_init() {
+    echo Check source files...
+    FAILED_FILES=0
+    WARNED_FILES=0
+    TOTAL_FILES=0
+}
+
+function check_done() {
+    echo $FAILED_FILES out of $TOTAL_FILES files has been failed.
+    echo $WARNED_FILES out of $TOTAL_FILES files triggered warnings.
+
+    if [ $WARNED_FILES -gt 0 -o $FAILED_FILES -gt 0 ]
+    then
+	if [ "$WARNING" == 'INTERACTIVE' ]
+	then
+	    echo -n "Are the files with errors/warnings acceptable? (yes/no) "
+	    while read answer
+	    do
+		if [ "$answer" == 'yes' ]
+		then
+		    return 0
+		elif [ "$answer" == 'no' ]
+		then
+		    return 1
+		fi
+		echo -n "Are the files with errors/warnings acceptable? (yes/no) "
+	    done
+	elif [ "$WARNING" == 'WERROR' ]
+	then
+	    return 1
+	fi
+    fi
+}
+
+function check_begin() {
+    ((TOTAL_FILES++))
+    FAILED=NO
+    WARNED=NO
+}
+
+function check_end() {
+    if [ $FAILED == YES ]
+    then
+	((++FAILED_FILES))
+    fi
+    if [ $WARNED == YES ]
+    then
+	((++WARNED_FILES))
+    fi
+}
+
+
+
+# checks
+
+function header_check() {
+    if echo $1 | grep -q -E 'Makefile\.am$'
+    then
+	return
+    fi
+
     TMP_FILE=`mktemp`
-    FILE_NAME=$1
 
     (echo "/* -*- mode: C++; indent-tabs-mode: nil; -*-
@@ -26,5 +201,5 @@
  */
 "
-	awk 'BEGIN { pm=0; }
+    awk 'BEGIN { pm=0; }
      pm==3 { print }
      /\/\* / && pm==0 { pm=1;}
@@ -32,103 +207,156 @@
      /\*\// && pm==1 { pm=2;}
     ' $1
-	) >$TMP_FILE
-
-    HEADER_CH=`diff -q $TMP_FILE $FILE_NAME >/dev/null&&echo NO||echo YES`
-
-    rm $FILE_NAME
-    mv $TMP_FILE $FILE_NAME
-}
-
-function update_tabs() {
+    ) >$TMP_FILE
+
+    "$ACTION"_action "$TMP_FILE" "$1" header
+}
+
+function tabs_check() {
+    if echo $1 | grep -q -v -E 'Makefile\.am$'
+    then
+        OLD_PATTERN=$(echo -e '\t')
+        NEW_PATTERN='        '
+    else
+        OLD_PATTERN='        '
+        NEW_PATTERN=$(echo -e '\t')
+    fi
     TMP_FILE=`mktemp`
-    FILE_NAME=$1
-
-    cat $1 |
-    sed -e 's/\t/        /g' >$TMP_FILE
-
-    TABS_CH=`diff -q $TMP_FILE $FILE_NAME >/dev/null&&echo NO||echo YES`
-
-    rm $FILE_NAME
-    mv $TMP_FILE $FILE_NAME
-}
-
-function remove_trailing_space() {
+    cat $1 | sed -e "s/$OLD_PATTERN/$NEW_PATTERN/g" >$TMP_FILE
+
+    "$ACTION"_action "$TMP_FILE" "$1" 'tabs'
+}
+
+function spaces_check() {
     TMP_FILE=`mktemp`
-    FILE_NAME=$1
-
-    cat $1 |
-    sed -e 's/ \+$//g' >$TMP_FILE
-
-    SPACES_CH=`diff -q $TMP_FILE $FILE_NAME >/dev/null&&echo NO||echo YES`
-
-    rm $FILE_NAME
-    mv $TMP_FILE $FILE_NAME
-}
-
-function long_line_test() {
-    cat $1 |grep -q -E '.{81,}'
-}
-
-function update_file() {
-    echo -n '    update' $i ...
-
-    update_header $1
-    update_tabs $1
-    remove_trailing_space $1
-
-    CHANGED=NO;
-    if [[ $HEADER_CH = YES ]];
-    then
-	echo -n '  [header updated]'
-	CHANGED=YES;
-    fi
-    if [[ $TABS_CH = YES ]];
-    then
-	echo -n ' [tabs removed]'
-	CHANGED=YES;
-    fi
-    if [[ $SPACES_CH = YES ]];
-    then
-	echo -n ' [trailing spaces removed]'
-	CHANGED=YES;
-    fi
-    if long_line_test $1 ;
-    then
-	echo -n ' [LONG LINES]'
-	((LONG_LINE_FILES++))
-    fi
-    echo
-    if [[ $CHANGED = YES ]];
-    then
-	((CHANGED_FILES++))
-    fi
-}
-
-CHANGED_FILES=0
-TOTAL_FILES=0
-LONG_LINE_FILES=0
-if [ $# == 0 ]; then
-    echo Update all source files...
-    for i in `hg manifest|grep -E  '\.(cc|h|dox)$'`
+    cat $1 | sed -e 's/ \+$//g' >$TMP_FILE
+
+    "$ACTION"_action "$TMP_FILE" "$1" 'trailing spaces'
+}
+
+function long_lines_check() {
+    if cat $1 | grep -q -E '.{81,}'
+    then
+	"$ACTION"_warning $1 'long lines'
+    fi
+}
+
+# process the file
+
+function process_file() {
+    if [ "$ACTION" == 'update' ]
+    then
+        echo -n "    $ACTION $1..."
+    else
+        echo "	  $ACTION $1..."
+    fi
+
+    CHECKING="header tabs spaces long_lines"
+
+    "$ACTION"_begin $1
+    for check in $CHECKING
     do
-	update_file $HGROOT/$i
-	((TOTAL_FILES++))
+	"$check"_check $1
     done
-    echo '  done.'
-else
-    for i in $*
+    "$ACTION"_end $1
+    if [ "$ACTION" == 'update' ]
+    then
+        echo
+    fi
+}
+
+function process_all {
+    "$ACTION"_init
+    while read file
     do
-	update_file $i
-	((TOTAL_FILES++))
-    done
+	process_file $file
+    done < <($FILES)
+    "$ACTION"_done
+}
+
+while [ $# -gt 0 ]
+do
+    
+    if [ "$1" == '--help' ] || [ "$1" == '-h' ]
+    then
+	echo -n \
+"Usage:
+  $0 [OPTIONS] [files]
+Options:
+  --dry-run|-n
+     Check the files, but do not modify them.
+  --interactive|-i
+     If --dry-run is specified and the checker emits warnings,
+     then the user is asked if the warnings should be considered
+     errors.
+  --werror|-w
+     Make all warnings into errors.
+  --all|-a
+     Check all source files in the repository.
+  --modified|-m
+     Check only the modified (and new) source files. This option is
+     useful to check the modification before making a commit.
+  --changed|-c
+     Check only the changed source files compared to the parent(s) of
+     the current hg node.  This option is useful as hg hook script.
+     To automatically check all your changes before making a commit,
+     add the following section to the appropriate .hg/hgrc file.
+
+       [hooks]
+       pretxncommit.checksources = scripts/unify-sources.sh -c -n -i
+
+  --help|-h
+     Print this help message.
+  files
+     The files to check/unify. If no file names are given, the modified
+     source files will be checked/unified (just like using the
+     --modified|-m option).
+"
+        exit 0
+    elif [ "$1" == '--dry-run' ] || [ "$1" == '-n' ]
+    then
+	[ -n "$ACTION" ] && echo "Conflicting action options" >&2 && exit 1
+	ACTION=check
+    elif [ "$1" == "--all" ] || [ "$1" == '-a' ]
+    then
+	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
+	FILES=all_files
+    elif [ "$1" == "--changed" ] || [ "$1" == '-c' ]
+    then
+	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
+	FILES=changed_files
+    elif [ "$1" == "--modified" ] || [ "$1" == '-m' ]
+    then
+	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
+	FILES=modified_files
+    elif [ "$1" == "--interactive" ] || [ "$1" == "-i" ]
+    then
+	[ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
+	WARNING='INTERACTIVE'
+    elif [ "$1" == "--werror" ] || [ "$1" == "-w" ]
+    then
+	[ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
+	WARNING='WERROR'
+    elif [ $(echo x$1 | cut -c 2) == '-' ]
+    then
+	echo "Invalid option $1" >&2 && exit 1
+    else
+	[ -n "$FILES" ] && echo "Invalid option $1" >&2 && exit 1
+	GIVEN_FILES=$@
+	FILES=given_files
+	break
+    fi
+    
+    shift
+done
+
+if [ -z $FILES ]
+then
+    FILES=modified_files
 fi
-echo $CHANGED_FILES out of $TOTAL_FILES files has been changed.
-if [[ $LONG_LINE_FILES -gt 1 ]]; then
-    echo
-    echo WARNING: $LONG_LINE_FILES files contains long lines!    
-    echo
-elif [[ $LONG_LINE_FILES -gt 0 ]]; then
-    echo
-    echo WARNING: a file contains long lines!
-    echo
+
+if [ -z $ACTION ]
+then
+    ACTION=update
 fi
+
+process_all
Index: test/CMakeLists.txt
===================================================================
--- test/CMakeLists.txt	(revision 225)
+++ test/CMakeLists.txt	(revision 424)
@@ -5,4 +5,5 @@
 SET(TESTS
   bfs_test
+  circulation_test
   counter_test
   dfs_test
@@ -11,12 +12,17 @@
   dim_test
   error_test
+  graph_adaptor_test
   graph_copy_test
   graph_test
   graph_utils_test
+  hao_orlin_test
   heap_test
   kruskal_test
   maps_test
+  max_matching_test
+  path_test
+  preflow_test
   random_test
-  path_test
+  suurballe_test
   time_measure_test
   unionfind_test)
Index: test/Makefile.am
===================================================================
--- test/Makefile.am	(revision 228)
+++ test/Makefile.am	(revision 440)
@@ -4,25 +4,31 @@
 noinst_HEADERS += \
 	test/graph_test.h \
-        test/test_tools.h
+	test/test_tools.h
 
 check_PROGRAMS += \
 	test/bfs_test \
-        test/counter_test \
+	test/circulation_test \
+	test/counter_test \
 	test/dfs_test \
 	test/digraph_test \
 	test/dijkstra_test \
-        test/dim_test \
+	test/dim_test \
 	test/error_test \
+	test/graph_adaptor_test \
 	test/graph_copy_test \
 	test/graph_test \
 	test/graph_utils_test \
+	test/hao_orlin_test \
 	test/heap_test \
 	test/kruskal_test \
-        test/maps_test \
-        test/random_test \
-        test/path_test \
-        test/test_tools_fail \
-        test/test_tools_pass \
-        test/time_measure_test \
+	test/maps_test \
+	test/max_matching_test \
+	test/path_test \
+	test/preflow_test \
+	test/random_test \
+	test/suurballe_test \
+	test/test_tools_fail \
+	test/test_tools_pass \
+	test/time_measure_test \
 	test/unionfind_test
 
@@ -31,4 +37,5 @@
 
 test_bfs_test_SOURCES = test/bfs_test.cc
+test_circulation_test_SOURCES = test/circulation_test.cc
 test_counter_test_SOURCES = test/counter_test.cc
 test_dfs_test_SOURCES = test/dfs_test.cc
@@ -37,4 +44,5 @@
 test_dim_test_SOURCES = test/dim_test.cc
 test_error_test_SOURCES = test/error_test.cc
+test_graph_adaptor_test_SOURCES = test/graph_adaptor_test.cc
 test_graph_copy_test_SOURCES = test/graph_copy_test.cc
 test_graph_test_SOURCES = test/graph_test.cc
@@ -42,6 +50,10 @@
 test_heap_test_SOURCES = test/heap_test.cc
 test_kruskal_test_SOURCES = test/kruskal_test.cc
+test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc
 test_maps_test_SOURCES = test/maps_test.cc
+test_max_matching_test_SOURCES = test/max_matching_test.cc
 test_path_test_SOURCES = test/path_test.cc
+test_preflow_test_SOURCES = test/preflow_test.cc
+test_suurballe_test_SOURCES = test/suurballe_test.cc
 test_random_test_SOURCES = test/random_test.cc
 test_test_tools_fail_SOURCES = test/test_tools_fail.cc
Index: test/bfs_test.cc
===================================================================
--- test/bfs_test.cc	(revision 293)
+++ test/bfs_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/circulation_test.cc
===================================================================
--- test/circulation_test.cc	(revision 440)
+++ test/circulation_test.cc	(revision 440)
@@ -0,0 +1,156 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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.
+ *
+ */
+
+#include <iostream>
+
+#include "test_tools.h"
+#include <lemon/list_graph.h>
+#include <lemon/circulation.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/maps.h>
+
+using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "@arcs\n"
+  "     lcap  ucap\n"
+  "0 1  2  10\n"
+  "0 2  2  6\n"
+  "1 3  4  7\n"
+  "1 4  0  5\n"
+  "2 4  1  3\n"
+  "3 5  3  8\n"
+  "4 5  3  7\n"
+  "@attributes\n"
+  "source 0\n"
+  "sink   5\n";
+
+void checkCirculationCompile()
+{
+  typedef int VType;
+  typedef concepts::Digraph Digraph;
+
+  typedef Digraph::Node Node;
+  typedef Digraph::Arc Arc;
+  typedef concepts::ReadMap<Arc,VType> CapMap;
+  typedef concepts::ReadMap<Node,VType> DeltaMap;
+  typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
+  typedef concepts::WriteMap<Node,bool> BarrierMap;
+
+  typedef Elevator<Digraph, Digraph::Node> Elev;
+  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
+
+  Digraph g;
+  Node n;
+  Arc a;
+  CapMap lcap, ucap;
+  DeltaMap delta;
+  FlowMap flow;
+  BarrierMap bar;
+
+  Circulation<Digraph, CapMap, CapMap, DeltaMap>
+    ::SetFlowMap<FlowMap>
+    ::SetElevator<Elev>
+    ::SetStandardElevator<LinkedElev>
+    ::Create circ_test(g,lcap,ucap,delta);
+
+  circ_test.lowerCapMap(lcap);
+  circ_test.upperCapMap(ucap);
+  circ_test.deltaMap(delta);
+  flow = circ_test.flowMap();
+  circ_test.flowMap(flow);
+
+  circ_test.init();
+  circ_test.greedyInit();
+  circ_test.start();
+  circ_test.run();
+
+  circ_test.barrier(n);
+  circ_test.barrierMap(bar);
+  circ_test.flow(a);
+}
+
+template <class G, class LM, class UM, class DM>
+void checkCirculation(const G& g, const LM& lm, const UM& um,
+                      const DM& dm, bool find)
+{
+  Circulation<G, LM, UM, DM> circ(g, lm, um, dm);
+  bool ret = circ.run();
+  if (find) {
+    check(ret, "A feasible solution should have been found.");
+    check(circ.checkFlow(), "The found flow is corrupt.");
+    check(!circ.checkBarrier(), "A barrier should not have been found.");
+  } else {
+    check(!ret, "A feasible solution should not have been found.");
+    check(circ.checkBarrier(), "The found barrier is corrupt.");
+  }
+}
+
+int main (int, char*[])
+{
+  typedef ListDigraph Digraph;
+  DIGRAPH_TYPEDEFS(Digraph);
+
+  Digraph g;
+  IntArcMap lo(g), up(g);
+  IntNodeMap delta(g, 0);
+  Node s, t;
+
+  std::istringstream input(test_lgf);
+  DigraphReader<Digraph>(g,input).
+    arcMap("lcap", lo).
+    arcMap("ucap", up).
+    node("source",s).
+    node("sink",t).
+    run();
+
+  delta[s] = 7; delta[t] = -7;
+  checkCirculation(g, lo, up, delta, true);
+
+  delta[s] = 13; delta[t] = -13;
+  checkCirculation(g, lo, up, delta, true);
+
+  delta[s] = 6; delta[t] = -6;
+  checkCirculation(g, lo, up, delta, false);
+
+  delta[s] = 14; delta[t] = -14;
+  checkCirculation(g, lo, up, delta, false);
+
+  delta[s] = 7; delta[t] = -13;
+  checkCirculation(g, lo, up, delta, true);
+
+  delta[s] = 5; delta[t] = -15;
+  checkCirculation(g, lo, up, delta, true);
+
+  delta[s] = 10; delta[t] = -11;
+  checkCirculation(g, lo, up, delta, true);
+
+  delta[s] = 11; delta[t] = -10;
+  checkCirculation(g, lo, up, delta, false);
+
+  return 0;
+}
Index: test/counter_test.cc
===================================================================
--- test/counter_test.cc	(revision 209)
+++ test/counter_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/dfs_test.cc
===================================================================
--- test/dfs_test.cc	(revision 293)
+++ test/dfs_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/digraph_test.cc
===================================================================
--- test/digraph_test.cc	(revision 228)
+++ test/digraph_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -20,6 +20,5 @@
 #include <lemon/list_graph.h>
 #include <lemon/smart_graph.h>
-//#include <lemon/full_graph.h>
-//#include <lemon/hypercube_graph.h>
+#include <lemon/full_graph.h>
 
 #include "test_tools.h"
@@ -30,5 +29,5 @@
 
 template <class Digraph>
-void checkDigraph() {
+void checkDigraphBuild() {
   TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
   Digraph G;
@@ -59,5 +58,8 @@
   checkGraphConArcList(G, 1);
 
-  Arc a2 = G.addArc(n2, n1), a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
+  Arc a2 = G.addArc(n2, n1),
+      a3 = G.addArc(n2, n3),
+      a4 = G.addArc(n2, n3);
+
   checkGraphNodeList(G, 3);
   checkGraphArcList(G, 4);
@@ -77,7 +79,213 @@
   checkGraphNodeMap(G);
   checkGraphArcMap(G);
-
-}
-
+}
+
+template <class Digraph>
+void checkDigraphSplit() {
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+  Digraph G;
+  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
+  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
+      a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
+
+  Node n4 = G.split(n2);
+
+  check(G.target(OutArcIt(G, n2)) == n4 &&
+        G.source(InArcIt(G, n4)) == n2,
+        "Wrong split.");
+
+  checkGraphNodeList(G, 4);
+  checkGraphArcList(G, 5);
+
+  checkGraphOutArcList(G, n1, 1);
+  checkGraphOutArcList(G, n2, 1);
+  checkGraphOutArcList(G, n3, 0);
+  checkGraphOutArcList(G, n4, 3);
+
+  checkGraphInArcList(G, n1, 1);
+  checkGraphInArcList(G, n2, 1);
+  checkGraphInArcList(G, n3, 2);
+  checkGraphInArcList(G, n4, 1);
+
+  checkGraphConArcList(G, 5);
+}
+
+template <class Digraph>
+void checkDigraphAlter() {
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+  Digraph G;
+  Node n1 = G.addNode(), n2 = G.addNode(),
+       n3 = G.addNode(), n4 = G.addNode();
+  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
+      a3 = G.addArc(n4, n3), a4 = G.addArc(n4, n3),
+      a5 = G.addArc(n2, n4);
+
+  checkGraphNodeList(G, 4);
+  checkGraphArcList(G, 5);
+
+  // Check changeSource() and changeTarget()
+  G.changeTarget(a4, n1);
+
+  checkGraphNodeList(G, 4);
+  checkGraphArcList(G, 5);
+
+  checkGraphOutArcList(G, n1, 1);
+  checkGraphOutArcList(G, n2, 1);
+  checkGraphOutArcList(G, n3, 0);
+  checkGraphOutArcList(G, n4, 3);
+
+  checkGraphInArcList(G, n1, 2);
+  checkGraphInArcList(G, n2, 1);
+  checkGraphInArcList(G, n3, 1);
+  checkGraphInArcList(G, n4, 1);
+
+  checkGraphConArcList(G, 5);
+
+  G.changeSource(a4, n3);
+
+  checkGraphNodeList(G, 4);
+  checkGraphArcList(G, 5);
+
+  checkGraphOutArcList(G, n1, 1);
+  checkGraphOutArcList(G, n2, 1);
+  checkGraphOutArcList(G, n3, 1);
+  checkGraphOutArcList(G, n4, 2);
+
+  checkGraphInArcList(G, n1, 2);
+  checkGraphInArcList(G, n2, 1);
+  checkGraphInArcList(G, n3, 1);
+  checkGraphInArcList(G, n4, 1);
+
+  checkGraphConArcList(G, 5);
+
+  // Check contract()
+  G.contract(n2, n4, false);
+
+  checkGraphNodeList(G, 3);
+  checkGraphArcList(G, 5);
+
+  checkGraphOutArcList(G, n1, 1);
+  checkGraphOutArcList(G, n2, 3);
+  checkGraphOutArcList(G, n3, 1);
+
+  checkGraphInArcList(G, n1, 2);
+  checkGraphInArcList(G, n2, 2);
+  checkGraphInArcList(G, n3, 1);
+
+  checkGraphConArcList(G, 5);
+
+  G.contract(n2, n1);
+
+  checkGraphNodeList(G, 2);
+  checkGraphArcList(G, 3);
+
+  checkGraphOutArcList(G, n2, 2);
+  checkGraphOutArcList(G, n3, 1);
+
+  checkGraphInArcList(G, n2, 2);
+  checkGraphInArcList(G, n3, 1);
+
+  checkGraphConArcList(G, 3);
+}
+
+template <class Digraph>
+void checkDigraphErase() {
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+  Digraph G;
+  Node n1 = G.addNode(), n2 = G.addNode(),
+       n3 = G.addNode(), n4 = G.addNode();
+  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
+      a3 = G.addArc(n4, n3), a4 = G.addArc(n3, n1),
+      a5 = G.addArc(n2, n4);
+
+  // Check arc deletion
+  G.erase(a1);
+
+  checkGraphNodeList(G, 4);
+  checkGraphArcList(G, 4);
+
+  checkGraphOutArcList(G, n1, 0);
+  checkGraphOutArcList(G, n2, 1);
+  checkGraphOutArcList(G, n3, 1);
+  checkGraphOutArcList(G, n4, 2);
+
+  checkGraphInArcList(G, n1, 2);
+  checkGraphInArcList(G, n2, 0);
+  checkGraphInArcList(G, n3, 1);
+  checkGraphInArcList(G, n4, 1);
+
+  checkGraphConArcList(G, 4);
+
+  // Check node deletion
+  G.erase(n4);
+
+  checkGraphNodeList(G, 3);
+  checkGraphArcList(G, 1);
+
+  checkGraphOutArcList(G, n1, 0);
+  checkGraphOutArcList(G, n2, 0);
+  checkGraphOutArcList(G, n3, 1);
+  checkGraphOutArcList(G, n4, 0);
+
+  checkGraphInArcList(G, n1, 1);
+  checkGraphInArcList(G, n2, 0);
+  checkGraphInArcList(G, n3, 0);
+  checkGraphInArcList(G, n4, 0);
+
+  checkGraphConArcList(G, 1);
+}
+
+
+template <class Digraph>
+void checkDigraphSnapshot() {
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+  Digraph G;
+  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
+  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
+      a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
+
+  typename Digraph::Snapshot snapshot(G);
+
+  Node n = G.addNode();
+  G.addArc(n3, n);
+  G.addArc(n, n3);
+
+  checkGraphNodeList(G, 4);
+  checkGraphArcList(G, 6);
+
+  snapshot.restore();
+
+  checkGraphNodeList(G, 3);
+  checkGraphArcList(G, 4);
+
+  checkGraphOutArcList(G, n1, 1);
+  checkGraphOutArcList(G, n2, 3);
+  checkGraphOutArcList(G, n3, 0);
+
+  checkGraphInArcList(G, n1, 1);
+  checkGraphInArcList(G, n2, 1);
+  checkGraphInArcList(G, n3, 2);
+
+  checkGraphConArcList(G, 4);
+
+  checkNodeIds(G);
+  checkArcIds(G);
+  checkGraphNodeMap(G);
+  checkGraphArcMap(G);
+
+  G.addNode();
+  snapshot.save(G);
+
+  G.addArc(G.addNode(), G.addNode());
+
+  snapshot.restore();
+
+  checkGraphNodeList(G, 4);
+  checkGraphArcList(G, 4);
+}
 
 void checkConcepts() {
@@ -110,10 +318,7 @@
     checkConcept<ClearableDigraphComponent<>, SmartDigraph>();
   }
-//  { // Checking FullDigraph
-//    checkConcept<Digraph, FullDigraph>();
-//  }
-//  { // Checking HyperCubeDigraph
-//    checkConcept<Digraph, HyperCubeDigraph>();
-//  }
+  { // Checking FullDigraph
+    checkConcept<Digraph, FullDigraph>();
+  }
 }
 
@@ -168,12 +373,53 @@
 }
 
+void checkFullDigraph(int num) {
+  typedef FullDigraph Digraph;
+  DIGRAPH_TYPEDEFS(Digraph);
+  Digraph G(num);
+
+  checkGraphNodeList(G, num);
+  checkGraphArcList(G, num * num);
+
+  for (NodeIt n(G); n != INVALID; ++n) {
+    checkGraphOutArcList(G, n, num);
+    checkGraphInArcList(G, n, num);
+  }
+
+  checkGraphConArcList(G, num * num);
+
+  checkNodeIds(G);
+  checkArcIds(G);
+  checkGraphNodeMap(G);
+  checkGraphArcMap(G);
+
+  for (int i = 0; i < G.nodeNum(); ++i) {
+    check(G.index(G(i)) == i, "Wrong index");
+  }
+
+  for (NodeIt s(G); s != INVALID; ++s) {
+    for (NodeIt t(G); t != INVALID; ++t) {
+      Arc a = G.arc(s, t);
+      check(G.source(a) == s && G.target(a) == t, "Wrong arc lookup");
+    }
+  }
+}
+
 void checkDigraphs() {
   { // Checking ListDigraph
-    checkDigraph<ListDigraph>();
+    checkDigraphBuild<ListDigraph>();
+    checkDigraphSplit<ListDigraph>();
+    checkDigraphAlter<ListDigraph>();
+    checkDigraphErase<ListDigraph>();
+    checkDigraphSnapshot<ListDigraph>();
     checkDigraphValidityErase<ListDigraph>();
   }
   { // Checking SmartDigraph
-    checkDigraph<SmartDigraph>();
+    checkDigraphBuild<SmartDigraph>();
+    checkDigraphSplit<SmartDigraph>();
+    checkDigraphSnapshot<SmartDigraph>();
     checkDigraphValidity<SmartDigraph>();
+  }
+  { // Checking FullDigraph
+    checkFullDigraph(8);
   }
 }
Index: test/dijkstra_test.cc
===================================================================
--- test/dijkstra_test.cc	(revision 397)
+++ test/dijkstra_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/dim_test.cc
===================================================================
--- test/dim_test.cc	(revision 253)
+++ test/dim_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/error_test.cc
===================================================================
--- test/error_test.cc	(revision 277)
+++ test/error_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/graph_adaptor_test.cc
===================================================================
--- test/graph_adaptor_test.cc	(revision 440)
+++ test/graph_adaptor_test.cc	(revision 440)
@@ -0,0 +1,984 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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.
+ *
+ */
+
+#include<iostream>
+#include<lemon/concept_check.h>
+
+#include<lemon/list_graph.h>
+#include<lemon/smart_graph.h>
+
+#include<lemon/concepts/digraph.h>
+#include<lemon/concepts/graph.h>
+
+#include<lemon/adaptors.h>
+
+#include <limits>
+#include <lemon/bfs.h>
+#include <lemon/path.h>
+
+#include"test/test_tools.h"
+#include"test/graph_test.h"
+
+using namespace lemon;
+
+void checkReverseDigraph() {
+  checkConcept<concepts::Digraph, ReverseDigraph<concepts::Digraph> >();
+
+  typedef ListDigraph Digraph;
+  typedef ReverseDigraph<Digraph> Adaptor;
+
+  Digraph digraph;
+  Adaptor adaptor(digraph);
+
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Digraph::Node n3 = digraph.addNode();
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n1, n3);
+  Digraph::Arc a3 = digraph.addArc(n2, n3);
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 3);
+  checkGraphConArcList(adaptor, 3);
+
+  checkGraphOutArcList(adaptor, n1, 0);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 2);
+
+  checkGraphInArcList(adaptor, n1, 2);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 0);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
+    check(adaptor.source(a) == digraph.target(a), "Wrong reverse");
+    check(adaptor.target(a) == digraph.source(a), "Wrong reverse");
+  }
+}
+
+void checkSubDigraph() {
+  checkConcept<concepts::Digraph,
+    SubDigraph<concepts::Digraph,
+    concepts::Digraph::NodeMap<bool>,
+    concepts::Digraph::ArcMap<bool> > >();
+
+  typedef ListDigraph Digraph;
+  typedef Digraph::NodeMap<bool> NodeFilter;
+  typedef Digraph::ArcMap<bool> ArcFilter;
+  typedef SubDigraph<Digraph, NodeFilter, ArcFilter> Adaptor;
+
+  Digraph digraph;
+  NodeFilter node_filter(digraph);
+  ArcFilter arc_filter(digraph);
+  Adaptor adaptor(digraph, node_filter, arc_filter);
+
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Digraph::Node n3 = digraph.addNode();
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n1, n3);
+  Digraph::Arc a3 = digraph.addArc(n2, n3);
+
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = true;
+  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = true;
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 3);
+  checkGraphConArcList(adaptor, 3);
+
+  checkGraphOutArcList(adaptor, n1, 2);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 2);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  arc_filter[a2] = false;
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 2);
+  checkGraphConArcList(adaptor, 2);
+
+  checkGraphOutArcList(adaptor, n1, 1);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  node_filter[n1] = false;
+
+  checkGraphNodeList(adaptor, 2);
+  checkGraphArcList(adaptor, 1);
+  checkGraphConArcList(adaptor, 1);
+
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n2, 0);
+  checkGraphInArcList(adaptor, n3, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = false;
+  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = false;
+
+  checkGraphNodeList(adaptor, 0);
+  checkGraphArcList(adaptor, 0);
+  checkGraphConArcList(adaptor, 0);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+}
+
+void checkFilterNodes1() {
+  checkConcept<concepts::Digraph,
+    FilterNodes<concepts::Digraph,
+      concepts::Digraph::NodeMap<bool> > >();
+
+  typedef ListDigraph Digraph;
+  typedef Digraph::NodeMap<bool> NodeFilter;
+  typedef FilterNodes<Digraph, NodeFilter> Adaptor;
+
+  Digraph digraph;
+  NodeFilter node_filter(digraph);
+  Adaptor adaptor(digraph, node_filter);
+
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Digraph::Node n3 = digraph.addNode();
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n1, n3);
+  Digraph::Arc a3 = digraph.addArc(n2, n3);
+
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = true;
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 3);
+  checkGraphConArcList(adaptor, 3);
+
+  checkGraphOutArcList(adaptor, n1, 2);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 2);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  node_filter[n1] = false;
+
+  checkGraphNodeList(adaptor, 2);
+  checkGraphArcList(adaptor, 1);
+  checkGraphConArcList(adaptor, 1);
+
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n2, 0);
+  checkGraphInArcList(adaptor, n3, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = false;
+
+  checkGraphNodeList(adaptor, 0);
+  checkGraphArcList(adaptor, 0);
+  checkGraphConArcList(adaptor, 0);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+}
+
+void checkFilterArcs() {
+  checkConcept<concepts::Digraph,
+    FilterArcs<concepts::Digraph,
+    concepts::Digraph::ArcMap<bool> > >();
+
+  typedef ListDigraph Digraph;
+  typedef Digraph::ArcMap<bool> ArcFilter;
+  typedef FilterArcs<Digraph, ArcFilter> Adaptor;
+
+  Digraph digraph;
+  ArcFilter arc_filter(digraph);
+  Adaptor adaptor(digraph, arc_filter);
+
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Digraph::Node n3 = digraph.addNode();
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n1, n3);
+  Digraph::Arc a3 = digraph.addArc(n2, n3);
+
+  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = true;
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 3);
+  checkGraphConArcList(adaptor, 3);
+
+  checkGraphOutArcList(adaptor, n1, 2);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 2);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  arc_filter[a2] = false;
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 2);
+  checkGraphConArcList(adaptor, 2);
+
+  checkGraphOutArcList(adaptor, n1, 1);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = false;
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 0);
+  checkGraphConArcList(adaptor, 0);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+}
+
+void checkUndirector() {
+  checkConcept<concepts::Graph, Undirector<concepts::Digraph> >();
+
+  typedef ListDigraph Digraph;
+  typedef Undirector<Digraph> Adaptor;
+
+  Digraph digraph;
+  Adaptor adaptor(digraph);
+
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Digraph::Node n3 = digraph.addNode();
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n1, n3);
+  Digraph::Arc a3 = digraph.addArc(n2, n3);
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 6);
+  checkGraphEdgeList(adaptor, 3);
+  checkGraphConArcList(adaptor, 6);
+  checkGraphConEdgeList(adaptor, 3);
+
+  checkGraphOutArcList(adaptor, n1, 2);
+  checkGraphOutArcList(adaptor, n2, 2);
+  checkGraphOutArcList(adaptor, n3, 2);
+
+  checkGraphInArcList(adaptor, n1, 2);
+  checkGraphInArcList(adaptor, n2, 2);
+  checkGraphInArcList(adaptor, n3, 2);
+
+  checkGraphIncEdgeList(adaptor, n1, 2);
+  checkGraphIncEdgeList(adaptor, n2, 2);
+  checkGraphIncEdgeList(adaptor, n3, 2);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  for (Adaptor::EdgeIt e(adaptor); e != INVALID; ++e) {
+    check(adaptor.u(e) == digraph.source(e), "Wrong undir");
+    check(adaptor.v(e) == digraph.target(e), "Wrong undir");
+  }
+
+}
+
+void checkResidual() {
+  checkConcept<concepts::Digraph,
+    Residual<concepts::Digraph,
+    concepts::Digraph::ArcMap<int>,
+    concepts::Digraph::ArcMap<int> > >();
+
+  typedef ListDigraph Digraph;
+  typedef Digraph::ArcMap<int> IntArcMap;
+  typedef Residual<Digraph, IntArcMap> Adaptor;
+
+  Digraph digraph;
+  IntArcMap capacity(digraph), flow(digraph);
+  Adaptor adaptor(digraph, capacity, flow);
+
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Digraph::Node n3 = digraph.addNode();
+  Digraph::Node n4 = digraph.addNode();
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n1, n3);
+  Digraph::Arc a3 = digraph.addArc(n1, n4);
+  Digraph::Arc a4 = digraph.addArc(n2, n3);
+  Digraph::Arc a5 = digraph.addArc(n2, n4);
+  Digraph::Arc a6 = digraph.addArc(n3, n4);
+
+  capacity[a1] = 8;
+  capacity[a2] = 6;
+  capacity[a3] = 4;
+  capacity[a4] = 4;
+  capacity[a5] = 6;
+  capacity[a6] = 10;
+
+  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
+    flow[a] = 0;
+  }
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 6);
+  checkGraphConArcList(adaptor, 6);
+
+  checkGraphOutArcList(adaptor, n1, 3);
+  checkGraphOutArcList(adaptor, n2, 2);
+  checkGraphOutArcList(adaptor, n3, 1);
+  checkGraphOutArcList(adaptor, n4, 0);
+
+  checkGraphInArcList(adaptor, n1, 0);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 2);
+  checkGraphInArcList(adaptor, n4, 3);
+
+  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
+    flow[a] = capacity[a] / 2;
+  }
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 12);
+  checkGraphConArcList(adaptor, 12);
+
+  checkGraphOutArcList(adaptor, n1, 3);
+  checkGraphOutArcList(adaptor, n2, 3);
+  checkGraphOutArcList(adaptor, n3, 3);
+  checkGraphOutArcList(adaptor, n4, 3);
+
+  checkGraphInArcList(adaptor, n1, 3);
+  checkGraphInArcList(adaptor, n2, 3);
+  checkGraphInArcList(adaptor, n3, 3);
+  checkGraphInArcList(adaptor, n4, 3);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
+    flow[a] = capacity[a];
+  }
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 6);
+  checkGraphConArcList(adaptor, 6);
+
+  checkGraphOutArcList(adaptor, n1, 0);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 2);
+  checkGraphOutArcList(adaptor, n4, 3);
+
+  checkGraphInArcList(adaptor, n1, 3);
+  checkGraphInArcList(adaptor, n2, 2);
+  checkGraphInArcList(adaptor, n3, 1);
+  checkGraphInArcList(adaptor, n4, 0);
+
+  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
+    flow[a] = 0;
+  }
+
+  int flow_value = 0;
+  while (true) {
+
+    Bfs<Adaptor> bfs(adaptor);
+    bfs.run(n1, n4);
+
+    if (!bfs.reached(n4)) break;
+
+    Path<Adaptor> p = bfs.path(n4);
+
+    int min = std::numeric_limits<int>::max();
+    for (Path<Adaptor>::ArcIt a(p); a != INVALID; ++a) {
+      if (adaptor.residualCapacity(a) < min)
+        min = adaptor.residualCapacity(a);
+    }
+
+    for (Path<Adaptor>::ArcIt a(p); a != INVALID; ++a) {
+      adaptor.augment(a, min);
+    }
+    flow_value += min;
+  }
+
+  check(flow_value == 18, "Wrong flow with res graph adaptor");
+
+}
+
+void checkSplitNodes() {
+  checkConcept<concepts::Digraph, SplitNodes<concepts::Digraph> >();
+
+  typedef ListDigraph Digraph;
+  typedef SplitNodes<Digraph> Adaptor;
+
+  Digraph digraph;
+  Adaptor adaptor(digraph);
+
+  Digraph::Node n1 = digraph.addNode();
+  Digraph::Node n2 = digraph.addNode();
+  Digraph::Node n3 = digraph.addNode();
+
+  Digraph::Arc a1 = digraph.addArc(n1, n2);
+  Digraph::Arc a2 = digraph.addArc(n1, n3);
+  Digraph::Arc a3 = digraph.addArc(n2, n3);
+
+  checkGraphNodeList(adaptor, 6);
+  checkGraphArcList(adaptor, 6);
+  checkGraphConArcList(adaptor, 6);
+
+  checkGraphOutArcList(adaptor, adaptor.inNode(n1), 1);
+  checkGraphOutArcList(adaptor, adaptor.outNode(n1), 2);
+  checkGraphOutArcList(adaptor, adaptor.inNode(n2), 1);
+  checkGraphOutArcList(adaptor, adaptor.outNode(n2), 1);
+  checkGraphOutArcList(adaptor, adaptor.inNode(n3), 1);
+  checkGraphOutArcList(adaptor, adaptor.outNode(n3), 0);
+
+  checkGraphInArcList(adaptor, adaptor.inNode(n1), 0);
+  checkGraphInArcList(adaptor, adaptor.outNode(n1), 1);
+  checkGraphInArcList(adaptor, adaptor.inNode(n2), 1);
+  checkGraphInArcList(adaptor, adaptor.outNode(n2), 1);
+  checkGraphInArcList(adaptor, adaptor.inNode(n3), 2);
+  checkGraphInArcList(adaptor, adaptor.outNode(n3), 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
+    if (adaptor.origArc(a)) {
+      Digraph::Arc oa = a;
+      check(adaptor.source(a) == adaptor.outNode(digraph.source(oa)),
+            "Wrong split");
+      check(adaptor.target(a) == adaptor.inNode(digraph.target(oa)),
+            "Wrong split");
+    } else {
+      Digraph::Node on = a;
+      check(adaptor.source(a) == adaptor.inNode(on), "Wrong split");
+      check(adaptor.target(a) == adaptor.outNode(on), "Wrong split");
+    }
+  }
+}
+
+void checkSubGraph() {
+  checkConcept<concepts::Graph,
+    SubGraph<concepts::Graph,
+    concepts::Graph::NodeMap<bool>,
+    concepts::Graph::EdgeMap<bool> > >();
+
+  typedef ListGraph Graph;
+  typedef Graph::NodeMap<bool> NodeFilter;
+  typedef Graph::EdgeMap<bool> EdgeFilter;
+  typedef SubGraph<Graph, NodeFilter, EdgeFilter> Adaptor;
+
+  Graph graph;
+  NodeFilter node_filter(graph);
+  EdgeFilter edge_filter(graph);
+  Adaptor adaptor(graph, node_filter, edge_filter);
+
+  Graph::Node n1 = graph.addNode();
+  Graph::Node n2 = graph.addNode();
+  Graph::Node n3 = graph.addNode();
+  Graph::Node n4 = graph.addNode();
+
+  Graph::Edge e1 = graph.addEdge(n1, n2);
+  Graph::Edge e2 = graph.addEdge(n1, n3);
+  Graph::Edge e3 = graph.addEdge(n2, n3);
+  Graph::Edge e4 = graph.addEdge(n3, n4);
+
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = true;
+  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = true;
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 8);
+  checkGraphEdgeList(adaptor, 4);
+  checkGraphConArcList(adaptor, 8);
+  checkGraphConEdgeList(adaptor, 4);
+
+  checkGraphOutArcList(adaptor, n1, 2);
+  checkGraphOutArcList(adaptor, n2, 2);
+  checkGraphOutArcList(adaptor, n3, 3);
+  checkGraphOutArcList(adaptor, n4, 1);
+
+  checkGraphInArcList(adaptor, n1, 2);
+  checkGraphInArcList(adaptor, n2, 2);
+  checkGraphInArcList(adaptor, n3, 3);
+  checkGraphInArcList(adaptor, n4, 1);
+
+  checkGraphIncEdgeList(adaptor, n1, 2);
+  checkGraphIncEdgeList(adaptor, n2, 2);
+  checkGraphIncEdgeList(adaptor, n3, 3);
+  checkGraphIncEdgeList(adaptor, n4, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  edge_filter[e2] = false;
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 6);
+  checkGraphEdgeList(adaptor, 3);
+  checkGraphConArcList(adaptor, 6);
+  checkGraphConEdgeList(adaptor, 3);
+
+  checkGraphOutArcList(adaptor, n1, 1);
+  checkGraphOutArcList(adaptor, n2, 2);
+  checkGraphOutArcList(adaptor, n3, 2);
+  checkGraphOutArcList(adaptor, n4, 1);
+
+  checkGraphInArcList(adaptor, n1, 1);
+  checkGraphInArcList(adaptor, n2, 2);
+  checkGraphInArcList(adaptor, n3, 2);
+  checkGraphInArcList(adaptor, n4, 1);
+
+  checkGraphIncEdgeList(adaptor, n1, 1);
+  checkGraphIncEdgeList(adaptor, n2, 2);
+  checkGraphIncEdgeList(adaptor, n3, 2);
+  checkGraphIncEdgeList(adaptor, n4, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  node_filter[n1] = false;
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 4);
+  checkGraphEdgeList(adaptor, 2);
+  checkGraphConArcList(adaptor, 4);
+  checkGraphConEdgeList(adaptor, 2);
+
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 2);
+  checkGraphOutArcList(adaptor, n4, 1);
+
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 2);
+  checkGraphInArcList(adaptor, n4, 1);
+
+  checkGraphIncEdgeList(adaptor, n2, 1);
+  checkGraphIncEdgeList(adaptor, n3, 2);
+  checkGraphIncEdgeList(adaptor, n4, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = false;
+  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = false;
+
+  checkGraphNodeList(adaptor, 0);
+  checkGraphArcList(adaptor, 0);
+  checkGraphEdgeList(adaptor, 0);
+  checkGraphConArcList(adaptor, 0);
+  checkGraphConEdgeList(adaptor, 0);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+}
+
+void checkFilterNodes2() {
+  checkConcept<concepts::Graph,
+    FilterNodes<concepts::Graph,
+      concepts::Graph::NodeMap<bool> > >();
+
+  typedef ListGraph Graph;
+  typedef Graph::NodeMap<bool> NodeFilter;
+  typedef FilterNodes<Graph, NodeFilter> Adaptor;
+
+  Graph graph;
+  NodeFilter node_filter(graph);
+  Adaptor adaptor(graph, node_filter);
+
+  Graph::Node n1 = graph.addNode();
+  Graph::Node n2 = graph.addNode();
+  Graph::Node n3 = graph.addNode();
+  Graph::Node n4 = graph.addNode();
+
+  Graph::Edge e1 = graph.addEdge(n1, n2);
+  Graph::Edge e2 = graph.addEdge(n1, n3);
+  Graph::Edge e3 = graph.addEdge(n2, n3);
+  Graph::Edge e4 = graph.addEdge(n3, n4);
+
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = true;
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 8);
+  checkGraphEdgeList(adaptor, 4);
+  checkGraphConArcList(adaptor, 8);
+  checkGraphConEdgeList(adaptor, 4);
+
+  checkGraphOutArcList(adaptor, n1, 2);
+  checkGraphOutArcList(adaptor, n2, 2);
+  checkGraphOutArcList(adaptor, n3, 3);
+  checkGraphOutArcList(adaptor, n4, 1);
+
+  checkGraphInArcList(adaptor, n1, 2);
+  checkGraphInArcList(adaptor, n2, 2);
+  checkGraphInArcList(adaptor, n3, 3);
+  checkGraphInArcList(adaptor, n4, 1);
+
+  checkGraphIncEdgeList(adaptor, n1, 2);
+  checkGraphIncEdgeList(adaptor, n2, 2);
+  checkGraphIncEdgeList(adaptor, n3, 3);
+  checkGraphIncEdgeList(adaptor, n4, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  node_filter[n1] = false;
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 4);
+  checkGraphEdgeList(adaptor, 2);
+  checkGraphConArcList(adaptor, 4);
+  checkGraphConEdgeList(adaptor, 2);
+
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 2);
+  checkGraphOutArcList(adaptor, n4, 1);
+
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 2);
+  checkGraphInArcList(adaptor, n4, 1);
+
+  checkGraphIncEdgeList(adaptor, n2, 1);
+  checkGraphIncEdgeList(adaptor, n3, 2);
+  checkGraphIncEdgeList(adaptor, n4, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = false;
+
+  checkGraphNodeList(adaptor, 0);
+  checkGraphArcList(adaptor, 0);
+  checkGraphEdgeList(adaptor, 0);
+  checkGraphConArcList(adaptor, 0);
+  checkGraphConEdgeList(adaptor, 0);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+}
+
+void checkFilterEdges() {
+  checkConcept<concepts::Graph,
+    FilterEdges<concepts::Graph,
+    concepts::Graph::EdgeMap<bool> > >();
+
+  typedef ListGraph Graph;
+  typedef Graph::EdgeMap<bool> EdgeFilter;
+  typedef FilterEdges<Graph, EdgeFilter> Adaptor;
+
+  Graph graph;
+  EdgeFilter edge_filter(graph);
+  Adaptor adaptor(graph, edge_filter);
+
+  Graph::Node n1 = graph.addNode();
+  Graph::Node n2 = graph.addNode();
+  Graph::Node n3 = graph.addNode();
+  Graph::Node n4 = graph.addNode();
+
+  Graph::Edge e1 = graph.addEdge(n1, n2);
+  Graph::Edge e2 = graph.addEdge(n1, n3);
+  Graph::Edge e3 = graph.addEdge(n2, n3);
+  Graph::Edge e4 = graph.addEdge(n3, n4);
+
+  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = true;
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 8);
+  checkGraphEdgeList(adaptor, 4);
+  checkGraphConArcList(adaptor, 8);
+  checkGraphConEdgeList(adaptor, 4);
+
+  checkGraphOutArcList(adaptor, n1, 2);
+  checkGraphOutArcList(adaptor, n2, 2);
+  checkGraphOutArcList(adaptor, n3, 3);
+  checkGraphOutArcList(adaptor, n4, 1);
+
+  checkGraphInArcList(adaptor, n1, 2);
+  checkGraphInArcList(adaptor, n2, 2);
+  checkGraphInArcList(adaptor, n3, 3);
+  checkGraphInArcList(adaptor, n4, 1);
+
+  checkGraphIncEdgeList(adaptor, n1, 2);
+  checkGraphIncEdgeList(adaptor, n2, 2);
+  checkGraphIncEdgeList(adaptor, n3, 3);
+  checkGraphIncEdgeList(adaptor, n4, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  edge_filter[e2] = false;
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 6);
+  checkGraphEdgeList(adaptor, 3);
+  checkGraphConArcList(adaptor, 6);
+  checkGraphConEdgeList(adaptor, 3);
+
+  checkGraphOutArcList(adaptor, n1, 1);
+  checkGraphOutArcList(adaptor, n2, 2);
+  checkGraphOutArcList(adaptor, n3, 2);
+  checkGraphOutArcList(adaptor, n4, 1);
+
+  checkGraphInArcList(adaptor, n1, 1);
+  checkGraphInArcList(adaptor, n2, 2);
+  checkGraphInArcList(adaptor, n3, 2);
+  checkGraphInArcList(adaptor, n4, 1);
+
+  checkGraphIncEdgeList(adaptor, n1, 1);
+  checkGraphIncEdgeList(adaptor, n2, 2);
+  checkGraphIncEdgeList(adaptor, n3, 2);
+  checkGraphIncEdgeList(adaptor, n4, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+
+  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = false;
+
+  checkGraphNodeList(adaptor, 4);
+  checkGraphArcList(adaptor, 0);
+  checkGraphEdgeList(adaptor, 0);
+  checkGraphConArcList(adaptor, 0);
+  checkGraphConEdgeList(adaptor, 0);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+  checkEdgeIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+  checkGraphEdgeMap(adaptor);
+}
+
+void checkOrienter() {
+  checkConcept<concepts::Digraph,
+    Orienter<concepts::Graph, concepts::Graph::EdgeMap<bool> > >();
+
+  typedef ListGraph Graph;
+  typedef ListGraph::EdgeMap<bool> DirMap;
+  typedef Orienter<Graph> Adaptor;
+
+  Graph graph;
+  DirMap dir(graph, true);
+  Adaptor adaptor(graph, dir);
+
+  Graph::Node n1 = graph.addNode();
+  Graph::Node n2 = graph.addNode();
+  Graph::Node n3 = graph.addNode();
+
+  Graph::Edge e1 = graph.addEdge(n1, n2);
+  Graph::Edge e2 = graph.addEdge(n1, n3);
+  Graph::Edge e3 = graph.addEdge(n2, n3);
+
+  checkGraphNodeList(adaptor, 3);
+  checkGraphArcList(adaptor, 3);
+  checkGraphConArcList(adaptor, 3);
+
+  {
+    dir[e1] = true;
+    Adaptor::Node u = adaptor.source(e1);
+    Adaptor::Node v = adaptor.target(e1);
+
+    dir[e1] = false;
+    check (u == adaptor.target(e1), "Wrong dir");
+    check (v == adaptor.source(e1), "Wrong dir");
+
+    check ((u == n1 && v == n2) || (u == n2 && v == n1), "Wrong dir");
+    dir[e1] = n1 == u;
+  }
+
+  {
+    dir[e2] = true;
+    Adaptor::Node u = adaptor.source(e2);
+    Adaptor::Node v = adaptor.target(e2);
+
+    dir[e2] = false;
+    check (u == adaptor.target(e2), "Wrong dir");
+    check (v == adaptor.source(e2), "Wrong dir");
+
+    check ((u == n1 && v == n3) || (u == n3 && v == n1), "Wrong dir");
+    dir[e2] = n3 == u;
+  }
+
+  {
+    dir[e3] = true;
+    Adaptor::Node u = adaptor.source(e3);
+    Adaptor::Node v = adaptor.target(e3);
+
+    dir[e3] = false;
+    check (u == adaptor.target(e3), "Wrong dir");
+    check (v == adaptor.source(e3), "Wrong dir");
+
+    check ((u == n2 && v == n3) || (u == n3 && v == n2), "Wrong dir");
+    dir[e3] = n2 == u;
+  }
+
+  checkGraphOutArcList(adaptor, n1, 1);
+  checkGraphOutArcList(adaptor, n2, 1);
+  checkGraphOutArcList(adaptor, n3, 1);
+
+  checkGraphInArcList(adaptor, n1, 1);
+  checkGraphInArcList(adaptor, n2, 1);
+  checkGraphInArcList(adaptor, n3, 1);
+
+  checkNodeIds(adaptor);
+  checkArcIds(adaptor);
+
+  checkGraphNodeMap(adaptor);
+  checkGraphArcMap(adaptor);
+
+}
+
+
+int main(int, const char **) {
+
+  checkReverseDigraph();
+  checkSubDigraph();
+  checkFilterNodes1();
+  checkFilterArcs();
+  checkUndirector();
+  checkResidual();
+  checkSplitNodes();
+
+  checkSubGraph();
+  checkFilterNodes2();
+  checkFilterEdges();
+  checkOrienter();
+
+  return 0;
+}
Index: test/graph_copy_test.cc
===================================================================
--- test/graph_copy_test.cc	(revision 282)
+++ test/graph_copy_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/graph_test.cc
===================================================================
--- test/graph_test.cc	(revision 228)
+++ test/graph_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -20,6 +20,7 @@
 #include <lemon/list_graph.h>
 #include <lemon/smart_graph.h>
-// #include <lemon/full_graph.h>
-// #include <lemon/grid_graph.h>
+#include <lemon/full_graph.h>
+#include <lemon/grid_graph.h>
+#include <lemon/hypercube_graph.h>
 
 #include "test_tools.h"
@@ -30,5 +31,5 @@
 
 template <class Graph>
-void checkGraph() {
+void checkGraphBuild() {
   TEMPLATE_GRAPH_TYPEDEFS(Graph);
 
@@ -36,4 +37,5 @@
   checkGraphNodeList(G, 0);
   checkGraphEdgeList(G, 0);
+  checkGraphArcList(G, 0);
 
   Node
@@ -43,46 +45,34 @@
   checkGraphNodeList(G, 3);
   checkGraphEdgeList(G, 0);
+  checkGraphArcList(G, 0);
 
   Edge e1 = G.addEdge(n1, n2);
   check((G.u(e1) == n1 && G.v(e1) == n2) || (G.u(e1) == n2 && G.v(e1) == n1),
         "Wrong edge");
-  checkGraphNodeList(G, 3);
+
+  checkGraphNodeList(G, 3);
+  checkGraphEdgeList(G, 1);
   checkGraphArcList(G, 2);
-  checkGraphEdgeList(G, 1);
-
-  checkGraphOutArcList(G, n1, 1);
-  checkGraphOutArcList(G, n2, 1);
-  checkGraphOutArcList(G, n3, 0);
-
-  checkGraphInArcList(G, n1, 1);
-  checkGraphInArcList(G, n2, 1);
-  checkGraphInArcList(G, n3, 0);
-
-  checkGraphIncEdgeList(G, n1, 1);
-  checkGraphIncEdgeList(G, n2, 1);
-  checkGraphIncEdgeList(G, n3, 0);
-
+
+  checkGraphIncEdgeArcLists(G, n1, 1);
+  checkGraphIncEdgeArcLists(G, n2, 1);
+  checkGraphIncEdgeArcLists(G, n3, 0);
+
+  checkGraphConEdgeList(G, 1);
   checkGraphConArcList(G, 2);
-  checkGraphConEdgeList(G, 1);
-
-  Edge e2 = G.addEdge(n2, n1), e3 = G.addEdge(n2, n3);
-  checkGraphNodeList(G, 3);
+
+  Edge e2 = G.addEdge(n2, n1),
+       e3 = G.addEdge(n2, n3);
+
+  checkGraphNodeList(G, 3);
+  checkGraphEdgeList(G, 3);
   checkGraphArcList(G, 6);
-  checkGraphEdgeList(G, 3);
-
-  checkGraphOutArcList(G, n1, 2);
-  checkGraphOutArcList(G, n2, 3);
-  checkGraphOutArcList(G, n3, 1);
-
-  checkGraphInArcList(G, n1, 2);
-  checkGraphInArcList(G, n2, 3);
-  checkGraphInArcList(G, n3, 1);
-
-  checkGraphIncEdgeList(G, n1, 2);
-  checkGraphIncEdgeList(G, n2, 3);
-  checkGraphIncEdgeList(G, n3, 1);
-
+
+  checkGraphIncEdgeArcLists(G, n1, 2);
+  checkGraphIncEdgeArcLists(G, n2, 3);
+  checkGraphIncEdgeArcLists(G, n3, 1);
+
+  checkGraphConEdgeList(G, 3);
   checkGraphConArcList(G, 6);
-  checkGraphConEdgeList(G, 3);
 
   checkArcDirections(G);
@@ -96,4 +86,228 @@
 }
 
+template <class Graph>
+void checkGraphAlter() {
+  TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+  Graph G;
+  Node n1 = G.addNode(), n2 = G.addNode(),
+       n3 = G.addNode(), n4 = G.addNode();
+  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
+       e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
+       e5 = G.addEdge(n4, n3);
+
+  checkGraphNodeList(G, 4);
+  checkGraphEdgeList(G, 5);
+  checkGraphArcList(G, 10);
+
+  // Check changeU() and changeV()
+  if (G.u(e2) == n2) {
+    G.changeU(e2, n3);
+  } else {
+    G.changeV(e2, n3);
+  }
+
+  checkGraphNodeList(G, 4);
+  checkGraphEdgeList(G, 5);
+  checkGraphArcList(G, 10);
+
+  checkGraphIncEdgeArcLists(G, n1, 3);
+  checkGraphIncEdgeArcLists(G, n2, 2);
+  checkGraphIncEdgeArcLists(G, n3, 3);
+  checkGraphIncEdgeArcLists(G, n4, 2);
+
+  checkGraphConEdgeList(G, 5);
+  checkGraphConArcList(G, 10);
+
+  if (G.u(e2) == n1) {
+    G.changeU(e2, n2);
+  } else {
+    G.changeV(e2, n2);
+  }
+
+  checkGraphNodeList(G, 4);
+  checkGraphEdgeList(G, 5);
+  checkGraphArcList(G, 10);
+
+  checkGraphIncEdgeArcLists(G, n1, 2);
+  checkGraphIncEdgeArcLists(G, n2, 3);
+  checkGraphIncEdgeArcLists(G, n3, 3);
+  checkGraphIncEdgeArcLists(G, n4, 2);
+
+  checkGraphConEdgeList(G, 5);
+  checkGraphConArcList(G, 10);
+
+  // Check contract()
+  G.contract(n1, n4, false);
+
+  checkGraphNodeList(G, 3);
+  checkGraphEdgeList(G, 5);
+  checkGraphArcList(G, 10);
+
+  checkGraphIncEdgeArcLists(G, n1, 4);
+  checkGraphIncEdgeArcLists(G, n2, 3);
+  checkGraphIncEdgeArcLists(G, n3, 3);
+
+  checkGraphConEdgeList(G, 5);
+  checkGraphConArcList(G, 10);
+
+  G.contract(n2, n3);
+
+  checkGraphNodeList(G, 2);
+  checkGraphEdgeList(G, 3);
+  checkGraphArcList(G, 6);
+
+  checkGraphIncEdgeArcLists(G, n1, 4);
+  checkGraphIncEdgeArcLists(G, n2, 2);
+
+  checkGraphConEdgeList(G, 3);
+  checkGraphConArcList(G, 6);
+}
+
+template <class Graph>
+void checkGraphErase() {
+  TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+  Graph G;
+  Node n1 = G.addNode(), n2 = G.addNode(),
+       n3 = G.addNode(), n4 = G.addNode();
+  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
+       e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
+       e5 = G.addEdge(n4, n3);
+
+  // Check edge deletion
+  G.erase(e2);
+
+  checkGraphNodeList(G, 4);
+  checkGraphEdgeList(G, 4);
+  checkGraphArcList(G, 8);
+
+  checkGraphIncEdgeArcLists(G, n1, 2);
+  checkGraphIncEdgeArcLists(G, n2, 2);
+  checkGraphIncEdgeArcLists(G, n3, 2);
+  checkGraphIncEdgeArcLists(G, n4, 2);
+
+  checkGraphConEdgeList(G, 4);
+  checkGraphConArcList(G, 8);
+
+  // Check node deletion
+  G.erase(n3);
+
+  checkGraphNodeList(G, 3);
+  checkGraphEdgeList(G, 2);
+  checkGraphArcList(G, 4);
+
+  checkGraphIncEdgeArcLists(G, n1, 2);
+  checkGraphIncEdgeArcLists(G, n2, 1);
+  checkGraphIncEdgeArcLists(G, n4, 1);
+
+  checkGraphConEdgeList(G, 2);
+  checkGraphConArcList(G, 4);
+}
+
+
+template <class Graph>
+void checkGraphSnapshot() {
+  TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+  Graph G;
+  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
+  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
+       e3 = G.addEdge(n2, n3);
+
+  checkGraphNodeList(G, 3);
+  checkGraphEdgeList(G, 3);
+  checkGraphArcList(G, 6);
+
+  typename Graph::Snapshot snapshot(G);
+
+  Node n = G.addNode();
+  G.addEdge(n3, n);
+  G.addEdge(n, n3);
+  G.addEdge(n3, n2);
+
+  checkGraphNodeList(G, 4);
+  checkGraphEdgeList(G, 6);
+  checkGraphArcList(G, 12);
+
+  snapshot.restore();
+
+  checkGraphNodeList(G, 3);
+  checkGraphEdgeList(G, 3);
+  checkGraphArcList(G, 6);
+
+  checkGraphIncEdgeArcLists(G, n1, 2);
+  checkGraphIncEdgeArcLists(G, n2, 3);
+  checkGraphIncEdgeArcLists(G, n3, 1);
+
+  checkGraphConEdgeList(G, 3);
+  checkGraphConArcList(G, 6);
+
+  checkNodeIds(G);
+  checkEdgeIds(G);
+  checkArcIds(G);
+  checkGraphNodeMap(G);
+  checkGraphEdgeMap(G);
+  checkGraphArcMap(G);
+
+  G.addNode();
+  snapshot.save(G);
+
+  G.addEdge(G.addNode(), G.addNode());
+
+  snapshot.restore();
+
+  checkGraphNodeList(G, 4);
+  checkGraphEdgeList(G, 3);
+  checkGraphArcList(G, 6);
+}
+
+void checkFullGraph(int num) {
+  typedef FullGraph Graph;
+  GRAPH_TYPEDEFS(Graph);
+
+  Graph G(num);
+  checkGraphNodeList(G, num);
+  checkGraphEdgeList(G, num * (num - 1) / 2);
+
+  for (NodeIt n(G); n != INVALID; ++n) {
+    checkGraphOutArcList(G, n, num - 1);
+    checkGraphInArcList(G, n, num - 1);
+    checkGraphIncEdgeList(G, n, num - 1);
+  }
+
+  checkGraphConArcList(G, num * (num - 1));
+  checkGraphConEdgeList(G, num * (num - 1) / 2);
+
+  checkArcDirections(G);
+
+  checkNodeIds(G);
+  checkArcIds(G);
+  checkEdgeIds(G);
+  checkGraphNodeMap(G);
+  checkGraphArcMap(G);
+  checkGraphEdgeMap(G);
+
+
+  for (int i = 0; i < G.nodeNum(); ++i) {
+    check(G.index(G(i)) == i, "Wrong index");
+  }
+
+  for (NodeIt u(G); u != INVALID; ++u) {
+    for (NodeIt v(G); v != INVALID; ++v) {
+      Edge e = G.edge(u, v);
+      Arc a = G.arc(u, v);
+      if (u == v) {
+        check(e == INVALID, "Wrong edge lookup");
+        check(a == INVALID, "Wrong arc lookup");
+      } else {
+        check((G.u(e) == u && G.v(e) == v) ||
+              (G.u(e) == v && G.v(e) == u), "Wrong edge lookup");
+        check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup");
+      }
+    }
+  }
+}
+
 void checkConcepts() {
   { // Checking graph components
@@ -125,12 +339,13 @@
     checkConcept<ClearableGraphComponent<>, SmartGraph>();
   }
-//  { // Checking FullGraph
-//    checkConcept<Graph, FullGraph>();
-//    checkGraphIterators<FullGraph>();
-//  }
-//  { // Checking GridGraph
-//    checkConcept<Graph, GridGraph>();
-//    checkGraphIterators<GridGraph>();
-//  }
+  { // Checking FullGraph
+    checkConcept<Graph, FullGraph>();
+  }
+  { // Checking GridGraph
+    checkConcept<Graph, GridGraph>();
+  }
+  { // Checking HypercubeGraph
+    checkConcept<Graph, HypercubeGraph>();
+  }
 }
 
@@ -189,68 +404,161 @@
 }
 
-// void checkGridGraph(const GridGraph& g, int w, int h) {
-//   check(g.width() == w, "Wrong width");
-//   check(g.height() == h, "Wrong height");
-
-//   for (int i = 0; i < w; ++i) {
-//     for (int j = 0; j < h; ++j) {
-//       check(g.col(g(i, j)) == i, "Wrong col");
-//       check(g.row(g(i, j)) == j, "Wrong row");
-//     }
-//   }
-
-//   for (int i = 0; i < w; ++i) {
-//     for (int j = 0; j < h - 1; ++j) {
-//       check(g.source(g.down(g(i, j))) == g(i, j), "Wrong down");
-//       check(g.target(g.down(g(i, j))) == g(i, j + 1), "Wrong down");
-//     }
-//     check(g.down(g(i, h - 1)) == INVALID, "Wrong down");
-//   }
-
-//   for (int i = 0; i < w; ++i) {
-//     for (int j = 1; j < h; ++j) {
-//       check(g.source(g.up(g(i, j))) == g(i, j), "Wrong up");
-//       check(g.target(g.up(g(i, j))) == g(i, j - 1), "Wrong up");
-//     }
-//     check(g.up(g(i, 0)) == INVALID, "Wrong up");
-//   }
-
-//   for (int j = 0; j < h; ++j) {
-//     for (int i = 0; i < w - 1; ++i) {
-//       check(g.source(g.right(g(i, j))) == g(i, j), "Wrong right");
-//       check(g.target(g.right(g(i, j))) == g(i + 1, j), "Wrong right");
-//     }
-//     check(g.right(g(w - 1, j)) == INVALID, "Wrong right");
-//   }
-
-//   for (int j = 0; j < h; ++j) {
-//     for (int i = 1; i < w; ++i) {
-//       check(g.source(g.left(g(i, j))) == g(i, j), "Wrong left");
-//       check(g.target(g.left(g(i, j))) == g(i - 1, j), "Wrong left");
-//     }
-//     check(g.left(g(0, j)) == INVALID, "Wrong left");
-//   }
-// }
+void checkGridGraph(int width, int height) {
+  typedef GridGraph Graph;
+  GRAPH_TYPEDEFS(Graph);
+  Graph G(width, height);
+
+  check(G.width() == width, "Wrong column number");
+  check(G.height() == height, "Wrong row number");
+
+  for (int i = 0; i < width; ++i) {
+    for (int j = 0; j < height; ++j) {
+      check(G.col(G(i, j)) == i, "Wrong column");
+      check(G.row(G(i, j)) == j, "Wrong row");
+      check(G.pos(G(i, j)).x == i, "Wrong column");
+      check(G.pos(G(i, j)).y == j, "Wrong row");
+    }
+  }
+
+  for (int j = 0; j < height; ++j) {
+    for (int i = 0; i < width - 1; ++i) {
+      check(G.source(G.right(G(i, j))) == G(i, j), "Wrong right");
+      check(G.target(G.right(G(i, j))) == G(i + 1, j), "Wrong right");
+    }
+    check(G.right(G(width - 1, j)) == INVALID, "Wrong right");
+  }
+
+  for (int j = 0; j < height; ++j) {
+    for (int i = 1; i < width; ++i) {
+      check(G.source(G.left(G(i, j))) == G(i, j), "Wrong left");
+      check(G.target(G.left(G(i, j))) == G(i - 1, j), "Wrong left");
+    }
+    check(G.left(G(0, j)) == INVALID, "Wrong left");
+  }
+
+  for (int i = 0; i < width; ++i) {
+    for (int j = 0; j < height - 1; ++j) {
+      check(G.source(G.up(G(i, j))) == G(i, j), "Wrong up");
+      check(G.target(G.up(G(i, j))) == G(i, j + 1), "Wrong up");
+    }
+    check(G.up(G(i, height - 1)) == INVALID, "Wrong up");
+  }
+
+  for (int i = 0; i < width; ++i) {
+    for (int j = 1; j < height; ++j) {
+      check(G.source(G.down(G(i, j))) == G(i, j), "Wrong down");
+      check(G.target(G.down(G(i, j))) == G(i, j - 1), "Wrong down");
+    }
+    check(G.down(G(i, 0)) == INVALID, "Wrong down");
+  }
+
+  checkGraphNodeList(G, width * height);
+  checkGraphEdgeList(G, width * (height - 1) + (width - 1) * height);
+  checkGraphArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
+
+  for (NodeIt n(G); n != INVALID; ++n) {
+    int nb = 4;
+    if (G.col(n) == 0) --nb;
+    if (G.col(n) == width - 1) --nb;
+    if (G.row(n) == 0) --nb;
+    if (G.row(n) == height - 1) --nb;
+
+    checkGraphOutArcList(G, n, nb);
+    checkGraphInArcList(G, n, nb);
+    checkGraphIncEdgeList(G, n, nb);
+  }
+
+  checkArcDirections(G);
+
+  checkGraphConArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
+  checkGraphConEdgeList(G, width * (height - 1) + (width - 1) * height);
+
+  checkNodeIds(G);
+  checkArcIds(G);
+  checkEdgeIds(G);
+  checkGraphNodeMap(G);
+  checkGraphArcMap(G);
+  checkGraphEdgeMap(G);
+
+}
+
+void checkHypercubeGraph(int dim) {
+  GRAPH_TYPEDEFS(HypercubeGraph);
+
+  HypercubeGraph G(dim);
+  checkGraphNodeList(G, 1 << dim);
+  checkGraphEdgeList(G, dim * (1 << (dim-1)));
+  checkGraphArcList(G, dim * (1 << dim));
+
+  Node n = G.nodeFromId(dim);
+
+  for (NodeIt n(G); n != INVALID; ++n) {
+    checkGraphIncEdgeList(G, n, dim);
+    for (IncEdgeIt e(G, n); e != INVALID; ++e) {
+      check( (G.u(e) == n &&
+              G.id(G.v(e)) == (G.id(n) ^ (1 << G.dimension(e)))) ||
+             (G.v(e) == n &&
+              G.id(G.u(e)) == (G.id(n) ^ (1 << G.dimension(e)))),
+             "Wrong edge or wrong dimension");
+    }
+
+    checkGraphOutArcList(G, n, dim);
+    for (OutArcIt a(G, n); a != INVALID; ++a) {
+      check(G.source(a) == n &&
+            G.id(G.target(a)) == (G.id(n) ^ (1 << G.dimension(a))),
+            "Wrong arc or wrong dimension");
+    }
+
+    checkGraphInArcList(G, n, dim);
+    for (InArcIt a(G, n); a != INVALID; ++a) {
+      check(G.target(a) == n &&
+            G.id(G.source(a)) == (G.id(n) ^ (1 << G.dimension(a))),
+            "Wrong arc or wrong dimension");
+    }
+  }
+
+  checkGraphConArcList(G, (1 << dim) * dim);
+  checkGraphConEdgeList(G, dim * (1 << (dim-1)));
+
+  checkArcDirections(G);
+
+  checkNodeIds(G);
+  checkArcIds(G);
+  checkEdgeIds(G);
+  checkGraphNodeMap(G);
+  checkGraphArcMap(G);
+  checkGraphEdgeMap(G);
+}
 
 void checkGraphs() {
   { // Checking ListGraph
-    checkGraph<ListGraph>();
+    checkGraphBuild<ListGraph>();
+    checkGraphAlter<ListGraph>();
+    checkGraphErase<ListGraph>();
+    checkGraphSnapshot<ListGraph>();
     checkGraphValidityErase<ListGraph>();
   }
   { // Checking SmartGraph
-    checkGraph<SmartGraph>();
+    checkGraphBuild<SmartGraph>();
+    checkGraphSnapshot<SmartGraph>();
     checkGraphValidity<SmartGraph>();
   }
-//   { // Checking FullGraph
-//     FullGraph g(5);
-//     checkGraphNodeList(g, 5);
-//     checkGraphEdgeList(g, 10);
-//   }
-//   { // Checking GridGraph
-//     GridGraph g(5, 6);
-//     checkGraphNodeList(g, 30);
-//     checkGraphEdgeList(g, 49);
-//     checkGridGraph(g, 5, 6);
-//   }
+  { // Checking FullGraph
+    checkFullGraph(7);
+    checkFullGraph(8);
+  }
+  { // Checking GridGraph
+    checkGridGraph(5, 8);
+    checkGridGraph(8, 5);
+    checkGridGraph(5, 5);
+    checkGridGraph(0, 0);
+    checkGridGraph(1, 1);
+  }
+  { // Checking HypercubeGraph
+    checkHypercubeGraph(1);
+    checkHypercubeGraph(2);
+    checkHypercubeGraph(3);
+    checkHypercubeGraph(4);
+  }
 }
 
Index: test/graph_test.h
===================================================================
--- test/graph_test.h	(revision 263)
+++ test/graph_test.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -115,4 +115,13 @@
     check(e==INVALID,"Wrong IncEdge list linking.");
     check(countIncEdges(G,n)==cnt,"Wrong IncEdge number.");
+  }
+
+  template <class Graph>
+  void checkGraphIncEdgeArcLists(const Graph &G, typename Graph::Node n,
+                                 int cnt)
+  {
+    checkGraphIncEdgeList(G, n, cnt);
+    checkGraphOutArcList(G, n, cnt);
+    checkGraphInArcList(G, n, cnt);
   }
 
Index: test/graph_utils_test.cc
===================================================================
--- test/graph_utils_test.cc	(revision 220)
+++ test/graph_utils_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/hao_orlin_test.cc
===================================================================
--- test/hao_orlin_test.cc	(revision 440)
+++ test/hao_orlin_test.cc	(revision 440)
@@ -0,0 +1,63 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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.
+ *
+ */
+
+#include <sstream>
+
+#include <lemon/smart_graph.h>
+#include <lemon/hao_orlin.h>
+
+#include <lemon/lgf_reader.h>
+#include "test_tools.h"
+
+using namespace lemon;
+using namespace std;
+
+const std::string lgf =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "@edges\n"
+  "     label  capacity\n"
+  "0 1  0      2\n"
+  "1 2  1      2\n"
+  "2 0  2      2\n"
+  "3 4  3      2\n"
+  "4 5  4      2\n"
+  "5 3  5      2\n"
+  "2 3  6      3\n";
+
+int main() {
+  SmartGraph graph;
+  SmartGraph::EdgeMap<int> capacity(graph);
+
+  istringstream lgfs(lgf);
+  graphReader(graph, lgfs).
+    edgeMap("capacity", capacity).run();
+
+  HaoOrlin<SmartGraph, SmartGraph::EdgeMap<int> > ho(graph, capacity);
+  ho.run();
+
+  check(ho.minCutValue() == 3, "Wrong cut value");
+
+  return 0;
+}
Index: test/heap_test.cc
===================================================================
--- test/heap_test.cc	(revision 293)
+++ test/heap_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/kruskal_test.cc
===================================================================
--- test/kruskal_test.cc	(revision 209)
+++ test/kruskal_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/maps_test.cc
===================================================================
--- test/maps_test.cc	(revision 210)
+++ test/maps_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/max_matching_test.cc
===================================================================
--- test/max_matching_test.cc	(revision 440)
+++ test/max_matching_test.cc	(revision 440)
@@ -0,0 +1,310 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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.
+ *
+ */
+
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <queue>
+#include <lemon/math.h>
+#include <cstdlib>
+
+#include <lemon/max_matching.h>
+#include <lemon/smart_graph.h>
+#include <lemon/lgf_reader.h>
+
+#include "test_tools.h"
+
+using namespace std;
+using namespace lemon;
+
+GRAPH_TYPEDEFS(SmartGraph);
+
+
+const int lgfn = 3;
+const std::string lgf[lgfn] = {
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "@edges\n"
+  "     label  weight\n"
+  "7 4  0      984\n"
+  "0 7  1      73\n"
+  "7 1  2      204\n"
+  "2 3  3      583\n"
+  "2 7  4      565\n"
+  "2 1  5      582\n"
+  "0 4  6      551\n"
+  "2 5  7      385\n"
+  "1 5  8      561\n"
+  "5 3  9      484\n"
+  "7 5  10     904\n"
+  "3 6  11     47\n"
+  "7 6  12     888\n"
+  "3 0  13     747\n"
+  "6 1  14     310\n",
+
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "@edges\n"
+  "     label  weight\n"
+  "2 5  0      710\n"
+  "0 5  1      241\n"
+  "2 4  2      856\n"
+  "2 6  3      762\n"
+  "4 1  4      747\n"
+  "6 1  5      962\n"
+  "4 7  6      723\n"
+  "1 7  7      661\n"
+  "2 3  8      376\n"
+  "1 0  9      416\n"
+  "6 7  10     391\n",
+
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "@edges\n"
+  "     label  weight\n"
+  "6 2  0      553\n"
+  "0 7  1      653\n"
+  "6 3  2      22\n"
+  "4 7  3      846\n"
+  "7 2  4      981\n"
+  "7 6  5      250\n"
+  "5 2  6      539\n",
+};
+
+void checkMatching(const SmartGraph& graph,
+                   const MaxMatching<SmartGraph>& mm) {
+  int num = 0;
+
+  IntNodeMap comp_index(graph);
+  UnionFind<IntNodeMap> comp(comp_index);
+
+  int barrier_num = 0;
+
+  for (NodeIt n(graph); n != INVALID; ++n) {
+    check(mm.decomposition(n) == MaxMatching<SmartGraph>::EVEN ||
+          mm.matching(n) != INVALID, "Wrong Gallai-Edmonds decomposition");
+    if (mm.decomposition(n) == MaxMatching<SmartGraph>::ODD) {
+      ++barrier_num;
+    } else {
+      comp.insert(n);
+    }
+  }
+
+  for (EdgeIt e(graph); e != INVALID; ++e) {
+    if (mm.matching(e)) {
+      check(e == mm.matching(graph.u(e)), "Wrong matching");
+      check(e == mm.matching(graph.v(e)), "Wrong matching");
+      ++num;
+    }
+    check(mm.decomposition(graph.u(e)) != MaxMatching<SmartGraph>::EVEN ||
+          mm.decomposition(graph.v(e)) != MaxMatching<SmartGraph>::MATCHED,
+          "Wrong Gallai-Edmonds decomposition");
+
+    check(mm.decomposition(graph.v(e)) != MaxMatching<SmartGraph>::EVEN ||
+          mm.decomposition(graph.u(e)) != MaxMatching<SmartGraph>::MATCHED,
+          "Wrong Gallai-Edmonds decomposition");
+
+    if (mm.decomposition(graph.u(e)) != MaxMatching<SmartGraph>::ODD &&
+        mm.decomposition(graph.v(e)) != MaxMatching<SmartGraph>::ODD) {
+      comp.join(graph.u(e), graph.v(e));
+    }
+  }
+
+  std::set<int> comp_root;
+  int odd_comp_num = 0;
+  for (NodeIt n(graph); n != INVALID; ++n) {
+    if (mm.decomposition(n) != MaxMatching<SmartGraph>::ODD) {
+      int root = comp.find(n);
+      if (comp_root.find(root) == comp_root.end()) {
+        comp_root.insert(root);
+        if (comp.size(n) % 2 == 1) {
+          ++odd_comp_num;
+        }
+      }
+    }
+  }
+
+  check(mm.matchingSize() == num, "Wrong matching");
+  check(2 * num == countNodes(graph) - (odd_comp_num - barrier_num),
+         "Wrong matching");
+  return;
+}
+
+void checkWeightedMatching(const SmartGraph& graph,
+                   const SmartGraph::EdgeMap<int>& weight,
+                   const MaxWeightedMatching<SmartGraph>& mwm) {
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    if (graph.u(e) == graph.v(e)) continue;
+    int rw = mwm.nodeValue(graph.u(e)) + mwm.nodeValue(graph.v(e));
+
+    for (int i = 0; i < mwm.blossomNum(); ++i) {
+      bool s = false, t = false;
+      for (MaxWeightedMatching<SmartGraph>::BlossomIt n(mwm, i);
+           n != INVALID; ++n) {
+        if (graph.u(e) == n) s = true;
+        if (graph.v(e) == n) t = true;
+      }
+      if (s == true && t == true) {
+        rw += mwm.blossomValue(i);
+      }
+    }
+    rw -= weight[e] * mwm.dualScale;
+
+    check(rw >= 0, "Negative reduced weight");
+    check(rw == 0 || !mwm.matching(e),
+          "Non-zero reduced weight on matching edge");
+  }
+
+  int pv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    if (mwm.matching(n) != INVALID) {
+      check(mwm.nodeValue(n) >= 0, "Invalid node value");
+      pv += weight[mwm.matching(n)];
+      SmartGraph::Node o = graph.target(mwm.matching(n));
+      check(mwm.mate(n) == o, "Invalid matching");
+      check(mwm.matching(n) == graph.oppositeArc(mwm.matching(o)),
+            "Invalid matching");
+    } else {
+      check(mwm.mate(n) == INVALID, "Invalid matching");
+      check(mwm.nodeValue(n) == 0, "Invalid matching");
+    }
+  }
+
+  int dv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    dv += mwm.nodeValue(n);
+  }
+
+  for (int i = 0; i < mwm.blossomNum(); ++i) {
+    check(mwm.blossomValue(i) >= 0, "Invalid blossom value");
+    check(mwm.blossomSize(i) % 2 == 1, "Even blossom size");
+    dv += mwm.blossomValue(i) * ((mwm.blossomSize(i) - 1) / 2);
+  }
+
+  check(pv * mwm.dualScale == dv * 2, "Wrong duality");
+
+  return;
+}
+
+void checkWeightedPerfectMatching(const SmartGraph& graph,
+                          const SmartGraph::EdgeMap<int>& weight,
+                          const MaxWeightedPerfectMatching<SmartGraph>& mwpm) {
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    if (graph.u(e) == graph.v(e)) continue;
+    int rw = mwpm.nodeValue(graph.u(e)) + mwpm.nodeValue(graph.v(e));
+
+    for (int i = 0; i < mwpm.blossomNum(); ++i) {
+      bool s = false, t = false;
+      for (MaxWeightedPerfectMatching<SmartGraph>::BlossomIt n(mwpm, i);
+           n != INVALID; ++n) {
+        if (graph.u(e) == n) s = true;
+        if (graph.v(e) == n) t = true;
+      }
+      if (s == true && t == true) {
+        rw += mwpm.blossomValue(i);
+      }
+    }
+    rw -= weight[e] * mwpm.dualScale;
+
+    check(rw >= 0, "Negative reduced weight");
+    check(rw == 0 || !mwpm.matching(e),
+          "Non-zero reduced weight on matching edge");
+  }
+
+  int pv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    check(mwpm.matching(n) != INVALID, "Non perfect");
+    pv += weight[mwpm.matching(n)];
+    SmartGraph::Node o = graph.target(mwpm.matching(n));
+    check(mwpm.mate(n) == o, "Invalid matching");
+    check(mwpm.matching(n) == graph.oppositeArc(mwpm.matching(o)),
+          "Invalid matching");
+  }
+
+  int dv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    dv += mwpm.nodeValue(n);
+  }
+
+  for (int i = 0; i < mwpm.blossomNum(); ++i) {
+    check(mwpm.blossomValue(i) >= 0, "Invalid blossom value");
+    check(mwpm.blossomSize(i) % 2 == 1, "Even blossom size");
+    dv += mwpm.blossomValue(i) * ((mwpm.blossomSize(i) - 1) / 2);
+  }
+
+  check(pv * mwpm.dualScale == dv * 2, "Wrong duality");
+
+  return;
+}
+
+
+int main() {
+
+  for (int i = 0; i < lgfn; ++i) {
+    SmartGraph graph;
+    SmartGraph::EdgeMap<int> weight(graph);
+
+    istringstream lgfs(lgf[i]);
+    graphReader(graph, lgfs).
+      edgeMap("weight", weight).run();
+
+    MaxMatching<SmartGraph> mm(graph);
+    mm.run();
+    checkMatching(graph, mm);
+
+    MaxWeightedMatching<SmartGraph> mwm(graph, weight);
+    mwm.run();
+    checkWeightedMatching(graph, weight, mwm);
+
+    MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
+    bool perfect = mwpm.run();
+
+    check(perfect == (mm.matchingSize() * 2 == countNodes(graph)),
+          "Perfect matching found");
+
+    if (perfect) {
+      checkWeightedPerfectMatching(graph, weight, mwpm);
+    }
+  }
+
+  return 0;
+}
Index: test/path_test.cc
===================================================================
--- test/path_test.cc	(revision 209)
+++ test/path_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/preflow_test.cc
===================================================================
--- test/preflow_test.cc	(revision 440)
+++ test/preflow_test.cc	(revision 440)
@@ -0,0 +1,239 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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.
+ *
+ */
+
+#include <iostream>
+
+#include "test_tools.h"
+#include <lemon/smart_graph.h>
+#include <lemon/preflow.h>
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/elevator.h>
+
+using namespace lemon;
+
+char test_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"
+  "    label capacity\n"
+  "0 1 0     20\n"
+  "0 2 1     0\n"
+  "1 1 2     3\n"
+  "1 2 3     8\n"
+  "1 3 4     8\n"
+  "2 5 5     5\n"
+  "3 2 6     5\n"
+  "3 5 7     5\n"
+  "3 6 8     5\n"
+  "4 3 9     3\n"
+  "5 7 10    3\n"
+  "5 6 11    10\n"
+  "5 8 12    10\n"
+  "6 8 13    8\n"
+  "8 9 14    20\n"
+  "8 1 15    5\n"
+  "9 5 16    5\n"
+  "@attributes\n"
+  "source 1\n"
+  "target 8\n";
+
+void checkPreflowCompile()
+{
+  typedef int VType;
+  typedef concepts::Digraph Digraph;
+
+  typedef Digraph::Node Node;
+  typedef Digraph::Arc Arc;
+  typedef concepts::ReadMap<Arc,VType> CapMap;
+  typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
+  typedef concepts::WriteMap<Node,bool> CutMap;
+
+  typedef Elevator<Digraph, Digraph::Node> Elev;
+  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
+
+  Digraph g;
+  Node n;
+  Arc e;
+  CapMap cap;
+  FlowMap flow;
+  CutMap cut;
+
+  Preflow<Digraph, CapMap>
+    ::SetFlowMap<FlowMap>
+    ::SetElevator<Elev>
+    ::SetStandardElevator<LinkedElev>
+    ::Create preflow_test(g,cap,n,n);
+
+  preflow_test.capacityMap(cap);
+  flow = preflow_test.flowMap();
+  preflow_test.flowMap(flow);
+  preflow_test.source(n);
+  preflow_test.target(n);
+
+  preflow_test.init();
+  preflow_test.init(cap);
+  preflow_test.startFirstPhase();
+  preflow_test.startSecondPhase();
+  preflow_test.run();
+  preflow_test.runMinCut();
+
+  preflow_test.flowValue();
+  preflow_test.minCut(n);
+  preflow_test.minCutMap(cut);
+  preflow_test.flow(e);
+
+}
+
+int cutValue (const SmartDigraph& g,
+              const SmartDigraph::NodeMap<bool>& cut,
+              const SmartDigraph::ArcMap<int>& cap) {
+
+  int c=0;
+  for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
+    if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
+  }
+  return c;
+}
+
+bool checkFlow(const SmartDigraph& g,
+               const SmartDigraph::ArcMap<int>& flow,
+               const SmartDigraph::ArcMap<int>& cap,
+               SmartDigraph::Node s, SmartDigraph::Node t) {
+
+  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
+    if (flow[e] < 0 || flow[e] > cap[e]) return false;
+  }
+
+  for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
+    if (n == s || n == t) continue;
+    int sum = 0;
+    for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {
+      sum += flow[e];
+    }
+    for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {
+      sum -= flow[e];
+    }
+    if (sum != 0) return false;
+  }
+  return true;
+}
+
+int main() {
+
+  typedef SmartDigraph Digraph;
+
+  typedef Digraph::Node Node;
+  typedef Digraph::NodeIt NodeIt;
+  typedef Digraph::ArcIt ArcIt;
+  typedef Digraph::ArcMap<int> CapMap;
+  typedef Digraph::ArcMap<int> FlowMap;
+  typedef Digraph::NodeMap<bool> CutMap;
+
+  typedef Preflow<Digraph, CapMap> PType;
+
+  Digraph g;
+  Node s, t;
+  CapMap cap(g);
+  std::istringstream input(test_lgf);
+  DigraphReader<Digraph>(g,input).
+    arcMap("capacity", cap).
+    node("source",s).
+    node("target",t).
+    run();
+
+  PType preflow_test(g, cap, s, t);
+  preflow_test.run();
+
+  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
+        "The flow is not feasible.");
+
+  CutMap min_cut(g);
+  preflow_test.minCutMap(min_cut);
+  int min_cut_value=cutValue(g,min_cut,cap);
+
+  check(preflow_test.flowValue() == min_cut_value,
+        "The max flow value is not equal to the three min cut values.");
+
+  FlowMap flow(g);
+  for(ArcIt e(g); e!=INVALID; ++e) flow[e] = preflow_test.flowMap()[e];
+
+  int flow_value=preflow_test.flowValue();
+
+  for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
+  preflow_test.init(flow);
+  preflow_test.startFirstPhase();
+
+  CutMap min_cut1(g);
+  preflow_test.minCutMap(min_cut1);
+  min_cut_value=cutValue(g,min_cut1,cap);
+
+  check(preflow_test.flowValue() == min_cut_value &&
+        min_cut_value == 2*flow_value,
+        "The max flow value or the min cut value is wrong.");
+
+  preflow_test.startSecondPhase();
+
+  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
+        "The flow is not feasible.");
+
+  CutMap min_cut2(g);
+  preflow_test.minCutMap(min_cut2);
+  min_cut_value=cutValue(g,min_cut2,cap);
+
+  check(preflow_test.flowValue() == min_cut_value &&
+        min_cut_value == 2*flow_value,
+        "The max flow value or the three min cut values were not doubled");
+
+
+  preflow_test.flowMap(flow);
+
+  NodeIt tmp1(g,s);
+  ++tmp1;
+  if ( tmp1 != INVALID ) s=tmp1;
+
+  NodeIt tmp2(g,t);
+  ++tmp2;
+  if ( tmp2 != INVALID ) t=tmp2;
+
+  preflow_test.source(s);
+  preflow_test.target(t);
+
+  preflow_test.run();
+
+  CutMap min_cut3(g);
+  preflow_test.minCutMap(min_cut3);
+  min_cut_value=cutValue(g,min_cut3,cap);
+
+
+  check(preflow_test.flowValue() == min_cut_value,
+        "The max flow value or the three min cut values are incorrect.");
+
+  return 0;
+}
Index: test/random_test.cc
===================================================================
--- test/random_test.cc	(revision 209)
+++ test/random_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/suurballe_test.cc
===================================================================
--- test/suurballe_test.cc	(revision 440)
+++ test/suurballe_test.cc	(revision 440)
@@ -0,0 +1,194 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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.
+ *
+ */
+
+#include <iostream>
+
+#include <lemon/list_graph.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/path.h>
+#include <lemon/suurballe.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label supply1 supply2 supply3\n"
+  "1     0        20      27\n"
+  "2     0       -4        0\n"
+  "3     0        0        0\n"
+  "4     0        0        0\n"
+  "5     0        9        0\n"
+  "6     0       -6        0\n"
+  "7     0        0        0\n"
+  "8     0        0        0\n"
+  "9     0        3        0\n"
+  "10    0       -2        0\n"
+  "11    0        0        0\n"
+  "12    0       -20     -27\n"
+  "@arcs\n"
+  "      cost capacity lower1 lower2\n"
+  " 1  2  70  11       0      8\n"
+  " 1  3 150   3       0      1\n"
+  " 1  4  80  15       0      2\n"
+  " 2  8  80  12       0      0\n"
+  " 3  5 140   5       0      3\n"
+  " 4  6  60  10       0      1\n"
+  " 4  7  80   2       0      0\n"
+  " 4  8 110   3       0      0\n"
+  " 5  7  60  14       0      0\n"
+  " 5 11 120  12       0      0\n"
+  " 6  3   0   3       0      0\n"
+  " 6  9 140   4       0      0\n"
+  " 6 10  90   8       0      0\n"
+  " 7  1  30   5       0      0\n"
+  " 8 12  60  16       0      4\n"
+  " 9 12  50   6       0      0\n"
+  "10 12  70  13       0      5\n"
+  "10  2 100   7       0      0\n"
+  "10  7  60  10       0      0\n"
+  "11 10  20  14       0      6\n"
+  "12 11  30  10       0      0\n"
+  "@attributes\n"
+  "source  1\n"
+  "target 12\n"
+  "@end\n";
+
+// Check the feasibility of the flow
+template <typename Digraph, typename FlowMap>
+bool checkFlow( const Digraph& gr, const FlowMap& flow,
+                typename Digraph::Node s, typename Digraph::Node t,
+                int value )
+{
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+  for (ArcIt e(gr); e != INVALID; ++e)
+    if (!(flow[e] == 0 || flow[e] == 1)) return false;
+
+  for (NodeIt n(gr); n != INVALID; ++n) {
+    int sum = 0;
+    for (OutArcIt e(gr, n); e != INVALID; ++e)
+      sum += flow[e];
+    for (InArcIt e(gr, n); e != INVALID; ++e)
+      sum -= flow[e];
+    if (n == s && sum != value) return false;
+    if (n == t && sum != -value) return false;
+    if (n != s && n != t && sum != 0) return false;
+  }
+
+  return true;
+}
+
+// Check the optimalitiy of the flow
+template < typename Digraph, typename CostMap,
+           typename FlowMap, typename PotentialMap >
+bool checkOptimality( const Digraph& gr, const CostMap& cost,
+                      const FlowMap& flow, const PotentialMap& pi )
+{
+  // Check the "Complementary Slackness" optimality condition
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+  bool opt = true;
+  for (ArcIt e(gr); e != INVALID; ++e) {
+    typename CostMap::Value red_cost =
+      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
+    opt = (flow[e] == 0 && red_cost >= 0) ||
+          (flow[e] == 1 && red_cost <= 0);
+    if (!opt) break;
+  }
+  return opt;
+}
+
+// Check a path
+template <typename Digraph, typename Path>
+bool checkPath( const Digraph& gr, const Path& path,
+                typename Digraph::Node s, typename Digraph::Node t)
+{
+  // Check the "Complementary Slackness" optimality condition
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+  Node n = s;
+  for (int i = 0; i < path.length(); ++i) {
+    if (gr.source(path.nth(i)) != n) return false;
+    n = gr.target(path.nth(i));
+  }
+  return n == t;
+}
+
+
+int main()
+{
+  DIGRAPH_TYPEDEFS(ListDigraph);
+
+  // Read the test digraph
+  ListDigraph digraph;
+  ListDigraph::ArcMap<int> length(digraph);
+  Node source, target;
+
+  std::istringstream input(test_lgf);
+  DigraphReader<ListDigraph>(digraph, input).
+    arcMap("cost", length).
+    node("source", source).
+    node("target", target).
+    run();
+
+  // Find 2 paths
+  {
+    Suurballe<ListDigraph> suurballe(digraph, length, source, target);
+    check(suurballe.run(2) == 2, "Wrong number of paths");
+    check(checkFlow(digraph, suurballe.flowMap(), source, target, 2),
+          "The flow is not feasible");
+    check(suurballe.totalLength() == 510, "The flow is not optimal");
+    check(checkOptimality(digraph, length, suurballe.flowMap(),
+                          suurballe.potentialMap()),
+          "Wrong potentials");
+    for (int i = 0; i < suurballe.pathNum(); ++i)
+      check(checkPath(digraph, suurballe.path(i), source, target),
+            "Wrong path");
+  }
+
+  // Find 3 paths
+  {
+    Suurballe<ListDigraph> suurballe(digraph, length, source, target);
+    check(suurballe.run(3) == 3, "Wrong number of paths");
+    check(checkFlow(digraph, suurballe.flowMap(), source, target, 3),
+          "The flow is not feasible");
+    check(suurballe.totalLength() == 1040, "The flow is not optimal");
+    check(checkOptimality(digraph, length, suurballe.flowMap(),
+                          suurballe.potentialMap()),
+          "Wrong potentials");
+    for (int i = 0; i < suurballe.pathNum(); ++i)
+      check(checkPath(digraph, suurballe.path(i), source, target),
+            "Wrong path");
+  }
+
+  // Find 5 paths (only 3 can be found)
+  {
+    Suurballe<ListDigraph> suurballe(digraph, length, source, target);
+    check(suurballe.run(5) == 3, "Wrong number of paths");
+    check(checkFlow(digraph, suurballe.flowMap(), source, target, 3),
+          "The flow is not feasible");
+    check(suurballe.totalLength() == 1040, "The flow is not optimal");
+    check(checkOptimality(digraph, length, suurballe.flowMap(),
+                          suurballe.potentialMap()),
+          "Wrong potentials");
+    for (int i = 0; i < suurballe.pathNum(); ++i)
+      check(checkPath(digraph, suurballe.path(i), source, target),
+            "Wrong path");
+  }
+
+  return 0;
+}
Index: test/test_tools.h
===================================================================
--- test/test_tools.h	(revision 209)
+++ test/test_tools.h	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/test_tools_fail.cc
===================================================================
--- test/test_tools_fail.cc	(revision 209)
+++ test/test_tools_fail.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/test_tools_pass.cc
===================================================================
--- test/test_tools_pass.cc	(revision 209)
+++ test/test_tools_pass.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/time_measure_test.cc
===================================================================
--- test/time_measure_test.cc	(revision 209)
+++ test/time_measure_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: test/unionfind_test.cc
===================================================================
--- test/unionfind_test.cc	(revision 209)
+++ test/unionfind_test.cc	(revision 440)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2009
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: tools/Makefile.am
===================================================================
--- tools/Makefile.am	(revision 310)
+++ tools/Makefile.am	(revision 385)
@@ -1,6 +1,10 @@
 if WANT_TOOLS
 
-bin_PROGRAMS +=
+bin_PROGRAMS += \
+	tools/dimacs-to-lgf
+
 dist_bin_SCRIPTS += tools/lemon-0.x-to-1.x.sh
 
 endif WANT_TOOLS
+
+tools_dimacs_to_lgf_SOURCES = tools/dimacs-to-lgf.cc
Index: tools/dimacs-to-lgf.cc
===================================================================
--- tools/dimacs-to-lgf.cc	(revision 440)
+++ tools/dimacs-to-lgf.cc	(revision 440)
@@ -0,0 +1,149 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * 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.
+ *
+ */
+
+///\ingroup tools
+///\file
+///\brief DIMACS to LGF converter.
+///
+/// This program converts various DIMACS formats to the LEMON Digraph Format
+/// (LGF).
+///
+/// See
+/// \verbatim
+///  dimacs-to-lgf --help
+/// \endverbatim
+/// for more info on usage.
+///
+
+#include <iostream>
+#include <fstream>
+#include <cstring>
+
+#include <lemon/smart_graph.h>
+#include <lemon/dimacs.h>
+#include <lemon/lgf_writer.h>
+
+#include <lemon/arg_parser.h>
+#include <lemon/error.h>
+
+using namespace std;
+using namespace lemon;
+
+
+int main(int argc, const char *argv[]) {
+  typedef SmartDigraph Digraph;
+
+  typedef Digraph::Arc Arc;
+  typedef Digraph::Node Node;
+  typedef Digraph::ArcIt ArcIt;
+  typedef Digraph::NodeIt NodeIt;
+  typedef Digraph::ArcMap<double> DoubleArcMap;
+  typedef Digraph::NodeMap<double> DoubleNodeMap;
+
+  std::string inputName;
+  std::string outputName;
+
+  ArgParser ap(argc, argv);
+  ap.other("[INFILE [OUTFILE]]",
+           "If either the INFILE or OUTFILE file is missing the standard\n"
+           "     input/output will be used instead.")
+    .run();
+
+  ifstream input;
+  ofstream output;
+
+  switch(ap.files().size())
+    {
+    case 2:
+      output.open(ap.files()[1].c_str());
+      if (!output) {
+        throw IoError("Cannot open the file for writing", ap.files()[1]);
+      }
+    case 1:
+      input.open(ap.files()[0].c_str());
+      if (!input) {
+        throw IoError("File cannot be found", ap.files()[0]);
+      }
+    case 0:
+      break;
+    default:
+      cerr << ap.commandName() << ": too many arguments\n";
+      return 1;
+  }
+  istream& is = (ap.files().size()<1 ? cin : input);
+  ostream& os = (ap.files().size()<2 ? cout : output);
+
+  DimacsDescriptor desc = dimacsType(is);
+  switch(desc.type)
+    {
+    case DimacsDescriptor::MIN:
+      {
+        Digraph digraph;
+        DoubleArcMap lower(digraph), capacity(digraph), cost(digraph);
+        DoubleNodeMap supply(digraph);
+        readDimacsMin(is, digraph, lower, capacity, cost, supply, desc);
+        DigraphWriter<Digraph>(digraph, os).
+          nodeMap("supply", supply).
+          arcMap("lower", lower).
+          arcMap("capacity", capacity).
+          arcMap("cost", cost).
+          attribute("problem","min").
+          run();
+      }
+      break;
+    case DimacsDescriptor::MAX:
+      {
+        Digraph digraph;
+        Node s, t;
+        DoubleArcMap capacity(digraph);
+        readDimacsMax(is, digraph, capacity, s, t, desc);
+        DigraphWriter<Digraph>(digraph, os).
+          arcMap("capacity", capacity).
+          node("source", s).
+          node("target", t).
+          attribute("problem","max").
+          run();
+      }
+      break;
+    case DimacsDescriptor::SP:
+      {
+        Digraph digraph;
+        Node s;
+        DoubleArcMap capacity(digraph);
+        readDimacsSp(is, digraph, capacity, s, desc);
+        DigraphWriter<Digraph>(digraph, os).
+          arcMap("capacity", capacity).
+          node("source", s).
+          attribute("problem","sp").
+          run();
+      }
+      break;
+    case DimacsDescriptor::MAT:
+      {
+        Digraph digraph;
+        readDimacsMat(is, digraph,desc);
+        DigraphWriter<Digraph>(digraph, os).
+          attribute("problem","mat").
+          run();
+      }
+      break;
+    default:
+      break;
+    }
+  return 0;
+}
Index: tools/lemon-0.x-to-1.x.sh
===================================================================
--- tools/lemon-0.x-to-1.x.sh	(revision 310)
+++ tools/lemon-0.x-to-1.x.sh	(revision 366)
@@ -4,124 +4,94 @@
 
 if [ $# -eq 0 -o x$1 = "x-h" -o x$1 = "x-help" -o x$1 = "x--help" ]; then
-	echo "Usage:"
-	echo "  $0 source-file"
-	exit
+    echo "Usage:"
+    echo "  $0 source-file(s)"
+    exit
 fi
 
-TMP=`mktemp`
-
-sed	-e "s/undirected graph/_gr_aph_label_/g"\
-	-e "s/undirected edge/_ed_ge_label_/g"\
-	-e "s/graph_/_gr_aph_label__/g"\
-	-e "s/_graph/__gr_aph_label_/g"\
-	-e "s/UGraph/_Gr_aph_label_/g"\
-	-e "s/uGraph/_gr_aph_label_/g"\
-	-e "s/ugraph/_gr_aph_label_/g"\
-	-e "s/Graph/_Digr_aph_label_/g"\
-	-e "s/graph/_digr_aph_label_/g"\
-	-e "s/UEdge/_Ed_ge_label_/g"\
-	-e "s/uEdge/_ed_ge_label_/g"\
-	-e "s/uedge/_ed_ge_label_/g"\
-	-e "s/IncEdgeIt/_In_cEd_geIt_label_/g"\
-	-e "s/Edge/_Ar_c_label_/g"\
-	-e "s/edge/_ar_c_label_/g"\
-	-e "s/ANode/_Re_d_label_/g"\
-	-e "s/BNode/_Blu_e_label_/g"\
-	-e "s/A-Node/_Re_d_label_/g"\
-	-e "s/B-Node/_Blu_e_label_/g"\
-	-e "s/anode/_re_d_label_/g"\
-	-e "s/bnode/_blu_e_label_/g"\
-	-e "s/aNode/_re_d_label_/g"\
-	-e "s/bNode/_blu_e_label_/g"\
-	-e "s/_Digr_aph_label_/Digraph/g"\
-	-e "s/_digr_aph_label_/digraph/g"\
-	-e "s/_Gr_aph_label_/Graph/g"\
-	-e "s/_gr_aph_label_/graph/g"\
-	-e "s/_Ar_c_label_/Arc/g"\
-	-e "s/_ar_c_label_/arc/g"\
-	-e "s/_Ed_ge_label_/Edge/g"\
-	-e "s/_ed_ge_label_/edge/g"\
-	-e "s/_In_cEd_geIt_label_/IncEdgeIt/g"\
-	-e "s/_Re_d_label_/Red/g"\
-	-e "s/_Blu_e_label_/Blue/g"\
-	-e "s/_re_d_label_/red/g"\
-	-e "s/_blu_e_label_/blue/g"\
-	-e "s/\(\W\)DefPredMap\(\W\)/\1SetPredMap\2/g"\
-	-e "s/\(\W\)DefPredMap$/\1SetPredMap/g"\
-	-e "s/^DefPredMap\(\W\)/SetPredMap\1/g"\
-	-e "s/^DefPredMap$/SetPredMap/g"\
-	-e "s/\(\W\)DefDistMap\(\W\)/\1SetDistMap\2/g"\
-	-e "s/\(\W\)DefDistMap$/\1SetDistMap/g"\
-	-e "s/^DefDistMap\(\W\)/SetDistMap\1/g"\
-	-e "s/^DefDistMap$/SetDistMap/g"\
-	-e "s/\(\W\)DefReachedMap\(\W\)/\1SetReachedMap\2/g"\
-	-e "s/\(\W\)DefReachedMap$/\1SetReachedMap/g"\
-	-e "s/^DefReachedMap\(\W\)/SetReachedMap\1/g"\
-	-e "s/^DefReachedMap$/SetReachedMap/g"\
-	-e "s/\(\W\)DefProcessedMap\(\W\)/\1SetProcessedMap\2/g"\
-	-e "s/\(\W\)DefProcessedMap$/\1SetProcessedMap/g"\
-	-e "s/^DefProcessedMap\(\W\)/SetProcessedMap\1/g"\
-	-e "s/^DefProcessedMap$/SetProcessedMap/g"\
-	-e "s/\(\W\)DefHeap\(\W\)/\1SetHeap\2/g"\
-	-e "s/\(\W\)DefHeap$/\1SetHeap/g"\
-	-e "s/^DefHeap\(\W\)/SetHeap\1/g"\
-	-e "s/^DefHeap$/SetHeap/g"\
-	-e "s/\(\W\)DefStandardHeap\(\W\)/\1SetStandradHeap\2/g"\
-	-e "s/\(\W\)DefStandardHeap$/\1SetStandradHeap/g"\
-	-e "s/^DefStandardHeap\(\W\)/SetStandradHeap\1/g"\
-	-e "s/^DefStandardHeap$/SetStandradHeap/g"\
-	-e "s/\(\W\)DefOperationTraits\(\W\)/\1SetOperationTraits\2/g"\
-	-e "s/\(\W\)DefOperationTraits$/\1SetOperationTraits/g"\
-	-e "s/^DefOperationTraits\(\W\)/SetOperationTraits\1/g"\
-	-e "s/^DefOperationTraits$/SetOperationTraits/g"\
-	-e "s/\(\W\)DefProcessedMapToBeDefaultMap\(\W\)/\1SetStandardProcessedMap\2/g"\
-	-e "s/\(\W\)DefProcessedMapToBeDefaultMap$/\1SetStandardProcessedMap/g"\
-	-e "s/^DefProcessedMapToBeDefaultMap\(\W\)/SetStandardProcessedMap\1/g"\
-	-e "s/^DefProcessedMapToBeDefaultMap$/SetStandardProcessedMap/g"\
-	-e "s/\(\W\)IntegerMap\(\W\)/\1RangeMap\2/g"\
-	-e "s/\(\W\)IntegerMap$/\1RangeMap/g"\
-	-e "s/^IntegerMap\(\W\)/RangeMap\1/g"\
-	-e "s/^IntegerMap$/RangeMap/g"\
-	-e "s/\(\W\)integerMap\(\W\)/\1rangeMap\2/g"\
-	-e "s/\(\W\)integerMap$/\1rangeMap/g"\
-	-e "s/^integerMap\(\W\)/rangeMap\1/g"\
-	-e "s/^integerMap$/rangeMap/g"\
-	-e "s/\(\W\)copyGraph\(\W\)/\1graphCopy\2/g"\
-	-e "s/\(\W\)copyGraph$/\1graphCopy/g"\
-	-e "s/^copyGraph\(\W\)/graphCopy\1/g"\
-	-e "s/^copyGraph$/graphCopy/g"\
-	-e "s/\(\W\)copyDigraph\(\W\)/\1digraphCopy\2/g"\
-	-e "s/\(\W\)copyDigraph$/\1digraphCopy/g"\
-	-e "s/^copyDigraph\(\W\)/digraphCopy\1/g"\
-	-e "s/^copyDigraph$/digraphCopy/g"\
-	-e "s/\(\W\)\([sS]\)tdMap\(\W\)/\1\2parseMap\3/g"\
-	-e "s/\(\W\)\([sS]\)tdMap$/\1\2parseMap/g"\
-	-e "s/^\([sS]\)tdMap\(\W\)/\1parseMap\2/g"\
-	-e "s/^\([sS]\)tdMap$/\1parseMap/g"\
-	-e "s/\(\W\)\([Ff]\)unctorMap\(\W\)/\1\2unctorToMap\3/g"\
-	-e "s/\(\W\)\([Ff]\)unctorMap$/\1\2unctorToMap/g"\
-	-e "s/^\([Ff]\)unctorMap\(\W\)/\1unctorToMap\2/g"\
-	-e "s/^\([Ff]\)unctorMap$/\1unctorToMap/g"\
-	-e "s/\(\W\)\([Mm]\)apFunctor\(\W\)/\1\2apToFunctor\3/g"\
-	-e "s/\(\W\)\([Mm]\)apFunctor$/\1\2apToFunctor/g"\
-	-e "s/^\([Mm]\)apFunctor\(\W\)/\1apToFunctor\2/g"\
-	-e "s/^\([Mm]\)apFunctor$/\1apToFunctor/g"\
-	-e "s/\(\W\)\([Ff]\)orkWriteMap\(\W\)/\1\2orkMap\3/g"\
-	-e "s/\(\W\)\([Ff]\)orkWriteMap$/\1\2orkMap/g"\
-	-e "s/^\([Ff]\)orkWriteMap\(\W\)/\1orkMap\2/g"\
-	-e "s/^\([Ff]\)orkWriteMap$/\1orkMap/g"\
-	-e "s/\(\W\)StoreBoolMap\(\W\)/\1LoggerBoolMap\2/g"\
-	-e "s/\(\W\)StoreBoolMap$/\1LoggerBoolMap/g"\
-	-e "s/^StoreBoolMap\(\W\)/LoggerBoolMap\1/g"\
-	-e "s/^StoreBoolMap$/LoggerBoolMap/g"\
-	-e "s/\(\W\)storeBoolMap\(\W\)/\1loggerBoolMap\2/g"\
-	-e "s/\(\W\)storeBoolMap$/\1loggerBoolMap/g"\
-	-e "s/^storeBoolMap\(\W\)/loggerBoolMap\1/g"\
-	-e "s/^storeBoolMap$/loggerBoolMap/g"\
-	-e "s/\(\W\)BoundingBox\(\W\)/\1Box\2/g"\
-	-e "s/\(\W\)BoundingBox$/\1Box/g"\
-	-e "s/^BoundingBox\(\W\)/Box\1/g"\
-	-e "s/^BoundingBox$/Box/g"\
-<$1 > $TMP
-
-mv $TMP $1
+for i in $@
+do
+    echo Update $i...
+    TMP=`mktemp`
+    sed -e "s/\<undirected graph\>/_gr_aph_label_/g"\
+        -e "s/\<undirected graphs\>/_gr_aph_label_s/g"\
+        -e "s/\<undirected edge\>/_ed_ge_label_/g"\
+        -e "s/\<undirected edges\>/_ed_ge_label_s/g"\
+        -e "s/\<directed graph\>/_digr_aph_label_/g"\
+        -e "s/\<directed graphs\>/_digr_aph_label_s/g"\
+        -e "s/\<directed edge\>/_ar_c_label_/g"\
+        -e "s/\<directed edges\>/_ar_c_label_s/g"\
+        -e "s/UGraph/_Gr_aph_label_/g"\
+        -e "s/u[Gg]raph/_gr_aph_label_/g"\
+        -e "s/\<Graph\>/_Digr_aph_label_/g"\
+        -e "s/\<graph\>/_digr_aph_label_/g"\
+        -e "s/\<Graphs\>/_Digr_aph_label_s/g"\
+        -e "s/\<graphs\>/_digr_aph_label_s/g"\
+        -e "s/_Graph/__Gr_aph_label_/g"\
+        -e "s/\([Gg]\)raph\([a-z_]\)/_\1r_aph_label_\2/g"\
+        -e "s/\([a-z_]\)graph/\1_gr_aph_label_/g"\
+        -e "s/Graph/_Digr_aph_label_/g"\
+        -e "s/graph/_digr_aph_label_/g"\
+        -e "s/UEdge/_Ed_ge_label_/g"\
+        -e "s/u[Ee]dge/_ed_ge_label_/g"\
+        -e "s/IncEdgeIt/_In_cEd_geIt_label_/g"\
+        -e "s/\<Edge\>/_Ar_c_label_/g"\
+        -e "s/\<edge\>/_ar_c_label_/g"\
+        -e "s/\<Edges\>/_Ar_c_label_s/g"\
+        -e "s/\<edges\>/_ar_c_label_s/g"\
+        -e "s/_Edge/__Ed_ge_label_/g"\
+        -e "s/Edge\([a-z_]\)/_Ed_ge_label_\1/g"\
+        -e "s/edge\([a-z_]\)/_ed_ge_label_\1/g"\
+        -e "s/\([a-z_]\)edge/\1_ed_ge_label_/g"\
+        -e "s/Edge/_Ar_c_label_/g"\
+        -e "s/edge/_ar_c_label_/g"\
+        -e "s/A[Nn]ode/_Re_d_label_/g"\
+        -e "s/B[Nn]ode/_Blu_e_label_/g"\
+        -e "s/A-[Nn]ode/_Re_d_label_/g"\
+        -e "s/B-[Nn]ode/_Blu_e_label_/g"\
+        -e "s/a[Nn]ode/_re_d_label_/g"\
+        -e "s/b[Nn]ode/_blu_e_label_/g"\
+        -e "s/\<UGRAPH_TYPEDEFS\([ \t]*([ \t]*\)typename[ \t]/TEMPLATE__GR_APH_TY_PEDE_FS_label_\1/g"\
+        -e "s/\<GRAPH_TYPEDEFS\([ \t]*([ \t]*\)typename[ \t]/TEMPLATE__DIGR_APH_TY_PEDE_FS_label_\1/g"\
+        -e "s/\<UGRAPH_TYPEDEFS\>/_GR_APH_TY_PEDE_FS_label_/g"\
+        -e "s/\<GRAPH_TYPEDEFS\>/_DIGR_APH_TY_PEDE_FS_label_/g"\
+        -e "s/_Digr_aph_label_/Digraph/g"\
+        -e "s/_digr_aph_label_/digraph/g"\
+        -e "s/_Gr_aph_label_/Graph/g"\
+        -e "s/_gr_aph_label_/graph/g"\
+        -e "s/_Ar_c_label_/Arc/g"\
+        -e "s/_ar_c_label_/arc/g"\
+        -e "s/_Ed_ge_label_/Edge/g"\
+        -e "s/_ed_ge_label_/edge/g"\
+        -e "s/_In_cEd_geIt_label_/IncEdgeIt/g"\
+        -e "s/_Re_d_label_/Red/g"\
+        -e "s/_Blu_e_label_/Blue/g"\
+        -e "s/_re_d_label_/red/g"\
+        -e "s/_blu_e_label_/blue/g"\
+        -e "s/_GR_APH_TY_PEDE_FS_label_/GRAPH_TYPEDEFS/g"\
+        -e "s/_DIGR_APH_TY_PEDE_FS_label_/DIGRAPH_TYPEDEFS/g"\
+        -e "s/DigraphToEps/GraphToEps/g"\
+        -e "s/digraphToEps/graphToEps/g"\
+        -e "s/\<DefPredMap\>/SetPredMap/g"\
+        -e "s/\<DefDistMap\>/SetDistMap/g"\
+        -e "s/\<DefReachedMap\>/SetReachedMap/g"\
+        -e "s/\<DefProcessedMap\>/SetProcessedMap/g"\
+        -e "s/\<DefHeap\>/SetHeap/g"\
+        -e "s/\<DefStandardHeap\>/SetStandradHeap/g"\
+        -e "s/\<DefOperationTraits\>/SetOperationTraits/g"\
+        -e "s/\<DefProcessedMapToBeDefaultMap\>/SetStandardProcessedMap/g"\
+        -e "s/\<copyGraph\>/graphCopy/g"\
+        -e "s/\<copyDigraph\>/digraphCopy/g"\
+        -e "s/\<HyperCubeDigraph\>/HypercubeGraph/g"\
+        -e "s/\<IntegerMap\>/RangeMap/g"\
+        -e "s/\<integerMap\>/rangeMap/g"\
+        -e "s/\<\([sS]\)tdMap\>/\1parseMap/g"\
+        -e "s/\<\([Ff]\)unctorMap\>/\1unctorToMap/g"\
+        -e "s/\<\([Mm]\)apFunctor\>/\1apToFunctor/g"\
+        -e "s/\<\([Ff]\)orkWriteMap\>/\1orkMap/g"\
+        -e "s/\<StoreBoolMap\>/LoggerBoolMap/g"\
+        -e "s/\<storeBoolMap\>/loggerBoolMap/g"\
+        -e "s/\<BoundingBox\>/Box/g"\
+        -e "s/\<readNauty\>/readNautyGraph/g"\
+    <$i > $TMP
+    mv $TMP $i
+done
