Index: .hgignore
===================================================================
--- .hgignore	(revision 494)
+++ .hgignore	(revision 456)
@@ -23,9 +23,13 @@
 lemon/stamp-h2
 doc/Doxyfile
-cmake/cmake.version
 .dirstamp
 .libs/*
 .deps/*
 demo/*.eps
+m4/libtool.m4
+m4/ltoptions.m4
+m4/ltsugar.m4
+m4/ltversion.m4
+m4/lt~obsolete.m4
 
 syntax: regexp
@@ -38,4 +42,5 @@
 ^objs.*/.*
 ^test/[a-z_]*$
+^tools/[a-z-_]*$
 ^demo/.*_demo$
 ^build/.*
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt	(revision 511)
+++ 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,9 +10,4 @@
 INCLUDE(FindDoxygen)
 INCLUDE(FindGhostscript)
-
-ADD_DEFINITIONS(-DHAVE_CONFIG_H)
-
-INCLUDE(CheckTypeSize)
-CHECK_TYPE_SIZE("long long" LEMON_LONG_LONG)
 
 ENABLE_TESTING()
@@ -28,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")
@@ -41,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")
@@ -81,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: INSTALL
===================================================================
--- INSTALL	(revision 504)
+++ INSTALL	(revision 318)
@@ -5,10 +5,4 @@
 tarballs and successfully extracted it. The latest version of LEMON is
 available at our web page (http://lemon.cs.elte.hu/).
-
-LEMON provides two different build environments, one is based on "autotool",
-while the other is based on "cmake". This file contains instructions only for
-the former one, which is the recommended build environment on Linux, Mac OSX
-and other unices or if you use Cygwin on Windows. For cmake installation
-instructions visit http://lemon.cs.elte.hu.
 
 In order to install LEMON from the extracted source tarball you have to
Index: LICENSE
===================================================================
--- LICENSE	(revision 506)
+++ LICENSE	(revision 440)
@@ -1,12 +1,8 @@
-LEMON code without an explicit copyright notice is covered by the following
+LEMON code without an explicit copyright is covered by the following
 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).
-
-===========================================================================
-Boost Software License, Version 1.0
-===========================================================================
 
 Permission is hereby granted, free of charge, to any person or organization
@@ -31,2 +27,7 @@
 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
+
+===========================================================================
+This license is a verbatim copy of the Boost Software License, Version 1.0.
+
+
Index: Makefile.am
===================================================================
--- Makefile.am	(revision 480)
+++ 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: NEWS
===================================================================
--- NEWS	(revision 507)
+++ NEWS	(revision 322)
@@ -1,9 +1,2 @@
-2009-03-27 LEMON joins to the COIN-OR initiative
-
-        COIN-OR (Computational Infrastructure for Operations Research,
-        http://www.coin-or.org) project is an initiative to spur the
-        development of open-source software for the operations research
-        community.
-
 2008-10-13 Version 1.0 released
 
Index: cmake/FindGhostscript.cmake
===================================================================
--- cmake/FindGhostscript.cmake	(revision 500)
+++ 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 480)
+++ 	(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 511)
+++ configure.ac	(revision 459)
@@ -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([LEMON_HAVE_LONG_LONG], [1], [Define to 1 if you have long long.])
-fi
 
 dnl Checks for programs.
@@ -53,12 +45,17 @@
 
 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.
-#LX_CHECK_GLPK
-#LX_CHECK_CPLEX
-#LX_CHECK_SOPLEX
+LX_CHECK_GLPK
+LX_CHECK_CPLEX
+LX_CHECK_SOPLEX
+LX_CHECK_CLP
+
+AM_CONDITIONAL([HAVE_LP], [test x"$lx_lp_found" = x"yes"])
+AM_CONDITIONAL([HAVE_MIP], [test x"$lx_mip_found" = x"yes"])
 
 dnl Disable/enable building the demo programs.
@@ -104,9 +101,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,12 +117,11 @@
 echo
 echo C++ compiler.................. : $CXX
-echo C++ compiles flags............ : $CXXFLAGS
+echo C++ compiles flags............ : $WARNINGCXXFLAGS $CXXFLAGS
 echo
-echo Compiler supports long long... : $long_long_found
+echo GLPK support.................. : $lx_glpk_found
+echo CPLEX support................. : $lx_cplex_found
+echo SOPLEX support................ : $lx_soplex_found
+echo CLP support................... : $lx_clp_found
 echo
-#echo GLPK support.................. : $lx_glpk_found
-#echo CPLEX support................. : $lx_cplex_found
-#echo SOPLEX support................ : $lx_soplex_found
-#echo
 echo Build demo programs........... : $enable_demo
 echo Build additional tools........ : $enable_tools
Index: demo/CMakeLists.txt
===================================================================
--- demo/CMakeLists.txt	(revision 510)
+++ demo/CMakeLists.txt	(revision 225)
@@ -1,6 +1,3 @@
-INCLUDE_DIRECTORIES(
-  ${CMAKE_SOURCE_DIR}
-  ${PROJECT_BINARY_DIR}
-)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
 
 LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/lemon)
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 500)
+++ 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 455)
@@ -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,80 @@
 
 /**
+@defgroup graph_adaptors Adaptor Classes for Graphs
+@ingroup graphs
+\brief Adaptor classes for digraphs and graphs
+
+This group contains several useful adaptor classes for digraphs and graphs.
+
+The main parts of LEMON are the different graph structures, generic
+graph algorithms, graph concepts, which couple them, 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 \ref concepts::Digraph "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 node or 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<ListDigraph> rg(g);
+int result = algorithm(rg);
+\endcode
+During running the algorithm, the original digraph \c g is untouched.
+This techniques give rise to an elegant code, and based on stable
+graph adaptors, complex algorithms can be implemented easily.
+
+In flow, circulation and matching problems, the residual
+graph is of particular importance. Combining an adaptor implementing
+this with shortest path algorithms or 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 meet depend
+on the graph adaptor, and the wrapped graph.
+For example, if an arc of a reversed digraph is deleted, this is carried
+out by deleting the corresponding arc of the original digraph, thus the
+adaptor modifies the original digraph.
+However in case of a residual digraph, this operation has no sense.
+
+Let us stand one more example here to simplify your work.
+ReverseDigraph 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) {
+  ReverseDigraph<const ListDigraph> rg(g);
+  return algorithm2(rg);
+}
+\endcode
+*/
+
+/**
 @defgroup semi_adaptors Semi-Adaptor Classes for Graphs
 @ingroup graphs
@@ -89,5 +167,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 +181,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 +283,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 +292,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 +316,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 +348,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 +385,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 +443,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 +476,5 @@
 
 This group describes the algorithms for finding a minimum cost spanning
-tree in a graph
+tree in a graph.
 */
 
@@ -465,5 +585,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 +600,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 +667,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 +677,5 @@
 
 /**
-@defgroup tools Standalone utility applications
+@defgroup tools Standalone Utility Applications
 
 Some utility applications are listed here.
@@ -549,2 +685,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 510)
+++ lemon/CMakeLists.txt	(revision 459)
@@ -1,11 +1,3 @@
-INCLUDE_DIRECTORIES(
-  ${CMAKE_SOURCE_DIR}
-  ${PROJECT_BINARY_DIR}
-)
-
-CONFIGURE_FILE(
-  ${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake
-  ${CMAKE_CURRENT_BINARY_DIR}/config.h
-)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
 
 ADD_LIBRARY(lemon
@@ -13,7 +5,5 @@
   base.cc
   color.cc
-  random.cc
-  bits/windows.cc
-)
+  random.cc)
 
 INSTALL(
@@ -27,7 +17,2 @@
   COMPONENT headers
   FILES_MATCHING PATTERN "*.h")
-
-INSTALL(
-  FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h
-  DESTINATION include/lemon
-  COMPONENT headers)
Index: lemon/Makefile.am
===================================================================
--- lemon/Makefile.am	(revision 512)
+++ lemon/Makefile.am	(revision 513)
@@ -8,42 +8,86 @@
 
 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/lp_base.cc \
+	lemon/lp_skeleton.cc \
+	lemon/random.cc
 
-#lemon_libemon_la_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS) $(SOPLEX_CXXFLAGS)
-#lemon_libemon_la_LDFLAGS = $(GLPK_LIBS) $(CPLEX_LIBS) $(SOPLEX_LIBS)
 
-nodist_lemon_HEADERS = lemon/config.h
+lemon_libemon_la_CXXFLAGS = \
+	$(GLPK_CFLAGS) \
+	$(CPLEX_CFLAGS) \
+	$(SOPLEX_CXXFLAGS) \
+	$(CLP_CXXFLAGS)
+
+lemon_libemon_la_LDFLAGS = \
+	$(GLPK_LIBS) \
+	$(CPLEX_LIBS) \
+	$(SOPLEX_LIBS) \
+	$(CLP_LIBS)
+
+if HAVE_GLPK
+lemon_libemon_la_SOURCES += lemon/lp_glpk.cc
+endif
+
+if HAVE_CPLEX
+lemon_libemon_la_SOURCES += lemon/lp_cplex.cc
+endif
+
+if HAVE_SOPLEX
+lemon_libemon_la_SOURCES += lemon/lp_soplex.cc
+endif
+
+if HAVE_CLP
+lemon_libemon_la_SOURCES += lemon/lp_clp.cc
+endif
 
 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 \
 	lemon/list_graph.h \
+	lemon/lp.h \
+	lemon/lp_base.h \
+	lemon/lp_clp.h \
+	lemon/lp_cplex.h \
+	lemon/lp_glpk.h \
+	lemon/lp_skeleton.h \
+	lemon/lp_soplex.h \
 	lemon/maps.h \
 	lemon/math.h \
+	lemon/max_matching.h \
+	lemon/nauty_reader.h \
 	lemon/path.h \
-        lemon/random.h \
+	lemon/preflow.h \
+	lemon/radix_sort.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 += \
@@ -51,11 +95,14 @@
 	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/solver_bits.h \
 	lemon/bits/traits.h \
+	lemon/bits/variant.h \
 	lemon/bits/vector_map.h
 
Index: lemon/adaptors.h
===================================================================
--- lemon/adaptors.h	(revision 455)
+++ lemon/adaptors.h	(revision 455)
@@ -0,0 +1,3606 @@
+/* -*- 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 Adaptor classes for digraphs and graphs
+///
+/// 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 ArcNumTagIndicator<Digraph> ArcNumTag;
+    int arcNum() const { return _digraph->arcNum(); }
+
+    typedef FindArcTagIndicator<Digraph> FindArcTag;
+    Arc findArc(const Node& u, const Node& v, const Arc& prev = INVALID) const {
+      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) { _digraph->erase(n); }
+    void erase(const Arc& a) { _digraph->erase(a); }
+
+    void clear() { _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 ArcNumTagIndicator<Graph> ArcNumTag;
+    int arcNum() const { return _graph->arcNum(); }
+
+    typedef EdgeNumTagIndicator<Graph> EdgeNumTag;
+    int edgeNum() const { return _graph->edgeNum(); }
+
+    typedef FindArcTagIndicator<Graph> FindArcTag;
+    Arc findArc(const Node& u, const Node& v,
+                const Arc& prev = INVALID) const {
+      return _graph->findArc(u, v, prev);
+    }
+
+    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
+    Edge findEdge(const Node& u, const Node& v,
+                  const Edge& prev = INVALID) const {
+      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 FindArcTagIndicator<Digraph> FindArcTag;
+    Arc findArc(const Node& u, const Node& v,
+                const Arc& prev = INVALID) const {
+      return Parent::findArc(v, u, prev);
+    }
+
+  };
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief Adaptor class for reversing the orientation of the arcs in
+  /// a digraph.
+  ///
+  /// ReverseDigraph can be used for reversing the arcs in a digraph.
+  /// It conforms to the \ref concepts::Digraph "Digraph" concept.
+  ///
+  /// The adapted digraph can also be modified through this adaptor
+  /// by adding or removing nodes or arcs, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam GR The type of the adapted digraph.
+  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
+  /// It can also be specified to be \c const.
+  ///
+  /// \note The \c Node and \c Arc types of this adaptor and the adapted
+  /// digraph are convertible to each other.
+  template<typename GR>
+#ifdef DOXYGEN
+  class ReverseDigraph {
+#else
+  class ReverseDigraph :
+    public DigraphAdaptorExtender<ReverseDigraphBase<GR> > {
+#endif
+  public:
+    /// The type of the adapted digraph.
+    typedef GR Digraph;
+    typedef DigraphAdaptorExtender<ReverseDigraphBase<GR> > Parent;
+  protected:
+    ReverseDigraph() { }
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Creates a reverse digraph adaptor for the given digraph.
+    explicit ReverseDigraph(Digraph& digraph) {
+      Parent::setDigraph(digraph);
+    }
+  };
+
+  /// \brief Returns a read-only ReverseDigraph adaptor
+  ///
+  /// This function just returns a read-only \ref ReverseDigraph adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates ReverseDigraph
+  template<typename GR>
+  ReverseDigraph<const GR> reverseDigraph(const GR& digraph) {
+    return ReverseDigraph<const GR>(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 status(const Node& n, bool v) const { _node_filter->set(n, v); }
+    void status(const Arc& a, bool v) const { _arc_filter->set(a, v); }
+
+    bool status(const Node& n) const { return (*_node_filter)[n]; }
+    bool status(const Arc& a) const { return (*_arc_filter)[a]; }
+
+    typedef False NodeNumTag;
+    typedef False ArcNumTag;
+
+    typedef FindArcTagIndicator<Digraph> FindArcTag;
+    Arc findArc(const Node& source, const Node& target,
+                const Arc& prev = INVALID) const {
+      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 status(const Node& n, bool v) const { _node_filter->set(n, v); }
+    void status(const Arc& a, bool v) const { _arc_filter->set(a, v); }
+
+    bool status(const Node& n) const { return (*_node_filter)[n]; }
+    bool status(const Arc& a) const { return (*_arc_filter)[a]; }
+
+    typedef False NodeNumTag;
+    typedef False ArcNumTag;
+
+    typedef FindArcTagIndicator<Digraph> FindArcTag;
+    Arc findArc(const Node& source, const Node& target,
+                const Arc& prev = INVALID) const {
+      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 Adaptor class for hiding nodes and arcs in a digraph
+  ///
+  /// SubDigraph can be used for hiding nodes and arcs in a digraph.
+  /// A \c bool node map and a \c bool arc map must be specified, which
+  /// define the filters for nodes and arcs.
+  /// Only the nodes and arcs with \c true filter value are
+  /// shown in the subdigraph. The arcs that are incident to hidden
+  /// nodes are also filtered out.
+  /// This adaptor conforms to the \ref concepts::Digraph "Digraph" concept.
+  ///
+  /// The adapted digraph can also be modified through this adaptor
+  /// by adding or removing nodes or arcs, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam GR The type of the adapted digraph.
+  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
+  /// It can also be specified to be \c const.
+  /// \tparam NF The type of the node filter map.
+  /// It must be a \c bool (or convertible) node map of the
+  /// adapted digraph. The default type is
+  /// \ref concepts::Digraph::NodeMap "GR::NodeMap<bool>".
+  /// \tparam AF The type of the arc filter map.
+  /// It must be \c bool (or convertible) arc map of the
+  /// adapted digraph. The default type is
+  /// \ref concepts::Digraph::ArcMap "GR::ArcMap<bool>".
+  ///
+  /// \note The \c Node and \c Arc types of this adaptor and the adapted
+  /// digraph are convertible to each other.
+  ///
+  /// \see FilterNodes
+  /// \see FilterArcs
+#ifdef DOXYGEN
+  template<typename GR, typename NF, typename AF>
+  class SubDigraph {
+#else
+  template<typename GR,
+           typename NF = typename GR::template NodeMap<bool>,
+           typename AF = typename GR::template ArcMap<bool> >
+  class SubDigraph :
+    public DigraphAdaptorExtender<SubDigraphBase<GR, NF, AF, true> > {
+#endif
+  public:
+    /// The type of the adapted digraph.
+    typedef GR Digraph;
+    /// The type of the node filter map.
+    typedef NF NodeFilterMap;
+    /// The type of the arc filter map.
+    typedef AF ArcFilterMap;
+
+    typedef DigraphAdaptorExtender<SubDigraphBase<GR, NF, AF, true> >
+      Parent;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+
+  protected:
+    SubDigraph() { }
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Creates a subdigraph for the given digraph with the
+    /// given node and arc filter maps.
+    SubDigraph(Digraph& digraph, NodeFilterMap& node_filter,
+               ArcFilterMap& arc_filter) {
+      setDigraph(digraph);
+      setNodeFilterMap(node_filter);
+      setArcFilterMap(arc_filter);
+    }
+
+    /// \brief Sets the status of the given node
+    ///
+    /// This function sets the status of the given node.
+    /// It is done by simply setting the assigned value of \c n
+    /// to \c v in the node filter map.
+    void status(const Node& n, bool v) const { Parent::status(n, v); }
+
+    /// \brief Sets the status of the given arc
+    ///
+    /// This function sets the status of the given arc.
+    /// It is done by simply setting the assigned value of \c a
+    /// to \c v in the arc filter map.
+    void status(const Arc& a, bool v) const { Parent::status(a, v); }
+
+    /// \brief Returns the status of the given node
+    ///
+    /// This function returns the status of the given node.
+    /// It is \c true if the given node is enabled (i.e. not hidden).
+    bool status(const Node& n) const { return Parent::status(n); }
+
+    /// \brief Returns the status of the given arc
+    ///
+    /// This function returns the status of the given arc.
+    /// It is \c true if the given arc is enabled (i.e. not hidden).
+    bool status(const Arc& a) const { return Parent::status(a); }
+
+    /// \brief Disables the given node
+    ///
+    /// This function disables the given node in the subdigraph,
+    /// so the iteration jumps over it.
+    /// It is the same as \ref status() "status(n, false)".
+    void disable(const Node& n) const { Parent::status(n, false); }
+
+    /// \brief Disables the given arc
+    ///
+    /// This function disables the given arc in the subdigraph,
+    /// so the iteration jumps over it.
+    /// It is the same as \ref status() "status(a, false)".
+    void disable(const Arc& a) const { Parent::status(a, false); }
+
+    /// \brief Enables the given node
+    ///
+    /// This function enables the given node in the subdigraph.
+    /// It is the same as \ref status() "status(n, true)".
+    void enable(const Node& n) const { Parent::status(n, true); }
+
+    /// \brief Enables the given arc
+    ///
+    /// This function enables the given arc in the subdigraph.
+    /// It is the same as \ref status() "status(a, true)".
+    void enable(const Arc& a) const { Parent::status(a, true); }
+
+  };
+
+  /// \brief Returns a read-only SubDigraph adaptor
+  ///
+  /// This function just returns a read-only \ref SubDigraph adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates SubDigraph
+  template<typename GR, typename NF, typename AF>
+  SubDigraph<const GR, NF, AF>
+  subDigraph(const GR& digraph,
+             NF& node_filter_map, AF& arc_filter_map) {
+    return SubDigraph<const GR, NF, AF>
+      (digraph, node_filter_map, arc_filter_map);
+  }
+
+  template<typename GR, typename NF, typename AF>
+  SubDigraph<const GR, const NF, AF>
+  subDigraph(const GR& digraph,
+             const NF& node_filter_map, AF& arc_filter_map) {
+    return SubDigraph<const GR, const NF, AF>
+      (digraph, node_filter_map, arc_filter_map);
+  }
+
+  template<typename GR, typename NF, typename AF>
+  SubDigraph<const GR, NF, const AF>
+  subDigraph(const GR& digraph,
+             NF& node_filter_map, const AF& arc_filter_map) {
+    return SubDigraph<const GR, NF, const AF>
+      (digraph, node_filter_map, arc_filter_map);
+  }
+
+  template<typename GR, typename NF, typename AF>
+  SubDigraph<const GR, const NF, const AF>
+  subDigraph(const GR& digraph,
+             const NF& node_filter_map, const AF& arc_filter_map) {
+    return SubDigraph<const GR, const NF, const AF>
+      (digraph, node_filter_map, arc_filter_map);
+  }
+
+
+  template <typename _Graph, typename _NodeFilterMap,
+            typename _EdgeFilterMap, bool _checked = true>
+  class SubGraphBase : public GraphAdaptorBase<_Graph> {
+  public:
+    typedef _Graph Graph;
+    typedef _NodeFilterMap NodeFilterMap;
+    typedef _EdgeFilterMap EdgeFilterMap;
+
+    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 status(const Node& n, bool v) const { _node_filter_map->set(n, v); }
+    void status(const Edge& e, bool v) const { _edge_filter_map->set(e, v); }
+
+    bool status(const Node& n) const { return (*_node_filter_map)[n]; }
+    bool status(const Edge& e) const { return (*_edge_filter_map)[e]; }
+
+    typedef False NodeNumTag;
+    typedef False ArcNumTag;
+    typedef False EdgeNumTag;
+
+    typedef FindArcTagIndicator<Graph> FindArcTag;
+    Arc findArc(const Node& u, const Node& v,
+                const Arc& prev = INVALID) const {
+      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;
+    }
+
+    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
+    Edge findEdge(const Node& u, const Node& v,
+                  const Edge& prev = INVALID) const {
+      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 _NodeFilterMap NodeFilterMap;
+    typedef _EdgeFilterMap EdgeFilterMap;
+
+    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 status(const Node& n, bool v) const { _node_filter_map->set(n, v); }
+    void status(const Edge& e, bool v) const { _edge_filter_map->set(e, v); }
+
+    bool status(const Node& n) const { return (*_node_filter_map)[n]; }
+    bool status(const Edge& e) const { return (*_edge_filter_map)[e]; }
+
+    typedef False NodeNumTag;
+    typedef False ArcNumTag;
+    typedef False EdgeNumTag;
+
+    typedef FindArcTagIndicator<Graph> FindArcTag;
+    Arc findArc(const Node& u, const Node& v,
+                const Arc& prev = INVALID) const {
+      Arc arc = Parent::findArc(u, v, prev);
+      while (arc != INVALID && !(*_edge_filter_map)[arc]) {
+        arc = Parent::findArc(u, v, arc);
+      }
+      return arc;
+    }
+
+    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
+    Edge findEdge(const Node& u, const Node& v,
+                  const Edge& prev = INVALID) const {
+      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 Adaptor class for hiding nodes and edges in an undirected
+  /// graph.
+  ///
+  /// SubGraph can be used for hiding nodes and edges in a graph.
+  /// A \c bool node map and a \c bool edge map must be specified, which
+  /// define the filters for nodes and edges.
+  /// Only the nodes and edges with \c true filter value are
+  /// shown in the subgraph. The edges that are incident to hidden
+  /// nodes are also filtered out.
+  /// This adaptor conforms to the \ref concepts::Graph "Graph" concept.
+  ///
+  /// The adapted graph can also be modified through this adaptor
+  /// by adding or removing nodes or edges, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam GR The type of the adapted graph.
+  /// It must conform to the \ref concepts::Graph "Graph" concept.
+  /// It can also be specified to be \c const.
+  /// \tparam NF The type of the node filter map.
+  /// It must be a \c bool (or convertible) node map of the
+  /// adapted graph. The default type is
+  /// \ref concepts::Graph::NodeMap "GR::NodeMap<bool>".
+  /// \tparam EF The type of the edge filter map.
+  /// It must be a \c bool (or convertible) edge map of the
+  /// adapted graph. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<bool>".
+  ///
+  /// \note The \c Node, \c Edge and \c Arc types of this adaptor and the
+  /// adapted graph are convertible to each other.
+  ///
+  /// \see FilterNodes
+  /// \see FilterEdges
+#ifdef DOXYGEN
+  template<typename GR, typename NF, typename EF>
+  class SubGraph {
+#else
+  template<typename GR,
+           typename NF = typename GR::template NodeMap<bool>,
+           typename EF = typename GR::template EdgeMap<bool> >
+  class SubGraph :
+    public GraphAdaptorExtender<SubGraphBase<GR, NF, EF, true> > {
+#endif
+  public:
+    /// The type of the adapted graph.
+    typedef GR Graph;
+    /// The type of the node filter map.
+    typedef NF NodeFilterMap;
+    /// The type of the edge filter map.
+    typedef EF EdgeFilterMap;
+
+    typedef GraphAdaptorExtender< SubGraphBase<GR, NF, EF, true> >
+      Parent;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Edge Edge;
+
+  protected:
+    SubGraph() { }
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Creates a subgraph for the given graph with the given node
+    /// and edge filter maps.
+    SubGraph(Graph& graph, NodeFilterMap& node_filter_map,
+             EdgeFilterMap& edge_filter_map) {
+      setGraph(graph);
+      setNodeFilterMap(node_filter_map);
+      setEdgeFilterMap(edge_filter_map);
+    }
+
+    /// \brief Sets the status of the given node
+    ///
+    /// This function sets the status of the given node.
+    /// It is done by simply setting the assigned value of \c n
+    /// to \c v in the node filter map.
+    void status(const Node& n, bool v) const { Parent::status(n, v); }
+
+    /// \brief Sets the status of the given edge
+    ///
+    /// This function sets the status of the given edge.
+    /// It is done by simply setting the assigned value of \c e
+    /// to \c v in the edge filter map.
+    void status(const Edge& e, bool v) const { Parent::status(e, v); }
+
+    /// \brief Returns the status of the given node
+    ///
+    /// This function returns the status of the given node.
+    /// It is \c true if the given node is enabled (i.e. not hidden).
+    bool status(const Node& n) const { return Parent::status(n); }
+
+    /// \brief Returns the status of the given edge
+    ///
+    /// This function returns the status of the given edge.
+    /// It is \c true if the given edge is enabled (i.e. not hidden).
+    bool status(const Edge& e) const { return Parent::status(e); }
+
+    /// \brief Disables the given node
+    ///
+    /// This function disables the given node in the subdigraph,
+    /// so the iteration jumps over it.
+    /// It is the same as \ref status() "status(n, false)".
+    void disable(const Node& n) const { Parent::status(n, false); }
+
+    /// \brief Disables the given edge
+    ///
+    /// This function disables the given edge in the subgraph,
+    /// so the iteration jumps over it.
+    /// It is the same as \ref status() "status(e, false)".
+    void disable(const Edge& e) const { Parent::status(e, false); }
+
+    /// \brief Enables the given node
+    ///
+    /// This function enables the given node in the subdigraph.
+    /// It is the same as \ref status() "status(n, true)".
+    void enable(const Node& n) const { Parent::status(n, true); }
+
+    /// \brief Enables the given edge
+    ///
+    /// This function enables the given edge in the subgraph.
+    /// It is the same as \ref status() "status(e, true)".
+    void enable(const Edge& e) const { Parent::status(e, true); }
+
+  };
+
+  /// \brief Returns a read-only SubGraph adaptor
+  ///
+  /// This function just returns a read-only \ref SubGraph adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates SubGraph
+  template<typename GR, typename NF, typename EF>
+  SubGraph<const GR, NF, EF>
+  subGraph(const GR& graph,
+           NF& node_filter_map, EF& edge_filter_map) {
+    return SubGraph<const GR, NF, EF>
+      (graph, node_filter_map, edge_filter_map);
+  }
+
+  template<typename GR, typename NF, typename EF>
+  SubGraph<const GR, const NF, EF>
+  subGraph(const GR& graph,
+           const NF& node_filter_map, EF& edge_filter_map) {
+    return SubGraph<const GR, const NF, EF>
+      (graph, node_filter_map, edge_filter_map);
+  }
+
+  template<typename GR, typename NF, typename EF>
+  SubGraph<const GR, NF, const EF>
+  subGraph(const GR& graph,
+           NF& node_filter_map, const EF& edge_filter_map) {
+    return SubGraph<const GR, NF, const EF>
+      (graph, node_filter_map, edge_filter_map);
+  }
+
+  template<typename GR, typename NF, typename EF>
+  SubGraph<const GR, const NF, const EF>
+  subGraph(const GR& graph,
+           const NF& node_filter_map, const EF& edge_filter_map) {
+    return SubGraph<const GR, const NF, const EF>
+      (graph, node_filter_map, edge_filter_map);
+  }
+
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief Adaptor class for hiding nodes in a digraph or a graph.
+  ///
+  /// FilterNodes adaptor can be used for hiding nodes in a digraph or a
+  /// graph. A \c bool node map must be specified, which defines the filter
+  /// for the nodes. Only the nodes with \c true filter value and the
+  /// arcs/edges incident to nodes both with \c true filter value are shown
+  /// in the subgraph. This adaptor conforms to the \ref concepts::Digraph
+  /// "Digraph" concept or the \ref concepts::Graph "Graph" concept
+  /// depending on the \c GR template parameter.
+  ///
+  /// The adapted (di)graph can also be modified through this adaptor
+  /// by adding or removing nodes or arcs/edges, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam GR The type of the adapted digraph or graph.
+  /// It must conform to the \ref concepts::Digraph "Digraph" concept
+  /// or the \ref concepts::Graph "Graph" concept.
+  /// It can also be specified to be \c const.
+  /// \tparam NF The type of the node filter map.
+  /// It must be a \c bool (or convertible) node map of the
+  /// adapted (di)graph. The default type is
+  /// \ref concepts::Graph::NodeMap "GR::NodeMap<bool>".
+  ///
+  /// \note The \c Node and <tt>Arc/Edge</tt> types of this adaptor and the
+  /// adapted (di)graph are convertible to each other.
+#ifdef DOXYGEN
+  template<typename GR, typename NF>
+  class FilterNodes {
+#else
+  template<typename GR,
+           typename NF = typename GR::template NodeMap<bool>,
+           typename Enable = void>
+  class FilterNodes :
+    public DigraphAdaptorExtender<
+      SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, bool>, true> > {
+#endif
+  public:
+
+    typedef GR Digraph;
+    typedef NF NodeFilterMap;
+
+    typedef DigraphAdaptorExtender<
+      SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, bool>, true> >
+      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 a subgraph for the given digraph or graph with the
+    /// given node filter map.
+    FilterNodes(GR& graph, NodeFilterMap& node_filter) :
+      Parent(), const_true_map(true)
+    {
+      Parent::setDigraph(graph);
+      Parent::setNodeFilterMap(node_filter);
+      Parent::setArcFilterMap(const_true_map);
+    }
+
+    /// \brief Sets the status of the given node
+    ///
+    /// This function sets the status of the given node.
+    /// It is done by simply setting the assigned value of \c n
+    /// to \c v in the node filter map.
+    void status(const Node& n, bool v) const { Parent::status(n, v); }
+
+    /// \brief Returns the status of the given node
+    ///
+    /// This function returns the status of the given node.
+    /// It is \c true if the given node is enabled (i.e. not hidden).
+    bool status(const Node& n) const { return Parent::status(n); }
+
+    /// \brief Disables the given node
+    ///
+    /// This function disables the given node, so the iteration
+    /// jumps over it.
+    /// It is the same as \ref status() "status(n, false)".
+    void disable(const Node& n) const { Parent::status(n, false); }
+
+    /// \brief Enables the given node
+    ///
+    /// This function enables the given node.
+    /// It is the same as \ref status() "status(n, true)".
+    void enable(const Node& n) const { Parent::status(n, true); }
+
+  };
+
+  template<typename GR, typename NF>
+  class FilterNodes<GR, NF,
+                    typename enable_if<UndirectedTagIndicator<GR> >::type> :
+    public GraphAdaptorExtender<
+      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, bool>, true> > {
+
+  public:
+    typedef GR Graph;
+    typedef NF NodeFilterMap;
+    typedef GraphAdaptorExtender<
+      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, bool>, true> >
+      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 status(const Node& n, bool v) const { Parent::status(n, v); }
+    bool status(const Node& n) const { return Parent::status(n); }
+    void disable(const Node& n) const { Parent::status(n, false); }
+    void enable(const Node& n) const { Parent::status(n, true); }
+
+  };
+
+
+  /// \brief Returns a read-only FilterNodes adaptor
+  ///
+  /// This function just returns a read-only \ref FilterNodes adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates FilterNodes
+  template<typename GR, typename NF>
+  FilterNodes<const GR, NF>
+  filterNodes(const GR& graph, NF& node_filter_map) {
+    return FilterNodes<const GR, NF>(graph, node_filter_map);
+  }
+
+  template<typename GR, typename NF>
+  FilterNodes<const GR, const NF>
+  filterNodes(const GR& graph, const NF& node_filter_map) {
+    return FilterNodes<const GR, const NF>(graph, node_filter_map);
+  }
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief Adaptor class for hiding arcs in a digraph.
+  ///
+  /// FilterArcs adaptor can be used for hiding arcs in a digraph.
+  /// A \c bool arc map must be specified, which defines the filter for
+  /// the arcs. Only the arcs with \c true filter value are shown in the
+  /// subdigraph. This adaptor conforms to the \ref concepts::Digraph
+  /// "Digraph" concept.
+  ///
+  /// The adapted digraph can also be modified through this adaptor
+  /// by adding or removing nodes or arcs, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam GR The type of the adapted digraph.
+  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
+  /// It can also be specified to be \c const.
+  /// \tparam AF The type of the arc filter map.
+  /// It must be a \c bool (or convertible) arc map of the
+  /// adapted digraph. The default type is
+  /// \ref concepts::Digraph::ArcMap "GR::ArcMap<bool>".
+  ///
+  /// \note The \c Node and \c Arc types of this adaptor and the adapted
+  /// digraph are convertible to each other.
+#ifdef DOXYGEN
+  template<typename GR,
+           typename AF>
+  class FilterArcs {
+#else
+  template<typename GR,
+           typename AF = typename GR::template ArcMap<bool> >
+  class FilterArcs :
+    public DigraphAdaptorExtender<
+      SubDigraphBase<GR, ConstMap<typename GR::Node, bool>, AF, false> > {
+#endif
+  public:
+    /// The type of the adapted digraph.
+    typedef GR Digraph;
+    /// The type of the arc filter map.
+    typedef AF ArcFilterMap;
+
+    typedef DigraphAdaptorExtender<
+      SubDigraphBase<GR, ConstMap<typename GR::Node, bool>, AF, 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 subdigraph for the given digraph with the given arc
+    /// filter map.
+    FilterArcs(Digraph& digraph, ArcFilterMap& arc_filter)
+      : Parent(), const_true_map(true) {
+      Parent::setDigraph(digraph);
+      Parent::setNodeFilterMap(const_true_map);
+      Parent::setArcFilterMap(arc_filter);
+    }
+
+    /// \brief Sets the status of the given arc
+    ///
+    /// This function sets the status of the given arc.
+    /// It is done by simply setting the assigned value of \c a
+    /// to \c v in the arc filter map.
+    void status(const Arc& a, bool v) const { Parent::status(a, v); }
+
+    /// \brief Returns the status of the given arc
+    ///
+    /// This function returns the status of the given arc.
+    /// It is \c true if the given arc is enabled (i.e. not hidden).
+    bool status(const Arc& a) const { return Parent::status(a); }
+
+    /// \brief Disables the given arc
+    ///
+    /// This function disables the given arc in the subdigraph,
+    /// so the iteration jumps over it.
+    /// It is the same as \ref status() "status(a, false)".
+    void disable(const Arc& a) const { Parent::status(a, false); }
+
+    /// \brief Enables the given arc
+    ///
+    /// This function enables the given arc in the subdigraph.
+    /// It is the same as \ref status() "status(a, true)".
+    void enable(const Arc& a) const { Parent::status(a, true); }
+
+  };
+
+  /// \brief Returns a read-only FilterArcs adaptor
+  ///
+  /// This function just returns a read-only \ref FilterArcs adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates FilterArcs
+  template<typename GR, typename AF>
+  FilterArcs<const GR, AF>
+  filterArcs(const GR& digraph, AF& arc_filter_map) {
+    return FilterArcs<const GR, AF>(digraph, arc_filter_map);
+  }
+
+  template<typename GR, typename AF>
+  FilterArcs<const GR, const AF>
+  filterArcs(const GR& digraph, const AF& arc_filter_map) {
+    return FilterArcs<const GR, const AF>(digraph, arc_filter_map);
+  }
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief Adaptor class for hiding edges in a graph.
+  ///
+  /// FilterEdges adaptor can be used for hiding edges in a graph.
+  /// A \c bool edge map must be specified, which defines the filter for
+  /// the edges. Only the edges with \c true filter value are shown in the
+  /// subgraph. This adaptor conforms to the \ref concepts::Graph
+  /// "Graph" concept.
+  ///
+  /// The adapted graph can also be modified through this adaptor
+  /// by adding or removing nodes or edges, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam GR The type of the adapted graph.
+  /// It must conform to the \ref concepts::Graph "Graph" concept.
+  /// It can also be specified to be \c const.
+  /// \tparam EF The type of the edge filter map.
+  /// It must be a \c bool (or convertible) edge map of the
+  /// adapted graph. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<bool>".
+  ///
+  /// \note The \c Node, \c Edge and \c Arc types of this adaptor and the
+  /// adapted graph are convertible to each other.
+#ifdef DOXYGEN
+  template<typename GR,
+           typename EF>
+  class FilterEdges {
+#else
+  template<typename GR,
+           typename EF = typename GR::template EdgeMap<bool> >
+  class FilterEdges :
+    public GraphAdaptorExtender<
+      SubGraphBase<GR, ConstMap<typename GR::Node,bool>, EF, false> > {
+#endif
+  public:
+    /// The type of the adapted graph.
+    typedef GR Graph;
+    /// The type of the edge filter map.
+    typedef EF EdgeFilterMap;
+
+    typedef GraphAdaptorExtender<
+      SubGraphBase<GR, ConstMap<typename GR::Node,bool>, EF, 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 subgraph for the given graph with the given edge
+    /// filter map.
+    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 Sets the status of the given edge
+    ///
+    /// This function sets the status of the given edge.
+    /// It is done by simply setting the assigned value of \c e
+    /// to \c v in the edge filter map.
+    void status(const Edge& e, bool v) const { Parent::status(e, v); }
+
+    /// \brief Returns the status of the given edge
+    ///
+    /// This function returns the status of the given edge.
+    /// It is \c true if the given edge is enabled (i.e. not hidden).
+    bool status(const Edge& e) const { return Parent::status(e); }
+
+    /// \brief Disables the given edge
+    ///
+    /// This function disables the given edge in the subgraph,
+    /// so the iteration jumps over it.
+    /// It is the same as \ref status() "status(e, false)".
+    void disable(const Edge& e) const { Parent::status(e, false); }
+
+    /// \brief Enables the given edge
+    ///
+    /// This function enables the given edge in the subgraph.
+    /// It is the same as \ref status() "status(e, true)".
+    void enable(const Edge& e) const { Parent::status(e, true); }
+
+  };
+
+  /// \brief Returns a read-only FilterEdges adaptor
+  ///
+  /// This function just returns a read-only \ref FilterEdges adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates FilterEdges
+  template<typename GR, typename EF>
+  FilterEdges<const GR, EF>
+  filterEdges(const GR& graph, EF& edge_filter_map) {
+    return FilterEdges<const GR, EF>(graph, edge_filter_map);
+  }
+
+  template<typename GR, typename EF>
+  FilterEdges<const GR, const EF>
+  filterEdges(const GR& graph, const EF& edge_filter_map) {
+    return FilterEdges<const GR, const EF>(graph, edge_filter_map);
+  }
+
+
+  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 _digraph->nodeNum(); }
+
+    typedef ArcNumTagIndicator<Digraph> ArcNumTag;
+    int arcNum() const { return 2 * _digraph->arcNum(); }
+
+    typedef ArcNumTag EdgeNumTag;
+    int edgeNum() const { return _digraph->arcNum(); }
+
+    typedef FindArcTagIndicator<Digraph> FindArcTag;
+    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;
+    }
+
+    typedef FindArcTag FindEdgeTag;
+    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->source(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;
+      typedef typename MapTraits<MapImpl>::ConstReturnValue ConstReturnValue;
+      typedef typename MapTraits<MapImpl>::ReturnValue ReturnValue;
+      typedef typename MapTraits<MapImpl>::ConstReturnValue ConstReference;
+      typedef typename MapTraits<MapImpl>::ReturnValue Reference;
+
+      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);
+        }
+      }
+
+      ConstReturnValue operator[](const Arc& a) const {
+        if (direction(a)) {
+          return _forward[a];
+        } else {
+          return _backward[a];
+        }
+      }
+
+      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;
+
+      explicit 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()); }
+
+    typedef typename ItemSetTraits<Digraph, Edge>::ItemNotifier EdgeNotifier;
+    EdgeNotifier& notifier(Edge) const { return _digraph->notifier(Edge()); }
+
+  protected:
+
+    UndirectorBase() : _digraph(0) {}
+
+    Digraph* _digraph;
+
+    void setDigraph(Digraph& digraph) {
+      _digraph = &digraph;
+    }
+
+  };
+
+  /// \ingroup graph_adaptors
+  ///
+  /// \brief Adaptor class for viewing a digraph as an undirected graph.
+  ///
+  /// Undirector adaptor can be used for viewing a digraph as an undirected
+  /// graph. All arcs of the underlying digraph are showed in the
+  /// adaptor as an edge (and also as a pair of arcs, of course).
+  /// This adaptor conforms to the \ref concepts::Graph "Graph" concept.
+  ///
+  /// The adapted digraph can also be modified through this adaptor
+  /// by adding or removing nodes or edges, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam GR The type of the adapted digraph.
+  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
+  /// It can also be specified to be \c const.
+  ///
+  /// \note The \c Node type of this adaptor and the adapted digraph are
+  /// convertible to each other, moreover the \c Edge type of the adaptor
+  /// and the \c Arc type of the adapted digraph are also convertible to
+  /// each other.
+  /// (Thus the \c Arc type of the adaptor is convertible to the \c Arc type
+  /// of the adapted digraph.)
+  template<typename GR>
+#ifdef DOXYGEN
+  class Undirector {
+#else
+  class Undirector :
+    public GraphAdaptorExtender<UndirectorBase<GR> > {
+#endif
+  public:
+    /// The type of the adapted digraph.
+    typedef GR Digraph;
+    typedef GraphAdaptorExtender<UndirectorBase<GR> > Parent;
+  protected:
+    Undirector() { }
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Creates an undirected graph from the given digraph.
+    Undirector(Digraph& digraph) {
+      setDigraph(digraph);
+    }
+
+    /// \brief Arc map combined from two original arc maps
+    ///
+    /// This map adaptor class adapts two arc maps of the underlying
+    /// digraph to get an arc map of the undirected graph.
+    /// Its value type is inherited from the first arc map type
+    /// (\c %ForwardMap).
+    template <typename ForwardMap, typename BackwardMap>
+    class CombinedArcMap {
+    public:
+
+      /// The key type of the map
+      typedef typename Parent::Arc Key;
+      /// The value type of the map
+      typedef typename ForwardMap::Value Value;
+
+      typedef typename MapTraits<ForwardMap>::ReferenceMapTag ReferenceMapTag;
+
+      typedef typename MapTraits<ForwardMap>::ReturnValue ReturnValue;
+      typedef typename MapTraits<ForwardMap>::ConstReturnValue ConstReturnValue;
+      typedef typename MapTraits<ForwardMap>::ReturnValue Reference;
+      typedef typename MapTraits<ForwardMap>::ConstReturnValue ConstReference;
+
+      /// Constructor
+      CombinedArcMap(ForwardMap& forward, BackwardMap& backward)
+        : _forward(&forward), _backward(&backward) {}
+
+      /// Sets the value associated with the given key.
+      void set(const Key& e, const Value& a) {
+        if (Parent::direction(e)) {
+          _forward->set(e, a);
+        } else {
+          _backward->set(e, a);
+        }
+      }
+
+      /// Returns the value associated with the given key.
+      ConstReturnValue operator[](const Key& e) const {
+        if (Parent::direction(e)) {
+          return (*_forward)[e];
+        } else {
+          return (*_backward)[e];
+        }
+      }
+
+      /// Returns a reference to the value associated with the given key.
+      ReturnValue operator[](const Key& e) {
+        if (Parent::direction(e)) {
+          return (*_forward)[e];
+        } else {
+          return (*_backward)[e];
+        }
+      }
+
+    protected:
+
+      ForwardMap* _forward;
+      BackwardMap* _backward;
+
+    };
+
+    /// \brief Returns a combined arc map
+    ///
+    /// This function just returns 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 Returns a read-only Undirector adaptor
+  ///
+  /// This function just returns a read-only \ref Undirector adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates Undirector
+  template<typename GR>
+  Undirector<const GR> undirector(const GR& digraph) {
+    return Undirector<const GR>(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 = true;
+      _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 = true;
+      _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> ArcNumTag;
+    int arcNum() const { return _graph->edgeNum(); }
+
+    typedef FindEdgeTagIndicator<Graph> FindArcTag;
+    Arc findArc(const Node& u, const Node& v,
+                const Arc& prev = INVALID) const {
+      Arc arc = _graph->findEdge(u, v, prev);
+      while (arc != INVALID && source(arc) != u) {
+        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->addEdge(u, v);
+      _direction->set(arc, _graph->u(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 Adaptor class for orienting the edges of a graph to get a digraph
+  ///
+  /// Orienter adaptor can be used for orienting the edges of a graph to
+  /// get a digraph. A \c bool edge map of the underlying graph must be
+  /// specified, which define the direction of the arcs in the adaptor.
+  /// The arcs can be easily reversed by the \c reverseArc() member function
+  /// of the adaptor.
+  /// This class conforms to the \ref concepts::Digraph "Digraph" concept.
+  ///
+  /// The adapted graph can also be modified through this adaptor
+  /// by adding or removing nodes or arcs, unless the \c GR template
+  /// parameter is set to be \c const.
+  ///
+  /// \tparam GR The type of the adapted graph.
+  /// It must conform to the \ref concepts::Graph "Graph" concept.
+  /// It can also be specified to be \c const.
+  /// \tparam DM The type of the direction map.
+  /// It must be a \c bool (or convertible) edge map of the
+  /// adapted graph. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<bool>".
+  ///
+  /// \note The \c Node type of this adaptor and the adapted graph are
+  /// convertible to each other, moreover the \c Arc type of the adaptor
+  /// and the \c Edge type of the adapted graph are also convertible to
+  /// each other.
+#ifdef DOXYGEN
+  template<typename GR,
+           typename DM>
+  class Orienter {
+#else
+  template<typename GR,
+           typename DM = typename GR::template EdgeMap<bool> >
+  class Orienter :
+    public DigraphAdaptorExtender<OrienterBase<GR, DM> > {
+#endif
+  public:
+
+    /// The type of the adapted graph.
+    typedef GR Graph;
+    /// The type of the direction edge map.
+    typedef DM DirectionMap;
+
+    typedef DigraphAdaptorExtender<OrienterBase<GR, DM> > Parent;
+    typedef typename Parent::Arc Arc;
+  protected:
+    Orienter() { }
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor of the adaptor.
+    Orienter(Graph& graph, DirectionMap& direction) {
+      setGraph(graph);
+      setDirectionMap(direction);
+    }
+
+    /// \brief Reverses the given arc
+    ///
+    /// This function reverses the given arc.
+    /// It is done by simply negate the assigned value of \c a
+    /// in the direction map.
+    void reverseArc(const Arc& a) {
+      Parent::reverseArc(a);
+    }
+  };
+
+  /// \brief Returns a read-only Orienter adaptor
+  ///
+  /// This function just returns a read-only \ref Orienter adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates Orienter
+  template<typename GR, typename DM>
+  Orienter<const GR, DM>
+  orienter(const GR& graph, DM& direction_map) {
+    return Orienter<const GR, DM>(graph, direction_map);
+  }
+
+  template<typename GR, typename DM>
+  Orienter<const GR, const DM>
+  orienter(const GR& graph, const DM& direction_map) {
+    return Orienter<const GR, const DM>(graph, direction_map);
+  }
+
+  namespace _adaptor_bits {
+
+    template<typename Digraph,
+             typename CapacityMap,
+             typename FlowMap,
+             typename Tolerance>
+    class ResForwardFilter {
+    public:
+
+      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 FlowMap,
+             typename Tolerance>
+    class ResBackwardFilter {
+    public:
+
+      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 Adaptor class for composing the residual digraph for directed
+  /// flow and circulation problems.
+  ///
+  /// Residual can be used for composing the \e residual digraph 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 \f$ flow, cap: A\to F \f$ be
+  /// functions on the arcs.
+  /// This adaptor implements a 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, flow(uv)<cap(uv)\} \f$ and
+  /// \f$ A_{backward}=\{vu : uv\in A, flow(uv)>0\} \f$, i.e. the so
+  /// called residual digraph.
+  /// When the union \f$ A_{forward}\cup A_{backward} \f$ is taken,
+  /// multiplicities are counted, i.e. the adaptor has exactly
+  /// \f$ |A_{forward}| + |A_{backward}|\f$ arcs (it may have parallel
+  /// arcs).
+  /// This class conforms to the \ref concepts::Digraph "Digraph" concept.
+  ///
+  /// \tparam GR The type of the adapted digraph.
+  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
+  /// It is implicitly \c const.
+  /// \tparam CM The type of the capacity map.
+  /// It must be an arc map of some numerical type, which defines
+  /// the capacities in the flow problem. It is implicitly \c const.
+  /// The default type is
+  /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+  /// \tparam FM The type of the flow map.
+  /// It must be an arc map of some numerical type, which defines
+  /// the flow values in the flow problem. The default type is \c CM.
+  /// \tparam TL The tolerance type for handling inexact computation.
+  /// The default tolerance type depends on the value type of the
+  /// capacity map.
+  ///
+  /// \note This adaptor is implemented using Undirector and FilterArcs
+  /// adaptors.
+  ///
+  /// \note The \c Node type of this adaptor and the adapted digraph are
+  /// convertible to each other, moreover the \c Arc type of the adaptor
+  /// is convertible to the \c Arc type of the adapted digraph.
+#ifdef DOXYGEN
+  template<typename GR, typename CM, typename FM, typename TL>
+  class Residual
+#else
+  template<typename GR,
+           typename CM = typename GR::template ArcMap<int>,
+           typename FM = CM,
+           typename TL = Tolerance<typename CM::Value> >
+  class Residual :
+    public FilterArcs<
+      Undirector<const GR>,
+      typename Undirector<const GR>::template CombinedArcMap<
+        _adaptor_bits::ResForwardFilter<const GR, CM, FM, TL>,
+        _adaptor_bits::ResBackwardFilter<const GR, CM, FM, TL> > >
+#endif
+  {
+  public:
+
+    /// The type of the underlying digraph.
+    typedef GR Digraph;
+    /// The type of the capacity map.
+    typedef CM CapacityMap;
+    /// The type of the flow map.
+    typedef FM FlowMap;
+    /// The tolerance type.
+    typedef TL 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
+    ///
+    /// Constructor of the residual digraph adaptor. The parameters are the
+    /// digraph, the capacity map, the flow 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 Returns the residual capacity of the given arc.
+    ///
+    /// Returns the residual capacity of the given arc.
+    Value residualCapacity(const Arc& a) const {
+      if (Undirected::direction(a)) {
+        return (*_capacity)[a] - (*_flow)[a];
+      } else {
+        return (*_flow)[a];
+      }
+    }
+
+    /// \brief Augments on the given arc in the residual digraph.
+    ///
+    /// Augments on the given arc in the residual digraph. It increases
+    /// or decreases the flow value on the original arc according to 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 \c true if the given residual arc is a forward arc.
+    ///
+    /// Returns \c true if the given residual arc has the same orientation
+    /// as the original arc, i.e. it is a so called forward arc.
+    static bool forward(const Arc& a) {
+      return Undirected::direction(a);
+    }
+
+    /// \brief Returns \c true if the given residual arc is a backward arc.
+    ///
+    /// Returns \c true if the given residual arc has the opposite orientation
+    /// than the original arc, i.e. it is a so called backward arc.
+    static bool backward(const Arc& a) {
+      return !Undirected::direction(a);
+    }
+
+    /// \brief Returns the forward oriented residual arc.
+    ///
+    /// Returns the forward oriented residual arc related to the given
+    /// arc of the underlying digraph.
+    static Arc forward(const typename Digraph::Arc& a) {
+      return Undirected::direct(a, true);
+    }
+
+    /// \brief Returns the backward oriented residual arc.
+    ///
+    /// Returns the backward oriented residual arc related to the given
+    /// arc of the underlying digraph.
+    static Arc backward(const typename Digraph::Arc& a) {
+      return Undirected::direct(a, false);
+    }
+
+    /// \brief Residual capacity map.
+    ///
+    /// This map adaptor class can be used for obtaining the residual
+    /// capacities as an arc map of the residual digraph.
+    /// Its value type is inherited from the capacity map.
+    class ResidualCapacity {
+    protected:
+      const Adaptor* _adaptor;
+    public:
+      /// The key type of the map
+      typedef Arc Key;
+      /// The value type of the map
+      typedef typename CapacityMap::Value Value;
+
+      /// Constructor
+      ResidualCapacity(const Adaptor& adaptor) : _adaptor(&adaptor) {}
+
+      /// Returns the value associated with the given residual arc
+      Value operator[](const Arc& a) const {
+        return _adaptor->residualCapacity(a);
+      }
+
+    };
+
+    /// \brief Returns a residual capacity map
+    ///
+    /// This function just returns a residual capacity map.
+    ResidualCapacity residualCapacity() const {
+      return ResidualCapacity(*this);
+    }
+
+  };
+
+  /// \brief Returns a (read-only) Residual adaptor
+  ///
+  /// This function just returns a (read-only) \ref Residual adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates Residual
+  template<typename GR, typename CM, typename FM>
+  Residual<GR, CM, FM> residual(const GR& digraph,
+                                const CM& capacity_map,
+                                FM& flow_map) {
+    return Residual<GR, CM, FM> (digraph, capacity_map, flow_map);
+  }
+
+
+  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 ArcNumTag;
+    int arcNum() const {
+      return countArcs(*_digraph) + countNodes(*_digraph);
+    }
+
+    typedef True FindArcTag;
+    Arc findArc(const Node& u, const Node& v,
+                const Arc& prev = INVALID) const {
+      if (inNode(u) && outNode(v)) {
+        if (static_cast<const DigraphNode&>(u) ==
+            static_cast<const DigraphNode&>(v) && prev == INVALID) {
+          return Arc(u);
+        }
+      }
+      else if (outNode(u) && 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;
+      typedef typename MapTraits<NodeImpl>::ReferenceMapTag ReferenceMapTag;
+      typedef typename MapTraits<NodeImpl>::ReturnValue ReturnValue;
+      typedef typename MapTraits<NodeImpl>::ConstReturnValue ConstReturnValue;
+      typedef typename MapTraits<NodeImpl>::ReturnValue Reference;
+      typedef typename MapTraits<NodeImpl>::ConstReturnValue ConstReference;
+
+      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); }
+      }
+
+      ReturnValue operator[](const Node& key) {
+        if (Adaptor::inNode(key)) { return _in_map[key]; }
+        else { return _out_map[key]; }
+      }
+
+      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;
+      typedef typename MapTraits<ArcImpl>::ReferenceMapTag ReferenceMapTag;
+      typedef typename MapTraits<ArcImpl>::ReturnValue ReturnValue;
+      typedef typename MapTraits<ArcImpl>::ConstReturnValue ConstReturnValue;
+      typedef typename MapTraits<ArcImpl>::ReturnValue Reference;
+      typedef typename MapTraits<ArcImpl>::ConstReturnValue ConstReference;
+
+      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);
+        }
+      }
+
+      ReturnValue operator[](const Arc& key) {
+        if (Adaptor::origArc(key)) {
+          return _arc_map[key._item.first()];
+        } else {
+          return _node_map[key._item.second()];
+        }
+      }
+
+      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 Adaptor class for splitting the nodes of a digraph.
+  ///
+  /// SplitNodes adaptor can be used for splitting each node into an
+  /// \e in-node and an \e out-node in a digraph. Formaly, the adaptor
+  /// replaces each node \f$ u \f$ 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, then the
+  /// new target of the arc will be \f$ u_{in} \f$ and similarly the
+  /// source of each original \f$ (u, v) \f$ arc will be \f$ u_{out} \f$.
+  /// The adaptor adds an additional \e bind \e arc from \f$ u_{in} \f$
+  /// to \f$ u_{out} \f$ for each node \f$ u \f$ of the original digraph.
+  ///
+  /// The aim of this class is running an algorithm with respect to node
+  /// costs or capacities if the algorithm considers only arc costs or
+  /// capacities directly.
+  /// In this case you can use \c SplitNodes adaptor, and set the node
+  /// costs/capacities of the original digraph to the \e bind \e arcs
+  /// in the adaptor.
+  ///
+  /// \tparam GR The type of the adapted digraph.
+  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
+  /// It is implicitly \c const.
+  ///
+  /// \note The \c Node type of this adaptor is converible to the \c Node
+  /// type of the adapted digraph.
+  template <typename GR>
+#ifdef DOXYGEN
+  class SplitNodes {
+#else
+  class SplitNodes
+    : public DigraphAdaptorExtender<SplitNodesBase<const GR> > {
+#endif
+  public:
+    typedef GR Digraph;
+    typedef DigraphAdaptorExtender<SplitNodesBase<const GR> > Parent;
+
+    typedef typename Digraph::Node DigraphNode;
+    typedef typename Digraph::Arc DigraphArc;
+
+    typedef typename Parent::Node Node;
+    typedef typename Parent::Arc Arc;
+
+    /// \brief Constructor
+    ///
+    /// Constructor of the adaptor.
+    SplitNodes(const Digraph& g) {
+      Parent::setDigraph(g);
+    }
+
+    /// \brief Returns \c true if the given node is an in-node.
+    ///
+    /// Returns \c true if the given node is an in-node.
+    static bool inNode(const Node& n) {
+      return Parent::inNode(n);
+    }
+
+    /// \brief Returns \c true if the given node is an out-node.
+    ///
+    /// Returns \c true if the given node is an out-node.
+    static bool outNode(const Node& n) {
+      return Parent::outNode(n);
+    }
+
+    /// \brief Returns \c true if the given arc is an original arc.
+    ///
+    /// Returns \c true if the given arc is one of the arcs in the
+    /// original digraph.
+    static bool origArc(const Arc& a) {
+      return Parent::origArc(a);
+    }
+
+    /// \brief Returns \c true if the given arc is a bind arc.
+    ///
+    /// Returns \c true if the given arc is a bind arc, i.e. it connects
+    /// an in-node and an out-node.
+    static bool bindArc(const Arc& a) {
+      return Parent::bindArc(a);
+    }
+
+    /// \brief Returns the in-node created from the given original node.
+    ///
+    /// Returns the in-node created from the given original node.
+    static Node inNode(const DigraphNode& n) {
+      return Parent::inNode(n);
+    }
+
+    /// \brief Returns the out-node created from the given original node.
+    ///
+    /// Returns the out-node created from the given original node.
+    static Node outNode(const DigraphNode& n) {
+      return Parent::outNode(n);
+    }
+
+    /// \brief Returns the bind arc that corresponds to the given
+    /// original node.
+    ///
+    /// Returns the bind arc in the adaptor that corresponds to the given
+    /// original node, i.e. the arc connecting the in-node and out-node
+    /// of \c n.
+    static Arc arc(const DigraphNode& n) {
+      return Parent::arc(n);
+    }
+
+    /// \brief Returns the arc that corresponds to the given original arc.
+    ///
+    /// Returns the arc in the adaptor that corresponds to the given
+    /// original arc.
+    static Arc arc(const DigraphArc& a) {
+      return Parent::arc(a);
+    }
+
+    /// \brief Node map combined from two original node maps
+    ///
+    /// This map adaptor class adapts two node maps of the original digraph
+    /// to get a node map of the split digraph.
+    /// Its value type is inherited from the first node map type
+    /// (\c InNodeMap).
+    template <typename InNodeMap, typename OutNodeMap>
+    class CombinedNodeMap {
+    public:
+
+      /// The key type of the map
+      typedef Node Key;
+      /// The value type of the map
+      typedef typename InNodeMap::Value Value;
+
+      typedef typename MapTraits<InNodeMap>::ReferenceMapTag ReferenceMapTag;
+      typedef typename MapTraits<InNodeMap>::ReturnValue ReturnValue;
+      typedef typename MapTraits<InNodeMap>::ConstReturnValue ConstReturnValue;
+      typedef typename MapTraits<InNodeMap>::ReturnValue Reference;
+      typedef typename MapTraits<InNodeMap>::ConstReturnValue ConstReference;
+
+      /// Constructor
+      CombinedNodeMap(InNodeMap& in_map, OutNodeMap& out_map)
+        : _in_map(in_map), _out_map(out_map) {}
+
+      /// Returns the value associated with the given key.
+      Value operator[](const Key& key) const {
+        if (Parent::inNode(key)) {
+          return _in_map[key];
+        } else {
+          return _out_map[key];
+        }
+      }
+
+      /// Returns a reference to the value associated with the given key.
+      Value& operator[](const Key& key) {
+        if (Parent::inNode(key)) {
+          return _in_map[key];
+        } else {
+          return _out_map[key];
+        }
+      }
+
+      /// Sets the value associated with the given key.
+      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 Returns a combined node map
+    ///
+    /// This function just returns 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 Arc map combined from an arc map and a node map of the
+    /// original digraph.
+    ///
+    /// This map adaptor class adapts an arc map and a node map of the
+    /// original digraph to get an arc map of the split digraph.
+    /// Its value type is inherited from the original arc map type
+    /// (\c ArcMap).
+    template <typename ArcMap, typename NodeMap>
+    class CombinedArcMap {
+    public:
+
+      /// The key type of the map
+      typedef Arc Key;
+      /// The value type of the map
+      typedef typename ArcMap::Value Value;
+
+      typedef typename MapTraits<ArcMap>::ReferenceMapTag ReferenceMapTag;
+      typedef typename MapTraits<ArcMap>::ReturnValue ReturnValue;
+      typedef typename MapTraits<ArcMap>::ConstReturnValue ConstReturnValue;
+      typedef typename MapTraits<ArcMap>::ReturnValue Reference;
+      typedef typename MapTraits<ArcMap>::ConstReturnValue ConstReference;
+
+      /// Constructor
+      CombinedArcMap(ArcMap& arc_map, NodeMap& node_map)
+        : _arc_map(arc_map), _node_map(node_map) {}
+
+      /// Returns the value associated with the given key.
+      Value operator[](const Key& arc) const {
+        if (Parent::origArc(arc)) {
+          return _arc_map[arc];
+        } else {
+          return _node_map[arc];
+        }
+      }
+
+      /// Returns a reference to the value associated with the given key.
+      Value& operator[](const Key& arc) {
+        if (Parent::origArc(arc)) {
+          return _arc_map[arc];
+        } else {
+          return _node_map[arc];
+        }
+      }
+
+      /// Sets the value associated with the given key.
+      void set(const Arc& arc, const Value& val) {
+        if (Parent::origArc(arc)) {
+          _arc_map.set(arc, val);
+        } else {
+          _node_map.set(arc, val);
+        }
+      }
+
+    private:
+      ArcMap& _arc_map;
+      NodeMap& _node_map;
+    };
+
+    /// \brief Returns a combined arc map
+    ///
+    /// This function just returns a combined arc map.
+    template <typename ArcMap, typename NodeMap>
+    static CombinedArcMap<ArcMap, NodeMap>
+    combinedArcMap(ArcMap& arc_map, NodeMap& node_map) {
+      return CombinedArcMap<ArcMap, NodeMap>(arc_map, node_map);
+    }
+
+    template <typename ArcMap, typename NodeMap>
+    static CombinedArcMap<const ArcMap, NodeMap>
+    combinedArcMap(const ArcMap& arc_map, NodeMap& node_map) {
+      return CombinedArcMap<const ArcMap, NodeMap>(arc_map, node_map);
+    }
+
+    template <typename ArcMap, typename NodeMap>
+    static CombinedArcMap<ArcMap, const NodeMap>
+    combinedArcMap(ArcMap& arc_map, const NodeMap& node_map) {
+      return CombinedArcMap<ArcMap, const NodeMap>(arc_map, node_map);
+    }
+
+    template <typename ArcMap, typename NodeMap>
+    static CombinedArcMap<const ArcMap, const NodeMap>
+    combinedArcMap(const ArcMap& arc_map, const NodeMap& node_map) {
+      return CombinedArcMap<const ArcMap, const NodeMap>(arc_map, node_map);
+    }
+
+  };
+
+  /// \brief Returns a (read-only) SplitNodes adaptor
+  ///
+  /// This function just returns a (read-only) \ref SplitNodes adaptor.
+  /// \ingroup graph_adaptors
+  /// \relates SplitNodes
+  template<typename GR>
+  SplitNodes<GR>
+  splitNodes(const GR& digraph) {
+    return SplitNodes<GR>(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 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).
@@ -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
 
     ///@{
@@ -232,4 +226,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///PredMap type.
+    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetPredMap : public Bfs< Digraph, SetPredMapTraits<T> > {
@@ -251,4 +246,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///DistMap type.
+    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetDistMap : public Bfs< Digraph, SetDistMapTraits<T> > {
@@ -270,4 +266,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///ReachedMap type.
+    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     template <class T>
     struct SetReachedMap : public Bfs< Digraph, SetReachedMapTraits<T> > {
@@ -289,4 +286,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///ProcessedMap type.
+    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetProcessedMap : public Bfs< Digraph, SetProcessedMapTraits<T> > {
@@ -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
@@ -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 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).
@@ -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.
@@ -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 511)
+++ 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 LEMON_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 455)
+++ lemon/bits/graph_adaptor_extender.h	(revision 455)
@@ -0,0 +1,399 @@
+/* -*- 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);
+    }
+
+  };
+
+  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/solver_bits.h
===================================================================
--- lemon/bits/solver_bits.h	(revision 459)
+++ lemon/bits/solver_bits.h	(revision 459)
@@ -0,0 +1,191 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * 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_SOLVER_BITS_H
+#define LEMON_BITS_SOLVER_BITS_H
+
+namespace lemon {
+
+  namespace _solver_bits {
+
+    class VarIndex {
+    private:
+      struct ItemT {
+        int prev, next;
+        int index;
+      };
+      std::vector<ItemT> items;
+      int first_item, last_item, first_free_item;
+
+      std::vector<int> cross;
+
+    public:
+
+      VarIndex()
+        : first_item(-1), last_item(-1), first_free_item(-1) {
+      }
+
+      void clear() {
+        first_item = -1;
+        first_free_item = -1;
+        items.clear();
+        cross.clear();
+      }
+
+      int addIndex(int idx) {
+        int n;
+        if (first_free_item == -1) {
+          n = items.size();
+          items.push_back(ItemT());
+        } else {
+          n = first_free_item;
+          first_free_item = items[n].next;
+          if (first_free_item != -1) {
+            items[first_free_item].prev = -1;
+          }
+        }
+        items[n].index = idx;
+        if (static_cast<int>(cross.size()) <= idx) {
+          cross.resize(idx + 1, -1);
+        }
+        cross[idx] = n;
+
+        items[n].prev = last_item;
+        items[n].next = -1;
+        if (last_item != -1) {
+          items[last_item].next = n;
+        } else {
+          first_item = n;
+        }
+        last_item = n;
+
+        return n;
+      }
+
+      int addIndex(int idx, int n) {
+        while (n >= static_cast<int>(items.size())) {
+          items.push_back(ItemT());
+          items.back().prev = -1;
+          items.back().next = first_free_item;
+          if (first_free_item != -1) {
+            items[first_free_item].prev = items.size() - 1;
+          }
+          first_free_item = items.size() - 1;
+        }
+        if (items[n].next != -1) {
+          items[items[n].next].prev = items[n].prev;
+        }
+        if (items[n].prev != -1) {
+          items[items[n].prev].next = items[n].next;
+        } else {
+          first_free_item = items[n].next;
+        }
+
+        items[n].index = idx;
+        if (static_cast<int>(cross.size()) <= idx) {
+          cross.resize(idx + 1, -1);
+        }
+        cross[idx] = n;
+
+        items[n].prev = last_item;
+        items[n].next = -1;
+        if (last_item != -1) {
+          items[last_item].next = n;
+        } else {
+          first_item = n;
+        }
+        last_item = n;
+
+        return n;
+      }
+
+      void eraseIndex(int idx) {
+        int n = cross[idx];
+
+        if (items[n].prev != -1) {
+          items[items[n].prev].next = items[n].next;
+        } else {
+          first_item = items[n].next;
+        }
+        if (items[n].next != -1) {
+          items[items[n].next].prev = items[n].prev;
+        } else {
+          last_item = items[n].prev;
+        }
+
+        if (first_free_item != -1) {
+          items[first_free_item].prev = n;
+        }
+        items[n].next = first_free_item;
+        items[n].prev = -1;
+        first_free_item = n;
+
+        while (!cross.empty() && cross.back() == -1) {
+          cross.pop_back();
+        }
+      }
+
+      int maxIndex() const {
+        return cross.size() - 1;
+      }
+
+      void shiftIndices(int idx) {
+        for (int i = idx + 1; i < static_cast<int>(cross.size()); ++i) {
+          cross[i - 1] = cross[i];
+          if (cross[i] != -1) {
+            --items[cross[i]].index;
+          }
+        }
+        cross.back() = -1;
+        cross.pop_back();
+        while (!cross.empty() && cross.back() == -1) {
+          cross.pop_back();
+        }
+      }
+
+      void relocateIndex(int idx, int jdx) {
+        cross[idx] = cross[jdx];
+        items[cross[jdx]].index = idx;
+        cross[jdx] = -1;
+
+        while (!cross.empty() && cross.back() == -1) {
+          cross.pop_back();
+        }
+      }
+
+      int operator[](int idx) const {
+        return cross[idx];
+      }
+
+      int operator()(int fdx) const {
+        return items[fdx].index;
+      }
+
+      void firstItem(int& fdx) const {
+        fdx = first_item;
+      }
+
+      void nextItem(int& fdx) const {
+        fdx = items[fdx].next;
+      }
+
+    };
+  }
+}
+
+#endif
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 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,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.
@@ -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 493)
+++ 	(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 491)
+++ 	(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 440)
+++ lemon/circulation.h	(revision 440)
@@ -0,0 +1,755 @@
+/* -*- 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 _Diraph Digraph type.
+  /// \tparam _LCapMap Lower bound capacity map type.
+  /// \tparam _UCapMap Upper bound capacity map type.
+  /// \tparam _DeltaMap Delta map type.
+  template <typename _Diraph, typename _LCapMap,
+            typename _UCapMap, typename _DeltaMap>
+  struct CirculationDefaultTraits {
+
+    /// \brief The type of the digraph the algorithm runs on.
+    typedef _Diraph 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 _LCapMap 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 _UCapMap 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 _DeltaMap 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 _Digraph The type of the digraph the algorithm runs on.
+     \tparam _LCapMap The type of the lower bound capacity map. The default
+     map type is \ref concepts::Digraph::ArcMap "_Digraph::ArcMap<int>".
+     \tparam _UCapMap The type of the upper bound capacity map. The default
+     map type is \c _LCapMap.
+     \tparam _DeltaMap The type of the map that stores the lower bound
+     for the supply of the nodes. The default map type is
+     \c _Digraph::ArcMap<_UCapMap::Value>.
+  */
+#ifdef DOXYGEN
+template< typename _Digraph,
+          typename _LCapMap,
+          typename _UCapMap,
+          typename _DeltaMap,
+          typename _Traits >
+#else
+template< typename _Digraph,
+          typename _LCapMap = typename _Digraph::template ArcMap<int>,
+          typename _UCapMap = _LCapMap,
+          typename _DeltaMap = typename _Digraph::
+                               template NodeMap<typename _UCapMap::Value>,
+          typename _Traits=CirculationDefaultTraits<_Digraph, _LCapMap,
+                                                    _UCapMap, _DeltaMap> >
+#endif
+  class Circulation {
+  public:
+
+    ///The \ref CirculationDefaultTraits "traits class" of the algorithm.
+    typedef _Traits 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 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/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 511)
+++ 	(revision )
@@ -1,1 +1,0 @@
-#cmakedefine LEMON_HAVE_LONG_LONG 1
Index: lemon/config.h.in
===================================================================
--- lemon/config.h.in	(revision 511)
+++ lemon/config.h.in	(revision 459)
@@ -1,8 +1,17 @@
+/* Define to 1 if you have any LP solver. */
+#undef HAVE_LP
+
+/* Define to 1 if you have any MIP solver. */
+#undef HAVE_MIP
+
 /* Define to 1 if you have CPLEX. */
-#undef LEMON_HAVE_CPLEX
+#undef HAVE_CPLEX
 
 /* Define to 1 if you have GLPK. */
-#undef LEMON_HAVE_GLPK
+#undef HAVE_GLPK
 
-/* Define to 1 if you have long long */
-#undef LEMON_HAVE_LONG_LONG
+/* Define to 1 if you have SOPLEX */
+#undef HAVE_SOPLEX
+
+/* Define to 1 if you have CLP */
+#undef HAVE_CLP
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 512)
+++ 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/config.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 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).
@@ -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;
 
@@ -231,4 +225,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///PredMap type.
+    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetPredMap : public Dfs<Digraph, SetPredMapTraits<T> > {
@@ -250,4 +245,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///DistMap type.
+    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetDistMap : public Dfs< Digraph, SetDistMapTraits<T> > {
@@ -269,4 +265,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///ReachedMap type.
+    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     template <class T>
     struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits<T> > {
@@ -288,4 +285,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///ProcessedMap type.
+    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetProcessedMap : public Dfs< Digraph, SetProcessedMapTraits<T> > {
@@ -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
@@ -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 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).
@@ -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>
@@ -227,5 +220,5 @@
     typedef typename TR::OperationTraits OperationTraits;
 
-    ///The traits class.
+    ///The \ref DijkstraDefaultTraits "traits class" of the algorithm.
     typedef TR Traits;
 
@@ -309,4 +302,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///PredMap type.
+    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetPredMap
@@ -329,4 +323,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///DistMap type.
+    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetDistMap
@@ -349,4 +344,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///ProcessedMap type.
+    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetProcessedMap
@@ -389,8 +385,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 +412,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
@@ -487,7 +493,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 +511,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 +530,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 +548,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 +579,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()
     {
@@ -659,15 +667,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 +797,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 +808,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 +818,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 +829,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 +843,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 +860,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 +870,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 +887,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 +897,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 +1081,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 +1277,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 491)
+++ 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 498)
+++ 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 498)
+++ 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/lp.h
===================================================================
--- lemon/lp.h	(revision 459)
+++ lemon/lp.h	(revision 459)
@@ -0,0 +1,93 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * 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_LP_H
+#define LEMON_LP_H
+
+#include<lemon/config.h>
+
+
+#ifdef HAVE_GLPK
+#include <lemon/lp_glpk.h>
+#elif HAVE_CPLEX
+#include <lemon/lp_cplex.h>
+#elif HAVE_SOPLEX
+#include <lemon/lp_soplex.h>
+#elif HAVE_CLP
+#include <lemon/lp_clp.h>
+#endif
+
+///\file
+///\brief Defines a default LP solver
+///\ingroup lp_group
+namespace lemon {
+
+#ifdef DOXYGEN
+  ///The default LP solver identifier
+
+  ///The default LP solver identifier.
+  ///\ingroup lp_group
+  ///
+  ///Currently, the possible values are \c LP_GLPK, \c LP_CPLEX, \c
+  ///LP_SOPLEX or \c LP_CLP
+#define LEMON_DEFAULT_LP SOLVER
+  ///The default LP solver
+
+  ///The default LP solver.
+  ///\ingroup lp_group
+  ///
+  ///Currently, it is either \c LpGlpk, \c LpCplex, \c LpSoplex or \c LpClp
+  typedef LpGlpk Lp;
+
+  ///The default MIP solver identifier
+
+  ///The default MIP solver identifier.
+  ///\ingroup lp_group
+  ///
+  ///Currently, the possible values are \c MIP_GLPK or \c MIP_CPLEX
+#define LEMON_DEFAULT_MIP SOLVER
+  ///The default MIP solver.
+
+  ///The default MIP solver.
+  ///\ingroup lp_group
+  ///
+  ///Currently, it is either \c MipGlpk or \c MipCplex
+  typedef MipGlpk Mip;
+#else
+#ifdef HAVE_GLPK
+# define LEMON_DEFAULT_LP LP_GLPK
+  typedef LpGlpk Lp;
+# define LEMON_DEFAULT_MIP MIP_GLPK
+  typedef MipGlpk Mip;
+#elif HAVE_CPLEX
+# define LEMON_DEFAULT_LP LP_CPLEX
+  typedef LpCplex Lp;
+# define LEMON_DEFAULT_MIP MIP_CPLEX
+  typedef MipCplex Mip;
+#elif HAVE_SOPLEX
+# define DEFAULT_LP LP_SOPLEX
+  typedef LpSoplex Lp;
+#elif HAVE_CLP
+# define DEFAULT_LP LP_CLP
+  typedef LpClp Lp;  
+#endif
+#endif
+
+} //namespace lemon
+
+#endif //LEMON_LP_H
Index: lemon/lp_base.cc
===================================================================
--- lemon/lp_base.cc	(revision 459)
+++ lemon/lp_base.cc	(revision 459)
@@ -0,0 +1,28 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * 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 The implementation of the LP solver interface.
+
+#include <lemon/lp_base.h>
+namespace lemon {
+
+  const LpBase::Value LpBase::INF = std::numeric_limits<Value>::infinity();
+  const LpBase::Value LpBase::NaN = std::numeric_limits<Value>::quiet_NaN();
+
+} //namespace lemon
Index: lemon/lp_base.h
===================================================================
--- lemon/lp_base.h	(revision 459)
+++ lemon/lp_base.h	(revision 459)
@@ -0,0 +1,2080 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * 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_LP_BASE_H
+#define LEMON_LP_BASE_H
+
+#include<iostream>
+#include<vector>
+#include<map>
+#include<limits>
+#include<lemon/math.h>
+
+#include<lemon/error.h>
+#include<lemon/assert.h>
+
+#include<lemon/core.h>
+#include<lemon/bits/solver_bits.h>
+
+///\file
+///\brief The interface of the LP solver interface.
+///\ingroup lp_group
+namespace lemon {
+
+  ///Common base class for LP and MIP solvers
+
+  ///Usually this class is not used directly, please use one of the concrete
+  ///implementations of the solver interface.
+  ///\ingroup lp_group
+  class LpBase {
+
+  protected:
+
+    _solver_bits::VarIndex rows;
+    _solver_bits::VarIndex cols;
+
+  public:
+
+    ///Possible outcomes of an LP solving procedure
+    enum SolveExitStatus {
+      ///This means that the problem has been successfully solved: either
+      ///an optimal solution has been found or infeasibility/unboundedness
+      ///has been proved.
+      SOLVED = 0,
+      ///Any other case (including the case when some user specified
+      ///limit has been exceeded)
+      UNSOLVED = 1
+    };
+
+    ///Direction of the optimization
+    enum Sense {
+      /// Minimization
+      MIN,
+      /// Maximization
+      MAX
+    };
+
+    ///The floating point type used by the solver
+    typedef double Value;
+    ///The infinity constant
+    static const Value INF;
+    ///The not a number constant
+    static const Value NaN;
+
+    friend class Col;
+    friend class ColIt;
+    friend class Row;
+    friend class RowIt;
+
+    ///Refer to a column of the LP.
+
+    ///This type is used to refer to a column of the LP.
+    ///
+    ///Its value remains valid and correct even after the addition or erase of
+    ///other columns.
+    ///
+    ///\note This class is similar to other Item types in LEMON, like
+    ///Node and Arc types in digraph.
+    class Col {
+      friend class LpBase;
+    protected:
+      int _id;
+      explicit Col(int id) : _id(id) {}
+    public:
+      typedef Value ExprValue;
+      typedef True LpCol;
+      /// Default constructor
+      
+      /// \warning The default constructor sets the Col to an
+      /// undefined value.
+      Col() {}
+      /// Invalid constructor \& conversion.
+      
+      /// This constructor initializes the Col to be invalid.
+      /// \sa Invalid for more details.      
+      Col(const Invalid&) : _id(-1) {}
+      /// Equality operator
+
+      /// Two \ref Col "Col"s are equal if and only if they point to
+      /// the same LP column or both are invalid.
+      bool operator==(Col c) const  {return _id == c._id;}
+      /// Inequality operator
+
+      /// \sa operator==(Col c)
+      ///
+      bool operator!=(Col c) const  {return _id != c._id;}
+      /// Artificial ordering operator.
+
+      /// To allow the use of this object in std::map or similar
+      /// associative container we require this.
+      ///
+      /// \note This operator only have to define some strict ordering of
+      /// the items; this order has nothing to do with the iteration
+      /// ordering of the items.
+      bool operator<(Col c) const  {return _id < c._id;}
+    };
+
+    ///Iterator for iterate over the columns of an LP problem
+
+    /// Its usage is quite simple, for example you can count the number
+    /// of columns in an LP \c lp:
+    ///\code
+    /// int count=0;
+    /// for (LpBase::ColIt c(lp); c!=INVALID; ++c) ++count;
+    ///\endcode
+    class ColIt : public Col {
+      const LpBase *_solver;
+    public:
+      /// Default constructor
+      
+      /// \warning The default constructor sets the iterator
+      /// to an undefined value.
+      ColIt() {}
+      /// Sets the iterator to the first Col
+      
+      /// Sets the iterator to the first Col.
+      ///
+      ColIt(const LpBase &solver) : _solver(&solver)
+      {
+        _solver->cols.firstItem(_id);
+      }
+      /// Invalid constructor \& conversion
+      
+      /// Initialize the iterator to be invalid.
+      /// \sa Invalid for more details.
+      ColIt(const Invalid&) : Col(INVALID) {}
+      /// Next column
+      
+      /// Assign the iterator to the next column.
+      ///
+      ColIt &operator++()
+      {
+        _solver->cols.nextItem(_id);
+        return *this;
+      }
+    };
+
+    /// \brief Returns the ID of the column.
+    static int id(const Col& col) { return col._id; }
+    /// \brief Returns the column with the given ID.
+    ///
+    /// \pre The argument should be a valid column ID in the LP problem.
+    static Col colFromId(int id) { return Col(id); }
+
+    ///Refer to a row of the LP.
+
+    ///This type is used to refer to a row of the LP.
+    ///
+    ///Its value remains valid and correct even after the addition or erase of
+    ///other rows.
+    ///
+    ///\note This class is similar to other Item types in LEMON, like
+    ///Node and Arc types in digraph.
+    class Row {
+      friend class LpBase;
+    protected:
+      int _id;
+      explicit Row(int id) : _id(id) {}
+    public:
+      typedef Value ExprValue;
+      typedef True LpRow;
+      /// Default constructor
+      
+      /// \warning The default constructor sets the Row to an
+      /// undefined value.
+      Row() {}
+      /// Invalid constructor \& conversion.
+      
+      /// This constructor initializes the Row to be invalid.
+      /// \sa Invalid for more details.      
+      Row(const Invalid&) : _id(-1) {}
+      /// Equality operator
+
+      /// Two \ref Row "Row"s are equal if and only if they point to
+      /// the same LP row or both are invalid.
+      bool operator==(Row r) const  {return _id == r._id;}
+      /// Inequality operator
+      
+      /// \sa operator==(Row r)
+      ///
+      bool operator!=(Row r) const  {return _id != r._id;}
+      /// Artificial ordering operator.
+
+      /// To allow the use of this object in std::map or similar
+      /// associative container we require this.
+      ///
+      /// \note This operator only have to define some strict ordering of
+      /// the items; this order has nothing to do with the iteration
+      /// ordering of the items.
+      bool operator<(Row r) const  {return _id < r._id;}
+    };
+
+    ///Iterator for iterate over the rows of an LP problem
+
+    /// Its usage is quite simple, for example you can count the number
+    /// of rows in an LP \c lp:
+    ///\code
+    /// int count=0;
+    /// for (LpBase::RowIt c(lp); c!=INVALID; ++c) ++count;
+    ///\endcode
+    class RowIt : public Row {
+      const LpBase *_solver;
+    public:
+      /// Default constructor
+      
+      /// \warning The default constructor sets the iterator
+      /// to an undefined value.
+      RowIt() {}
+      /// Sets the iterator to the first Row
+      
+      /// Sets the iterator to the first Row.
+      ///
+      RowIt(const LpBase &solver) : _solver(&solver)
+      {
+        _solver->rows.firstItem(_id);
+      }
+      /// Invalid constructor \& conversion
+      
+      /// Initialize the iterator to be invalid.
+      /// \sa Invalid for more details.
+      RowIt(const Invalid&) : Row(INVALID) {}
+      /// Next row
+      
+      /// Assign the iterator to the next row.
+      ///
+      RowIt &operator++()
+      {
+        _solver->rows.nextItem(_id);
+        return *this;
+      }
+    };
+
+    /// \brief Returns the ID of the row.
+    static int id(const Row& row) { return row._id; }
+    /// \brief Returns the row with the given ID.
+    ///
+    /// \pre The argument should be a valid row ID in the LP problem.
+    static Row rowFromId(int id) { return Row(id); }
+
+  public:
+
+    ///Linear expression of variables and a constant component
+
+    ///This data structure stores a linear expression of the variables
+    ///(\ref Col "Col"s) and also has a constant component.
+    ///
+    ///There are several ways to access and modify the contents of this
+    ///container.
+    ///\code
+    ///e[v]=5;
+    ///e[v]+=12;
+    ///e.erase(v);
+    ///\endcode
+    ///or you can also iterate through its elements.
+    ///\code
+    ///double s=0;
+    ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i)
+    ///  s+=*i * primal(i);
+    ///\endcode
+    ///(This code computes the primal value of the expression).
+    ///- Numbers (<tt>double</tt>'s)
+    ///and variables (\ref Col "Col"s) directly convert to an
+    ///\ref Expr and the usual linear operations are defined, so
+    ///\code
+    ///v+w
+    ///2*v-3.12*(v-w/2)+2
+    ///v*2.1+(3*v+(v*12+w+6)*3)/2
+    ///\endcode
+    ///are valid expressions.
+    ///The usual assignment operations are also defined.
+    ///\code
+    ///e=v+w;
+    ///e+=2*v-3.12*(v-w/2)+2;
+    ///e*=3.4;
+    ///e/=5;
+    ///\endcode
+    ///- The constant member can be set and read by dereference
+    ///  operator (unary *)
+    ///
+    ///\code
+    ///*e=12;
+    ///double c=*e;
+    ///\endcode
+    ///
+    ///\sa Constr
+    class Expr {
+      friend class LpBase;
+    public:
+      /// The key type of the expression
+      typedef LpBase::Col Key;
+      /// The value type of the expression
+      typedef LpBase::Value Value;
+
+    protected:
+      Value const_comp;
+      std::map<int, Value> comps;
+
+    public:
+      typedef True SolverExpr;
+      /// Default constructor
+      
+      /// Construct an empty expression, the coefficients and
+      /// the constant component are initialized to zero.
+      Expr() : const_comp(0) {}
+      /// Construct an expression from a column
+
+      /// Construct an expression, which has a term with \c c variable
+      /// and 1.0 coefficient.
+      Expr(const Col &c) : const_comp(0) {
+        typedef std::map<int, Value>::value_type pair_type;
+        comps.insert(pair_type(id(c), 1));
+      }
+      /// Construct an expression from a constant
+
+      /// Construct an expression, which's constant component is \c v.
+      ///
+      Expr(const Value &v) : const_comp(v) {}
+      /// Returns the coefficient of the column
+      Value operator[](const Col& c) const {
+        std::map<int, Value>::const_iterator it=comps.find(id(c));
+        if (it != comps.end()) {
+          return it->second;
+        } else {
+          return 0;
+        }
+      }
+      /// Returns the coefficient of the column
+      Value& operator[](const Col& c) {
+        return comps[id(c)];
+      }
+      /// Sets the coefficient of the column
+      void set(const Col &c, const Value &v) {
+        if (v != 0.0) {
+          typedef std::map<int, Value>::value_type pair_type;
+          comps.insert(pair_type(id(c), v));
+        } else {
+          comps.erase(id(c));
+        }
+      }
+      /// Returns the constant component of the expression
+      Value& operator*() { return const_comp; }
+      /// Returns the constant component of the expression
+      const Value& operator*() const { return const_comp; }
+      /// \brief Removes the coefficients which's absolute value does
+      /// not exceed \c epsilon. It also sets to zero the constant
+      /// component, if it does not exceed epsilon in absolute value.
+      void simplify(Value epsilon = 0.0) {
+        std::map<int, Value>::iterator it=comps.begin();
+        while (it != comps.end()) {
+          std::map<int, Value>::iterator jt=it;
+          ++jt;
+          if (std::fabs((*it).second) <= epsilon) comps.erase(it);
+          it=jt;
+        }
+        if (std::fabs(const_comp) <= epsilon) const_comp = 0;
+      }
+
+      void simplify(Value epsilon = 0.0) const {
+        const_cast<Expr*>(this)->simplify(epsilon);
+      }
+
+      ///Sets all coefficients and the constant component to 0.
+      void clear() {
+        comps.clear();
+        const_comp=0;
+      }
+
+      ///Compound assignment
+      Expr &operator+=(const Expr &e) {
+        for (std::map<int, Value>::const_iterator it=e.comps.begin();
+             it!=e.comps.end(); ++it)
+          comps[it->first]+=it->second;
+        const_comp+=e.const_comp;
+        return *this;
+      }
+      ///Compound assignment
+      Expr &operator-=(const Expr &e) {
+        for (std::map<int, Value>::const_iterator it=e.comps.begin();
+             it!=e.comps.end(); ++it)
+          comps[it->first]-=it->second;
+        const_comp-=e.const_comp;
+        return *this;
+      }
+      ///Multiply with a constant
+      Expr &operator*=(const Value &v) {
+        for (std::map<int, Value>::iterator it=comps.begin();
+             it!=comps.end(); ++it)
+          it->second*=v;
+        const_comp*=v;
+        return *this;
+      }
+      ///Division with a constant
+      Expr &operator/=(const Value &c) {
+        for (std::map<int, Value>::iterator it=comps.begin();
+             it!=comps.end(); ++it)
+          it->second/=c;
+        const_comp/=c;
+        return *this;
+      }
+
+      ///Iterator over the expression
+      
+      ///The iterator iterates over the terms of the expression. 
+      /// 
+      ///\code
+      ///double s=0;
+      ///for(LpBase::Expr::CoeffIt i(e);i!=INVALID;++i)
+      ///  s+= *i * primal(i);
+      ///\endcode
+      class CoeffIt {
+      private:
+
+        std::map<int, Value>::iterator _it, _end;
+
+      public:
+
+        /// Sets the iterator to the first term
+        
+        /// Sets the iterator to the first term of the expression.
+        ///
+        CoeffIt(Expr& e)
+          : _it(e.comps.begin()), _end(e.comps.end()){}
+
+        /// Convert the iterator to the column of the term
+        operator Col() const {
+          return colFromId(_it->first);
+        }
+
+        /// Returns the coefficient of the term
+        Value& operator*() { return _it->second; }
+
+        /// Returns the coefficient of the term
+        const Value& operator*() const { return _it->second; }
+        /// Next term
+        
+        /// Assign the iterator to the next term.
+        ///
+        CoeffIt& operator++() { ++_it; return *this; }
+
+        /// Equality operator
+        bool operator==(Invalid) const { return _it == _end; }
+        /// Inequality operator
+        bool operator!=(Invalid) const { return _it != _end; }
+      };
+
+      /// Const iterator over the expression
+      
+      ///The iterator iterates over the terms of the expression. 
+      /// 
+      ///\code
+      ///double s=0;
+      ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i)
+      ///  s+=*i * primal(i);
+      ///\endcode
+      class ConstCoeffIt {
+      private:
+
+        std::map<int, Value>::const_iterator _it, _end;
+
+      public:
+
+        /// Sets the iterator to the first term
+        
+        /// Sets the iterator to the first term of the expression.
+        ///
+        ConstCoeffIt(const Expr& e)
+          : _it(e.comps.begin()), _end(e.comps.end()){}
+
+        /// Convert the iterator to the column of the term
+        operator Col() const {
+          return colFromId(_it->first);
+        }
+
+        /// Returns the coefficient of the term
+        const Value& operator*() const { return _it->second; }
+
+        /// Next term
+        
+        /// Assign the iterator to the next term.
+        ///
+        ConstCoeffIt& operator++() { ++_it; return *this; }
+
+        /// Equality operator
+        bool operator==(Invalid) const { return _it == _end; }
+        /// Inequality operator
+        bool operator!=(Invalid) const { return _it != _end; }
+      };
+
+    };
+
+    ///Linear constraint
+
+    ///This data stucture represents a linear constraint in the LP.
+    ///Basically it is a linear expression with a lower or an upper bound
+    ///(or both). These parts of the constraint can be obtained by the member
+    ///functions \ref expr(), \ref lowerBound() and \ref upperBound(),
+    ///respectively.
+    ///There are two ways to construct a constraint.
+    ///- You can set the linear expression and the bounds directly
+    ///  by the functions above.
+    ///- The operators <tt>\<=</tt>, <tt>==</tt> and  <tt>\>=</tt>
+    ///  are defined between expressions, or even between constraints whenever
+    ///  it makes sense. Therefore if \c e and \c f are linear expressions and
+    ///  \c s and \c t are numbers, then the followings are valid expressions
+    ///  and thus they can be used directly e.g. in \ref addRow() whenever
+    ///  it makes sense.
+    ///\code
+    ///  e<=s
+    ///  e<=f
+    ///  e==f
+    ///  s<=e<=t
+    ///  e>=t
+    ///\endcode
+    ///\warning The validity of a constraint is checked only at run
+    ///time, so e.g. \ref addRow(<tt>x[1]\<=x[2]<=5</tt>) will
+    ///compile, but will fail an assertion.
+    class Constr
+    {
+    public:
+      typedef LpBase::Expr Expr;
+      typedef Expr::Key Key;
+      typedef Expr::Value Value;
+
+    protected:
+      Expr _expr;
+      Value _lb,_ub;
+    public:
+      ///\e
+      Constr() : _expr(), _lb(NaN), _ub(NaN) {}
+      ///\e
+      Constr(Value lb, const Expr &e, Value ub) :
+        _expr(e), _lb(lb), _ub(ub) {}
+      Constr(const Expr &e) :
+        _expr(e), _lb(NaN), _ub(NaN) {}
+      ///\e
+      void clear()
+      {
+        _expr.clear();
+        _lb=_ub=NaN;
+      }
+
+      ///Reference to the linear expression
+      Expr &expr() { return _expr; }
+      ///Cont reference to the linear expression
+      const Expr &expr() const { return _expr; }
+      ///Reference to the lower bound.
+
+      ///\return
+      ///- \ref INF "INF": the constraint is lower unbounded.
+      ///- \ref NaN "NaN": lower bound has not been set.
+      ///- finite number: the lower bound
+      Value &lowerBound() { return _lb; }
+      ///The const version of \ref lowerBound()
+      const Value &lowerBound() const { return _lb; }
+      ///Reference to the upper bound.
+
+      ///\return
+      ///- \ref INF "INF": the constraint is upper unbounded.
+      ///- \ref NaN "NaN": upper bound has not been set.
+      ///- finite number: the upper bound
+      Value &upperBound() { return _ub; }
+      ///The const version of \ref upperBound()
+      const Value &upperBound() const { return _ub; }
+      ///Is the constraint lower bounded?
+      bool lowerBounded() const {
+        return _lb != -INF && !std::isnan(_lb);
+      }
+      ///Is the constraint upper bounded?
+      bool upperBounded() const {
+        return _ub != INF && !std::isnan(_ub);
+      }
+
+    };
+
+    ///Linear expression of rows
+
+    ///This data structure represents a column of the matrix,
+    ///thas is it strores a linear expression of the dual variables
+    ///(\ref Row "Row"s).
+    ///
+    ///There are several ways to access and modify the contents of this
+    ///container.
+    ///\code
+    ///e[v]=5;
+    ///e[v]+=12;
+    ///e.erase(v);
+    ///\endcode
+    ///or you can also iterate through its elements.
+    ///\code
+    ///double s=0;
+    ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i)
+    ///  s+=*i;
+    ///\endcode
+    ///(This code computes the sum of all coefficients).
+    ///- Numbers (<tt>double</tt>'s)
+    ///and variables (\ref Row "Row"s) directly convert to an
+    ///\ref DualExpr and the usual linear operations are defined, so
+    ///\code
+    ///v+w
+    ///2*v-3.12*(v-w/2)
+    ///v*2.1+(3*v+(v*12+w)*3)/2
+    ///\endcode
+    ///are valid \ref DualExpr dual expressions.
+    ///The usual assignment operations are also defined.
+    ///\code
+    ///e=v+w;
+    ///e+=2*v-3.12*(v-w/2);
+    ///e*=3.4;
+    ///e/=5;
+    ///\endcode
+    ///
+    ///\sa Expr
+    class DualExpr {
+      friend class LpBase;
+    public:
+      /// The key type of the expression
+      typedef LpBase::Row Key;
+      /// The value type of the expression
+      typedef LpBase::Value Value;
+
+    protected:
+      std::map<int, Value> comps;
+
+    public:
+      typedef True SolverExpr;
+      /// Default constructor
+      
+      /// Construct an empty expression, the coefficients are
+      /// initialized to zero.
+      DualExpr() {}
+      /// Construct an expression from a row
+
+      /// Construct an expression, which has a term with \c r dual
+      /// variable and 1.0 coefficient.
+      DualExpr(const Row &r) {
+        typedef std::map<int, Value>::value_type pair_type;
+        comps.insert(pair_type(id(r), 1));
+      }
+      /// Returns the coefficient of the row
+      Value operator[](const Row& r) const {
+        std::map<int, Value>::const_iterator it = comps.find(id(r));
+        if (it != comps.end()) {
+          return it->second;
+        } else {
+          return 0;
+        }
+      }
+      /// Returns the coefficient of the row
+      Value& operator[](const Row& r) {
+        return comps[id(r)];
+      }
+      /// Sets the coefficient of the row
+      void set(const Row &r, const Value &v) {
+        if (v != 0.0) {
+          typedef std::map<int, Value>::value_type pair_type;
+          comps.insert(pair_type(id(r), v));
+        } else {
+          comps.erase(id(r));
+        }
+      }
+      /// \brief Removes the coefficients which's absolute value does
+      /// not exceed \c epsilon. 
+      void simplify(Value epsilon = 0.0) {
+        std::map<int, Value>::iterator it=comps.begin();
+        while (it != comps.end()) {
+          std::map<int, Value>::iterator jt=it;
+          ++jt;
+          if (std::fabs((*it).second) <= epsilon) comps.erase(it);
+          it=jt;
+        }
+      }
+
+      void simplify(Value epsilon = 0.0) const {
+        const_cast<DualExpr*>(this)->simplify(epsilon);
+      }
+
+      ///Sets all coefficients to 0.
+      void clear() {
+        comps.clear();
+      }
+      ///Compound assignment
+      DualExpr &operator+=(const DualExpr &e) {
+        for (std::map<int, Value>::const_iterator it=e.comps.begin();
+             it!=e.comps.end(); ++it)
+          comps[it->first]+=it->second;
+        return *this;
+      }
+      ///Compound assignment
+      DualExpr &operator-=(const DualExpr &e) {
+        for (std::map<int, Value>::const_iterator it=e.comps.begin();
+             it!=e.comps.end(); ++it)
+          comps[it->first]-=it->second;
+        return *this;
+      }
+      ///Multiply with a constant
+      DualExpr &operator*=(const Value &v) {
+        for (std::map<int, Value>::iterator it=comps.begin();
+             it!=comps.end(); ++it)
+          it->second*=v;
+        return *this;
+      }
+      ///Division with a constant
+      DualExpr &operator/=(const Value &v) {
+        for (std::map<int, Value>::iterator it=comps.begin();
+             it!=comps.end(); ++it)
+          it->second/=v;
+        return *this;
+      }
+
+      ///Iterator over the expression
+      
+      ///The iterator iterates over the terms of the expression. 
+      /// 
+      ///\code
+      ///double s=0;
+      ///for(LpBase::DualExpr::CoeffIt i(e);i!=INVALID;++i)
+      ///  s+= *i * dual(i);
+      ///\endcode
+      class CoeffIt {
+      private:
+
+        std::map<int, Value>::iterator _it, _end;
+
+      public:
+
+        /// Sets the iterator to the first term
+        
+        /// Sets the iterator to the first term of the expression.
+        ///
+        CoeffIt(DualExpr& e)
+          : _it(e.comps.begin()), _end(e.comps.end()){}
+
+        /// Convert the iterator to the row of the term
+        operator Row() const {
+          return rowFromId(_it->first);
+        }
+
+        /// Returns the coefficient of the term
+        Value& operator*() { return _it->second; }
+
+        /// Returns the coefficient of the term
+        const Value& operator*() const { return _it->second; }
+
+        /// Next term
+        
+        /// Assign the iterator to the next term.
+        ///
+        CoeffIt& operator++() { ++_it; return *this; }
+
+        /// Equality operator
+        bool operator==(Invalid) const { return _it == _end; }
+        /// Inequality operator
+        bool operator!=(Invalid) const { return _it != _end; }
+      };
+
+      ///Iterator over the expression
+      
+      ///The iterator iterates over the terms of the expression. 
+      /// 
+      ///\code
+      ///double s=0;
+      ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i)
+      ///  s+= *i * dual(i);
+      ///\endcode
+      class ConstCoeffIt {
+      private:
+
+        std::map<int, Value>::const_iterator _it, _end;
+
+      public:
+
+        /// Sets the iterator to the first term
+        
+        /// Sets the iterator to the first term of the expression.
+        ///
+        ConstCoeffIt(const DualExpr& e)
+          : _it(e.comps.begin()), _end(e.comps.end()){}
+
+        /// Convert the iterator to the row of the term
+        operator Row() const {
+          return rowFromId(_it->first);
+        }
+
+        /// Returns the coefficient of the term
+        const Value& operator*() const { return _it->second; }
+
+        /// Next term
+        
+        /// Assign the iterator to the next term.
+        ///
+        ConstCoeffIt& operator++() { ++_it; return *this; }
+
+        /// Equality operator
+        bool operator==(Invalid) const { return _it == _end; }
+        /// Inequality operator
+        bool operator!=(Invalid) const { return _it != _end; }
+      };
+    };
+
+
+  protected:
+
+    class InsertIterator {
+    private:
+
+      std::map<int, Value>& _host;
+      const _solver_bits::VarIndex& _index;
+
+    public:
+
+      typedef std::output_iterator_tag iterator_category;
+      typedef void difference_type;
+      typedef void value_type;
+      typedef void reference;
+      typedef void pointer;
+
+      InsertIterator(std::map<int, Value>& host,
+                   const _solver_bits::VarIndex& index)
+        : _host(host), _index(index) {}
+
+      InsertIterator& operator=(const std::pair<int, Value>& value) {
+        typedef std::map<int, Value>::value_type pair_type;
+        _host.insert(pair_type(_index[value.first], value.second));
+        return *this;
+      }
+
+      InsertIterator& operator*() { return *this; }
+      InsertIterator& operator++() { return *this; }
+      InsertIterator operator++(int) { return *this; }
+
+    };
+
+    class ExprIterator {
+    private:
+      std::map<int, Value>::const_iterator _host_it;
+      const _solver_bits::VarIndex& _index;
+    public:
+
+      typedef std::bidirectional_iterator_tag iterator_category;
+      typedef std::ptrdiff_t difference_type;
+      typedef const std::pair<int, Value> value_type;
+      typedef value_type reference;
+
+      class pointer {
+      public:
+        pointer(value_type& _value) : value(_value) {}
+        value_type* operator->() { return &value; }
+      private:
+        value_type value;
+      };
+
+      ExprIterator(const std::map<int, Value>::const_iterator& host_it,
+                   const _solver_bits::VarIndex& index)
+        : _host_it(host_it), _index(index) {}
+
+      reference operator*() {
+        return std::make_pair(_index(_host_it->first), _host_it->second);
+      }
+
+      pointer operator->() {
+        return pointer(operator*());
+      }
+
+      ExprIterator& operator++() { ++_host_it; return *this; }
+      ExprIterator operator++(int) {
+        ExprIterator tmp(*this); ++_host_it; return tmp;
+      }
+
+      ExprIterator& operator--() { --_host_it; return *this; }
+      ExprIterator operator--(int) {
+        ExprIterator tmp(*this); --_host_it; return tmp;
+      }
+
+      bool operator==(const ExprIterator& it) const {
+        return _host_it == it._host_it;
+      }
+
+      bool operator!=(const ExprIterator& it) const {
+        return _host_it != it._host_it;
+      }
+
+    };
+
+  protected:
+
+    //Abstract virtual functions
+    virtual LpBase* _newSolver() const = 0;
+    virtual LpBase* _cloneSolver() const = 0;
+
+    virtual int _addColId(int col) { return cols.addIndex(col); }
+    virtual int _addRowId(int row) { return rows.addIndex(row); }
+
+    virtual void _eraseColId(int col) { cols.eraseIndex(col); }
+    virtual void _eraseRowId(int row) { rows.eraseIndex(row); }
+
+    virtual int _addCol() = 0;
+    virtual int _addRow() = 0;
+
+    virtual void _eraseCol(int col) = 0;
+    virtual void _eraseRow(int row) = 0;
+
+    virtual void _getColName(int col, std::string& name) const = 0;
+    virtual void _setColName(int col, const std::string& name) = 0;
+    virtual int _colByName(const std::string& name) const = 0;
+
+    virtual void _getRowName(int row, std::string& name) const = 0;
+    virtual void _setRowName(int row, const std::string& name) = 0;
+    virtual int _rowByName(const std::string& name) const = 0;
+
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
+    virtual void _getRowCoeffs(int i, InsertIterator b) const = 0;
+
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
+    virtual void _getColCoeffs(int i, InsertIterator b) const = 0;
+
+    virtual void _setCoeff(int row, int col, Value value) = 0;
+    virtual Value _getCoeff(int row, int col) const = 0;
+
+    virtual void _setColLowerBound(int i, Value value) = 0;
+    virtual Value _getColLowerBound(int i) const = 0;
+
+    virtual void _setColUpperBound(int i, Value value) = 0;
+    virtual Value _getColUpperBound(int i) const = 0;
+
+    virtual void _setRowLowerBound(int i, Value value) = 0;
+    virtual Value _getRowLowerBound(int i) const = 0;
+
+    virtual void _setRowUpperBound(int i, Value value) = 0;
+    virtual Value _getRowUpperBound(int i) const = 0;
+
+    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e) = 0;
+    virtual void _getObjCoeffs(InsertIterator b) const = 0;
+
+    virtual void _setObjCoeff(int i, Value obj_coef) = 0;
+    virtual Value _getObjCoeff(int i) const = 0;
+
+    virtual void _setSense(Sense) = 0;
+    virtual Sense _getSense() const = 0;
+
+    virtual void _clear() = 0;
+
+    virtual const char* _solverName() const = 0;
+
+    //Own protected stuff
+
+    //Constant component of the objective function
+    Value obj_const_comp;
+
+    LpBase() : rows(), cols(), obj_const_comp(0) {}
+
+  public:
+
+    /// Virtual destructor
+    virtual ~LpBase() {}
+
+    ///Creates a new LP problem
+    LpBase* newSolver() {return _newSolver();}
+    ///Makes a copy of the LP problem
+    LpBase* cloneSolver() {return _cloneSolver();}
+
+    ///Gives back the name of the solver.
+    const char* solverName() const {return _solverName();}
+
+    ///\name Build up and modify the LP
+
+    ///@{
+
+    ///Add a new empty column (i.e a new variable) to the LP
+    Col addCol() { Col c; c._id = _addColId(_addCol()); return c;}
+
+    ///\brief Adds several new columns (i.e variables) at once
+    ///
+    ///This magic function takes a container as its argument and fills
+    ///its elements with new columns (i.e. variables)
+    ///\param t can be
+    ///- a standard STL compatible iterable container with
+    ///\ref Col as its \c values_type like
+    ///\code
+    ///std::vector<LpBase::Col>
+    ///std::list<LpBase::Col>
+    ///\endcode
+    ///- a standard STL compatible iterable container with
+    ///\ref Col as its \c mapped_type like
+    ///\code
+    ///std::map<AnyType,LpBase::Col>
+    ///\endcode
+    ///- an iterable lemon \ref concepts::WriteMap "write map" like
+    ///\code
+    ///ListGraph::NodeMap<LpBase::Col>
+    ///ListGraph::ArcMap<LpBase::Col>
+    ///\endcode
+    ///\return The number of the created column.
+#ifdef DOXYGEN
+    template<class T>
+    int addColSet(T &t) { return 0;}
+#else
+    template<class T>
+    typename enable_if<typename T::value_type::LpCol,int>::type
+    addColSet(T &t,dummy<0> = 0) {
+      int s=0;
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;}
+      return s;
+    }
+    template<class T>
+    typename enable_if<typename T::value_type::second_type::LpCol,
+                       int>::type
+    addColSet(T &t,dummy<1> = 1) {
+      int s=0;
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        i->second=addCol();
+        s++;
+      }
+      return s;
+    }
+    template<class T>
+    typename enable_if<typename T::MapIt::Value::LpCol,
+                       int>::type
+    addColSet(T &t,dummy<2> = 2) {
+      int s=0;
+      for(typename T::MapIt i(t); i!=INVALID; ++i)
+        {
+          i.set(addCol());
+          s++;
+        }
+      return s;
+    }
+#endif
+
+    ///Set a column (i.e a dual constraint) of the LP
+
+    ///\param c is the column to be modified
+    ///\param e is a dual linear expression (see \ref DualExpr)
+    ///a better one.
+    void col(Col c, const DualExpr &e) {
+      e.simplify();
+      _setColCoeffs(cols(id(c)), ExprIterator(e.comps.begin(), cols),
+                    ExprIterator(e.comps.end(), cols));
+    }
+
+    ///Get a column (i.e a dual constraint) of the LP
+
+    ///\param c is the column to get
+    ///\return the dual expression associated to the column
+    DualExpr col(Col c) const {
+      DualExpr e;
+      _getColCoeffs(cols(id(c)), InsertIterator(e.comps, rows));
+      return e;
+    }
+
+    ///Add a new column to the LP
+
+    ///\param e is a dual linear expression (see \ref DualExpr)
+    ///\param o is the corresponding component of the objective
+    ///function. It is 0 by default.
+    ///\return The created column.
+    Col addCol(const DualExpr &e, Value o = 0) {
+      Col c=addCol();
+      col(c,e);
+      objCoeff(c,o);
+      return c;
+    }
+
+    ///Add a new empty row (i.e a new constraint) to the LP
+
+    ///This function adds a new empty row (i.e a new constraint) to the LP.
+    ///\return The created row
+    Row addRow() { Row r; r._id = _addRowId(_addRow()); return r;}
+
+    ///\brief Add several new rows (i.e constraints) at once
+    ///
+    ///This magic function takes a container as its argument and fills
+    ///its elements with new row (i.e. variables)
+    ///\param t can be
+    ///- a standard STL compatible iterable container with
+    ///\ref Row as its \c values_type like
+    ///\code
+    ///std::vector<LpBase::Row>
+    ///std::list<LpBase::Row>
+    ///\endcode
+    ///- a standard STL compatible iterable container with
+    ///\ref Row as its \c mapped_type like
+    ///\code
+    ///std::map<AnyType,LpBase::Row>
+    ///\endcode
+    ///- an iterable lemon \ref concepts::WriteMap "write map" like
+    ///\code
+    ///ListGraph::NodeMap<LpBase::Row>
+    ///ListGraph::ArcMap<LpBase::Row>
+    ///\endcode
+    ///\return The number of rows created.
+#ifdef DOXYGEN
+    template<class T>
+    int addRowSet(T &t) { return 0;}
+#else
+    template<class T>
+    typename enable_if<typename T::value_type::LpRow,int>::type
+    addRowSet(T &t, dummy<0> = 0) {
+      int s=0;
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addRow();s++;}
+      return s;
+    }
+    template<class T>
+    typename enable_if<typename T::value_type::second_type::LpRow, int>::type
+    addRowSet(T &t, dummy<1> = 1) {
+      int s=0;
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        i->second=addRow();
+        s++;
+      }
+      return s;
+    }
+    template<class T>
+    typename enable_if<typename T::MapIt::Value::LpRow, int>::type
+    addRowSet(T &t, dummy<2> = 2) {
+      int s=0;
+      for(typename T::MapIt i(t); i!=INVALID; ++i)
+        {
+          i.set(addRow());
+          s++;
+        }
+      return s;
+    }
+#endif
+
+    ///Set a row (i.e a constraint) of the LP
+
+    ///\param r is the row to be modified
+    ///\param l is lower bound (-\ref INF means no bound)
+    ///\param e is a linear expression (see \ref Expr)
+    ///\param u is the upper bound (\ref INF means no bound)
+    void row(Row r, Value l, const Expr &e, Value u) {
+      e.simplify();
+      _setRowCoeffs(rows(id(r)), ExprIterator(e.comps.begin(), cols),
+                    ExprIterator(e.comps.end(), cols));
+      _setRowLowerBound(rows(id(r)),l - *e);
+      _setRowUpperBound(rows(id(r)),u - *e);
+    }
+
+    ///Set a row (i.e a constraint) of the LP
+
+    ///\param r is the row to be modified
+    ///\param c is a linear expression (see \ref Constr)
+    void row(Row r, const Constr &c) {
+      row(r, c.lowerBounded()?c.lowerBound():-INF,
+          c.expr(), c.upperBounded()?c.upperBound():INF);
+    }
+
+
+    ///Get a row (i.e a constraint) of the LP
+
+    ///\param r is the row to get
+    ///\return the expression associated to the row
+    Expr row(Row r) const {
+      Expr e;
+      _getRowCoeffs(rows(id(r)), InsertIterator(e.comps, cols));
+      return e;
+    }
+
+    ///Add a new row (i.e a new constraint) to the LP
+
+    ///\param l is the lower bound (-\ref INF means no bound)
+    ///\param e is a linear expression (see \ref Expr)
+    ///\param u is the upper bound (\ref INF means no bound)
+    ///\return The created row.
+    Row addRow(Value l,const Expr &e, Value u) {
+      Row r=addRow();
+      row(r,l,e,u);
+      return r;
+    }
+
+    ///Add a new row (i.e a new constraint) to the LP
+
+    ///\param c is a linear expression (see \ref Constr)
+    ///\return The created row.
+    Row addRow(const Constr &c) {
+      Row r=addRow();
+      row(r,c);
+      return r;
+    }
+    ///Erase a column (i.e a variable) from the LP
+
+    ///\param c is the column to be deleted
+    void erase(Col c) {
+      _eraseCol(cols(id(c)));
+      _eraseColId(cols(id(c)));
+    }
+    ///Erase a row (i.e a constraint) from the LP
+
+    ///\param r is the row to be deleted
+    void erase(Row r) {
+      _eraseRow(rows(id(r)));
+      _eraseRowId(rows(id(r)));
+    }
+
+    /// Get the name of a column
+
+    ///\param c is the coresponding column
+    ///\return The name of the colunm
+    std::string colName(Col c) const {
+      std::string name;
+      _getColName(cols(id(c)), name);
+      return name;
+    }
+
+    /// Set the name of a column
+
+    ///\param c is the coresponding column
+    ///\param name The name to be given
+    void colName(Col c, const std::string& name) {
+      _setColName(cols(id(c)), name);
+    }
+
+    /// Get the column by its name
+
+    ///\param name The name of the column
+    ///\return the proper column or \c INVALID
+    Col colByName(const std::string& name) const {
+      int k = _colByName(name);
+      return k != -1 ? Col(cols[k]) : Col(INVALID);
+    }
+
+    /// Get the name of a row
+
+    ///\param r is the coresponding row
+    ///\return The name of the row
+    std::string rowName(Row r) const {
+      std::string name;
+      _getRowName(rows(id(r)), name);
+      return name;
+    }
+
+    /// Set the name of a row
+
+    ///\param r is the coresponding row
+    ///\param name The name to be given
+    void rowName(Row r, const std::string& name) {
+      _setRowName(rows(id(r)), name);
+    }
+
+    /// Get the row by its name
+
+    ///\param name The name of the row
+    ///\return the proper row or \c INVALID
+    Row rowByName(const std::string& name) const {
+      int k = _rowByName(name);
+      return k != -1 ? Row(rows[k]) : Row(INVALID);
+    }
+
+    /// Set an element of the coefficient matrix of the LP
+
+    ///\param r is the row of the element to be modified
+    ///\param c is the column of the element to be modified
+    ///\param val is the new value of the coefficient
+    void coeff(Row r, Col c, Value val) {
+      _setCoeff(rows(id(r)),cols(id(c)), val);
+    }
+
+    /// Get an element of the coefficient matrix of the LP
+
+    ///\param r is the row of the element
+    ///\param c is the column of the element
+    ///\return the corresponding coefficient
+    Value coeff(Row r, Col c) const {
+      return _getCoeff(rows(id(r)),cols(id(c)));
+    }
+
+    /// Set the lower bound of a column (i.e a variable)
+
+    /// The lower bound of a variable (column) has to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    void colLowerBound(Col c, Value value) {
+      _setColLowerBound(cols(id(c)),value);
+    }
+
+    /// Get the lower bound of a column (i.e a variable)
+
+    /// This function returns the lower bound for column (variable) \c c
+    /// (this might be -\ref INF as well).
+    ///\return The lower bound for column \c c
+    Value colLowerBound(Col c) const {
+      return _getColLowerBound(cols(id(c)));
+    }
+
+    ///\brief Set the lower bound of  several columns
+    ///(i.e variables) at once
+    ///
+    ///This magic function takes a container as its argument
+    ///and applies the function on all of its elements.
+    ///The lower bound of a variable (column) has to be given by an
+    ///extended number of type Value, i.e. a finite number of type
+    ///Value or -\ref INF.
+#ifdef DOXYGEN
+    template<class T>
+    void colLowerBound(T &t, Value value) { return 0;}
+#else
+    template<class T>
+    typename enable_if<typename T::value_type::LpCol,void>::type
+    colLowerBound(T &t, Value value,dummy<0> = 0) {
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        colLowerBound(*i, value);
+      }
+    }
+    template<class T>
+    typename enable_if<typename T::value_type::second_type::LpCol,
+                       void>::type
+    colLowerBound(T &t, Value value,dummy<1> = 1) {
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        colLowerBound(i->second, value);
+      }
+    }
+    template<class T>
+    typename enable_if<typename T::MapIt::Value::LpCol,
+                       void>::type
+    colLowerBound(T &t, Value value,dummy<2> = 2) {
+      for(typename T::MapIt i(t); i!=INVALID; ++i){
+        colLowerBound(*i, value);
+      }
+    }
+#endif
+
+    /// Set the upper bound of a column (i.e a variable)
+
+    /// The upper bound of a variable (column) has to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or \ref INF.
+    void colUpperBound(Col c, Value value) {
+      _setColUpperBound(cols(id(c)),value);
+    };
+
+    /// Get the upper bound of a column (i.e a variable)
+
+    /// This function returns the upper bound for column (variable) \c c
+    /// (this might be \ref INF as well).
+    /// \return The upper bound for column \c c
+    Value colUpperBound(Col c) const {
+      return _getColUpperBound(cols(id(c)));
+    }
+
+    ///\brief Set the upper bound of  several columns
+    ///(i.e variables) at once
+    ///
+    ///This magic function takes a container as its argument
+    ///and applies the function on all of its elements.
+    ///The upper bound of a variable (column) has to be given by an
+    ///extended number of type Value, i.e. a finite number of type
+    ///Value or \ref INF.
+#ifdef DOXYGEN
+    template<class T>
+    void colUpperBound(T &t, Value value) { return 0;}
+#else
+    template<class T>
+    typename enable_if<typename T::value_type::LpCol,void>::type
+    colUpperBound(T &t, Value value,dummy<0> = 0) {
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        colUpperBound(*i, value);
+      }
+    }
+    template<class T>
+    typename enable_if<typename T::value_type::second_type::LpCol,
+                       void>::type
+    colUpperBound(T &t, Value value,dummy<1> = 1) {
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        colUpperBound(i->second, value);
+      }
+    }
+    template<class T>
+    typename enable_if<typename T::MapIt::Value::LpCol,
+                       void>::type
+    colUpperBound(T &t, Value value,dummy<2> = 2) {
+      for(typename T::MapIt i(t); i!=INVALID; ++i){
+        colUpperBound(*i, value);
+      }
+    }
+#endif
+
+    /// Set the lower and the upper bounds of a column (i.e a variable)
+
+    /// The lower and the upper bounds of
+    /// a variable (column) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value, -\ref INF or \ref INF.
+    void colBounds(Col c, Value lower, Value upper) {
+      _setColLowerBound(cols(id(c)),lower);
+      _setColUpperBound(cols(id(c)),upper);
+    }
+
+    ///\brief Set the lower and the upper bound of several columns
+    ///(i.e variables) at once
+    ///
+    ///This magic function takes a container as its argument
+    ///and applies the function on all of its elements.
+    /// The lower and the upper bounds of
+    /// a variable (column) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value, -\ref INF or \ref INF.
+#ifdef DOXYGEN
+    template<class T>
+    void colBounds(T &t, Value lower, Value upper) { return 0;}
+#else
+    template<class T>
+    typename enable_if<typename T::value_type::LpCol,void>::type
+    colBounds(T &t, Value lower, Value upper,dummy<0> = 0) {
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        colBounds(*i, lower, upper);
+      }
+    }
+    template<class T>
+    typename enable_if<typename T::value_type::second_type::LpCol, void>::type
+    colBounds(T &t, Value lower, Value upper,dummy<1> = 1) {
+      for(typename T::iterator i=t.begin();i!=t.end();++i) {
+        colBounds(i->second, lower, upper);
+      }
+    }
+    template<class T>
+    typename enable_if<typename T::MapIt::Value::LpCol, void>::type
+    colBounds(T &t, Value lower, Value upper,dummy<2> = 2) {
+      for(typename T::MapIt i(t); i!=INVALID; ++i){
+        colBounds(*i, lower, upper);
+      }
+    }
+#endif
+
+    /// Set the lower bound of a row (i.e a constraint)
+
+    /// The lower bound of a constraint (row) has to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    void rowLowerBound(Row r, Value value) {
+      _setRowLowerBound(rows(id(r)),value);
+    }
+
+    /// Get the lower bound of a row (i.e a constraint)
+
+    /// This function returns the lower bound for row (constraint) \c c
+    /// (this might be -\ref INF as well).
+    ///\return The lower bound for row \c r
+    Value rowLowerBound(Row r) const {
+      return _getRowLowerBound(rows(id(r)));
+    }
+
+    /// Set the upper bound of a row (i.e a constraint)
+
+    /// The upper bound of a constraint (row) has to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    void rowUpperBound(Row r, Value value) {
+      _setRowUpperBound(rows(id(r)),value);
+    }
+
+    /// Get the upper bound of a row (i.e a constraint)
+
+    /// This function returns the upper bound for row (constraint) \c c
+    /// (this might be -\ref INF as well).
+    ///\return The upper bound for row \c r
+    Value rowUpperBound(Row r) const {
+      return _getRowUpperBound(rows(id(r)));
+    }
+
+    ///Set an element of the objective function
+    void objCoeff(Col c, Value v) {_setObjCoeff(cols(id(c)),v); };
+
+    ///Get an element of the objective function
+    Value objCoeff(Col c) const { return _getObjCoeff(cols(id(c))); };
+
+    ///Set the objective function
+
+    ///\param e is a linear expression of type \ref Expr.
+    ///
+    void obj(const Expr& e) {
+      _setObjCoeffs(ExprIterator(e.comps.begin(), cols),
+                    ExprIterator(e.comps.end(), cols));
+      obj_const_comp = *e;
+    }
+
+    ///Get the objective function
+
+    ///\return the objective function as a linear expression of type
+    ///Expr.
+    Expr obj() const {
+      Expr e;
+      _getObjCoeffs(InsertIterator(e.comps, cols));
+      *e = obj_const_comp;
+      return e;
+    }
+
+
+    ///Set the direction of optimization
+    void sense(Sense sense) { _setSense(sense); }
+
+    ///Query the direction of the optimization
+    Sense sense() const {return _getSense(); }
+
+    ///Set the sense to maximization
+    void max() { _setSense(MAX); }
+
+    ///Set the sense to maximization
+    void min() { _setSense(MIN); }
+
+    ///Clears the problem
+    void clear() { _clear(); }
+
+    ///@}
+
+  };
+
+  /// Addition
+
+  ///\relates LpBase::Expr
+  ///
+  inline LpBase::Expr operator+(const LpBase::Expr &a, const LpBase::Expr &b) {
+    LpBase::Expr tmp(a);
+    tmp+=b;
+    return tmp;
+  }
+  ///Substraction
+
+  ///\relates LpBase::Expr
+  ///
+  inline LpBase::Expr operator-(const LpBase::Expr &a, const LpBase::Expr &b) {
+    LpBase::Expr tmp(a);
+    tmp-=b;
+    return tmp;
+  }
+  ///Multiply with constant
+
+  ///\relates LpBase::Expr
+  ///
+  inline LpBase::Expr operator*(const LpBase::Expr &a, const LpBase::Value &b) {
+    LpBase::Expr tmp(a);
+    tmp*=b;
+    return tmp;
+  }
+
+  ///Multiply with constant
+
+  ///\relates LpBase::Expr
+  ///
+  inline LpBase::Expr operator*(const LpBase::Value &a, const LpBase::Expr &b) {
+    LpBase::Expr tmp(b);
+    tmp*=a;
+    return tmp;
+  }
+  ///Divide with constant
+
+  ///\relates LpBase::Expr
+  ///
+  inline LpBase::Expr operator/(const LpBase::Expr &a, const LpBase::Value &b) {
+    LpBase::Expr tmp(a);
+    tmp/=b;
+    return tmp;
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator<=(const LpBase::Expr &e,
+                                   const LpBase::Expr &f) {
+    return LpBase::Constr(0, f - e, LpBase::INF);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator<=(const LpBase::Value &e,
+                                   const LpBase::Expr &f) {
+    return LpBase::Constr(e, f, LpBase::NaN);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator<=(const LpBase::Expr &e,
+                                   const LpBase::Value &f) {
+    return LpBase::Constr(- LpBase::INF, e, f);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator>=(const LpBase::Expr &e,
+                                   const LpBase::Expr &f) {
+    return LpBase::Constr(0, e - f, LpBase::INF);
+  }
+
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator>=(const LpBase::Value &e,
+                                   const LpBase::Expr &f) {
+    return LpBase::Constr(LpBase::NaN, f, e);
+  }
+
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator>=(const LpBase::Expr &e,
+                                   const LpBase::Value &f) {
+    return LpBase::Constr(f, e, LpBase::INF);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator==(const LpBase::Expr &e,
+                                   const LpBase::Value &f) {
+    return LpBase::Constr(f, e, f);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator==(const LpBase::Expr &e,
+                                   const LpBase::Expr &f) {
+    return LpBase::Constr(0, f - e, 0);
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator<=(const LpBase::Value &n,
+                                   const LpBase::Constr &c) {
+    LpBase::Constr tmp(c);
+    LEMON_ASSERT(std::isnan(tmp.lowerBound()), "Wrong LP constraint");
+    tmp.lowerBound()=n;
+    return tmp;
+  }
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator<=(const LpBase::Constr &c,
+                                   const LpBase::Value &n)
+  {
+    LpBase::Constr tmp(c);
+    LEMON_ASSERT(std::isnan(tmp.upperBound()), "Wrong LP constraint");
+    tmp.upperBound()=n;
+    return tmp;
+  }
+
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator>=(const LpBase::Value &n,
+                                   const LpBase::Constr &c) {
+    LpBase::Constr tmp(c);
+    LEMON_ASSERT(std::isnan(tmp.upperBound()), "Wrong LP constraint");
+    tmp.upperBound()=n;
+    return tmp;
+  }
+  ///Create constraint
+
+  ///\relates LpBase::Constr
+  ///
+  inline LpBase::Constr operator>=(const LpBase::Constr &c,
+                                   const LpBase::Value &n)
+  {
+    LpBase::Constr tmp(c);
+    LEMON_ASSERT(std::isnan(tmp.lowerBound()), "Wrong LP constraint");
+    tmp.lowerBound()=n;
+    return tmp;
+  }
+
+  ///Addition
+
+  ///\relates LpBase::DualExpr
+  ///
+  inline LpBase::DualExpr operator+(const LpBase::DualExpr &a,
+                                    const LpBase::DualExpr &b) {
+    LpBase::DualExpr tmp(a);
+    tmp+=b;
+    return tmp;
+  }
+  ///Substraction
+
+  ///\relates LpBase::DualExpr
+  ///
+  inline LpBase::DualExpr operator-(const LpBase::DualExpr &a,
+                                    const LpBase::DualExpr &b) {
+    LpBase::DualExpr tmp(a);
+    tmp-=b;
+    return tmp;
+  }
+  ///Multiply with constant
+
+  ///\relates LpBase::DualExpr
+  ///
+  inline LpBase::DualExpr operator*(const LpBase::DualExpr &a,
+                                    const LpBase::Value &b) {
+    LpBase::DualExpr tmp(a);
+    tmp*=b;
+    return tmp;
+  }
+
+  ///Multiply with constant
+
+  ///\relates LpBase::DualExpr
+  ///
+  inline LpBase::DualExpr operator*(const LpBase::Value &a,
+                                    const LpBase::DualExpr &b) {
+    LpBase::DualExpr tmp(b);
+    tmp*=a;
+    return tmp;
+  }
+  ///Divide with constant
+
+  ///\relates LpBase::DualExpr
+  ///
+  inline LpBase::DualExpr operator/(const LpBase::DualExpr &a,
+                                    const LpBase::Value &b) {
+    LpBase::DualExpr tmp(a);
+    tmp/=b;
+    return tmp;
+  }
+
+  /// \ingroup lp_group
+  ///
+  /// \brief Common base class for LP solvers
+  ///
+  /// This class is an abstract base class for LP solvers. This class
+  /// provides a full interface for set and modify an LP problem,
+  /// solve it and retrieve the solution. You can use one of the
+  /// descendants as a concrete implementation, or the \c Lp
+  /// default LP solver. However, if you would like to handle LP
+  /// solvers as reference or pointer in a generic way, you can use
+  /// this class directly.
+  class LpSolver : virtual public LpBase {
+  public:
+
+    /// The problem types for primal and dual problems
+    enum ProblemType {
+      ///Feasible solution hasn't been found (but may exist).
+      UNDEFINED = 0,
+      ///The problem has no feasible solution
+      INFEASIBLE = 1,
+      ///Feasible solution found
+      FEASIBLE = 2,
+      ///Optimal solution exists and found
+      OPTIMAL = 3,
+      ///The cost function is unbounded
+      UNBOUNDED = 4
+    };
+
+    ///The basis status of variables
+    enum VarStatus {
+      /// The variable is in the basis
+      BASIC, 
+      /// The variable is free, but not basic
+      FREE,
+      /// The variable has active lower bound 
+      LOWER,
+      /// The variable has active upper bound
+      UPPER,
+      /// The variable is non-basic and fixed
+      FIXED
+    };
+
+  protected:
+
+    virtual SolveExitStatus _solve() = 0;
+
+    virtual Value _getPrimal(int i) const = 0;
+    virtual Value _getDual(int i) const = 0;
+
+    virtual Value _getPrimalRay(int i) const = 0;
+    virtual Value _getDualRay(int i) const = 0;
+
+    virtual Value _getPrimalValue() const = 0;
+
+    virtual VarStatus _getColStatus(int i) const = 0;
+    virtual VarStatus _getRowStatus(int i) const = 0;
+
+    virtual ProblemType _getPrimalType() const = 0;
+    virtual ProblemType _getDualType() const = 0;
+
+  public:
+
+    ///\name Solve the LP
+
+    ///@{
+
+    ///\e Solve the LP problem at hand
+    ///
+    ///\return The result of the optimization procedure. Possible
+    ///values and their meanings can be found in the documentation of
+    ///\ref SolveExitStatus.
+    SolveExitStatus solve() { return _solve(); }
+
+    ///@}
+
+    ///\name Obtain the solution
+
+    ///@{
+
+    /// The type of the primal problem
+    ProblemType primalType() const {
+      return _getPrimalType();
+    }
+
+    /// The type of the dual problem
+    ProblemType dualType() const {
+      return _getDualType();
+    }
+
+    /// Return the primal value of the column
+
+    /// Return the primal value of the column.
+    /// \pre The problem is solved.
+    Value primal(Col c) const { return _getPrimal(cols(id(c))); }
+
+    /// Return the primal value of the expression
+
+    /// Return the primal value of the expression, i.e. the dot
+    /// product of the primal solution and the expression.
+    /// \pre The problem is solved.
+    Value primal(const Expr& e) const {
+      double res = *e;
+      for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) {
+        res += *c * primal(c);
+      }
+      return res;
+    }
+    /// Returns a component of the primal ray
+    
+    /// The primal ray is solution of the modified primal problem,
+    /// where we change each finite bound to 0, and we looking for a
+    /// negative objective value in case of minimization, and positive
+    /// objective value for maximization. If there is such solution,
+    /// that proofs the unsolvability of the dual problem, and if a
+    /// feasible primal solution exists, then the unboundness of
+    /// primal problem.
+    ///
+    /// \pre The problem is solved and the dual problem is infeasible.
+    /// \note Some solvers does not provide primal ray calculation
+    /// functions.
+    Value primalRay(Col c) const { return _getPrimalRay(cols(id(c))); }
+
+    /// Return the dual value of the row
+
+    /// Return the dual value of the row.
+    /// \pre The problem is solved.
+    Value dual(Row r) const { return _getDual(rows(id(r))); }
+
+    /// Return the dual value of the dual expression
+
+    /// Return the dual value of the dual expression, i.e. the dot
+    /// product of the dual solution and the dual expression.
+    /// \pre The problem is solved.
+    Value dual(const DualExpr& e) const {
+      double res = 0.0;
+      for (DualExpr::ConstCoeffIt r(e); r != INVALID; ++r) {
+        res += *r * dual(r);
+      }
+      return res;
+    }
+
+    /// Returns a component of the dual ray
+    
+    /// The dual ray is solution of the modified primal problem, where
+    /// we change each finite bound to 0 (i.e. the objective function
+    /// coefficients in the primal problem), and we looking for a
+    /// ositive objective value. If there is such solution, that
+    /// proofs the unsolvability of the primal problem, and if a
+    /// feasible dual solution exists, then the unboundness of
+    /// dual problem.
+    ///
+    /// \pre The problem is solved and the primal problem is infeasible.
+    /// \note Some solvers does not provide dual ray calculation
+    /// functions.
+    Value dualRay(Row r) const { return _getDualRay(rows(id(r))); }
+
+    /// Return the basis status of the column
+
+    /// \see VarStatus
+    VarStatus colStatus(Col c) const { return _getColStatus(cols(id(c))); }
+
+    /// Return the basis status of the row
+
+    /// \see VarStatus
+    VarStatus rowStatus(Row r) const { return _getRowStatus(rows(id(r))); }
+
+    ///The value of the objective function
+
+    ///\return
+    ///- \ref INF or -\ref INF means either infeasibility or unboundedness
+    /// of the primal problem, depending on whether we minimize or maximize.
+    ///- \ref NaN if no primal solution is found.
+    ///- The (finite) objective value if an optimal solution is found.
+    Value primal() const { return _getPrimalValue()+obj_const_comp;}
+    ///@}
+
+    LpSolver* newSolver() {return _newSolver();}
+    LpSolver* cloneSolver() {return _cloneSolver();}
+
+  protected:
+
+    virtual LpSolver* _newSolver() const = 0;
+    virtual LpSolver* _cloneSolver() const = 0;
+  };
+
+
+  /// \ingroup lp_group
+  ///
+  /// \brief Common base class for MIP solvers
+  ///
+  /// This class is an abstract base class for MIP solvers. This class
+  /// provides a full interface for set and modify an MIP problem,
+  /// solve it and retrieve the solution. You can use one of the
+  /// descendants as a concrete implementation, or the \c Lp
+  /// default MIP solver. However, if you would like to handle MIP
+  /// solvers as reference or pointer in a generic way, you can use
+  /// this class directly.
+  class MipSolver : virtual public LpBase {
+  public:
+
+    /// The problem types for MIP problems
+    enum ProblemType {
+      ///Feasible solution hasn't been found (but may exist).
+      UNDEFINED = 0,
+      ///The problem has no feasible solution
+      INFEASIBLE = 1,
+      ///Feasible solution found
+      FEASIBLE = 2,
+      ///Optimal solution exists and found
+      OPTIMAL = 3,
+      ///The cost function is unbounded
+      ///
+      ///The Mip or at least the relaxed problem is unbounded
+      UNBOUNDED = 4
+    };
+
+    ///\name Solve the MIP
+
+    ///@{
+
+    /// Solve the MIP problem at hand
+    ///
+    ///\return The result of the optimization procedure. Possible
+    ///values and their meanings can be found in the documentation of
+    ///\ref SolveExitStatus.
+    SolveExitStatus solve() { return _solve(); }
+
+    ///@}
+
+    ///\name Setting column type
+    ///@{
+
+    ///Possible variable (column) types (e.g. real, integer, binary etc.)
+    enum ColTypes {
+      ///Continuous variable (default)
+      REAL = 0,
+      ///Integer variable
+      INTEGER = 1
+    };
+
+    ///Sets the type of the given column to the given type
+
+    ///Sets the type of the given column to the given type.
+    ///
+    void colType(Col c, ColTypes col_type) {
+      _setColType(cols(id(c)),col_type);
+    }
+
+    ///Gives back the type of the column.
+
+    ///Gives back the type of the column.
+    ///
+    ColTypes colType(Col c) const {
+      return _getColType(cols(id(c)));
+    }
+    ///@}
+
+    ///\name Obtain the solution
+
+    ///@{
+
+    /// The type of the MIP problem
+    ProblemType type() const {
+      return _getType();
+    }
+
+    /// Return the value of the row in the solution
+
+    ///  Return the value of the row in the solution.
+    /// \pre The problem is solved.
+    Value sol(Col c) const { return _getSol(cols(id(c))); }
+
+    /// Return the value of the expression in the solution
+
+    /// Return the value of the expression in the solution, i.e. the
+    /// dot product of the solution and the expression.
+    /// \pre The problem is solved.
+    Value sol(const Expr& e) const {
+      double res = *e;
+      for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) {
+        res += *c * sol(c);
+      }
+      return res;
+    }
+    ///The value of the objective function
+    
+    ///\return
+    ///- \ref INF or -\ref INF means either infeasibility or unboundedness
+    /// of the problem, depending on whether we minimize or maximize.
+    ///- \ref NaN if no primal solution is found.
+    ///- The (finite) objective value if an optimal solution is found.
+    Value solValue() const { return _getSolValue()+obj_const_comp;}
+    ///@}
+
+  protected:
+
+    virtual SolveExitStatus _solve() = 0;
+    virtual ColTypes _getColType(int col) const = 0;
+    virtual void _setColType(int col, ColTypes col_type) = 0;
+    virtual ProblemType _getType() const = 0;
+    virtual Value _getSol(int i) const = 0;
+    virtual Value _getSolValue() const = 0;
+
+  public:
+
+    MipSolver* newSolver() {return _newSolver();}
+    MipSolver* cloneSolver() {return _cloneSolver();}
+
+  protected:
+
+    virtual MipSolver* _newSolver() const = 0;
+    virtual MipSolver* _cloneSolver() const = 0;
+  };
+
+
+
+} //namespace lemon
+
+#endif //LEMON_LP_BASE_H
Index: lemon/lp_clp.cc
===================================================================
--- lemon/lp_clp.cc	(revision 459)
+++ lemon/lp_clp.cc	(revision 459)
@@ -0,0 +1,437 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * 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 <lemon/lp_clp.h>
+#include <coin/ClpSimplex.hpp>
+
+namespace lemon {
+
+  LpClp::LpClp() {
+    _prob = new ClpSimplex();
+    _init_temporals();
+    messageLevel(MESSAGE_NO_OUTPUT);
+  }
+
+  LpClp::LpClp(const LpClp& other) {
+    _prob = new ClpSimplex(*other._prob);
+    rows = other.rows;
+    cols = other.cols;
+    _init_temporals();
+    messageLevel(MESSAGE_NO_OUTPUT);
+  }
+
+  LpClp::~LpClp() {
+    delete _prob;
+    _clear_temporals();
+  }
+
+  void LpClp::_init_temporals() {
+    _primal_ray = 0;
+    _dual_ray = 0;
+  }
+
+  void LpClp::_clear_temporals() {
+    if (_primal_ray) {
+      delete[] _primal_ray;
+      _primal_ray = 0;
+    }
+    if (_dual_ray) {
+      delete[] _dual_ray;
+      _dual_ray = 0;
+    }
+  }
+
+  LpClp* LpClp::_newSolver() const {
+    LpClp* newlp = new LpClp;
+    return newlp;
+  }
+
+  LpClp* LpClp::_cloneSolver() const {
+    LpClp* copylp = new LpClp(*this);
+    return copylp;
+  }
+
+  const char* LpClp::_solverName() const { return "LpClp"; }
+
+  int LpClp::_addCol() {
+    _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0);
+    return _prob->numberColumns() - 1;
+  }
+
+  int LpClp::_addRow() {
+    _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
+    return _prob->numberRows() - 1;
+  }
+
+
+  void LpClp::_eraseCol(int c) {
+    _col_names_ref.erase(_prob->getColumnName(c));
+    _prob->deleteColumns(1, &c);
+  }
+
+  void LpClp::_eraseRow(int r) {
+    _row_names_ref.erase(_prob->getRowName(r));
+    _prob->deleteRows(1, &r);
+  }
+
+  void LpClp::_eraseColId(int i) {
+    cols.eraseIndex(i);
+    cols.shiftIndices(i);
+  }
+
+  void LpClp::_eraseRowId(int i) {
+    rows.eraseIndex(i);
+    rows.shiftIndices(i);
+  }
+
+  void LpClp::_getColName(int c, std::string& name) const {
+    name = _prob->getColumnName(c);
+  }
+
+  void LpClp::_setColName(int c, const std::string& name) {
+    _prob->setColumnName(c, const_cast<std::string&>(name));
+    _col_names_ref[name] = c;
+  }
+
+  int LpClp::_colByName(const std::string& name) const {
+    std::map<std::string, int>::const_iterator it = _col_names_ref.find(name);
+    return it != _col_names_ref.end() ? it->second : -1;
+  }
+
+  void LpClp::_getRowName(int r, std::string& name) const {
+    name = _prob->getRowName(r);
+  }
+
+  void LpClp::_setRowName(int r, const std::string& name) {
+    _prob->setRowName(r, const_cast<std::string&>(name));
+    _row_names_ref[name] = r;
+  }
+
+  int LpClp::_rowByName(const std::string& name) const {
+    std::map<std::string, int>::const_iterator it = _row_names_ref.find(name);
+    return it != _row_names_ref.end() ? it->second : -1;
+  }
+
+
+  void LpClp::_setRowCoeffs(int ix, ExprIterator b, ExprIterator e) {
+    std::map<int, Value> coeffs;
+
+    int n = _prob->clpMatrix()->getNumCols();
+
+    const int* indices = _prob->clpMatrix()->getIndices();
+    const double* elements = _prob->clpMatrix()->getElements();
+
+    for (int i = 0; i < n; ++i) {
+      CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i];
+      CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i];
+
+      const int* it = std::lower_bound(indices + begin, indices + end, ix);
+      if (it != indices + end && *it == ix && elements[it - indices] != 0.0) {
+        coeffs[i] = 0.0;
+      }
+    }
+
+    for (ExprIterator it = b; it != e; ++it) {
+      coeffs[it->first] = it->second;
+    }
+
+    for (std::map<int, Value>::iterator it = coeffs.begin();
+         it != coeffs.end(); ++it) {
+      _prob->modifyCoefficient(ix, it->first, it->second);
+    }
+  }
+
+  void LpClp::_getRowCoeffs(int ix, InsertIterator b) const {
+    int n = _prob->clpMatrix()->getNumCols();
+
+    const int* indices = _prob->clpMatrix()->getIndices();
+    const double* elements = _prob->clpMatrix()->getElements();
+
+    for (int i = 0; i < n; ++i) {
+      CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i];
+      CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i];
+
+      const int* it = std::lower_bound(indices + begin, indices + end, ix);
+      if (it != indices + end && *it == ix) {
+        *b = std::make_pair(i, elements[it - indices]);
+      }
+    }
+  }
+
+  void LpClp::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) {
+    std::map<int, Value> coeffs;
+
+    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
+    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
+
+    const int* indices = _prob->clpMatrix()->getIndices();
+    const double* elements = _prob->clpMatrix()->getElements();
+
+    for (CoinBigIndex i = begin; i != end; ++i) {
+      if (elements[i] != 0.0) {
+        coeffs[indices[i]] = 0.0;
+      }
+    }
+    for (ExprIterator it = b; it != e; ++it) {
+      coeffs[it->first] = it->second;
+    }
+    for (std::map<int, Value>::iterator it = coeffs.begin();
+         it != coeffs.end(); ++it) {
+      _prob->modifyCoefficient(it->first, ix, it->second);
+    }
+  }
+
+  void LpClp::_getColCoeffs(int ix, InsertIterator b) const {
+    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
+    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
+
+    const int* indices = _prob->clpMatrix()->getIndices();
+    const double* elements = _prob->clpMatrix()->getElements();
+
+    for (CoinBigIndex i = begin; i != end; ++i) {
+      *b = std::make_pair(indices[i], elements[i]);
+      ++b;
+    }
+  }
+
+  void LpClp::_setCoeff(int ix, int jx, Value value) {
+    _prob->modifyCoefficient(ix, jx, value);
+  }
+
+  LpClp::Value LpClp::_getCoeff(int ix, int jx) const {
+    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
+    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
+
+    const int* indices = _prob->clpMatrix()->getIndices();
+    const double* elements = _prob->clpMatrix()->getElements();
+
+    const int* it = std::lower_bound(indices + begin, indices + end, jx);
+    if (it != indices + end && *it == jx) {
+      return elements[it - indices];
+    } else {
+      return 0.0;
+    }
+  }
+
+  void LpClp::_setColLowerBound(int i, Value lo) {
+    _prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
+  }
+
+  LpClp::Value LpClp::_getColLowerBound(int i) const {
+    double val = _prob->getColLower()[i];
+    return val == - COIN_DBL_MAX ? - INF : val;
+  }
+
+  void LpClp::_setColUpperBound(int i, Value up) {
+    _prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up);
+  }
+
+  LpClp::Value LpClp::_getColUpperBound(int i) const {
+    double val = _prob->getColUpper()[i];
+    return val == COIN_DBL_MAX ? INF : val;
+  }
+
+  void LpClp::_setRowLowerBound(int i, Value lo) {
+    _prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
+  }
+
+  LpClp::Value LpClp::_getRowLowerBound(int i) const {
+    double val = _prob->getRowLower()[i];
+    return val == - COIN_DBL_MAX ? - INF : val;
+  }
+
+  void LpClp::_setRowUpperBound(int i, Value up) {
+    _prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up);
+  }
+
+  LpClp::Value LpClp::_getRowUpperBound(int i) const {
+    double val = _prob->getRowUpper()[i];
+    return val == COIN_DBL_MAX ? INF : val;
+  }
+
+  void LpClp::_setObjCoeffs(ExprIterator b, ExprIterator e) {
+    int num = _prob->clpMatrix()->getNumCols();
+    for (int i = 0; i < num; ++i) {
+      _prob->setObjectiveCoefficient(i, 0.0);
+    }
+    for (ExprIterator it = b; it != e; ++it) {
+      _prob->setObjectiveCoefficient(it->first, it->second);
+    }
+  }
+
+  void LpClp::_getObjCoeffs(InsertIterator b) const {
+    int num = _prob->clpMatrix()->getNumCols();
+    for (int i = 0; i < num; ++i) {
+      Value coef = _prob->getObjCoefficients()[i];
+      if (coef != 0.0) {
+        *b = std::make_pair(i, coef);
+        ++b;
+      }
+    }
+  }
+
+  void LpClp::_setObjCoeff(int i, Value obj_coef) {
+    _prob->setObjectiveCoefficient(i, obj_coef);
+  }
+
+  LpClp::Value LpClp::_getObjCoeff(int i) const {
+    return _prob->getObjCoefficients()[i];
+  }
+
+  LpClp::SolveExitStatus LpClp::_solve() {
+    return _prob->primal() >= 0 ? SOLVED : UNSOLVED;
+  }
+
+  LpClp::SolveExitStatus LpClp::solvePrimal() {
+    return _prob->primal() >= 0 ? SOLVED : UNSOLVED;
+  }
+
+  LpClp::SolveExitStatus LpClp::solveDual() {
+    return _prob->dual() >= 0 ? SOLVED : UNSOLVED;
+  }
+
+  LpClp::SolveExitStatus LpClp::solveBarrier() {
+    return _prob->barrier() >= 0 ? SOLVED : UNSOLVED;
+  }
+
+  LpClp::Value LpClp::_getPrimal(int i) const {
+    return _prob->primalColumnSolution()[i];
+  }
+  LpClp::Value LpClp::_getPrimalValue() const {
+    return _prob->objectiveValue();
+  }
+
+  LpClp::Value LpClp::_getDual(int i) const {
+    return _prob->dualRowSolution()[i];
+  }
+
+  LpClp::Value LpClp::_getPrimalRay(int i) const {
+    if (!_primal_ray) {
+      _primal_ray = _prob->unboundedRay();
+      LEMON_ASSERT(_primal_ray != 0, "Primal ray is not provided");
+    }
+    return _primal_ray[i];
+  }
+
+  LpClp::Value LpClp::_getDualRay(int i) const {
+    if (!_dual_ray) {
+      _dual_ray = _prob->infeasibilityRay();
+      LEMON_ASSERT(_dual_ray != 0, "Dual ray is not provided");
+    }
+    return _dual_ray[i];
+  }
+
+  LpClp::VarStatus LpClp::_getColStatus(int i) const {
+    switch (_prob->getColumnStatus(i)) {
+    case ClpSimplex::basic:
+      return BASIC;
+    case ClpSimplex::isFree:
+      return FREE;
+    case ClpSimplex::atUpperBound:
+      return UPPER;
+    case ClpSimplex::atLowerBound:
+      return LOWER;
+    case ClpSimplex::isFixed:
+      return FIXED;
+    case ClpSimplex::superBasic:
+      return FREE;
+    default:
+      LEMON_ASSERT(false, "Wrong column status");
+      return VarStatus();
+    }
+  }
+
+  LpClp::VarStatus LpClp::_getRowStatus(int i) const {
+    switch (_prob->getColumnStatus(i)) {
+    case ClpSimplex::basic:
+      return BASIC;
+    case ClpSimplex::isFree:
+      return FREE;
+    case ClpSimplex::atUpperBound:
+      return UPPER;
+    case ClpSimplex::atLowerBound:
+      return LOWER;
+    case ClpSimplex::isFixed:
+      return FIXED;
+    case ClpSimplex::superBasic:
+      return FREE;
+    default:
+      LEMON_ASSERT(false, "Wrong row status");
+      return VarStatus();
+    }
+  }
+
+
+  LpClp::ProblemType LpClp::_getPrimalType() const {
+    if (_prob->isProvenOptimal()) {
+      return OPTIMAL;
+    } else if (_prob->isProvenPrimalInfeasible()) {
+      return INFEASIBLE;
+    } else if (_prob->isProvenDualInfeasible()) {
+      return UNBOUNDED;
+    } else {
+      return UNDEFINED;
+    }
+  }
+
+  LpClp::ProblemType LpClp::_getDualType() const {
+    if (_prob->isProvenOptimal()) {
+      return OPTIMAL;
+    } else if (_prob->isProvenDualInfeasible()) {
+      return INFEASIBLE;
+    } else if (_prob->isProvenPrimalInfeasible()) {
+      return INFEASIBLE;
+    } else {
+      return UNDEFINED;
+    }
+  }
+
+  void LpClp::_setSense(LpClp::Sense sense) {
+    switch (sense) {
+    case MIN:
+      _prob->setOptimizationDirection(1);
+      break;
+    case MAX:
+      _prob->setOptimizationDirection(-1);
+      break;
+    }
+  }
+
+  LpClp::Sense LpClp::_getSense() const {
+    double dir = _prob->optimizationDirection();
+    if (dir > 0.0) {
+      return MIN;
+    } else {
+      return MAX;
+    }
+  }
+
+  void LpClp::_clear() {
+    delete _prob;
+    _prob = new ClpSimplex();
+    rows.clear();
+    cols.clear();
+    _col_names_ref.clear();
+    _clear_temporals();
+  }
+
+  void LpClp::messageLevel(MessageLevel m) {
+    _prob->setLogLevel(static_cast<int>(m));
+  }
+
+} //END OF NAMESPACE LEMON
Index: lemon/lp_clp.h
===================================================================
--- lemon/lp_clp.h	(revision 459)
+++ lemon/lp_clp.h	(revision 459)
@@ -0,0 +1,179 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * 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_LP_CLP_H
+#define LEMON_LP_CLP_H
+
+///\file
+///\brief Header of the LEMON-CLP lp solver interface.
+
+#include <vector>
+#include <string>
+
+#include <lemon/lp_base.h>
+
+class ClpSimplex;
+
+namespace lemon {
+
+  /// \ingroup lp_group
+  ///
+  /// \brief Interface for the CLP solver
+  ///
+  /// This class implements an interface for the Clp LP solver.  The
+  /// Clp library is an object oriented lp solver library developed at
+  /// the IBM. The CLP is part of the COIN-OR package and it can be
+  /// used with Common Public License.
+  class LpClp : public LpSolver {
+  protected:
+
+    ClpSimplex* _prob;
+
+    std::map<std::string, int> _col_names_ref;
+    std::map<std::string, int> _row_names_ref;
+
+  public:
+
+    /// \e
+    LpClp();
+    /// \e
+    LpClp(const LpClp&);
+    /// \e
+    ~LpClp();
+
+  protected:
+
+    mutable double* _primal_ray;
+    mutable double* _dual_ray;
+
+    void _init_temporals();
+    void _clear_temporals();
+
+  protected:
+
+    virtual LpClp* _newSolver() const;
+    virtual LpClp* _cloneSolver() const;
+
+    virtual const char* _solverName() const;
+
+    virtual int _addCol();
+    virtual int _addRow();
+
+    virtual void _eraseCol(int i);
+    virtual void _eraseRow(int i);
+
+    virtual void _eraseColId(int i);
+    virtual void _eraseRowId(int i);
+
+    virtual void _getColName(int col, std::string& name) const;
+    virtual void _setColName(int col, const std::string& name);
+    virtual int _colByName(const std::string& name) const;
+
+    virtual void _getRowName(int row, std::string& name) const;
+    virtual void _setRowName(int row, const std::string& name);
+    virtual int _rowByName(const std::string& name) const;
+
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getRowCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getColCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setCoeff(int row, int col, Value value);
+    virtual Value _getCoeff(int row, int col) const;
+
+    virtual void _setColLowerBound(int i, Value value);
+    virtual Value _getColLowerBound(int i) const;
+    virtual void _setColUpperBound(int i, Value value);
+    virtual Value _getColUpperBound(int i) const;
+
+    virtual void _setRowLowerBound(int i, Value value);
+    virtual Value _getRowLowerBound(int i) const;
+    virtual void _setRowUpperBound(int i, Value value);
+    virtual Value _getRowUpperBound(int i) const;
+
+    virtual void _setObjCoeffs(ExprIterator, ExprIterator);
+    virtual void _getObjCoeffs(InsertIterator) const;
+
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    virtual Value _getObjCoeff(int i) const;
+
+    virtual void _setSense(Sense sense);
+    virtual Sense _getSense() const;
+
+    virtual SolveExitStatus _solve();
+
+    virtual Value _getPrimal(int i) const;
+    virtual Value _getDual(int i) const;
+
+    virtual Value _getPrimalValue() const;
+
+    virtual Value _getPrimalRay(int i) const;
+    virtual Value _getDualRay(int i) const;
+
+    virtual VarStatus _getColStatus(int i) const;
+    virtual VarStatus _getRowStatus(int i) const;
+
+    virtual ProblemType _getPrimalType() const;
+    virtual ProblemType _getDualType() const;
+
+    virtual void _clear();
+
+  public:
+
+    ///Solves LP with primal simplex method.
+    SolveExitStatus solvePrimal();
+
+    ///Solves LP with dual simplex method.
+    SolveExitStatus solveDual();
+
+    ///Solves LP with barrier method.
+    SolveExitStatus solveBarrier();
+
+    ///Returns the constraint identifier understood by CLP.
+    int clpRow(Row r) const { return rows(id(r)); }
+
+    ///Returns the variable identifier understood by CLP.
+    int clpCol(Col c) const { return cols(id(c)); }
+
+    ///Enum for \c messageLevel() parameter
+    enum MessageLevel {
+      /// no output (default value)
+      MESSAGE_NO_OUTPUT = 0,
+      /// print final solution
+      MESSAGE_FINAL_SOLUTION = 1,
+      /// print factorization
+      MESSAGE_FACTORIZATION = 2,
+      /// normal output
+      MESSAGE_NORMAL_OUTPUT = 3,
+      /// verbose output
+      MESSAGE_VERBOSE_OUTPUT = 4
+    };
+    ///Set the verbosity of the messages
+
+    ///Set the verbosity of the messages
+    ///
+    ///\param m is the level of the messages output by the solver routines.
+    void messageLevel(MessageLevel m);
+
+  };
+
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_LP_CLP_H
+
Index: lemon/lp_cplex.cc
===================================================================
--- lemon/lp_cplex.cc	(revision 459)
+++ lemon/lp_cplex.cc	(revision 459)
@@ -0,0 +1,925 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * 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 <vector>
+#include <cstring>
+
+#include <lemon/lp_cplex.h>
+
+extern "C" {
+#include <ilcplex/cplex.h>
+}
+
+
+///\file
+///\brief Implementation of the LEMON-CPLEX lp solver interface.
+namespace lemon {
+
+  CplexEnv::LicenseError::LicenseError(int status) {
+    if (!CPXgeterrorstring(0, status, _message)) {
+      std::strcpy(_message, "Cplex unknown error");
+    }
+  }
+
+  CplexEnv::CplexEnv() {
+    int status;
+    _cnt = new int;
+    _env = CPXopenCPLEX(&status);
+    if (_env == 0) {
+      delete _cnt;
+      _cnt = 0;
+      throw LicenseError(status);
+    }
+  }
+
+  CplexEnv::CplexEnv(const CplexEnv& other) {
+    _env = other._env;
+    _cnt = other._cnt;
+    ++(*_cnt);
+  }
+
+  CplexEnv& CplexEnv::operator=(const CplexEnv& other) {
+    _env = other._env;
+    _cnt = other._cnt;
+    ++(*_cnt);
+    return *this;
+  }
+
+  CplexEnv::~CplexEnv() {
+    --(*_cnt);
+    if (*_cnt == 0) {
+      delete _cnt;
+      CPXcloseCPLEX(&_env);
+    }
+  }
+
+  CplexBase::CplexBase() : LpBase() {
+    int status;
+    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
+  }
+
+  CplexBase::CplexBase(const CplexEnv& env)
+    : LpBase(), _env(env) {
+    int status;
+    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
+  }
+
+  CplexBase::CplexBase(const CplexBase& cplex)
+    : LpBase() {
+    int status;
+    _prob = CPXcloneprob(cplexEnv(), cplex._prob, &status);
+    rows = cplex.rows;
+    cols = cplex.cols;
+  }
+
+  CplexBase::~CplexBase() {
+    CPXfreeprob(cplexEnv(),&_prob);
+  }
+
+  int CplexBase::_addCol() {
+    int i = CPXgetnumcols(cplexEnv(), _prob);
+    double lb = -INF, ub = INF;
+    CPXnewcols(cplexEnv(), _prob, 1, 0, &lb, &ub, 0, 0);
+    return i;
+  }
+
+
+  int CplexBase::_addRow() {
+    int i = CPXgetnumrows(cplexEnv(), _prob);
+    const double ub = INF;
+    const char s = 'L';
+    CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
+    return i;
+  }
+
+
+  void CplexBase::_eraseCol(int i) {
+    CPXdelcols(cplexEnv(), _prob, i, i);
+  }
+
+  void CplexBase::_eraseRow(int i) {
+    CPXdelrows(cplexEnv(), _prob, i, i);
+  }
+
+  void CplexBase::_eraseColId(int i) {
+    cols.eraseIndex(i);
+    cols.shiftIndices(i);
+  }
+  void CplexBase::_eraseRowId(int i) {
+    rows.eraseIndex(i);
+    rows.shiftIndices(i);
+  }
+
+  void CplexBase::_getColName(int col, std::string &name) const {
+    int size;
+    CPXgetcolname(cplexEnv(), _prob, 0, 0, 0, &size, col, col);
+    if (size == 0) {
+      name.clear();
+      return;
+    }
+
+    size *= -1;
+    std::vector<char> buf(size);
+    char *cname;
+    int tmp;
+    CPXgetcolname(cplexEnv(), _prob, &cname, &buf.front(), size,
+                  &tmp, col, col);
+    name = cname;
+  }
+
+  void CplexBase::_setColName(int col, const std::string &name) {
+    char *cname;
+    cname = const_cast<char*>(name.c_str());
+    CPXchgcolname(cplexEnv(), _prob, 1, &col, &cname);
+  }
+
+  int CplexBase::_colByName(const std::string& name) const {
+    int index;
+    if (CPXgetcolindex(cplexEnv(), _prob,
+                       const_cast<char*>(name.c_str()), &index) == 0) {
+      return index;
+    }
+    return -1;
+  }
+
+  void CplexBase::_getRowName(int row, std::string &name) const {
+    int size;
+    CPXgetrowname(cplexEnv(), _prob, 0, 0, 0, &size, row, row);
+    if (size == 0) {
+      name.clear();
+      return;
+    }
+
+    size *= -1;
+    std::vector<char> buf(size);
+    char *cname;
+    int tmp;
+    CPXgetrowname(cplexEnv(), _prob, &cname, &buf.front(), size,
+                  &tmp, row, row);
+    name = cname;
+  }
+
+  void CplexBase::_setRowName(int row, const std::string &name) {
+    char *cname;
+    cname = const_cast<char*>(name.c_str());
+    CPXchgrowname(cplexEnv(), _prob, 1, &row, &cname);
+  }
+
+  int CplexBase::_rowByName(const std::string& name) const {
+    int index;
+    if (CPXgetrowindex(cplexEnv(), _prob,
+                       const_cast<char*>(name.c_str()), &index) == 0) {
+      return index;
+    }
+    return -1;
+  }
+
+  void CplexBase::_setRowCoeffs(int i, ExprIterator b,
+                                      ExprIterator e)
+  {
+    std::vector<int> indices;
+    std::vector<int> rowlist;
+    std::vector<Value> values;
+
+    for(ExprIterator it=b; it!=e; ++it) {
+      indices.push_back(it->first);
+      values.push_back(it->second);
+      rowlist.push_back(i);
+    }
+
+    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
+                   &rowlist.front(), &indices.front(), &values.front());
+  }
+
+  void CplexBase::_getRowCoeffs(int i, InsertIterator b) const {
+    int tmp1, tmp2, tmp3, length;
+    CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
+
+    length = -length;
+    std::vector<int> indices(length);
+    std::vector<double> values(length);
+
+    CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2,
+               &indices.front(), &values.front(),
+               length, &tmp3, i, i);
+
+    for (int i = 0; i < length; ++i) {
+      *b = std::make_pair(indices[i], values[i]);
+      ++b;
+    }
+  }
+
+  void CplexBase::_setColCoeffs(int i, ExprIterator b, ExprIterator e) {
+    std::vector<int> indices;
+    std::vector<int> collist;
+    std::vector<Value> values;
+
+    for(ExprIterator it=b; it!=e; ++it) {
+      indices.push_back(it->first);
+      values.push_back(it->second);
+      collist.push_back(i);
+    }
+
+    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
+                   &indices.front(), &collist.front(), &values.front());
+  }
+
+  void CplexBase::_getColCoeffs(int i, InsertIterator b) const {
+
+    int tmp1, tmp2, tmp3, length;
+    CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
+
+    length = -length;
+    std::vector<int> indices(length);
+    std::vector<double> values(length);
+
+    CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2,
+               &indices.front(), &values.front(),
+               length, &tmp3, i, i);
+
+    for (int i = 0; i < length; ++i) {
+      *b = std::make_pair(indices[i], values[i]);
+      ++b;
+    }
+
+  }
+
+  void CplexBase::_setCoeff(int row, int col, Value value) {
+    CPXchgcoef(cplexEnv(), _prob, row, col, value);
+  }
+
+  CplexBase::Value CplexBase::_getCoeff(int row, int col) const {
+    CplexBase::Value value;
+    CPXgetcoef(cplexEnv(), _prob, row, col, &value);
+    return value;
+  }
+
+  void CplexBase::_setColLowerBound(int i, Value value) {
+    const char s = 'L';
+    CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value);
+  }
+
+  CplexBase::Value CplexBase::_getColLowerBound(int i) const {
+    CplexBase::Value res;
+    CPXgetlb(cplexEnv(), _prob, &res, i, i);
+    return res <= -CPX_INFBOUND ? -INF : res;
+  }
+
+  void CplexBase::_setColUpperBound(int i, Value value)
+  {
+    const char s = 'U';
+    CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value);
+  }
+
+  CplexBase::Value CplexBase::_getColUpperBound(int i) const {
+    CplexBase::Value res;
+    CPXgetub(cplexEnv(), _prob, &res, i, i);
+    return res >= CPX_INFBOUND ? INF : res;
+  }
+
+  CplexBase::Value CplexBase::_getRowLowerBound(int i) const {
+    char s;
+    CPXgetsense(cplexEnv(), _prob, &s, i, i);
+    CplexBase::Value res;
+
+    switch (s) {
+    case 'G':
+    case 'R':
+    case 'E':
+      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
+      return res <= -CPX_INFBOUND ? -INF : res;
+    default:
+      return -INF;
+    }
+  }
+
+  CplexBase::Value CplexBase::_getRowUpperBound(int i) const {
+    char s;
+    CPXgetsense(cplexEnv(), _prob, &s, i, i);
+    CplexBase::Value res;
+
+    switch (s) {
+    case 'L':
+    case 'E':
+      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
+      return res >= CPX_INFBOUND ? INF : res;
+    case 'R':
+      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
+      {
+        double rng;
+        CPXgetrngval(cplexEnv(), _prob, &rng, i, i);
+        res += rng;
+      }
+      return res >= CPX_INFBOUND ? INF : res;
+    default:
+      return INF;
+    }
+  }
+
+  //This is easier to implement
+  void CplexBase::_set_row_bounds(int i, Value lb, Value ub) {
+    if (lb == -INF) {
+      const char s = 'L';
+      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
+      CPXchgrhs(cplexEnv(), _prob, 1, &i, &ub);
+    } else if (ub == INF) {
+      const char s = 'G';
+      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
+      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
+    } else if (lb == ub){
+      const char s = 'E';
+      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
+      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
+    } else {
+      const char s = 'R';
+      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
+      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
+      double len = ub - lb;
+      CPXchgrngval(cplexEnv(), _prob, 1, &i, &len);
+    }
+  }
+
+  void CplexBase::_setRowLowerBound(int i, Value lb)
+  {
+    LEMON_ASSERT(lb != INF, "Invalid bound");
+    _set_row_bounds(i, lb, CplexBase::_getRowUpperBound(i));
+  }
+
+  void CplexBase::_setRowUpperBound(int i, Value ub)
+  {
+
+    LEMON_ASSERT(ub != -INF, "Invalid bound");
+    _set_row_bounds(i, CplexBase::_getRowLowerBound(i), ub);
+  }
+
+  void CplexBase::_setObjCoeffs(ExprIterator b, ExprIterator e)
+  {
+    std::vector<int> indices;
+    std::vector<Value> values;
+    for(ExprIterator it=b; it!=e; ++it) {
+      indices.push_back(it->first);
+      values.push_back(it->second);
+    }
+    CPXchgobj(cplexEnv(), _prob, values.size(),
+              &indices.front(), &values.front());
+
+  }
+
+  void CplexBase::_getObjCoeffs(InsertIterator b) const
+  {
+    int num = CPXgetnumcols(cplexEnv(), _prob);
+    std::vector<Value> x(num);
+
+    CPXgetobj(cplexEnv(), _prob, &x.front(), 0, num - 1);
+    for (int i = 0; i < num; ++i) {
+      if (x[i] != 0.0) {
+        *b = std::make_pair(i, x[i]);
+        ++b;
+      }
+    }
+  }
+
+  void CplexBase::_setObjCoeff(int i, Value obj_coef)
+  {
+    CPXchgobj(cplexEnv(), _prob, 1, &i, &obj_coef);
+  }
+
+  CplexBase::Value CplexBase::_getObjCoeff(int i) const
+  {
+    Value x;
+    CPXgetobj(cplexEnv(), _prob, &x, i, i);
+    return x;
+  }
+
+  void CplexBase::_setSense(CplexBase::Sense sense) {
+    switch (sense) {
+    case MIN:
+      CPXchgobjsen(cplexEnv(), _prob, CPX_MIN);
+      break;
+    case MAX:
+      CPXchgobjsen(cplexEnv(), _prob, CPX_MAX);
+      break;
+    }
+  }
+
+  CplexBase::Sense CplexBase::_getSense() const {
+    switch (CPXgetobjsen(cplexEnv(), _prob)) {
+    case CPX_MIN:
+      return MIN;
+    case CPX_MAX:
+      return MAX;
+    default:
+      LEMON_ASSERT(false, "Invalid sense");
+      return CplexBase::Sense();
+    }
+  }
+
+  void CplexBase::_clear() {
+    CPXfreeprob(cplexEnv(),&_prob);
+    int status;
+    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
+    rows.clear();
+    cols.clear();
+  }
+
+  // LpCplex members
+
+  LpCplex::LpCplex()
+    : LpBase(), CplexBase(), LpSolver() {}
+
+  LpCplex::LpCplex(const CplexEnv& env)
+    : LpBase(), CplexBase(env), LpSolver() {}
+
+  LpCplex::LpCplex(const LpCplex& other)
+    : LpBase(), CplexBase(other), LpSolver() {}
+
+  LpCplex::~LpCplex() {}
+
+  LpCplex* LpCplex::_newSolver() const { return new LpCplex; }
+  LpCplex* LpCplex::_cloneSolver() const {return new LpCplex(*this); }
+
+  const char* LpCplex::_solverName() const { return "LpCplex"; }
+
+  void LpCplex::_clear_temporals() {
+    _col_status.clear();
+    _row_status.clear();
+    _primal_ray.clear();
+    _dual_ray.clear();
+  }
+
+  // The routine returns zero unless an error occurred during the
+  // optimization. Examples of errors include exhausting available
+  // memory (CPXERR_NO_MEMORY) or encountering invalid data in the
+  // CPLEX problem object (CPXERR_NO_PROBLEM). Exceeding a
+  // user-specified CPLEX limit, or proving the model infeasible or
+  // unbounded, are not considered errors. Note that a zero return
+  // value does not necessarily mean that a solution exists. Use query
+  // routines CPXsolninfo, CPXgetstat, and CPXsolution to obtain
+  // further information about the status of the optimization.
+  LpCplex::SolveExitStatus LpCplex::convertStatus(int status) {
+#if CPX_VERSION >= 800
+    if (status == 0) {
+      switch (CPXgetstat(cplexEnv(), _prob)) {
+      case CPX_STAT_OPTIMAL:
+      case CPX_STAT_INFEASIBLE:
+      case CPX_STAT_UNBOUNDED:
+        return SOLVED;
+      default:
+        return UNSOLVED;
+      }
+    } else {
+      return UNSOLVED;
+    }
+#else
+    if (status == 0) {
+      //We want to exclude some cases
+      switch (CPXgetstat(cplexEnv(), _prob)) {
+      case CPX_OBJ_LIM:
+      case CPX_IT_LIM_FEAS:
+      case CPX_IT_LIM_INFEAS:
+      case CPX_TIME_LIM_FEAS:
+      case CPX_TIME_LIM_INFEAS:
+        return UNSOLVED;
+      default:
+        return SOLVED;
+      }
+    } else {
+      return UNSOLVED;
+    }
+#endif
+  }
+
+  LpCplex::SolveExitStatus LpCplex::_solve() {
+    _clear_temporals();
+    return convertStatus(CPXlpopt(cplexEnv(), _prob));
+  }
+
+  LpCplex::SolveExitStatus LpCplex::solvePrimal() {
+    _clear_temporals();
+    return convertStatus(CPXprimopt(cplexEnv(), _prob));
+  }
+
+  LpCplex::SolveExitStatus LpCplex::solveDual() {
+    _clear_temporals();
+    return convertStatus(CPXdualopt(cplexEnv(), _prob));
+  }
+
+  LpCplex::SolveExitStatus LpCplex::solveBarrier() {
+    _clear_temporals();
+    return convertStatus(CPXbaropt(cplexEnv(), _prob));
+  }
+
+  LpCplex::Value LpCplex::_getPrimal(int i) const {
+    Value x;
+    CPXgetx(cplexEnv(), _prob, &x, i, i);
+    return x;
+  }
+
+  LpCplex::Value LpCplex::_getDual(int i) const {
+    Value y;
+    CPXgetpi(cplexEnv(), _prob, &y, i, i);
+    return y;
+  }
+
+  LpCplex::Value LpCplex::_getPrimalValue() const {
+    Value objval;
+    CPXgetobjval(cplexEnv(), _prob, &objval);
+    return objval;
+  }
+
+  LpCplex::VarStatus LpCplex::_getColStatus(int i) const {
+    if (_col_status.empty()) {
+      _col_status.resize(CPXgetnumcols(cplexEnv(), _prob));
+      CPXgetbase(cplexEnv(), _prob, &_col_status.front(), 0);
+    }
+    switch (_col_status[i]) {
+    case CPX_BASIC:
+      return BASIC;
+    case CPX_FREE_SUPER:
+      return FREE;
+    case CPX_AT_LOWER:
+      return LOWER;
+    case CPX_AT_UPPER:
+      return UPPER;
+    default:
+      LEMON_ASSERT(false, "Wrong column status");
+      return LpCplex::VarStatus();
+    }
+  }
+
+  LpCplex::VarStatus LpCplex::_getRowStatus(int i) const {
+    if (_row_status.empty()) {
+      _row_status.resize(CPXgetnumrows(cplexEnv(), _prob));
+      CPXgetbase(cplexEnv(), _prob, 0, &_row_status.front());
+    }
+    switch (_row_status[i]) {
+    case CPX_BASIC:
+      return BASIC;
+    case CPX_AT_LOWER:
+      {
+        char s;
+        CPXgetsense(cplexEnv(), _prob, &s, i, i);
+        return s != 'L' ? LOWER : UPPER;
+      }
+    case CPX_AT_UPPER:
+      return UPPER;
+    default:
+      LEMON_ASSERT(false, "Wrong row status");
+      return LpCplex::VarStatus();
+    }
+  }
+
+  LpCplex::Value LpCplex::_getPrimalRay(int i) const {
+    if (_primal_ray.empty()) {
+      _primal_ray.resize(CPXgetnumcols(cplexEnv(), _prob));
+      CPXgetray(cplexEnv(), _prob, &_primal_ray.front());
+    }
+    return _primal_ray[i];
+  }
+
+  LpCplex::Value LpCplex::_getDualRay(int i) const {
+    if (_dual_ray.empty()) {
+
+    }
+    return _dual_ray[i];
+  }
+
+  //7.5-os cplex statusai (Vigyazat: a 9.0-asei masok!)
+  // This table lists the statuses, returned by the CPXgetstat()
+  // routine, for solutions to LP problems or mixed integer problems. If
+  // no solution exists, the return value is zero.
+
+  // For Simplex, Barrier
+  // 1          CPX_OPTIMAL
+  //          Optimal solution found
+  // 2          CPX_INFEASIBLE
+  //          Problem infeasible
+  // 3    CPX_UNBOUNDED
+  //          Problem unbounded
+  // 4          CPX_OBJ_LIM
+  //          Objective limit exceeded in Phase II
+  // 5          CPX_IT_LIM_FEAS
+  //          Iteration limit exceeded in Phase II
+  // 6          CPX_IT_LIM_INFEAS
+  //          Iteration limit exceeded in Phase I
+  // 7          CPX_TIME_LIM_FEAS
+  //          Time limit exceeded in Phase II
+  // 8          CPX_TIME_LIM_INFEAS
+  //          Time limit exceeded in Phase I
+  // 9          CPX_NUM_BEST_FEAS
+  //          Problem non-optimal, singularities in Phase II
+  // 10         CPX_NUM_BEST_INFEAS
+  //          Problem non-optimal, singularities in Phase I
+  // 11         CPX_OPTIMAL_INFEAS
+  //          Optimal solution found, unscaled infeasibilities
+  // 12         CPX_ABORT_FEAS
+  //          Aborted in Phase II
+  // 13         CPX_ABORT_INFEAS
+  //          Aborted in Phase I
+  // 14          CPX_ABORT_DUAL_INFEAS
+  //          Aborted in barrier, dual infeasible
+  // 15          CPX_ABORT_PRIM_INFEAS
+  //          Aborted in barrier, primal infeasible
+  // 16          CPX_ABORT_PRIM_DUAL_INFEAS
+  //          Aborted in barrier, primal and dual infeasible
+  // 17          CPX_ABORT_PRIM_DUAL_FEAS
+  //          Aborted in barrier, primal and dual feasible
+  // 18          CPX_ABORT_CROSSOVER
+  //          Aborted in crossover
+  // 19          CPX_INForUNBD
+  //          Infeasible or unbounded
+  // 20   CPX_PIVOT
+  //       User pivot used
+  //
+  //     Ezeket hova tegyem:
+  // ??case CPX_ABORT_DUAL_INFEAS
+  // ??case CPX_ABORT_CROSSOVER
+  // ??case CPX_INForUNBD
+  // ??case CPX_PIVOT
+
+  //Some more interesting stuff:
+
+  // CPX_PARAM_PROBMETHOD  1062  int  LPMETHOD
+  // 0 Automatic
+  // 1 Primal Simplex
+  // 2 Dual Simplex
+  // 3 Network Simplex
+  // 4 Standard Barrier
+  // Default: 0
+  // Description: Method for linear optimization.
+  // Determines which algorithm is used when CPXlpopt() (or "optimize"
+  // in the Interactive Optimizer) is called. Currently the behavior of
+  // the "Automatic" setting is that CPLEX simply invokes the dual
+  // simplex method, but this capability may be expanded in the future
+  // so that CPLEX chooses the method based on problem characteristics
+#if CPX_VERSION < 900
+  void statusSwitch(CPXENVptr cplexEnv(),int& stat){
+    int lpmethod;
+    CPXgetintparam (cplexEnv(),CPX_PARAM_PROBMETHOD,&lpmethod);
+    if (lpmethod==2){
+      if (stat==CPX_UNBOUNDED){
+        stat=CPX_INFEASIBLE;
+      }
+      else{
+        if (stat==CPX_INFEASIBLE)
+          stat=CPX_UNBOUNDED;
+      }
+    }
+  }
+#else
+  void statusSwitch(CPXENVptr,int&){}
+#endif
+
+  LpCplex::ProblemType LpCplex::_getPrimalType() const {
+    // Unboundedness not treated well: the following is from cplex 9.0 doc
+    // About Unboundedness
+
+    // The treatment of models that are unbounded involves a few
+    // subtleties. Specifically, a declaration of unboundedness means that
+    // ILOG CPLEX has determined that the model has an unbounded
+    // ray. Given any feasible solution x with objective z, a multiple of
+    // the unbounded ray can be added to x to give a feasible solution
+    // with objective z-1 (or z+1 for maximization models). Thus, if a
+    // feasible solution exists, then the optimal objective is
+    // unbounded. Note that ILOG CPLEX has not necessarily concluded that
+    // a feasible solution exists. Users can call the routine CPXsolninfo
+    // to determine whether ILOG CPLEX has also concluded that the model
+    // has a feasible solution.
+
+    int stat = CPXgetstat(cplexEnv(), _prob);
+#if CPX_VERSION >= 800
+    switch (stat)
+      {
+      case CPX_STAT_OPTIMAL:
+        return OPTIMAL;
+      case CPX_STAT_UNBOUNDED:
+        return UNBOUNDED;
+      case CPX_STAT_INFEASIBLE:
+        return INFEASIBLE;
+      default:
+        return UNDEFINED;
+      }
+#else
+    statusSwitch(cplexEnv(),stat);
+    //CPXgetstat(cplexEnv(), _prob);
+    //printf("A primal status: %d, CPX_OPTIMAL=%d \n",stat,CPX_OPTIMAL);
+    switch (stat) {
+    case 0:
+      return UNDEFINED; //Undefined
+    case CPX_OPTIMAL://Optimal
+      return OPTIMAL;
+    case CPX_UNBOUNDED://Unbounded
+      return INFEASIBLE;//In case of dual simplex
+      //return UNBOUNDED;
+    case CPX_INFEASIBLE://Infeasible
+      //    case CPX_IT_LIM_INFEAS:
+      //     case CPX_TIME_LIM_INFEAS:
+      //     case CPX_NUM_BEST_INFEAS:
+      //     case CPX_OPTIMAL_INFEAS:
+      //     case CPX_ABORT_INFEAS:
+      //     case CPX_ABORT_PRIM_INFEAS:
+      //     case CPX_ABORT_PRIM_DUAL_INFEAS:
+      return UNBOUNDED;//In case of dual simplex
+      //return INFEASIBLE;
+      //     case CPX_OBJ_LIM:
+      //     case CPX_IT_LIM_FEAS:
+      //     case CPX_TIME_LIM_FEAS:
+      //     case CPX_NUM_BEST_FEAS:
+      //     case CPX_ABORT_FEAS:
+      //     case CPX_ABORT_PRIM_DUAL_FEAS:
+      //       return FEASIBLE;
+    default:
+      return UNDEFINED; //Everything else comes here
+      //FIXME error
+    }
+#endif
+  }
+
+  //9.0-as cplex verzio statusai
+  // CPX_STAT_ABORT_DUAL_OBJ_LIM
+  // CPX_STAT_ABORT_IT_LIM
+  // CPX_STAT_ABORT_OBJ_LIM
+  // CPX_STAT_ABORT_PRIM_OBJ_LIM
+  // CPX_STAT_ABORT_TIME_LIM
+  // CPX_STAT_ABORT_USER
+  // CPX_STAT_FEASIBLE_RELAXED
+  // CPX_STAT_INFEASIBLE
+  // CPX_STAT_INForUNBD
+  // CPX_STAT_NUM_BEST
+  // CPX_STAT_OPTIMAL
+  // CPX_STAT_OPTIMAL_FACE_UNBOUNDED
+  // CPX_STAT_OPTIMAL_INFEAS
+  // CPX_STAT_OPTIMAL_RELAXED
+  // CPX_STAT_UNBOUNDED
+
+  LpCplex::ProblemType LpCplex::_getDualType() const {
+    int stat = CPXgetstat(cplexEnv(), _prob);
+#if CPX_VERSION >= 800
+    switch (stat) {
+    case CPX_STAT_OPTIMAL:
+      return OPTIMAL;
+    case CPX_STAT_UNBOUNDED:
+      return INFEASIBLE;
+    default:
+      return UNDEFINED;
+    }
+#else
+    statusSwitch(cplexEnv(),stat);
+    switch (stat) {
+    case 0:
+      return UNDEFINED; //Undefined
+    case CPX_OPTIMAL://Optimal
+      return OPTIMAL;
+    case CPX_UNBOUNDED:
+      return INFEASIBLE;
+    default:
+      return UNDEFINED; //Everything else comes here
+      //FIXME error
+    }
+#endif
+  }
+
+  // MipCplex members
+
+  MipCplex::MipCplex()
+    : LpBase(), CplexBase(), MipSolver() {
+
+#if CPX_VERSION < 800
+    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MIP);
+#else
+    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MILP);
+#endif
+  }
+
+  MipCplex::MipCplex(const CplexEnv& env)
+    : LpBase(), CplexBase(env), MipSolver() {
+
+#if CPX_VERSION < 800
+    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MIP);
+#else
+    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MILP);
+#endif
+
+  }
+
+  MipCplex::MipCplex(const MipCplex& other)
+    : LpBase(), CplexBase(other), MipSolver() {}
+
+  MipCplex::~MipCplex() {}
+
+  MipCplex* MipCplex::_newSolver() const { return new MipCplex; }
+  MipCplex* MipCplex::_cloneSolver() const {return new MipCplex(*this); }
+
+  const char* MipCplex::_solverName() const { return "MipCplex"; }
+
+  void MipCplex::_setColType(int i, MipCplex::ColTypes col_type) {
+
+    // Note If a variable is to be changed to binary, a call to CPXchgbds
+    // should also be made to change the bounds to 0 and 1.
+
+    switch (col_type){
+    case INTEGER: {
+      const char t = 'I';
+      CPXchgctype (cplexEnv(), _prob, 1, &i, &t);
+    } break;
+    case REAL: {
+      const char t = 'C';
+      CPXchgctype (cplexEnv(), _prob, 1, &i, &t);
+    } break;
+    default:
+      break;
+    }
+  }
+
+  MipCplex::ColTypes MipCplex::_getColType(int i) const {
+    char t;
+    CPXgetctype (cplexEnv(), _prob, &t, i, i);
+    switch (t) {
+    case 'I':
+      return INTEGER;
+    case 'C':
+      return REAL;
+    default:
+      LEMON_ASSERT(false, "Invalid column type");
+      return ColTypes();
+    }
+
+  }
+
+  MipCplex::SolveExitStatus MipCplex::_solve() {
+    int status;
+    status = CPXmipopt (cplexEnv(), _prob);
+    if (status==0)
+      return SOLVED;
+    else
+      return UNSOLVED;
+
+  }
+
+
+  MipCplex::ProblemType MipCplex::_getType() const {
+
+    int stat = CPXgetstat(cplexEnv(), _prob);
+
+    //Fortunately, MIP statuses did not change for cplex 8.0
+    switch (stat) {
+    case CPXMIP_OPTIMAL:
+      // Optimal integer solution has been found.
+    case CPXMIP_OPTIMAL_TOL:
+      // Optimal soluton with the tolerance defined by epgap or epagap has
+      // been found.
+      return OPTIMAL;
+      //This also exists in later issues
+      //    case CPXMIP_UNBOUNDED:
+      //return UNBOUNDED;
+      case CPXMIP_INFEASIBLE:
+        return INFEASIBLE;
+    default:
+      return UNDEFINED;
+    }
+    //Unboundedness not treated well: the following is from cplex 9.0 doc
+    // About Unboundedness
+
+    // The treatment of models that are unbounded involves a few
+    // subtleties. Specifically, a declaration of unboundedness means that
+    // ILOG CPLEX has determined that the model has an unbounded
+    // ray. Given any feasible solution x with objective z, a multiple of
+    // the unbounded ray can be added to x to give a feasible solution
+    // with objective z-1 (or z+1 for maximization models). Thus, if a
+    // feasible solution exists, then the optimal objective is
+    // unbounded. Note that ILOG CPLEX has not necessarily concluded that
+    // a feasible solution exists. Users can call the routine CPXsolninfo
+    // to determine whether ILOG CPLEX has also concluded that the model
+    // has a feasible solution.
+  }
+
+  MipCplex::Value MipCplex::_getSol(int i) const {
+    Value x;
+    CPXgetmipx(cplexEnv(), _prob, &x, i, i);
+    return x;
+  }
+
+  MipCplex::Value MipCplex::_getSolValue() const {
+    Value objval;
+    CPXgetmipobjval(cplexEnv(), _prob, &objval);
+    return objval;
+  }
+
+} //namespace lemon
+
Index: lemon/lp_cplex.h
===================================================================
--- lemon/lp_cplex.h	(revision 459)
+++ lemon/lp_cplex.h	(revision 459)
@@ -0,0 +1,256 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * 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_LP_CPLEX_H
+#define LEMON_LP_CPLEX_H
+
+///\file
+///\brief Header of the LEMON-CPLEX lp solver interface.
+
+#include <lemon/lp_base.h>
+
+struct cpxenv;
+struct cpxlp;
+
+namespace lemon {
+
+  /// \brief Reference counted wrapper around cpxenv pointer
+  ///
+  /// The cplex uses environment object which is responsible for
+  /// checking the proper license usage. This class provides a simple
+  /// interface for share the environment object between different
+  /// problems.
+  class CplexEnv {
+    friend class CplexBase;
+  private:
+    cpxenv* _env;
+    mutable int* _cnt;
+
+  public:
+
+    /// \brief This exception is thrown when the license check is not
+    /// sufficient
+    class LicenseError : public Exception {
+      friend class CplexEnv;
+    private:
+
+      LicenseError(int status);
+      char _message[510];
+
+    public:
+
+      /// The short error message
+      virtual const char* what() const throw() {
+        return _message;
+      }
+    };
+
+    /// Constructor
+    CplexEnv();
+    /// Shallow copy constructor
+    CplexEnv(const CplexEnv&);
+    /// Shallow assignement
+    CplexEnv& operator=(const CplexEnv&);
+    /// Destructor
+    virtual ~CplexEnv();
+
+  protected:
+
+    cpxenv* cplexEnv() { return _env; }
+    const cpxenv* cplexEnv() const { return _env; }
+  };
+
+  /// \brief Base interface for the CPLEX LP and MIP solver
+  ///
+  /// This class implements the common interface of the CPLEX LP and
+  /// MIP solvers.  
+  /// \ingroup lp_group
+  class CplexBase : virtual public LpBase {
+  protected:
+
+    CplexEnv _env;
+    cpxlp* _prob;
+
+    CplexBase();
+    CplexBase(const CplexEnv&);
+    CplexBase(const CplexBase &);
+    virtual ~CplexBase();
+
+    virtual int _addCol();
+    virtual int _addRow();
+
+    virtual void _eraseCol(int i);
+    virtual void _eraseRow(int i);
+
+    virtual void _eraseColId(int i);
+    virtual void _eraseRowId(int i);
+
+    virtual void _getColName(int col, std::string& name) const;
+    virtual void _setColName(int col, const std::string& name);
+    virtual int _colByName(const std::string& name) const;
+
+    virtual void _getRowName(int row, std::string& name) const;
+    virtual void _setRowName(int row, const std::string& name);
+    virtual int _rowByName(const std::string& name) const;
+
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getRowCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getColCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setCoeff(int row, int col, Value value);
+    virtual Value _getCoeff(int row, int col) const;
+
+    virtual void _setColLowerBound(int i, Value value);
+    virtual Value _getColLowerBound(int i) const;
+
+    virtual void _setColUpperBound(int i, Value value);
+    virtual Value _getColUpperBound(int i) const;
+
+  private:
+    void _set_row_bounds(int i, Value lb, Value ub);
+  protected:
+
+    virtual void _setRowLowerBound(int i, Value value);
+    virtual Value _getRowLowerBound(int i) const;
+
+    virtual void _setRowUpperBound(int i, Value value);
+    virtual Value _getRowUpperBound(int i) const;
+
+    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
+    virtual void _getObjCoeffs(InsertIterator b) const;
+
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    virtual Value _getObjCoeff(int i) const;
+
+    virtual void _setSense(Sense sense);
+    virtual Sense _getSense() const;
+
+    virtual void _clear();
+
+  public:
+
+    /// Returns the used \c CplexEnv instance
+    const CplexEnv& env() const { return _env; }
+    ///
+    const cpxenv* cplexEnv() const { return _env.cplexEnv(); }
+
+    cpxlp* cplexLp() { return _prob; }
+    const cpxlp* cplexLp() const { return _prob; }
+
+  };
+
+  /// \brief Interface for the CPLEX LP solver
+  ///
+  /// This class implements an interface for the CPLEX LP solver.
+  ///\ingroup lp_group
+  class LpCplex : public CplexBase, public LpSolver {
+  public:
+    /// \e
+    LpCplex();
+    /// \e
+    LpCplex(const CplexEnv&);
+    /// \e
+    LpCplex(const LpCplex&);
+    /// \e
+    virtual ~LpCplex();
+
+  private:
+
+    // these values cannot retrieved element by element
+    mutable std::vector<int> _col_status;
+    mutable std::vector<int> _row_status;
+
+    mutable std::vector<Value> _primal_ray;
+    mutable std::vector<Value> _dual_ray;
+
+    void _clear_temporals();
+
+    SolveExitStatus convertStatus(int status);
+
+  protected:
+
+    virtual LpCplex* _cloneSolver() const;
+    virtual LpCplex* _newSolver() const;
+
+    virtual const char* _solverName() const;
+
+    virtual SolveExitStatus _solve();
+    virtual Value _getPrimal(int i) const;
+    virtual Value _getDual(int i) const;
+    virtual Value _getPrimalValue() const;
+
+    virtual VarStatus _getColStatus(int i) const;
+    virtual VarStatus _getRowStatus(int i) const;
+
+    virtual Value _getPrimalRay(int i) const;
+    virtual Value _getDualRay(int i) const;
+
+    virtual ProblemType _getPrimalType() const;
+    virtual ProblemType _getDualType() const;
+
+  public:
+
+    /// Solve with primal simplex method
+    SolveExitStatus solvePrimal();
+
+    /// Solve with dual simplex method
+    SolveExitStatus solveDual();
+
+    /// Solve with barrier method
+    SolveExitStatus solveBarrier();
+
+  };
+
+  /// \brief Interface for the CPLEX MIP solver
+  ///
+  /// This class implements an interface for the CPLEX MIP solver.
+  ///\ingroup lp_group
+  class MipCplex : public CplexBase, public MipSolver {
+  public:
+    /// \e
+    MipCplex();
+    /// \e
+    MipCplex(const CplexEnv&);
+    /// \e
+    MipCplex(const MipCplex&);
+    /// \e
+    virtual ~MipCplex();
+
+  protected:
+
+    virtual MipCplex* _cloneSolver() const;
+    virtual MipCplex* _newSolver() const;
+
+    virtual const char* _solverName() const;
+
+    virtual ColTypes _getColType(int col) const;
+    virtual void _setColType(int col, ColTypes col_type);
+
+    virtual SolveExitStatus _solve();
+    virtual ProblemType _getType() const;
+    virtual Value _getSol(int i) const;
+    virtual Value _getSolValue() const;
+
+  };
+
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_LP_CPLEX_H
+
Index: lemon/lp_glpk.cc
===================================================================
--- lemon/lp_glpk.cc	(revision 459)
+++ lemon/lp_glpk.cc	(revision 459)
@@ -0,0 +1,952 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * 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 Implementation of the LEMON GLPK LP and MIP solver interface.
+
+#include <lemon/lp_glpk.h>
+#include <glpk.h>
+
+#include <lemon/assert.h>
+
+namespace lemon {
+
+  // GlpkBase members
+
+  GlpkBase::GlpkBase() : LpBase() {
+    lp = glp_create_prob();
+    glp_create_index(lp);
+  }
+
+  GlpkBase::GlpkBase(const GlpkBase &other) : LpBase() {
+    lp = glp_create_prob();
+    glp_copy_prob(lp, other.lp, GLP_ON);
+    glp_create_index(lp);
+    rows = other.rows;
+    cols = other.cols;
+  }
+
+  GlpkBase::~GlpkBase() {
+    glp_delete_prob(lp);
+  }
+
+  int GlpkBase::_addCol() {
+    int i = glp_add_cols(lp, 1);
+    glp_set_col_bnds(lp, i, GLP_FR, 0.0, 0.0);
+    return i;
+  }
+
+  int GlpkBase::_addRow() {
+    int i = glp_add_rows(lp, 1);
+    glp_set_row_bnds(lp, i, GLP_FR, 0.0, 0.0);
+    return i;
+  }
+
+  void GlpkBase::_eraseCol(int i) {
+    int ca[2];
+    ca[1] = i;
+    glp_del_cols(lp, 1, ca);
+  }
+
+  void GlpkBase::_eraseRow(int i) {
+    int ra[2];
+    ra[1] = i;
+    glp_del_rows(lp, 1, ra);
+  }
+
+  void GlpkBase::_eraseColId(int i) {
+    cols.eraseIndex(i);
+    cols.shiftIndices(i);
+  }
+
+  void GlpkBase::_eraseRowId(int i) {
+    rows.eraseIndex(i);
+    rows.shiftIndices(i);
+  }
+
+  void GlpkBase::_getColName(int c, std::string& name) const {
+    const char *str = glp_get_col_name(lp, c);
+    if (str) name = str;
+    else name.clear();
+  }
+
+  void GlpkBase::_setColName(int c, const std::string & name) {
+    glp_set_col_name(lp, c, const_cast<char*>(name.c_str()));
+
+  }
+
+  int GlpkBase::_colByName(const std::string& name) const {
+    int k = glp_find_col(lp, const_cast<char*>(name.c_str()));
+    return k > 0 ? k : -1;
+  }
+
+  void GlpkBase::_getRowName(int r, std::string& name) const {
+    const char *str = glp_get_row_name(lp, r);
+    if (str) name = str;
+    else name.clear();
+  }
+
+  void GlpkBase::_setRowName(int r, const std::string & name) {
+    glp_set_row_name(lp, r, const_cast<char*>(name.c_str()));
+
+  }
+
+  int GlpkBase::_rowByName(const std::string& name) const {
+    int k = glp_find_row(lp, const_cast<char*>(name.c_str()));
+    return k > 0 ? k : -1;
+  }
+
+  void GlpkBase::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
+    std::vector<int> indexes;
+    std::vector<Value> values;
+
+    indexes.push_back(0);
+    values.push_back(0);
+
+    for(ExprIterator it = b; it != e; ++it) {
+      indexes.push_back(it->first);
+      values.push_back(it->second);
+    }
+
+    glp_set_mat_row(lp, i, values.size() - 1,
+                    &indexes.front(), &values.front());
+  }
+
+  void GlpkBase::_getRowCoeffs(int ix, InsertIterator b) const {
+    int length = glp_get_mat_row(lp, ix, 0, 0);
+
+    std::vector<int> indexes(length + 1);
+    std::vector<Value> values(length + 1);
+
+    glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
+
+    for (int i = 1; i <= length; ++i) {
+      *b = std::make_pair(indexes[i], values[i]);
+      ++b;
+    }
+  }
+
+  void GlpkBase::_setColCoeffs(int ix, ExprIterator b,
+                                     ExprIterator e) {
+
+    std::vector<int> indexes;
+    std::vector<Value> values;
+
+    indexes.push_back(0);
+    values.push_back(0);
+
+    for(ExprIterator it = b; it != e; ++it) {
+      indexes.push_back(it->first);
+      values.push_back(it->second);
+    }
+
+    glp_set_mat_col(lp, ix, values.size() - 1,
+                    &indexes.front(), &values.front());
+  }
+
+  void GlpkBase::_getColCoeffs(int ix, InsertIterator b) const {
+    int length = glp_get_mat_col(lp, ix, 0, 0);
+
+    std::vector<int> indexes(length + 1);
+    std::vector<Value> values(length + 1);
+
+    glp_get_mat_col(lp, ix, &indexes.front(), &values.front());
+
+    for (int i = 1; i  <= length; ++i) {
+      *b = std::make_pair(indexes[i], values[i]);
+      ++b;
+    }
+  }
+
+  void GlpkBase::_setCoeff(int ix, int jx, Value value) {
+
+    if (glp_get_num_cols(lp) < glp_get_num_rows(lp)) {
+
+      int length = glp_get_mat_row(lp, ix, 0, 0);
+
+      std::vector<int> indexes(length + 2);
+      std::vector<Value> values(length + 2);
+
+      glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
+
+      //The following code does not suppose that the elements of the
+      //array indexes are sorted
+      bool found = false;
+      for (int i = 1; i  <= length; ++i) {
+        if (indexes[i] == jx) {
+          found = true;
+          values[i] = value;
+          break;
+        }
+      }
+      if (!found) {
+        ++length;
+        indexes[length] = jx;
+        values[length] = value;
+      }
+
+      glp_set_mat_row(lp, ix, length, &indexes.front(), &values.front());
+
+    } else {
+
+      int length = glp_get_mat_col(lp, jx, 0, 0);
+
+      std::vector<int> indexes(length + 2);
+      std::vector<Value> values(length + 2);
+
+      glp_get_mat_col(lp, jx, &indexes.front(), &values.front());
+
+      //The following code does not suppose that the elements of the
+      //array indexes are sorted
+      bool found = false;
+      for (int i = 1; i <= length; ++i) {
+        if (indexes[i] == ix) {
+          found = true;
+          values[i] = value;
+          break;
+        }
+      }
+      if (!found) {
+        ++length;
+        indexes[length] = ix;
+        values[length] = value;
+      }
+
+      glp_set_mat_col(lp, jx, length, &indexes.front(), &values.front());
+    }
+
+  }
+
+  GlpkBase::Value GlpkBase::_getCoeff(int ix, int jx) const {
+
+    int length = glp_get_mat_row(lp, ix, 0, 0);
+
+    std::vector<int> indexes(length + 1);
+    std::vector<Value> values(length + 1);
+
+    glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
+
+    for (int i = 1; i  <= length; ++i) {
+      if (indexes[i] == jx) {
+        return values[i];
+      }
+    }
+
+    return 0;
+  }
+
+  void GlpkBase::_setColLowerBound(int i, Value lo) {
+    LEMON_ASSERT(lo != INF, "Invalid bound");
+
+    int b = glp_get_col_type(lp, i);
+    double up = glp_get_col_ub(lp, i);
+    if (lo == -INF) {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        glp_set_col_bnds(lp, i, GLP_FR, lo, up);
+        break;
+      case GLP_UP:
+        break;
+      case GLP_DB:
+      case GLP_FX:
+        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      default:
+        break;
+      }
+    } else {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        glp_set_col_bnds(lp, i, GLP_LO, lo, up);
+        break;
+      case GLP_UP:
+      case GLP_DB:
+      case GLP_FX:
+        if (lo == up)
+          glp_set_col_bnds(lp, i, GLP_FX, lo, up);
+        else
+          glp_set_col_bnds(lp, i, GLP_DB, lo, up);
+        break;
+      default:
+        break;
+      }
+    }
+  }
+
+  GlpkBase::Value GlpkBase::_getColLowerBound(int i) const {
+    int b = glp_get_col_type(lp, i);
+    switch (b) {
+    case GLP_LO:
+    case GLP_DB:
+    case GLP_FX:
+      return glp_get_col_lb(lp, i);
+    default:
+      return -INF;
+    }
+  }
+
+  void GlpkBase::_setColUpperBound(int i, Value up) {
+    LEMON_ASSERT(up != -INF, "Invalid bound");
+
+    int b = glp_get_col_type(lp, i);
+    double lo = glp_get_col_lb(lp, i);
+    if (up == INF) {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        break;
+      case GLP_UP:
+        glp_set_col_bnds(lp, i, GLP_FR, lo, up);
+        break;
+      case GLP_DB:
+      case GLP_FX:
+        glp_set_col_bnds(lp, i, GLP_LO, lo, up);
+        break;
+      default:
+        break;
+      }
+    } else {
+      switch (b) {
+      case GLP_FR:
+        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      case GLP_UP:
+        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      case GLP_LO:
+      case GLP_DB:
+      case GLP_FX:
+        if (lo == up)
+          glp_set_col_bnds(lp, i, GLP_FX, lo, up);
+        else
+          glp_set_col_bnds(lp, i, GLP_DB, lo, up);
+        break;
+      default:
+        break;
+      }
+    }
+
+  }
+
+  GlpkBase::Value GlpkBase::_getColUpperBound(int i) const {
+    int b = glp_get_col_type(lp, i);
+      switch (b) {
+      case GLP_UP:
+      case GLP_DB:
+      case GLP_FX:
+        return glp_get_col_ub(lp, i);
+      default:
+        return INF;
+      }
+  }
+
+  void GlpkBase::_setRowLowerBound(int i, Value lo) {
+    LEMON_ASSERT(lo != INF, "Invalid bound");
+
+    int b = glp_get_row_type(lp, i);
+    double up = glp_get_row_ub(lp, i);
+    if (lo == -INF) {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
+        break;
+      case GLP_UP:
+        break;
+      case GLP_DB:
+      case GLP_FX:
+        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      default:
+        break;
+      }
+    } else {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
+        break;
+      case GLP_UP:
+      case GLP_DB:
+      case GLP_FX:
+        if (lo == up)
+          glp_set_row_bnds(lp, i, GLP_FX, lo, up);
+        else
+          glp_set_row_bnds(lp, i, GLP_DB, lo, up);
+        break;
+      default:
+        break;
+      }
+    }
+
+  }
+
+  GlpkBase::Value GlpkBase::_getRowLowerBound(int i) const {
+    int b = glp_get_row_type(lp, i);
+    switch (b) {
+    case GLP_LO:
+    case GLP_DB:
+    case GLP_FX:
+      return glp_get_row_lb(lp, i);
+    default:
+      return -INF;
+    }
+  }
+
+  void GlpkBase::_setRowUpperBound(int i, Value up) {
+    LEMON_ASSERT(up != -INF, "Invalid bound");
+
+    int b = glp_get_row_type(lp, i);
+    double lo = glp_get_row_lb(lp, i);
+    if (up == INF) {
+      switch (b) {
+      case GLP_FR:
+      case GLP_LO:
+        break;
+      case GLP_UP:
+        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
+        break;
+      case GLP_DB:
+      case GLP_FX:
+        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
+        break;
+      default:
+        break;
+      }
+    } else {
+      switch (b) {
+      case GLP_FR:
+        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      case GLP_UP:
+        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
+        break;
+      case GLP_LO:
+      case GLP_DB:
+      case GLP_FX:
+        if (lo == up)
+          glp_set_row_bnds(lp, i, GLP_FX, lo, up);
+        else
+          glp_set_row_bnds(lp, i, GLP_DB, lo, up);
+        break;
+      default:
+        break;
+      }
+    }
+  }
+
+  GlpkBase::Value GlpkBase::_getRowUpperBound(int i) const {
+    int b = glp_get_row_type(lp, i);
+    switch (b) {
+    case GLP_UP:
+    case GLP_DB:
+    case GLP_FX:
+      return glp_get_row_ub(lp, i);
+    default:
+      return INF;
+    }
+  }
+
+  void GlpkBase::_setObjCoeffs(ExprIterator b, ExprIterator e) {
+    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
+      glp_set_obj_coef(lp, i, 0.0);
+    }
+    for (ExprIterator it = b; it != e; ++it) {
+      glp_set_obj_coef(lp, it->first, it->second);
+    }
+  }
+
+  void GlpkBase::_getObjCoeffs(InsertIterator b) const {
+    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
+      Value val = glp_get_obj_coef(lp, i);
+      if (val != 0.0) {
+        *b = std::make_pair(i, val);
+        ++b;
+      }
+    }
+  }
+
+  void GlpkBase::_setObjCoeff(int i, Value obj_coef) {
+    //i = 0 means the constant term (shift)
+    glp_set_obj_coef(lp, i, obj_coef);
+  }
+
+  GlpkBase::Value GlpkBase::_getObjCoeff(int i) const {
+    //i = 0 means the constant term (shift)
+    return glp_get_obj_coef(lp, i);
+  }
+
+  void GlpkBase::_setSense(GlpkBase::Sense sense) {
+    switch (sense) {
+    case MIN:
+      glp_set_obj_dir(lp, GLP_MIN);
+      break;
+    case MAX:
+      glp_set_obj_dir(lp, GLP_MAX);
+      break;
+    }
+  }
+
+  GlpkBase::Sense GlpkBase::_getSense() const {
+    switch(glp_get_obj_dir(lp)) {
+    case GLP_MIN:
+      return MIN;
+    case GLP_MAX:
+      return MAX;
+    default:
+      LEMON_ASSERT(false, "Wrong sense");
+      return GlpkBase::Sense();
+    }
+  }
+
+  void GlpkBase::_clear() {
+    glp_erase_prob(lp);
+    rows.clear();
+    cols.clear();
+  }
+
+  // LpGlpk members
+
+  LpGlpk::LpGlpk()
+    : LpBase(), GlpkBase(), LpSolver() {
+    messageLevel(MESSAGE_NO_OUTPUT);
+  }
+
+  LpGlpk::LpGlpk(const LpGlpk& other)
+    : LpBase(other), GlpkBase(other), LpSolver(other) {
+    messageLevel(MESSAGE_NO_OUTPUT);
+  }
+
+  LpGlpk* LpGlpk::_newSolver() const { return new LpGlpk; }
+  LpGlpk* LpGlpk::_cloneSolver() const { return new LpGlpk(*this); }
+
+  const char* LpGlpk::_solverName() const { return "LpGlpk"; }
+
+  void LpGlpk::_clear_temporals() {
+    _primal_ray.clear();
+    _dual_ray.clear();
+  }
+
+  LpGlpk::SolveExitStatus LpGlpk::_solve() {
+    return solvePrimal();
+  }
+
+  LpGlpk::SolveExitStatus LpGlpk::solvePrimal() {
+    _clear_temporals();
+
+    glp_smcp smcp;
+    glp_init_smcp(&smcp);
+
+    switch (_message_level) {
+    case MESSAGE_NO_OUTPUT:
+      smcp.msg_lev = GLP_MSG_OFF;
+      break;
+    case MESSAGE_ERROR_MESSAGE:
+      smcp.msg_lev = GLP_MSG_ERR;
+      break;
+    case MESSAGE_NORMAL_OUTPUT:
+      smcp.msg_lev = GLP_MSG_ON;
+      break;
+    case MESSAGE_FULL_OUTPUT:
+      smcp.msg_lev = GLP_MSG_ALL;
+      break;
+    }
+
+    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
+    return SOLVED;
+  }
+
+  LpGlpk::SolveExitStatus LpGlpk::solveDual() {
+    _clear_temporals();
+
+    glp_smcp smcp;
+    glp_init_smcp(&smcp);
+
+    switch (_message_level) {
+    case MESSAGE_NO_OUTPUT:
+      smcp.msg_lev = GLP_MSG_OFF;
+      break;
+    case MESSAGE_ERROR_MESSAGE:
+      smcp.msg_lev = GLP_MSG_ERR;
+      break;
+    case MESSAGE_NORMAL_OUTPUT:
+      smcp.msg_lev = GLP_MSG_ON;
+      break;
+    case MESSAGE_FULL_OUTPUT:
+      smcp.msg_lev = GLP_MSG_ALL;
+      break;
+    }
+    smcp.meth = GLP_DUAL;
+
+    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
+    return SOLVED;
+  }
+
+  LpGlpk::Value LpGlpk::_getPrimal(int i) const {
+    return glp_get_col_prim(lp, i);
+  }
+
+  LpGlpk::Value LpGlpk::_getDual(int i) const {
+    return glp_get_row_dual(lp, i);
+  }
+
+  LpGlpk::Value LpGlpk::_getPrimalValue() const {
+    return glp_get_obj_val(lp);
+  }
+
+  LpGlpk::VarStatus LpGlpk::_getColStatus(int i) const {
+    switch (glp_get_col_stat(lp, i)) {
+    case GLP_BS:
+      return BASIC;
+    case GLP_UP:
+      return UPPER;
+    case GLP_LO:
+      return LOWER;
+    case GLP_NF:
+      return FREE;
+    case GLP_NS:
+      return FIXED;
+    default:
+      LEMON_ASSERT(false, "Wrong column status");
+      return LpGlpk::VarStatus();
+    }
+  }
+
+  LpGlpk::VarStatus LpGlpk::_getRowStatus(int i) const {
+    switch (glp_get_row_stat(lp, i)) {
+    case GLP_BS:
+      return BASIC;
+    case GLP_UP:
+      return UPPER;
+    case GLP_LO:
+      return LOWER;
+    case GLP_NF:
+      return FREE;
+    case GLP_NS:
+      return FIXED;
+    default:
+      LEMON_ASSERT(false, "Wrong row status");
+      return LpGlpk::VarStatus();
+    }
+  }
+
+  LpGlpk::Value LpGlpk::_getPrimalRay(int i) const {
+    if (_primal_ray.empty()) {
+      int row_num = glp_get_num_rows(lp);
+      int col_num = glp_get_num_cols(lp);
+
+      _primal_ray.resize(col_num + 1, 0.0);
+
+      int index = glp_get_unbnd_ray(lp);
+      if (index != 0) {
+        // The primal ray is found in primal simplex second phase
+        LEMON_ASSERT((index <= row_num ? glp_get_row_stat(lp, index) :
+                      glp_get_col_stat(lp, index - row_num)) != GLP_BS,
+                     "Wrong primal ray");
+
+        bool negate = glp_get_obj_dir(lp) == GLP_MAX;
+
+        if (index > row_num) {
+          _primal_ray[index - row_num] = 1.0;
+          if (glp_get_col_dual(lp, index - row_num) > 0) {
+            negate = !negate;
+          }
+        } else {
+          if (glp_get_row_dual(lp, index) > 0) {
+            negate = !negate;
+          }
+        }
+
+        std::vector<int> ray_indexes(row_num + 1);
+        std::vector<Value> ray_values(row_num + 1);
+        int ray_length = glp_eval_tab_col(lp, index, &ray_indexes.front(),
+                                          &ray_values.front());
+
+        for (int i = 1; i <= ray_length; ++i) {
+          if (ray_indexes[i] > row_num) {
+            _primal_ray[ray_indexes[i] - row_num] = ray_values[i];
+          }
+        }
+
+        if (negate) {
+          for (int i = 1; i <= col_num; ++i) {
+            _primal_ray[i] = - _primal_ray[i];
+          }
+        }
+      } else {
+        for (int i = 1; i <= col_num; ++i) {
+          _primal_ray[i] = glp_get_col_prim(lp, i);
+        }
+      }
+    }
+    return _primal_ray[i];
+  }
+
+  LpGlpk::Value LpGlpk::_getDualRay(int i) const {
+    if (_dual_ray.empty()) {
+      int row_num = glp_get_num_rows(lp);
+
+      _dual_ray.resize(row_num + 1, 0.0);
+
+      int index = glp_get_unbnd_ray(lp);
+      if (index != 0) {
+        // The dual ray is found in dual simplex second phase
+        LEMON_ASSERT((index <= row_num ? glp_get_row_stat(lp, index) :
+                      glp_get_col_stat(lp, index - row_num)) == GLP_BS,
+
+                     "Wrong dual ray");
+
+        int idx;
+        bool negate = false;
+
+        if (index > row_num) {
+          idx = glp_get_col_bind(lp, index - row_num);
+          if (glp_get_col_prim(lp, index - row_num) >
+              glp_get_col_ub(lp, index - row_num)) {
+            negate = true;
+          }
+        } else {
+          idx = glp_get_row_bind(lp, index);
+          if (glp_get_row_prim(lp, index) > glp_get_row_ub(lp, index)) {
+            negate = true;
+          }
+        }
+
+        _dual_ray[idx] = negate ?  - 1.0 : 1.0;
+
+        glp_btran(lp, &_dual_ray.front());
+      } else {
+        double eps = 1e-7;
+        // The dual ray is found in primal simplex first phase
+        // We assume that the glpk minimizes the slack to get feasible solution
+        for (int i = 1; i <= row_num; ++i) {
+          int index = glp_get_bhead(lp, i);
+          if (index <= row_num) {
+            double res = glp_get_row_prim(lp, index);
+            if (res > glp_get_row_ub(lp, index) + eps) {
+              _dual_ray[i] = -1;
+            } else if (res < glp_get_row_lb(lp, index) - eps) {
+              _dual_ray[i] = 1;
+            } else {
+              _dual_ray[i] = 0;
+            }
+            _dual_ray[i] *= glp_get_rii(lp, index);
+          } else {
+            double res = glp_get_col_prim(lp, index - row_num);
+            if (res > glp_get_col_ub(lp, index - row_num) + eps) {
+              _dual_ray[i] = -1;
+            } else if (res < glp_get_col_lb(lp, index - row_num) - eps) {
+              _dual_ray[i] = 1;
+            } else {
+              _dual_ray[i] = 0;
+            }
+            _dual_ray[i] /= glp_get_sjj(lp, index - row_num);
+          }
+        }
+
+        glp_btran(lp, &_dual_ray.front());
+
+        for (int i = 1; i <= row_num; ++i) {
+          _dual_ray[i] /= glp_get_rii(lp, i);
+        }
+      }
+    }
+    return _dual_ray[i];
+  }
+
+  LpGlpk::ProblemType LpGlpk::_getPrimalType() const {
+    if (glp_get_status(lp) == GLP_OPT)
+      return OPTIMAL;
+    switch (glp_get_prim_stat(lp)) {
+    case GLP_UNDEF:
+      return UNDEFINED;
+    case GLP_FEAS:
+    case GLP_INFEAS:
+      if (glp_get_dual_stat(lp) == GLP_NOFEAS) {
+        return UNBOUNDED;
+      } else {
+        return UNDEFINED;
+      }
+    case GLP_NOFEAS:
+      return INFEASIBLE;
+    default:
+      LEMON_ASSERT(false, "Wrong primal type");
+      return  LpGlpk::ProblemType();
+    }
+  }
+
+  LpGlpk::ProblemType LpGlpk::_getDualType() const {
+    if (glp_get_status(lp) == GLP_OPT)
+      return OPTIMAL;
+    switch (glp_get_dual_stat(lp)) {
+    case GLP_UNDEF:
+      return UNDEFINED;
+    case GLP_FEAS:
+    case GLP_INFEAS:
+      if (glp_get_prim_stat(lp) == GLP_NOFEAS) {
+        return UNBOUNDED;
+      } else {
+        return UNDEFINED;
+      }
+    case GLP_NOFEAS:
+      return INFEASIBLE;
+    default:
+      LEMON_ASSERT(false, "Wrong primal type");
+      return  LpGlpk::ProblemType();
+    }
+  }
+
+  void LpGlpk::presolver(bool b) {
+    lpx_set_int_parm(lp, LPX_K_PRESOL, b ? 1 : 0);
+  }
+
+  void LpGlpk::messageLevel(MessageLevel m) {
+    _message_level = m;
+  }
+
+  // MipGlpk members
+
+  MipGlpk::MipGlpk()
+    : LpBase(), GlpkBase(), MipSolver() {
+    messageLevel(MESSAGE_NO_OUTPUT);
+  }
+
+  MipGlpk::MipGlpk(const MipGlpk& other)
+    : LpBase(), GlpkBase(other), MipSolver() {
+    messageLevel(MESSAGE_NO_OUTPUT);
+  }
+
+  void MipGlpk::_setColType(int i, MipGlpk::ColTypes col_type) {
+    switch (col_type) {
+    case INTEGER:
+      glp_set_col_kind(lp, i, GLP_IV);
+      break;
+    case REAL:
+      glp_set_col_kind(lp, i, GLP_CV);
+      break;
+    }
+  }
+
+  MipGlpk::ColTypes MipGlpk::_getColType(int i) const {
+    switch (glp_get_col_kind(lp, i)) {
+    case GLP_IV:
+    case GLP_BV:
+      return INTEGER;
+    default:
+      return REAL;
+    }
+
+  }
+
+  MipGlpk::SolveExitStatus MipGlpk::_solve() {
+    glp_smcp smcp;
+    glp_init_smcp(&smcp);
+
+    switch (_message_level) {
+    case MESSAGE_NO_OUTPUT:
+      smcp.msg_lev = GLP_MSG_OFF;
+      break;
+    case MESSAGE_ERROR_MESSAGE:
+      smcp.msg_lev = GLP_MSG_ERR;
+      break;
+    case MESSAGE_NORMAL_OUTPUT:
+      smcp.msg_lev = GLP_MSG_ON;
+      break;
+    case MESSAGE_FULL_OUTPUT:
+      smcp.msg_lev = GLP_MSG_ALL;
+      break;
+    }
+    smcp.meth = GLP_DUAL;
+
+    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
+    if (glp_get_status(lp) != GLP_OPT) return SOLVED;
+
+    glp_iocp iocp;
+    glp_init_iocp(&iocp);
+
+    switch (_message_level) {
+    case MESSAGE_NO_OUTPUT:
+      iocp.msg_lev = GLP_MSG_OFF;
+      break;
+    case MESSAGE_ERROR_MESSAGE:
+      iocp.msg_lev = GLP_MSG_ERR;
+      break;
+    case MESSAGE_NORMAL_OUTPUT:
+      iocp.msg_lev = GLP_MSG_ON;
+      break;
+    case MESSAGE_FULL_OUTPUT:
+      iocp.msg_lev = GLP_MSG_ALL;
+      break;
+    }
+
+    if (glp_intopt(lp, &iocp) != 0) return UNSOLVED;
+    return SOLVED;
+  }
+
+
+  MipGlpk::ProblemType MipGlpk::_getType() const {
+    switch (glp_get_status(lp)) {
+    case GLP_OPT:
+      switch (glp_mip_status(lp)) {
+      case GLP_UNDEF:
+        return UNDEFINED;
+      case GLP_NOFEAS:
+        return INFEASIBLE;
+      case GLP_FEAS:
+        return FEASIBLE;
+      case GLP_OPT:
+        return OPTIMAL;
+      default:
+        LEMON_ASSERT(false, "Wrong problem type.");
+        return MipGlpk::ProblemType();
+      }
+    case GLP_NOFEAS:
+      return INFEASIBLE;
+    case GLP_INFEAS:
+    case GLP_FEAS:
+      if (glp_get_dual_stat(lp) == GLP_NOFEAS) {
+        return UNBOUNDED;
+      } else {
+        return UNDEFINED;
+      }
+    default:
+      LEMON_ASSERT(false, "Wrong problem type.");
+      return MipGlpk::ProblemType();
+    }
+  }
+
+  MipGlpk::Value MipGlpk::_getSol(int i) const {
+    return glp_mip_col_val(lp, i);
+  }
+
+  MipGlpk::Value MipGlpk::_getSolValue() const {
+    return glp_mip_obj_val(lp);
+  }
+
+  MipGlpk* MipGlpk::_newSolver() const { return new MipGlpk; }
+  MipGlpk* MipGlpk::_cloneSolver() const {return new MipGlpk(*this); }
+
+  const char* MipGlpk::_solverName() const { return "MipGlpk"; }
+
+  void MipGlpk::messageLevel(MessageLevel m) {
+    _message_level = m;
+  }
+
+} //END OF NAMESPACE LEMON
Index: lemon/lp_glpk.h
===================================================================
--- lemon/lp_glpk.h	(revision 459)
+++ lemon/lp_glpk.h	(revision 459)
@@ -0,0 +1,259 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * 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_LP_GLPK_H
+#define LEMON_LP_GLPK_H
+
+///\file
+///\brief Header of the LEMON-GLPK lp solver interface.
+///\ingroup lp_group
+
+#include <lemon/lp_base.h>
+
+// forward declaration
+#ifndef _GLP_PROB
+#define _GLP_PROB
+typedef struct { double _prob; } glp_prob;
+/* LP/MIP problem object */
+#endif
+
+namespace lemon {
+
+
+  /// \brief Base interface for the GLPK LP and MIP solver
+  ///
+  /// This class implements the common interface of the GLPK LP and MIP solver.
+  /// \ingroup lp_group
+  class GlpkBase : virtual public LpBase {
+  protected:
+
+    typedef glp_prob LPX;
+    glp_prob* lp;
+
+    GlpkBase();
+    GlpkBase(const GlpkBase&);
+    virtual ~GlpkBase();
+
+  protected:
+
+    virtual int _addCol();
+    virtual int _addRow();
+
+    virtual void _eraseCol(int i);
+    virtual void _eraseRow(int i);
+
+    virtual void _eraseColId(int i);
+    virtual void _eraseRowId(int i);
+
+    virtual void _getColName(int col, std::string& name) const;
+    virtual void _setColName(int col, const std::string& name);
+    virtual int _colByName(const std::string& name) const;
+
+    virtual void _getRowName(int row, std::string& name) const;
+    virtual void _setRowName(int row, const std::string& name);
+    virtual int _rowByName(const std::string& name) const;
+
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getRowCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getColCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setCoeff(int row, int col, Value value);
+    virtual Value _getCoeff(int row, int col) const;
+
+    virtual void _setColLowerBound(int i, Value value);
+    virtual Value _getColLowerBound(int i) const;
+
+    virtual void _setColUpperBound(int i, Value value);
+    virtual Value _getColUpperBound(int i) const;
+
+    virtual void _setRowLowerBound(int i, Value value);
+    virtual Value _getRowLowerBound(int i) const;
+
+    virtual void _setRowUpperBound(int i, Value value);
+    virtual Value _getRowUpperBound(int i) const;
+
+    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
+    virtual void _getObjCoeffs(InsertIterator b) const;
+
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    virtual Value _getObjCoeff(int i) const;
+
+    virtual void _setSense(Sense);
+    virtual Sense _getSense() const;
+
+    virtual void _clear();
+
+  public:
+
+    ///Pointer to the underlying GLPK data structure.
+    LPX *lpx() {return lp;}
+    ///Const pointer to the underlying GLPK data structure.
+    const LPX *lpx() const {return lp;}
+
+    ///Returns the constraint identifier understood by GLPK.
+    int lpxRow(Row r) const { return rows(id(r)); }
+
+    ///Returns the variable identifier understood by GLPK.
+    int lpxCol(Col c) const { return cols(id(c)); }
+
+  };
+
+  /// \brief Interface for the GLPK LP solver
+  ///
+  /// This class implements an interface for the GLPK LP solver.
+  ///\ingroup lp_group
+  class LpGlpk : public GlpkBase, public LpSolver {
+  public:
+
+    ///\e
+    LpGlpk();
+    ///\e
+    LpGlpk(const LpGlpk&);
+
+  private:
+
+    mutable std::vector<double> _primal_ray;
+    mutable std::vector<double> _dual_ray;
+
+    void _clear_temporals();
+
+  protected:
+
+    virtual LpGlpk* _cloneSolver() const;
+    virtual LpGlpk* _newSolver() const;
+
+    virtual const char* _solverName() const;
+
+    virtual SolveExitStatus _solve();
+    virtual Value _getPrimal(int i) const;
+    virtual Value _getDual(int i) const;
+
+    virtual Value _getPrimalValue() const;
+
+    virtual VarStatus _getColStatus(int i) const;
+    virtual VarStatus _getRowStatus(int i) const;
+
+    virtual Value _getPrimalRay(int i) const;
+    virtual Value _getDualRay(int i) const;
+
+    ///\todo It should be clarified
+    ///
+    virtual ProblemType _getPrimalType() const;
+    virtual ProblemType _getDualType() const;
+
+  public:
+
+    ///Solve with primal simplex
+    SolveExitStatus solvePrimal();
+
+    ///Solve with dual simplex
+    SolveExitStatus solveDual();
+
+    ///Turns on or off the presolver
+
+    ///Turns on (\c b is \c true) or off (\c b is \c false) the presolver
+    ///
+    ///The presolver is off by default.
+    void presolver(bool b);
+
+    ///Enum for \c messageLevel() parameter
+    enum MessageLevel {
+      /// no output (default value)
+      MESSAGE_NO_OUTPUT = 0,
+      /// error messages only
+      MESSAGE_ERROR_MESSAGE = 1,
+      /// normal output
+      MESSAGE_NORMAL_OUTPUT = 2,
+      /// full output (includes informational messages)
+      MESSAGE_FULL_OUTPUT = 3
+    };
+
+  private:
+
+    MessageLevel _message_level;
+
+  public:
+
+    ///Set the verbosity of the messages
+
+    ///Set the verbosity of the messages
+    ///
+    ///\param m is the level of the messages output by the solver routines.
+    void messageLevel(MessageLevel m);
+  };
+
+  /// \brief Interface for the GLPK MIP solver
+  ///
+  /// This class implements an interface for the GLPK MIP solver.
+  ///\ingroup lp_group
+  class MipGlpk : public GlpkBase, public MipSolver {
+  public:
+
+    ///\e
+    MipGlpk();
+    ///\e
+    MipGlpk(const MipGlpk&);
+
+  protected:
+
+    virtual MipGlpk* _cloneSolver() const;
+    virtual MipGlpk* _newSolver() const;
+
+    virtual const char* _solverName() const;
+
+    virtual ColTypes _getColType(int col) const;
+    virtual void _setColType(int col, ColTypes col_type);
+
+    virtual SolveExitStatus _solve();
+    virtual ProblemType _getType() const;
+    virtual Value _getSol(int i) const;
+    virtual Value _getSolValue() const;
+
+    ///Enum for \c messageLevel() parameter
+    enum MessageLevel {
+      /// no output (default value)
+      MESSAGE_NO_OUTPUT = 0,
+      /// error messages only
+      MESSAGE_ERROR_MESSAGE = 1,
+      /// normal output
+      MESSAGE_NORMAL_OUTPUT = 2,
+      /// full output (includes informational messages)
+      MESSAGE_FULL_OUTPUT = 3
+    };
+
+  private:
+
+    MessageLevel _message_level;
+
+  public:
+
+    ///Set the verbosity of the messages
+
+    ///Set the verbosity of the messages
+    ///
+    ///\param m is the level of the messages output by the solver routines.
+    void messageLevel(MessageLevel m);
+  };
+
+
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_LP_GLPK_H
+
Index: lemon/lp_skeleton.cc
===================================================================
--- lemon/lp_skeleton.cc	(revision 459)
+++ lemon/lp_skeleton.cc	(revision 459)
@@ -0,0 +1,134 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * 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 <lemon/lp_skeleton.h>
+
+///\file
+///\brief A skeleton file to implement LP solver interfaces
+namespace lemon {
+
+  int SkeletonSolverBase::_addCol()
+  {
+    return ++col_num;
+  }
+
+  int SkeletonSolverBase::_addRow()
+  {
+    return ++row_num;
+  }
+
+  void SkeletonSolverBase::_eraseCol(int) {}
+  void SkeletonSolverBase::_eraseRow(int) {}
+
+  void SkeletonSolverBase::_getColName(int, std::string &) const {}
+  void SkeletonSolverBase::_setColName(int, const std::string &) {}
+  int SkeletonSolverBase::_colByName(const std::string&) const { return -1; }
+
+  void SkeletonSolverBase::_getRowName(int, std::string &) const {}
+  void SkeletonSolverBase::_setRowName(int, const std::string &) {}
+  int SkeletonSolverBase::_rowByName(const std::string&) const { return -1; }
+
+  void SkeletonSolverBase::_setRowCoeffs(int, ExprIterator, ExprIterator) {}
+  void SkeletonSolverBase::_getRowCoeffs(int, InsertIterator) const {}
+
+  void SkeletonSolverBase::_setColCoeffs(int, ExprIterator, ExprIterator) {}
+  void SkeletonSolverBase::_getColCoeffs(int, InsertIterator) const {}
+
+  void SkeletonSolverBase::_setCoeff(int, int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getCoeff(int, int) const
+  { return 0; }
+
+  void SkeletonSolverBase::_setColLowerBound(int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getColLowerBound(int) const
+  {  return 0; }
+
+  void SkeletonSolverBase::_setColUpperBound(int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getColUpperBound(int) const
+  {  return 0; }
+
+  void SkeletonSolverBase::_setRowLowerBound(int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getRowLowerBound(int) const
+  {  return 0; }
+
+  void SkeletonSolverBase::_setRowUpperBound(int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getRowUpperBound(int) const
+  {  return 0; }
+
+  void SkeletonSolverBase::_setObjCoeffs(ExprIterator, ExprIterator) {}
+  void SkeletonSolverBase::_getObjCoeffs(InsertIterator) const {};
+
+  void SkeletonSolverBase::_setObjCoeff(int, Value) {}
+  SkeletonSolverBase::Value SkeletonSolverBase::_getObjCoeff(int) const
+  {  return 0; }
+
+  void SkeletonSolverBase::_setSense(Sense) {}
+  SkeletonSolverBase::Sense SkeletonSolverBase::_getSense() const
+  { return MIN; }
+
+  void SkeletonSolverBase::_clear() {
+    row_num = col_num = 0;
+  }
+
+  LpSkeleton::SolveExitStatus LpSkeleton::_solve() { return SOLVED; }
+
+  LpSkeleton::Value LpSkeleton::_getPrimal(int) const { return 0; }
+  LpSkeleton::Value LpSkeleton::_getDual(int) const { return 0; }
+  LpSkeleton::Value LpSkeleton::_getPrimalValue() const { return 0; }
+
+  LpSkeleton::Value LpSkeleton::_getPrimalRay(int) const { return 0; }
+  LpSkeleton::Value LpSkeleton::_getDualRay(int) const { return 0; }
+
+  LpSkeleton::ProblemType LpSkeleton::_getPrimalType() const
+  { return UNDEFINED; }
+
+  LpSkeleton::ProblemType LpSkeleton::_getDualType() const
+  { return UNDEFINED; }
+
+  LpSkeleton::VarStatus LpSkeleton::_getColStatus(int) const
+  { return BASIC; }
+
+  LpSkeleton::VarStatus LpSkeleton::_getRowStatus(int) const
+  { return BASIC; }
+
+  LpSkeleton* LpSkeleton::_newSolver() const
+  { return static_cast<LpSkeleton*>(0); }
+
+  LpSkeleton* LpSkeleton::_cloneSolver() const
+  { return static_cast<LpSkeleton*>(0); }
+
+  const char* LpSkeleton::_solverName() const { return "LpSkeleton"; }
+
+  MipSkeleton::SolveExitStatus MipSkeleton::_solve()
+  { return SOLVED; }
+
+  MipSkeleton::Value MipSkeleton::_getSol(int) const { return 0; }
+  MipSkeleton::Value MipSkeleton::_getSolValue() const { return 0; }
+
+  MipSkeleton::ProblemType MipSkeleton::_getType() const
+  { return UNDEFINED; }
+
+  MipSkeleton* MipSkeleton::_newSolver() const
+  { return static_cast<MipSkeleton*>(0); }
+
+  MipSkeleton* MipSkeleton::_cloneSolver() const
+  { return static_cast<MipSkeleton*>(0); }
+
+  const char* MipSkeleton::_solverName() const { return "MipSkeleton"; }
+
+} //namespace lemon
+
Index: lemon/lp_skeleton.h
===================================================================
--- lemon/lp_skeleton.h	(revision 459)
+++ lemon/lp_skeleton.h	(revision 459)
@@ -0,0 +1,229 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * 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_LP_SKELETON
+#define LEMON_LP_SKELETON
+
+#include <lemon/lp_base.h>
+
+///\file
+///\brief A skeleton file to implement LP solver interfaces
+namespace lemon {
+
+  ///A skeleton class to implement LP solver interfaces
+  class SkeletonSolverBase : public virtual LpBase {
+    int col_num,row_num;
+
+  protected:
+
+    SkeletonSolverBase()
+      : col_num(-1), row_num(-1) {}
+
+    /// \e
+    virtual int _addCol();
+    /// \e
+    virtual int _addRow();
+    /// \e
+    virtual void _eraseCol(int i);
+    /// \e
+    virtual void _eraseRow(int i);
+
+    /// \e
+    virtual void _getColName(int col, std::string& name) const;
+    /// \e
+    virtual void _setColName(int col, const std::string& name);
+    /// \e
+    virtual int _colByName(const std::string& name) const;
+
+    /// \e
+    virtual void _getRowName(int row, std::string& name) const;
+    /// \e
+    virtual void _setRowName(int row, const std::string& name);
+    /// \e
+    virtual int _rowByName(const std::string& name) const;
+
+    /// \e
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
+    /// \e
+    virtual void _getRowCoeffs(int i, InsertIterator b) const;
+    /// \e
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
+    /// \e
+    virtual void _getColCoeffs(int i, InsertIterator b) const;
+
+    /// Set one element of the coefficient matrix
+    virtual void _setCoeff(int row, int col, Value value);
+
+    /// Get one element of the coefficient matrix
+    virtual Value _getCoeff(int row, int col) const;
+
+    /// The lower bound of a variable (column) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    virtual void _setColLowerBound(int i, Value value);
+    /// \e
+
+    /// The lower bound of a variable (column) is an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    virtual Value _getColLowerBound(int i) const;
+
+    /// The upper bound of a variable (column) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or \ref INF.
+    virtual void _setColUpperBound(int i, Value value);
+    /// \e
+
+    /// The upper bound of a variable (column) is an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or \ref INF.
+    virtual Value _getColUpperBound(int i) const;
+
+    /// The lower bound of a constraint (row) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    virtual void _setRowLowerBound(int i, Value value);
+    /// \e
+
+    /// The lower bound of a constraint (row) is an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or -\ref INF.
+    virtual Value _getRowLowerBound(int i) const;
+
+    /// The upper bound of a constraint (row) have to be given by an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or \ref INF.
+    virtual void _setRowUpperBound(int i, Value value);
+    /// \e
+
+    /// The upper bound of a constraint (row) is an
+    /// extended number of type Value, i.e. a finite number of type
+    /// Value or \ref INF.
+    virtual Value _getRowUpperBound(int i) const;
+
+    /// \e
+    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
+    /// \e
+    virtual void _getObjCoeffs(InsertIterator b) const;
+
+    /// \e
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    /// \e
+    virtual Value _getObjCoeff(int i) const;
+
+    ///\e
+    virtual void _setSense(Sense);
+    ///\e
+    virtual Sense _getSense() const;
+
+    ///\e
+    virtual void _clear();
+
+  };
+
+  /// \brief Interface for a skeleton LP solver
+  ///
+  /// This class implements an interface for a skeleton LP solver.
+  ///\ingroup lp_group
+  class LpSkeleton : public SkeletonSolverBase, public LpSolver {
+  public:
+    LpSkeleton() : SkeletonSolverBase(), LpSolver() {}
+
+  protected:
+
+    ///\e
+    virtual SolveExitStatus _solve();
+
+    ///\e
+    virtual Value _getPrimal(int i) const;
+    ///\e
+    virtual Value _getDual(int i) const;
+
+    ///\e
+    virtual Value _getPrimalValue() const;
+
+    ///\e
+    virtual Value _getPrimalRay(int i) const;
+    ///\e
+    virtual Value _getDualRay(int i) const;
+
+    ///\e
+    virtual ProblemType _getPrimalType() const;
+    ///\e
+    virtual ProblemType _getDualType() const;
+
+    ///\e
+    virtual VarStatus _getColStatus(int i) const;
+    ///\e
+    virtual VarStatus _getRowStatus(int i) const;
+
+    ///\e
+    virtual LpSkeleton* _newSolver() const;
+    ///\e
+    virtual LpSkeleton* _cloneSolver() const;
+    ///\e
+    virtual const char* _solverName() const;
+
+  };
+
+  /// \brief Interface for a skeleton MIP solver
+  ///
+  /// This class implements an interface for a skeleton MIP solver.
+  ///\ingroup lp_group
+  class MipSkeleton : public SkeletonSolverBase, public MipSolver {
+  public:
+    MipSkeleton() : SkeletonSolverBase(), MipSolver() {}
+
+  protected:
+    ///\e
+
+    ///\bug Wrong interface
+    ///
+    virtual SolveExitStatus _solve();
+
+    ///\e
+
+    ///\bug Wrong interface
+    ///
+    virtual Value _getSol(int i) const;
+
+    ///\e
+
+    ///\bug Wrong interface
+    ///
+    virtual Value _getSolValue() const;
+
+    ///\e
+
+    ///\bug Wrong interface
+    ///
+    virtual ProblemType _getType() const;
+
+    ///\e
+    virtual MipSkeleton* _newSolver() const;
+
+    ///\e
+    virtual MipSkeleton* _cloneSolver() const;
+    ///\e
+    virtual const char* _solverName() const;
+
+  };
+
+} //namespace lemon
+
+#endif // LEMON_LP_SKELETON
Index: lemon/lp_soplex.cc
===================================================================
--- lemon/lp_soplex.cc	(revision 459)
+++ lemon/lp_soplex.cc	(revision 459)
@@ -0,0 +1,423 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * 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/lp_soplex.h>
+
+#include <soplex/soplex.h>
+
+
+///\file
+///\brief Implementation of the LEMON-SOPLEX lp solver interface.
+namespace lemon {
+
+  LpSoplex::LpSoplex() {
+    soplex = new soplex::SoPlex;
+  }
+
+  LpSoplex::~LpSoplex() {
+    delete soplex;
+  }
+
+  LpSoplex::LpSoplex(const LpSoplex& lp) {
+    rows = lp.rows;
+    cols = lp.cols;
+
+    soplex = new soplex::SoPlex;
+    (*static_cast<soplex::SPxLP*>(soplex)) = *(lp.soplex);
+
+    _col_names = lp._col_names;
+    _col_names_ref = lp._col_names_ref;
+
+    _row_names = lp._row_names;
+    _row_names_ref = lp._row_names_ref;
+
+  }
+
+  void LpSoplex::_clear_temporals() {
+    _primal_values.clear();
+    _dual_values.clear();
+  }
+
+  LpSoplex* LpSoplex::_newSolver() const {
+    LpSoplex* newlp = new LpSoplex();
+    return newlp;
+  }
+
+  LpSoplex* LpSoplex::_cloneSolver() const {
+    LpSoplex* newlp = new LpSoplex(*this);
+    return newlp;
+  }
+
+  const char* LpSoplex::_solverName() const { return "LpSoplex"; }
+
+  int LpSoplex::_addCol() {
+    soplex::LPCol c;
+    c.setLower(-soplex::infinity);
+    c.setUpper(soplex::infinity);
+    soplex->addCol(c);
+
+    _col_names.push_back(std::string());
+
+    return soplex->nCols() - 1;
+  }
+
+  int LpSoplex::_addRow() {
+    soplex::LPRow r;
+    r.setLhs(-soplex::infinity);
+    r.setRhs(soplex::infinity);
+    soplex->addRow(r);
+
+    _row_names.push_back(std::string());
+
+    return soplex->nRows() - 1;
+  }
+
+
+  void LpSoplex::_eraseCol(int i) {
+    soplex->removeCol(i);
+    _col_names_ref.erase(_col_names[i]);
+    _col_names[i] = _col_names.back();
+    _col_names_ref[_col_names.back()] = i;
+    _col_names.pop_back();
+  }
+
+  void LpSoplex::_eraseRow(int i) {
+    soplex->removeRow(i);
+    _row_names_ref.erase(_row_names[i]);
+    _row_names[i] = _row_names.back();
+    _row_names_ref[_row_names.back()] = i;
+    _row_names.pop_back();
+  }
+
+  void LpSoplex::_eraseColId(int i) {
+    cols.eraseIndex(i);
+    cols.relocateIndex(i, cols.maxIndex());
+  }
+  void LpSoplex::_eraseRowId(int i) {
+    rows.eraseIndex(i);
+    rows.relocateIndex(i, rows.maxIndex());
+  }
+
+  void LpSoplex::_getColName(int c, std::string &name) const {
+    name = _col_names[c];
+  }
+
+  void LpSoplex::_setColName(int c, const std::string &name) {
+    _col_names_ref.erase(_col_names[c]);
+    _col_names[c] = name;
+    if (!name.empty()) {
+      _col_names_ref.insert(std::make_pair(name, c));
+    }
+  }
+
+  int LpSoplex::_colByName(const std::string& name) const {
+    std::map<std::string, int>::const_iterator it =
+      _col_names_ref.find(name);
+    if (it != _col_names_ref.end()) {
+      return it->second;
+    } else {
+      return -1;
+    }
+  }
+
+  void LpSoplex::_getRowName(int r, std::string &name) const {
+    name = _row_names[r];
+  }
+
+  void LpSoplex::_setRowName(int r, const std::string &name) {
+    _row_names_ref.erase(_row_names[r]);
+    _row_names[r] = name;
+    if (!name.empty()) {
+      _row_names_ref.insert(std::make_pair(name, r));
+    }
+  }
+
+  int LpSoplex::_rowByName(const std::string& name) const {
+    std::map<std::string, int>::const_iterator it =
+      _row_names_ref.find(name);
+    if (it != _row_names_ref.end()) {
+      return it->second;
+    } else {
+      return -1;
+    }
+  }
+
+
+  void LpSoplex::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
+    for (int j = 0; j < soplex->nCols(); ++j) {
+      soplex->changeElement(i, j, 0.0);
+    }
+    for(ExprIterator it = b; it != e; ++it) {
+      soplex->changeElement(i, it->first, it->second);
+    }
+  }
+
+  void LpSoplex::_getRowCoeffs(int i, InsertIterator b) const {
+    const soplex::SVector& vec = soplex->rowVector(i);
+    for (int k = 0; k < vec.size(); ++k) {
+      *b = std::make_pair(vec.index(k), vec.value(k));
+      ++b;
+    }
+  }
+
+  void LpSoplex::_setColCoeffs(int j, ExprIterator b, ExprIterator e) {
+    for (int i = 0; i < soplex->nRows(); ++i) {
+      soplex->changeElement(i, j, 0.0);
+    }
+    for(ExprIterator it = b; it != e; ++it) {
+      soplex->changeElement(it->first, j, it->second);
+    }
+  }
+
+  void LpSoplex::_getColCoeffs(int i, InsertIterator b) const {
+    const soplex::SVector& vec = soplex->colVector(i);
+    for (int k = 0; k < vec.size(); ++k) {
+      *b = std::make_pair(vec.index(k), vec.value(k));
+      ++b;
+    }
+  }
+
+  void LpSoplex::_setCoeff(int i, int j, Value value) {
+    soplex->changeElement(i, j, value);
+  }
+
+  LpSoplex::Value LpSoplex::_getCoeff(int i, int j) const {
+    return soplex->rowVector(i)[j];
+  }
+
+  void LpSoplex::_setColLowerBound(int i, Value value) {
+    LEMON_ASSERT(value != INF, "Invalid bound");
+    soplex->changeLower(i, value != -INF ? value : -soplex::infinity);
+  }
+
+  LpSoplex::Value LpSoplex::_getColLowerBound(int i) const {
+    double value = soplex->lower(i);
+    return value != -soplex::infinity ? value : -INF;
+  }
+
+  void LpSoplex::_setColUpperBound(int i, Value value) {
+    LEMON_ASSERT(value != -INF, "Invalid bound");
+    soplex->changeUpper(i, value != INF ? value : soplex::infinity);
+  }
+
+  LpSoplex::Value LpSoplex::_getColUpperBound(int i) const {
+    double value = soplex->upper(i);
+    return value != soplex::infinity ? value : INF;
+  }
+
+  void LpSoplex::_setRowLowerBound(int i, Value lb) {
+    LEMON_ASSERT(lb != INF, "Invalid bound");
+    soplex->changeRange(i, lb != -INF ? lb : -soplex::infinity, soplex->rhs(i));
+  }
+
+  LpSoplex::Value LpSoplex::_getRowLowerBound(int i) const {
+    double res = soplex->lhs(i);
+    return res == -soplex::infinity ? -INF : res;
+  }
+
+  void LpSoplex::_setRowUpperBound(int i, Value ub) {
+    LEMON_ASSERT(ub != -INF, "Invalid bound");
+    soplex->changeRange(i, soplex->lhs(i), ub != INF ? ub : soplex::infinity);
+  }
+
+  LpSoplex::Value LpSoplex::_getRowUpperBound(int i) const {
+    double res = soplex->rhs(i);
+    return res == soplex::infinity ? INF : res;
+  }
+
+  void LpSoplex::_setObjCoeffs(ExprIterator b, ExprIterator e) {
+    for (int j = 0; j < soplex->nCols(); ++j) {
+      soplex->changeObj(j, 0.0);
+    }
+    for (ExprIterator it = b; it != e; ++it) {
+      soplex->changeObj(it->first, it->second);
+    }
+  }
+
+  void LpSoplex::_getObjCoeffs(InsertIterator b) const {
+    for (int j = 0; j < soplex->nCols(); ++j) {
+      Value coef = soplex->obj(j);
+      if (coef != 0.0) {
+        *b = std::make_pair(j, coef);
+        ++b;
+      }
+    }
+  }
+
+  void LpSoplex::_setObjCoeff(int i, Value obj_coef) {
+    soplex->changeObj(i, obj_coef);
+  }
+
+  LpSoplex::Value LpSoplex::_getObjCoeff(int i) const {
+    return soplex->obj(i);
+  }
+
+  LpSoplex::SolveExitStatus LpSoplex::_solve() {
+
+    _clear_temporals();
+
+    soplex::SPxSolver::Status status = soplex->solve();
+
+    switch (status) {
+    case soplex::SPxSolver::OPTIMAL:
+    case soplex::SPxSolver::INFEASIBLE:
+    case soplex::SPxSolver::UNBOUNDED:
+      return SOLVED;
+    default:
+      return UNSOLVED;
+    }
+  }
+
+  LpSoplex::Value LpSoplex::_getPrimal(int i) const {
+    if (_primal_values.empty()) {
+      _primal_values.resize(soplex->nCols());
+      soplex::Vector pv(_primal_values.size(), &_primal_values.front());
+      soplex->getPrimal(pv);
+    }
+    return _primal_values[i];
+  }
+
+  LpSoplex::Value LpSoplex::_getDual(int i) const {
+    if (_dual_values.empty()) {
+      _dual_values.resize(soplex->nRows());
+      soplex::Vector dv(_dual_values.size(), &_dual_values.front());
+      soplex->getDual(dv);
+    }
+    return _dual_values[i];
+  }
+
+  LpSoplex::Value LpSoplex::_getPrimalValue() const {
+    return soplex->objValue();
+  }
+
+  LpSoplex::VarStatus LpSoplex::_getColStatus(int i) const {
+    switch (soplex->getBasisColStatus(i)) {
+    case soplex::SPxSolver::BASIC:
+      return BASIC;
+    case soplex::SPxSolver::ON_UPPER:
+      return UPPER;
+    case soplex::SPxSolver::ON_LOWER:
+      return LOWER;
+    case soplex::SPxSolver::FIXED:
+      return FIXED;
+    case soplex::SPxSolver::ZERO:
+      return FREE;
+    default:
+      LEMON_ASSERT(false, "Wrong column status");
+      return VarStatus();
+    }
+  }
+
+  LpSoplex::VarStatus LpSoplex::_getRowStatus(int i) const {
+    switch (soplex->getBasisRowStatus(i)) {
+    case soplex::SPxSolver::BASIC:
+      return BASIC;
+    case soplex::SPxSolver::ON_UPPER:
+      return UPPER;
+    case soplex::SPxSolver::ON_LOWER:
+      return LOWER;
+    case soplex::SPxSolver::FIXED:
+      return FIXED;
+    case soplex::SPxSolver::ZERO:
+      return FREE;
+    default:
+      LEMON_ASSERT(false, "Wrong row status");
+      return VarStatus();
+    }
+  }
+
+  LpSoplex::Value LpSoplex::_getPrimalRay(int i) const {
+    if (_primal_ray.empty()) {
+      _primal_ray.resize(soplex->nCols());
+      soplex::Vector pv(_primal_ray.size(), &_primal_ray.front());
+      soplex->getDualfarkas(pv);
+    }
+    return _primal_ray[i];
+  }
+
+  LpSoplex::Value LpSoplex::_getDualRay(int i) const {
+    if (_dual_ray.empty()) {
+      _dual_ray.resize(soplex->nRows());
+      soplex::Vector dv(_dual_ray.size(), &_dual_ray.front());
+      soplex->getDualfarkas(dv);
+    }
+    return _dual_ray[i];
+  }
+
+  LpSoplex::ProblemType LpSoplex::_getPrimalType() const {
+    switch (soplex->status()) {
+    case soplex::SPxSolver::OPTIMAL:
+      return OPTIMAL;
+    case soplex::SPxSolver::UNBOUNDED:
+      return UNBOUNDED;
+    case soplex::SPxSolver::INFEASIBLE:
+      return INFEASIBLE;
+    default:
+      return UNDEFINED;
+    }
+  }
+
+  LpSoplex::ProblemType LpSoplex::_getDualType() const {
+    switch (soplex->status()) {
+    case soplex::SPxSolver::OPTIMAL:
+      return OPTIMAL;
+    case soplex::SPxSolver::UNBOUNDED:
+      return UNBOUNDED;
+    case soplex::SPxSolver::INFEASIBLE:
+      return INFEASIBLE;
+    default:
+      return UNDEFINED;
+    }
+  }
+
+  void LpSoplex::_setSense(Sense sense) {
+    switch (sense) {
+    case MIN:
+      soplex->changeSense(soplex::SPxSolver::MINIMIZE);
+      break;
+    case MAX:
+      soplex->changeSense(soplex::SPxSolver::MAXIMIZE);
+    }
+  }
+
+  LpSoplex::Sense LpSoplex::_getSense() const {
+    switch (soplex->spxSense()) {
+    case soplex::SPxSolver::MAXIMIZE:
+      return MAX;
+    case soplex::SPxSolver::MINIMIZE:
+      return MIN;
+    default:
+      LEMON_ASSERT(false, "Wrong sense.");
+      return LpSoplex::Sense();
+    }
+  }
+
+  void LpSoplex::_clear() {
+    soplex->clear();
+    _col_names.clear();
+    _col_names_ref.clear();
+    _row_names.clear();
+    _row_names_ref.clear();
+    cols.clear();
+    rows.clear();
+    _clear_temporals();
+  }
+
+} //namespace lemon
+
Index: lemon/lp_soplex.h
===================================================================
--- lemon/lp_soplex.h	(revision 459)
+++ lemon/lp_soplex.h	(revision 459)
@@ -0,0 +1,151 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * 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_LP_SOPLEX_H
+#define LEMON_LP_SOPLEX_H
+
+///\file
+///\brief Header of the LEMON-SOPLEX lp solver interface.
+
+#include <vector>
+#include <string>
+
+#include <lemon/lp_base.h>
+
+// Forward declaration
+namespace soplex {
+  class SoPlex;
+}
+
+namespace lemon {
+
+  /// \ingroup lp_group
+  ///
+  /// \brief Interface for the SOPLEX solver
+  ///
+  /// This class implements an interface for the SoPlex LP solver.
+  /// The SoPlex library is an object oriented lp solver library
+  /// developed at the Konrad-Zuse-Zentrum für Informationstechnik
+  /// Berlin (ZIB). You can find detailed information about it at the
+  /// <tt>http://soplex.zib.de</tt> address.
+  class LpSoplex : public LpSolver {
+  private:
+
+    soplex::SoPlex* soplex;
+
+    std::vector<std::string> _col_names;
+    std::map<std::string, int> _col_names_ref;
+
+    std::vector<std::string> _row_names;
+    std::map<std::string, int> _row_names_ref;
+
+  private:
+
+    // these values cannot be retrieved element by element
+    mutable std::vector<Value> _primal_values;
+    mutable std::vector<Value> _dual_values;
+
+    mutable std::vector<Value> _primal_ray;
+    mutable std::vector<Value> _dual_ray;
+
+    void _clear_temporals();
+
+  public:
+
+    /// \e
+    LpSoplex();
+    /// \e
+    LpSoplex(const LpSoplex&);
+    /// \e
+    ~LpSoplex();
+
+  protected:
+
+    virtual LpSoplex* _newSolver() const;
+    virtual LpSoplex* _cloneSolver() const;
+
+    virtual const char* _solverName() const;
+
+    virtual int _addCol();
+    virtual int _addRow();
+
+    virtual void _eraseCol(int i);
+    virtual void _eraseRow(int i);
+
+    virtual void _eraseColId(int i);
+    virtual void _eraseRowId(int i);
+
+    virtual void _getColName(int col, std::string& name) const;
+    virtual void _setColName(int col, const std::string& name);
+    virtual int _colByName(const std::string& name) const;
+
+    virtual void _getRowName(int row, std::string& name) const;
+    virtual void _setRowName(int row, const std::string& name);
+    virtual int _rowByName(const std::string& name) const;
+
+    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getRowCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
+    virtual void _getColCoeffs(int i, InsertIterator b) const;
+
+    virtual void _setCoeff(int row, int col, Value value);
+    virtual Value _getCoeff(int row, int col) const;
+
+    virtual void _setColLowerBound(int i, Value value);
+    virtual Value _getColLowerBound(int i) const;
+    virtual void _setColUpperBound(int i, Value value);
+    virtual Value _getColUpperBound(int i) const;
+
+    virtual void _setRowLowerBound(int i, Value value);
+    virtual Value _getRowLowerBound(int i) const;
+    virtual void _setRowUpperBound(int i, Value value);
+    virtual Value _getRowUpperBound(int i) const;
+
+    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
+    virtual void _getObjCoeffs(InsertIterator b) const;
+
+    virtual void _setObjCoeff(int i, Value obj_coef);
+    virtual Value _getObjCoeff(int i) const;
+
+    virtual void _setSense(Sense sense);
+    virtual Sense _getSense() const;
+
+    virtual SolveExitStatus _solve();
+    virtual Value _getPrimal(int i) const;
+    virtual Value _getDual(int i) const;
+
+    virtual Value _getPrimalValue() const;
+
+    virtual Value _getPrimalRay(int i) const;
+    virtual Value _getDualRay(int i) const;
+
+    virtual VarStatus _getColStatus(int i) const;
+    virtual VarStatus _getRowStatus(int i) const;
+
+    virtual ProblemType _getPrimalType() const;
+    virtual ProblemType _getDualType() const;
+
+    virtual void _clear();
+
+  };
+
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_LP_SOPLEX_H
+
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 498)
+++ 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 440)
+++ lemon/preflow.h	(revision 440)
@@ -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 _Digraph Digraph type.
+  /// \tparam _CapacityMap Capacity map type.
+  template <typename _Digraph, typename _CapacityMap>
+  struct PreflowDefaultTraits {
+
+    /// \brief The type of the digraph the algorithm runs on.
+    typedef _Digraph 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 _CapacityMap 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 _Digraph The type of the digraph the algorithm runs on.
+  /// \tparam _CapacityMap The type of the capacity map. The default map
+  /// type is \ref concepts::Digraph::ArcMap "_Digraph::ArcMap<int>".
+#ifdef DOXYGEN
+  template <typename _Digraph, typename _CapacityMap, typename _Traits>
+#else
+  template <typename _Digraph,
+            typename _CapacityMap = typename _Digraph::template ArcMap<int>,
+            typename _Traits = PreflowDefaultTraits<_Digraph, _CapacityMap> >
+#endif
+  class Preflow {
+  public:
+
+    ///The \ref PreflowDefaultTraits "traits class" of the algorithm.
+    typedef _Traits 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/radix_sort.h
===================================================================
--- lemon/radix_sort.h	(revision 444)
+++ lemon/radix_sort.h	(revision 444)
@@ -0,0 +1,487 @@
+/* -*- 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 RADIX_SORT_H
+#define RADIX_SORT_H
+
+/// \ingroup auxalg
+/// \file
+/// \brief Radix sort
+///
+/// Linear time sorting algorithms
+
+#include <vector>
+#include <limits>
+#include <iterator>
+#include <algorithm>
+
+namespace lemon {
+
+  namespace _radix_sort_bits {
+
+    template <typename Value>
+    struct Identity {
+      const Value& operator()(const Value& val) {
+        return val;
+      }
+    };
+
+
+    template <typename Value, typename Iterator, typename Functor>
+    Iterator radixSortPartition(Iterator first, Iterator last,
+                                Functor functor, Value mask) {
+      while (first != last && !(functor(*first) & mask)) {
+        ++first;
+      }
+      if (first == last) {
+        return first;
+      }
+      --last;
+      while (first != last && (functor(*last) & mask)) {
+        --last;
+      }
+      if (first == last) {
+        return first;
+      }
+      std::iter_swap(first, last);
+      ++first;
+      if (!(first < last)) {
+        return first;
+      }
+      while (true) {
+        while (!(functor(*first) & mask)) {
+          ++first;
+        }
+        --last;
+        while (functor(*last) & mask) {
+          --last;
+        }
+        if (!(first < last)) {
+          return first;
+        }
+        std::iter_swap(first, last);
+        ++first;
+      }
+    }
+
+    template <typename Iterator, typename Functor>
+    Iterator radixSortSignPartition(Iterator first, Iterator last,
+                                    Functor functor) {
+      while (first != last && functor(*first) < 0) {
+        ++first;
+      }
+      if (first == last) {
+        return first;
+      }
+      --last;
+      while (first != last && functor(*last) >= 0) {
+        --last;
+      }
+      if (first == last) {
+        return first;
+      }
+      std::iter_swap(first, last);
+      ++first;
+      if (!(first < last)) {
+        return first;
+      }
+      while (true) {
+        while (functor(*first) < 0) {
+          ++first;
+        }
+        --last;
+        while (functor(*last) >= 0) {
+          --last;
+        }
+        if (!(first < last)) {
+          return first;
+        }
+        std::iter_swap(first, last);
+        ++first;
+      }
+    }
+
+    template <typename Value, typename Iterator, typename Functor>
+    void radixIntroSort(Iterator first, Iterator last,
+                        Functor functor, Value mask) {
+      while (mask != 0 && last - first > 1) {
+        Iterator cut = radixSortPartition(first, last, functor, mask);
+        mask >>= 1;
+        radixIntroSort(first, cut, functor, mask);
+        first = cut;
+      }
+    }
+
+    template <typename Value, typename Iterator, typename Functor>
+    void radixSignedSort(Iterator first, Iterator last, Functor functor) {
+
+      Iterator cut = radixSortSignPartition(first, last, functor);
+
+      Value mask;
+      int max_digit;
+      Iterator it;
+
+      mask = ~0; max_digit = 0;
+      for (it = first; it != cut; ++it) {
+        while ((mask & functor(*it)) != mask) {
+          ++max_digit;
+          mask <<= 1;
+        }
+      }
+      radixIntroSort(first, cut, functor, 1 << max_digit);
+
+      mask = 0; max_digit = 0;
+      for (it = cut; it != last; ++it) {
+        while ((mask | functor(*it)) != mask) {
+          ++max_digit;
+          mask <<= 1; mask |= 1;
+        }
+      }
+      radixIntroSort(cut, last, functor, 1 << max_digit);
+    }
+
+    template <typename Value, typename Iterator, typename Functor>
+    void radixUnsignedSort(Iterator first, Iterator last, Functor functor) {
+
+      Value mask = 0;
+      int max_digit = 0;
+
+      Iterator it;
+      for (it = first; it != last; ++it) {
+        while ((mask | functor(*it)) != mask) {
+          ++max_digit;
+          mask <<= 1; mask |= 1;
+        }
+      }
+      radixIntroSort(first, last, functor, 1 << max_digit);
+    }
+
+
+    template <typename Value,
+              bool sign = std::numeric_limits<Value>::is_signed >
+    struct RadixSortSelector {
+      template <typename Iterator, typename Functor>
+      static void sort(Iterator first, Iterator last, Functor functor) {
+        radixSignedSort<Value>(first, last, functor);
+      }
+    };
+
+    template <typename Value>
+    struct RadixSortSelector<Value, false> {
+      template <typename Iterator, typename Functor>
+      static void sort(Iterator first, Iterator last, Functor functor) {
+        radixUnsignedSort<Value>(first, last, functor);
+      }
+    };
+
+  }
+
+  /// \ingroup auxalg
+  ///
+  /// \brief Sorts the STL compatible range into ascending order.
+  ///
+  /// The \c radixSort sorts an STL compatible range into ascending
+  /// order.  The radix sort algorithm can sort items which are mapped
+  /// to integers with an adaptable unary function \c functor and the
+  /// order will be ascending according to these mapped values.
+  ///
+  /// It is also possible to use a normal function instead
+  /// of the functor object. If the functor is not given it will use
+  /// the identity function instead.
+  ///
+  /// This is a special quick sort algorithm where the pivot
+  /// values to split the items are choosen to be \f$ 2^k \f$ for each \c k.
+  /// Therefore, the time complexity of the
+  /// algorithm is \f$ O(\log(c)n) \f$ and it uses \f$ O(\log(c)) \f$,
+  /// additional space, where \c c is the maximal value and \c n is the
+  /// number of the items in the container.
+  ///
+  /// \param first The begin of the given range.
+  /// \param last The end of the given range.
+  /// \param functor An adaptible unary function or a normal function
+  /// which maps the items to any integer type which can be either
+  /// signed or unsigned.
+  ///
+  /// \sa stableRadixSort()
+  template <typename Iterator, typename Functor>
+  void radixSort(Iterator first, Iterator last, Functor functor) {
+    using namespace _radix_sort_bits;
+    typedef typename Functor::result_type Value;
+    RadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void radixSort(Iterator first, Iterator last, Value (*functor)(Key)) {
+    using namespace _radix_sort_bits;
+    RadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void radixSort(Iterator first, Iterator last, Value& (*functor)(Key)) {
+    using namespace _radix_sort_bits;
+    RadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void radixSort(Iterator first, Iterator last, Value (*functor)(Key&)) {
+    using namespace _radix_sort_bits;
+    RadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void radixSort(Iterator first, Iterator last, Value& (*functor)(Key&)) {
+    using namespace _radix_sort_bits;
+    RadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator>
+  void radixSort(Iterator first, Iterator last) {
+    using namespace _radix_sort_bits;
+    typedef typename std::iterator_traits<Iterator>::value_type Value;
+    RadixSortSelector<Value>::sort(first, last, Identity<Value>());
+  }
+
+  namespace _radix_sort_bits {
+
+    template <typename Value>
+    unsigned char valueByte(Value value, int byte) {
+      return value >> (std::numeric_limits<unsigned char>::digits * byte);
+    }
+
+    template <typename Functor, typename Key>
+    void stableRadixIntroSort(Key *first, Key *last, Key *target,
+                              int byte, Functor functor) {
+      const int size =
+        unsigned(std::numeric_limits<unsigned char>::max()) + 1;
+      std::vector<int> counter(size);
+      for (int i = 0; i < size; ++i) {
+        counter[i] = 0;
+      }
+      Key *it = first;
+      while (first != last) {
+        ++counter[valueByte(functor(*first), byte)];
+        ++first;
+      }
+      int prev, num = 0;
+      for (int i = 0; i < size; ++i) {
+        prev = num;
+        num += counter[i];
+        counter[i] = prev;
+      }
+      while (it != last) {
+        target[counter[valueByte(functor(*it), byte)]++] = *it;
+        ++it;
+      }
+    }
+
+    template <typename Functor, typename Key>
+    void signedStableRadixIntroSort(Key *first, Key *last, Key *target,
+                                    int byte, Functor functor) {
+      const int size =
+        unsigned(std::numeric_limits<unsigned char>::max()) + 1;
+      std::vector<int> counter(size);
+      for (int i = 0; i < size; ++i) {
+        counter[i] = 0;
+      }
+      Key *it = first;
+      while (first != last) {
+        counter[valueByte(functor(*first), byte)]++;
+        ++first;
+      }
+      int prev, num = 0;
+      for (int i = size / 2; i < size; ++i) {
+        prev = num;
+        num += counter[i];
+        counter[i] = prev;
+      }
+      for (int i = 0; i < size / 2; ++i) {
+        prev = num;
+        num += counter[i];
+        counter[i] = prev;
+      }
+      while (it != last) {
+        target[counter[valueByte(functor(*it), byte)]++] = *it;
+        ++it;
+      }
+    }
+
+
+    template <typename Value, typename Iterator, typename Functor>
+    void stableRadixSignedSort(Iterator first, Iterator last, Functor functor) {
+      if (first == last) return;
+      typedef typename std::iterator_traits<Iterator>::value_type Key;
+      typedef std::allocator<Key> Allocator;
+      Allocator allocator;
+
+      int length = std::distance(first, last);
+      Key* buffer = allocator.allocate(2 * length);
+      try {
+        bool dir = true;
+        std::copy(first, last, buffer);
+        for (int i = 0; i < int(sizeof(Value)) - 1; ++i) {
+          if (dir) {
+            stableRadixIntroSort(buffer, buffer + length, buffer + length,
+                                 i, functor);
+          } else {
+            stableRadixIntroSort(buffer + length, buffer + 2 * length, buffer,
+                                 i, functor);
+          }
+          dir = !dir;
+        }
+        if (dir) {
+          signedStableRadixIntroSort(buffer, buffer + length, buffer + length,
+                                     sizeof(Value) - 1, functor);
+          std::copy(buffer + length, buffer + 2 * length, first);
+        }        else {
+          signedStableRadixIntroSort(buffer + length, buffer + 2 * length,
+                                     buffer, sizeof(Value) - 1, functor);
+          std::copy(buffer, buffer + length, first);
+        }
+      } catch (...) {
+        allocator.deallocate(buffer, 2 * length);
+        throw;
+      }
+      allocator.deallocate(buffer, 2 * length);
+    }
+
+    template <typename Value, typename Iterator, typename Functor>
+    void stableRadixUnsignedSort(Iterator first, Iterator last,
+                                 Functor functor) {
+      if (first == last) return;
+      typedef typename std::iterator_traits<Iterator>::value_type Key;
+      typedef std::allocator<Key> Allocator;
+      Allocator allocator;
+
+      int length = std::distance(first, last);
+      Key *buffer = allocator.allocate(2 * length);
+      try {
+        bool dir = true;
+        std::copy(first, last, buffer);
+        for (int i = 0; i < int(sizeof(Value)); ++i) {
+          if (dir) {
+            stableRadixIntroSort(buffer, buffer + length,
+                                 buffer + length, i, functor);
+          } else {
+            stableRadixIntroSort(buffer + length, buffer + 2 * length,
+                                 buffer, i, functor);
+          }
+          dir = !dir;
+        }
+        if (dir) {
+          std::copy(buffer, buffer + length, first);
+        }        else {
+          std::copy(buffer + length, buffer + 2 * length, first);
+        }
+      } catch (...) {
+        allocator.deallocate(buffer, 2 * length);
+        throw;
+      }
+      allocator.deallocate(buffer, 2 * length);
+    }
+
+
+
+    template <typename Value,
+              bool sign = std::numeric_limits<Value>::is_signed >
+    struct StableRadixSortSelector {
+      template <typename Iterator, typename Functor>
+      static void sort(Iterator first, Iterator last, Functor functor) {
+        stableRadixSignedSort<Value>(first, last, functor);
+      }
+    };
+
+    template <typename Value>
+    struct StableRadixSortSelector<Value, false> {
+      template <typename Iterator, typename Functor>
+      static void sort(Iterator first, Iterator last, Functor functor) {
+        stableRadixUnsignedSort<Value>(first, last, functor);
+      }
+    };
+
+  }
+
+  /// \ingroup auxalg
+  ///
+  /// \brief Sorts the STL compatible range into ascending order in a stable
+  /// way.
+  ///
+  /// This function sorts an STL compatible range into ascending
+  /// order according to an integer mapping in the same as radixSort() does.
+  ///
+  /// This sorting algorithm is stable, i.e. the order of two equal
+  /// elements remains the same after the sorting.
+  ///
+  /// This sort algorithm  use a radix forward sort on the
+  /// bytes of the integer number. The algorithm sorts the items
+  /// byte-by-byte. First, it counts how many times a byte value occurs
+  /// in the container, then it copies the corresponding items to
+  /// another container in asceding order in \c O(n) time.
+  ///
+  /// The time complexity of the algorithm is \f$ O(\log(c)n) \f$ and
+  /// it uses \f$ O(n) \f$, additional space, where \c c is the
+  /// maximal value and \c n is the number of the items in the
+  /// container.
+  ///
+
+  /// \param first The begin of the given range.
+  /// \param last The end of the given range.
+  /// \param functor An adaptible unary function or a normal function
+  /// which maps the items to any integer type which can be either
+  /// signed or unsigned.
+  /// \sa radixSort()
+  template <typename Iterator, typename Functor>
+  void stableRadixSort(Iterator first, Iterator last, Functor functor) {
+    using namespace _radix_sort_bits;
+    typedef typename Functor::result_type Value;
+    StableRadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void stableRadixSort(Iterator first, Iterator last, Value (*functor)(Key)) {
+    using namespace _radix_sort_bits;
+    StableRadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void stableRadixSort(Iterator first, Iterator last, Value& (*functor)(Key)) {
+    using namespace _radix_sort_bits;
+    StableRadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void stableRadixSort(Iterator first, Iterator last, Value (*functor)(Key&)) {
+    using namespace _radix_sort_bits;
+    StableRadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator, typename Value, typename Key>
+  void stableRadixSort(Iterator first, Iterator last, Value& (*functor)(Key&)) {
+    using namespace _radix_sort_bits;
+    StableRadixSortSelector<Value>::sort(first, last, functor);
+  }
+
+  template <typename Iterator>
+  void stableRadixSort(Iterator first, Iterator last) {
+    using namespace _radix_sort_bits;
+    typedef typename std::iterator_traits<Iterator>::value_type Value;
+    StableRadixSortSelector<Value>::sort(first, last, Identity<Value>());
+  }
+
+}
+
+#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 498)
+++ 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 505)
+++ 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
     }
@@ -203,5 +224,5 @@
   };
 
-  inline TimeStamp operator*(double b,const TimeStamp &t)
+  TimeStamp operator*(double b,const TimeStamp &t)
   {
     return t*b;
Index: lemon/tolerance.h
===================================================================
--- lemon/tolerance.h	(revision 497)
+++ 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: m4/lx_check_clp.m4
===================================================================
--- m4/lx_check_clp.m4	(revision 459)
+++ m4/lx_check_clp.m4	(revision 459)
@@ -0,0 +1,73 @@
+AC_DEFUN([LX_CHECK_CLP],
+[
+  AC_ARG_WITH([clp],
+AS_HELP_STRING([--with-clp@<:@=PREFIX@:>@], [search for CLP under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@])
+AS_HELP_STRING([--without-clp], [disable checking for CLP]),
+              [], [with_clp=yes])
+
+  AC_ARG_WITH([clp-includedir],
+AS_HELP_STRING([--with-clp-includedir=DIR], [search for CLP headers in DIR]),
+              [], [with_clp_includedir=no])
+
+  AC_ARG_WITH([clp-libdir],
+AS_HELP_STRING([--with-clp-libdir=DIR], [search for CLP libraries in DIR]),
+              [], [with_clp_libdir=no])
+
+  lx_clp_found=no
+  if test x"$with_clp" != x"no"; then
+    AC_MSG_CHECKING([for CLP])
+
+    if test x"$with_clp_includedir" != x"no"; then
+      CLP_CXXFLAGS="-I$with_clp_includedir"
+    elif test x"$with_clp" != x"yes"; then
+      CLP_CXXFLAGS="-I$with_clp/include"
+    fi
+
+    if test x"$with_clp_libdir" != x"no"; then
+      CLP_LDFLAGS="-L$with_clp_libdir"
+    elif test x"$with_clp" != x"yes"; then
+      CLP_LDFLAGS="-L$with_clp/lib"
+    fi
+    CLP_LIBS="-lClp -lCoinUtils -lm"
+
+    lx_save_cxxflags="$CXXFLAGS"
+    lx_save_ldflags="$LDFLAGS"
+    lx_save_libs="$LIBS"
+    CXXFLAGS="$CLP_CXXFLAGS"
+    LDFLAGS="$CLP_LDFLAGS"
+    LIBS="$CLP_LIBS"
+
+    lx_clp_test_prog='
+      #include <coin/ClpModel.hpp>
+
+      int main(int argc, char** argv)
+      {
+        ClpModel clp;
+        return 0;
+      }'
+
+    AC_LANG_PUSH(C++)
+    AC_LINK_IFELSE([$lx_clp_test_prog], [lx_clp_found=yes], [lx_clp_found=no])
+    AC_LANG_POP(C++)
+
+    CXXFLAGS="$lx_save_cxxflags"
+    LDFLAGS="$lx_save_ldflags"
+    LIBS="$lx_save_libs"
+
+    if test x"$lx_clp_found" = x"yes"; then
+      AC_DEFINE([HAVE_CLP], [1], [Define to 1 if you have CLP.])
+      lx_lp_found=yes
+      AC_DEFINE([HAVE_LP], [1], [Define to 1 if you have any LP solver.])
+      AC_MSG_RESULT([yes])
+    else
+      CLP_CXXFLAGS=""
+      CLP_LDFLAGS=""
+      CLP_LIBS=""
+      AC_MSG_RESULT([no])
+    fi
+  fi
+  CLP_LIBS="$CLP_LDFLAGS $CLP_LIBS"
+  AC_SUBST(CLP_CXXFLAGS)
+  AC_SUBST(CLP_LIBS)
+  AM_CONDITIONAL([HAVE_CLP], [test x"$lx_clp_found" = x"yes"])
+])
Index: m4/lx_check_cplex.m4
===================================================================
--- m4/lx_check_cplex.m4	(revision 511)
+++ m4/lx_check_cplex.m4	(revision 457)
@@ -62,5 +62,9 @@
 
     if test x"$lx_cplex_found" = x"yes"; then
-      AC_DEFINE([LEMON_HAVE_CPLEX], [1], [Define to 1 if you have CPLEX.])
+      AC_DEFINE([HAVE_CPLEX], [1], [Define to 1 if you have CPLEX.])
+      lx_lp_found=yes
+      AC_DEFINE([HAVE_LP], [1], [Define to 1 if you have any LP solver.])
+      lx_mip_found=yes
+      AC_DEFINE([HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
       AC_MSG_RESULT([yes])
     else
Index: m4/lx_check_glpk.m4
===================================================================
--- m4/lx_check_glpk.m4	(revision 511)
+++ m4/lx_check_glpk.m4	(revision 459)
@@ -43,4 +43,9 @@
       }
 
+      #if (GLP_MAJOR_VERSION < 4) \
+         || (GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION < 33)
+      #error Supported GLPK versions: 4.33 or above
+      #endif
+
       int main(int argc, char** argv)
       {
@@ -60,5 +65,9 @@
 
     if test x"$lx_glpk_found" = x"yes"; then
-      AC_DEFINE([LEMON_HAVE_GLPK], [1], [Define to 1 if you have GLPK.])
+      AC_DEFINE([HAVE_GLPK], [1], [Define to 1 if you have GLPK.])
+      lx_lp_found=yes
+      AC_DEFINE([HAVE_LP], [1], [Define to 1 if you have any LP solver.])
+      lx_mip_found=yes
+      AC_DEFINE([HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
       AC_MSG_RESULT([yes])
     else
Index: m4/lx_check_soplex.m4
===================================================================
--- m4/lx_check_soplex.m4	(revision 511)
+++ m4/lx_check_soplex.m4	(revision 457)
@@ -56,5 +56,7 @@
 
     if test x"$lx_soplex_found" = x"yes"; then
-      AC_DEFINE([LEMON_HAVE_SOPLEX], [1], [Define to 1 if you have SOPLEX.])
+      AC_DEFINE([HAVE_SOPLEX], [1], [Define to 1 if you have SOPLEX.])
+      lx_lp_found=yes
+      AC_DEFINE([HAVE_LP], [1], [Define to 1 if you have any LP solver.])
       AC_MSG_RESULT([yes])
     else
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: ripts/mk-release.sh
===================================================================
--- scripts/mk-release.sh	(revision 508)
+++ 	(revision )
@@ -1,35 +1,0 @@
-#!/bin/bash
-
-set -e
-
-if [ $# = 0 ]; then
-    echo "Usage: $0 release-id"
-    exit 1
-else
-    export LEMON_VERSION=$1
-fi
-
-echo '*****************************************************************'
-echo ' Start making release tarballs for version '${LEMON_VERSION}
-echo '*****************************************************************'
-
-autoreconf -vif
-./configure --enable-demo
-
-make
-make html
-make distcheck
-tar xf lemon-${LEMON_VERSION}.tar.gz
-zip -r lemon-${LEMON_VERSION}.zip lemon-${LEMON_VERSION}
-mv lemon-${LEMON_VERSION}/doc/html lemon-doc-${LEMON_VERSION}
-tar czf lemon-doc-${LEMON_VERSION}.tar.gz lemon-doc-${LEMON_VERSION}
-zip -r lemon-doc-${LEMON_VERSION}.zip lemon-doc-${LEMON_VERSION}
-tar czf lemon-nodoc-${LEMON_VERSION}.tar.gz lemon-${LEMON_VERSION}
-zip -r lemon-nodoc-${LEMON_VERSION}.zip lemon-${LEMON_VERSION}
-hg tag -m 'LEMON '${LEMON_VERSION}' released ('$(hg par --template="{node|short}")' tagged as r'${LEMON_VERSION}')' r${LEMON_VERSION}
-
-rm -rf lemon-${LEMON_VERSION} lemon-doc-${LEMON_VERSION}
-
-echo '*****************************************************************'
-echo '  Release '${LEMON_VERSION}' has been created' 
-echo '*****************************************************************'
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 510)
+++ test/CMakeLists.txt	(revision 458)
@@ -1,6 +1,3 @@
-INCLUDE_DIRECTORIES(
-  ${CMAKE_SOURCE_DIR}
-  ${PROJECT_BINARY_DIR}
-)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
 
 LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/lemon)
@@ -8,4 +5,5 @@
 SET(TESTS
   bfs_test
+  circulation_test
   counter_test
   dfs_test
@@ -14,12 +12,20 @@
   dim_test
   error_test
+  graph_adaptor_test
   graph_copy_test
   graph_test
   graph_utils_test
+  hao_orlin_test
   heap_test
   kruskal_test
+  lp_test
+  mip_test
   maps_test
+  max_matching_test
+  radix_sort_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 458)
@@ -4,26 +4,40 @@
 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/radix_sort_test \
+	test/random_test \
+	test/suurballe_test \
+	test/test_tools_fail \
+	test/test_tools_pass \
+	test/time_measure_test \
 	test/unionfind_test
+
+if HAVE_LP
+check_PROGRAMS += test/lp_test
+endif HAVE_LP
+if HAVE_MIP
+check_PROGRAMS += test/mip_test
+endif HAVE_MIP
 
 TESTS += $(check_PROGRAMS)
@@ -31,4 +45,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 +52,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 +58,13 @@
 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_lp_test_SOURCES = test/lp_test.cc
 test_maps_test_SOURCES = test/maps_test.cc
+test_mip_test_SOURCES = test/mip_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_radix_sort_test_SOURCES = test/radix_sort_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/lp_test.cc
===================================================================
--- test/lp_test.cc	(revision 459)
+++ test/lp_test.cc	(revision 459)
@@ -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-2008
+ * 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/lp_skeleton.h>
+#include "test_tools.h"
+#include <lemon/tolerance.h>
+
+#ifdef HAVE_CONFIG_H
+#include <lemon/config.h>
+#endif
+
+#ifdef HAVE_GLPK
+#include <lemon/lp_glpk.h>
+#endif
+
+#ifdef HAVE_CPLEX
+#include <lemon/lp_cplex.h>
+#endif
+
+#ifdef HAVE_SOPLEX
+#include <lemon/lp_soplex.h>
+#endif
+
+#ifdef HAVE_CLP
+#include <lemon/lp_clp.h>
+#endif
+
+using namespace lemon;
+
+void lpTest(LpSolver& lp)
+{
+
+  typedef LpSolver LP;
+
+  std::vector<LP::Col> x(10);
+  //  for(int i=0;i<10;i++) x.push_back(lp.addCol());
+  lp.addColSet(x);
+  lp.colLowerBound(x,1);
+  lp.colUpperBound(x,1);
+  lp.colBounds(x,1,2);
+
+  std::vector<LP::Col> y(10);
+  lp.addColSet(y);
+
+  lp.colLowerBound(y,1);
+  lp.colUpperBound(y,1);
+  lp.colBounds(y,1,2);
+
+  std::map<int,LP::Col> z;
+
+  z.insert(std::make_pair(12,INVALID));
+  z.insert(std::make_pair(2,INVALID));
+  z.insert(std::make_pair(7,INVALID));
+  z.insert(std::make_pair(5,INVALID));
+
+  lp.addColSet(z);
+
+  lp.colLowerBound(z,1);
+  lp.colUpperBound(z,1);
+  lp.colBounds(z,1,2);
+
+  {
+    LP::Expr e,f,g;
+    LP::Col p1,p2,p3,p4,p5;
+    LP::Constr c;
+
+    p1=lp.addCol();
+    p2=lp.addCol();
+    p3=lp.addCol();
+    p4=lp.addCol();
+    p5=lp.addCol();
+
+    e[p1]=2;
+    *e=12;
+    e[p1]+=2;
+    *e+=12;
+    e[p1]-=2;
+    *e-=12;
+
+    e=2;
+    e=2.2;
+    e=p1;
+    e=f;
+
+    e+=2;
+    e+=2.2;
+    e+=p1;
+    e+=f;
+
+    e-=2;
+    e-=2.2;
+    e-=p1;
+    e-=f;
+
+    e*=2;
+    e*=2.2;
+    e/=2;
+    e/=2.2;
+
+    e=((p1+p2)+(p1-p2)+(p1+12)+(12+p1)+(p1-12)+(12-p1)+
+       (f+12)+(12+f)+(p1+f)+(f+p1)+(f+g)+
+       (f-12)+(12-f)+(p1-f)+(f-p1)+(f-g)+
+       2.2*f+f*2.2+f/2.2+
+       2*f+f*2+f/2+
+       2.2*p1+p1*2.2+p1/2.2+
+       2*p1+p1*2+p1/2
+       );
+
+
+    c = (e  <= f  );
+    c = (e  <= 2.2);
+    c = (e  <= 2  );
+    c = (e  <= p1 );
+    c = (2.2<= f  );
+    c = (2  <= f  );
+    c = (p1 <= f  );
+    c = (p1 <= p2 );
+    c = (p1 <= 2.2);
+    c = (p1 <= 2  );
+    c = (2.2<= p2 );
+    c = (2  <= p2 );
+
+    c = (e  >= f  );
+    c = (e  >= 2.2);
+    c = (e  >= 2  );
+    c = (e  >= p1 );
+    c = (2.2>= f  );
+    c = (2  >= f  );
+    c = (p1 >= f  );
+    c = (p1 >= p2 );
+    c = (p1 >= 2.2);
+    c = (p1 >= 2  );
+    c = (2.2>= p2 );
+    c = (2  >= p2 );
+
+    c = (e  == f  );
+    c = (e  == 2.2);
+    c = (e  == 2  );
+    c = (e  == p1 );
+    c = (2.2== f  );
+    c = (2  == f  );
+    c = (p1 == f  );
+    //c = (p1 == p2 );
+    c = (p1 == 2.2);
+    c = (p1 == 2  );
+    c = (2.2== p2 );
+    c = (2  == p2 );
+
+    c = (2 <= e <= 3);
+    c = (2 <= p1<= 3);
+
+    c = (2 >= e >= 3);
+    c = (2 >= p1>= 3);
+
+    e[x[3]]=2;
+    e[x[3]]=4;
+    e[x[3]]=1;
+    *e=12;
+
+    lp.addRow(-LP::INF,e,23);
+    lp.addRow(-LP::INF,3.0*(x[1]+x[2]/2)-x[3],23);
+    lp.addRow(-LP::INF,3.0*(x[1]+x[2]*2-5*x[3]+12-x[4]/3)+2*x[4]-4,23);
+
+    lp.addRow(x[1]+x[3]<=x[5]-3);
+    lp.addRow(-7<=x[1]+x[3]-12<=3);
+    lp.addRow(x[1]<=x[5]);
+
+    std::ostringstream buf;
+
+
+    e=((p1+p2)+(p1-0.99*p2));
+    //e.prettyPrint(std::cout);
+    //(e<=2).prettyPrint(std::cout);
+    double tolerance=0.001;
+    e.simplify(tolerance);
+    buf << "Coeff. of p2 should be 0.01";
+    check(e[p2]>0, buf.str());
+
+    tolerance=0.02;
+    e.simplify(tolerance);
+    buf << "Coeff. of p2 should be 0";
+    check(const_cast<const LpSolver::Expr&>(e)[p2]==0, buf.str());
+
+
+  }
+
+  {
+    LP::DualExpr e,f,g;
+    LP::Row p1 = INVALID, p2 = INVALID, p3 = INVALID,
+      p4 = INVALID, p5 = INVALID;
+
+    e[p1]=2;
+    e[p1]+=2;
+    e[p1]-=2;
+
+    e=p1;
+    e=f;
+
+    e+=p1;
+    e+=f;
+
+    e-=p1;
+    e-=f;
+
+    e*=2;
+    e*=2.2;
+    e/=2;
+    e/=2.2;
+
+    e=((p1+p2)+(p1-p2)+
+       (p1+f)+(f+p1)+(f+g)+
+       (p1-f)+(f-p1)+(f-g)+
+       2.2*f+f*2.2+f/2.2+
+       2*f+f*2+f/2+
+       2.2*p1+p1*2.2+p1/2.2+
+       2*p1+p1*2+p1/2
+       );
+  }
+
+}
+
+void solveAndCheck(LpSolver& lp, LpSolver::ProblemType stat,
+                   double exp_opt) {
+  using std::string;
+  lp.solve();
+
+  std::ostringstream buf;
+  buf << "PrimalType should be: " << int(stat) << int(lp.primalType());
+
+  check(lp.primalType()==stat, buf.str());
+
+  if (stat ==  LpSolver::OPTIMAL) {
+    std::ostringstream sbuf;
+    sbuf << "Wrong optimal value: the right optimum is " << exp_opt;
+    check(std::abs(lp.primal()-exp_opt) < 1e-3, sbuf.str());
+  }
+}
+
+void aTest(LpSolver & lp)
+{
+  typedef LpSolver LP;
+
+ //The following example is very simple
+
+  typedef LpSolver::Row Row;
+  typedef LpSolver::Col Col;
+
+
+  Col x1 = lp.addCol();
+  Col x2 = lp.addCol();
+
+
+  //Constraints
+  Row upright=lp.addRow(x1+2*x2 <=1);
+  lp.addRow(x1+x2 >=-1);
+  lp.addRow(x1-x2 <=1);
+  lp.addRow(x1-x2 >=-1);
+  //Nonnegativity of the variables
+  lp.colLowerBound(x1, 0);
+  lp.colLowerBound(x2, 0);
+  //Objective function
+  lp.obj(x1+x2);
+
+  lp.sense(lp.MAX);
+
+  //Testing the problem retrieving routines
+  check(lp.objCoeff(x1)==1,"First term should be 1 in the obj function!");
+  check(lp.sense() == lp.MAX,"This is a maximization!");
+  check(lp.coeff(upright,x1)==1,"The coefficient in question is 1!");
+  check(lp.colLowerBound(x1)==0,
+        "The lower bound for variable x1 should be 0.");
+  check(lp.colUpperBound(x1)==LpSolver::INF,
+        "The upper bound for variable x1 should be infty.");
+  check(lp.rowLowerBound(upright) == -LpSolver::INF,
+        "The lower bound for the first row should be -infty.");
+  check(lp.rowUpperBound(upright)==1,
+        "The upper bound for the first row should be 1.");
+  LpSolver::Expr e = lp.row(upright);
+  check(e[x1] == 1, "The first coefficient should 1.");
+  check(e[x2] == 2, "The second coefficient should 1.");
+
+  lp.row(upright, x1+x2 <=1);
+  e = lp.row(upright);
+  check(e[x1] == 1, "The first coefficient should 1.");
+  check(e[x2] == 1, "The second coefficient should 1.");
+
+  LpSolver::DualExpr de = lp.col(x1);
+  check(  de[upright] == 1, "The first coefficient should 1.");
+
+  LpSolver* clp = lp.cloneSolver();
+
+  //Testing the problem retrieving routines
+  check(clp->objCoeff(x1)==1,"First term should be 1 in the obj function!");
+  check(clp->sense() == clp->MAX,"This is a maximization!");
+  check(clp->coeff(upright,x1)==1,"The coefficient in question is 1!");
+  //  std::cout<<lp.colLowerBound(x1)<<std::endl;
+  check(clp->colLowerBound(x1)==0,
+        "The lower bound for variable x1 should be 0.");
+  check(clp->colUpperBound(x1)==LpSolver::INF,
+        "The upper bound for variable x1 should be infty.");
+
+  check(lp.rowLowerBound(upright)==-LpSolver::INF,
+        "The lower bound for the first row should be -infty.");
+  check(lp.rowUpperBound(upright)==1,
+        "The upper bound for the first row should be 1.");
+  e = clp->row(upright);
+  check(e[x1] == 1, "The first coefficient should 1.");
+  check(e[x2] == 1, "The second coefficient should 1.");
+
+  de = clp->col(x1);
+  check(de[upright] == 1, "The first coefficient should 1.");
+
+  delete clp;
+
+  //Maximization of x1+x2
+  //over the triangle with vertices (0,0) (0,1) (1,0)
+  double expected_opt=1;
+  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
+
+  //Minimization
+  lp.sense(lp.MIN);
+  expected_opt=0;
+  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
+
+  //Vertex (-1,0) instead of (0,0)
+  lp.colLowerBound(x1, -LpSolver::INF);
+  expected_opt=-1;
+  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
+
+  //Erase one constraint and return to maximization
+  lp.erase(upright);
+  lp.sense(lp.MAX);
+  expected_opt=LpSolver::INF;
+  solveAndCheck(lp, LpSolver::UNBOUNDED, expected_opt);
+
+  //Infeasibilty
+  lp.addRow(x1+x2 <=-2);
+  solveAndCheck(lp, LpSolver::INFEASIBLE, expected_opt);
+
+}
+
+int main()
+{
+  LpSkeleton lp_skel;
+  lpTest(lp_skel);
+
+#ifdef HAVE_GLPK
+  {
+    LpGlpk lp_glpk1,lp_glpk2;
+    lpTest(lp_glpk1);
+    aTest(lp_glpk2);
+  }
+#endif
+
+#ifdef HAVE_CPLEX
+  try {
+    LpCplex lp_cplex1,lp_cplex2;
+    lpTest(lp_cplex1);
+    aTest(lp_cplex2);
+  } catch (CplexEnv::LicenseError& error) {
+#ifdef LEMON_FORCE_CPLEX_CHECK
+    check(false, error.what());
+#else
+    std::cerr << error.what() << std::endl;
+    std::cerr << "Cplex license check failed, lp check skipped" << std::endl;
+#endif
+  }
+#endif
+
+#ifdef HAVE_SOPLEX
+  {
+    LpSoplex lp_soplex1,lp_soplex2;
+    lpTest(lp_soplex1);
+    aTest(lp_soplex2);
+  }
+#endif
+
+#ifdef HAVE_CLP
+  {
+    LpClp lp_clp1,lp_clp2;
+    lpTest(lp_clp1);
+    aTest(lp_clp2);
+  }
+#endif
+
+  return 0;
+}
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/mip_test.cc
===================================================================
--- test/mip_test.cc	(revision 459)
+++ test/mip_test.cc	(revision 459)
@@ -0,0 +1,136 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * 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 "test_tools.h"
+
+
+#ifdef HAVE_CONFIG_H
+#include <lemon/config.h>
+#endif
+
+#ifdef HAVE_CPLEX
+#include <lemon/lp_cplex.h>
+#endif
+
+#ifdef HAVE_GLPK
+#include <lemon/lp_glpk.h>
+#endif
+
+
+using namespace lemon;
+
+void solveAndCheck(MipSolver& mip, MipSolver::ProblemType stat,
+                   double exp_opt) {
+  using std::string;
+
+  mip.solve();
+  //int decimal,sign;
+  std::ostringstream buf;
+  buf << "Type should be: " << int(stat)<<" and it is "<<int(mip.type());
+
+
+  //  itoa(stat,buf1, 10);
+  check(mip.type()==stat, buf.str());
+
+  if (stat ==  MipSolver::OPTIMAL) {
+    std::ostringstream sbuf;
+    buf << "Wrong optimal value: the right optimum is " << exp_opt;
+    check(std::abs(mip.solValue()-exp_opt) < 1e-3, sbuf.str());
+    //+ecvt(exp_opt,2)
+  }
+}
+
+void aTest(MipSolver& mip)
+{
+ //The following example is very simple
+
+
+  typedef MipSolver::Row Row;
+  typedef MipSolver::Col Col;
+
+
+
+  Col x1 = mip.addCol();
+  Col x2 = mip.addCol();
+
+
+  //Objective function
+  mip.obj(x1);
+
+  mip.max();
+
+
+  //Unconstrained optimization
+  mip.solve();
+  //Check it out!
+
+  //Constraints
+  mip.addRow(2*x1+x2 <=2);
+  mip.addRow(x1-2*x2 <=0);
+
+  //Nonnegativity of the variable x1
+  mip.colLowerBound(x1, 0);
+
+  //Maximization of x1
+  //over the triangle with vertices (0,0),(4/5,2/5),(0,2)
+  double expected_opt=4.0/5.0;
+  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
+
+  //Restrict x2 to integer
+  mip.colType(x2,MipSolver::INTEGER);
+  expected_opt=1.0/2.0;
+  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
+
+
+  //Restrict both to integer
+  mip.colType(x1,MipSolver::INTEGER);
+  expected_opt=0;
+  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
+
+
+
+}
+
+
+int main()
+{
+
+#ifdef HAVE_GLPK
+  {
+    MipGlpk mip1;
+    aTest(mip1);
+  }
+#endif
+
+#ifdef HAVE_CPLEX
+  try {
+    MipCplex mip2;
+    aTest(mip2);
+  } catch (CplexEnv::LicenseError& error) {
+#ifdef LEMON_FORCE_CPLEX_CHECK
+    check(false, error.what());
+#else
+    std::cerr << error.what() << std::endl;
+    std::cerr << "Cplex license check failed, lp check skipped" << std::endl;
+#endif
+  }
+#endif
+
+  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/radix_sort_test.cc
===================================================================
--- test/radix_sort_test.cc	(revision 444)
+++ test/radix_sort_test.cc	(revision 444)
@@ -0,0 +1,147 @@
+/* -*- 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 <lemon/time_measure.h>
+#include <lemon/smart_graph.h>
+#include <lemon/maps.h>
+#include <lemon/radix_sort.h>
+#include <lemon/math.h>
+
+#include "test_tools.h"
+
+#include <vector>
+#include <algorithm>
+
+using namespace lemon;
+
+static const int n = 10000;
+
+struct Negate {
+  typedef int argument_type;
+  typedef int result_type;
+  int operator()(int a) { return - a; }
+};
+
+int negate(int a) { return - a; }
+
+
+void generateIntSequence(int n, std::vector<int>& data) {
+  int prime = 9973;
+  int root = 136, value = 1;
+  for (int i = 0; i < n; ++i) {
+    data.push_back(value - prime / 2);
+    value = (value * root) % prime;
+  }
+}
+
+void generateCharSequence(int n, std::vector<unsigned char>& data) {
+  int prime = 251;
+  int root = 3, value = root;
+  for (int i = 0; i < n; ++i) {
+    data.push_back(static_cast<unsigned char>(value));
+    value = (value * root) % prime;
+  }
+}
+
+void checkRadixSort() {
+  {
+    std::vector<int> data1;
+    generateIntSequence(n, data1);
+
+    std::vector<int> data2(data1);
+    std::sort(data1.begin(), data1.end());
+
+    radixSort(data2.begin(), data2.end());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[i], "Test failed");
+    }
+
+    radixSort(data2.begin(), data2.end(), Negate());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[n - 1 - i], "Test failed");
+    }
+
+    radixSort(data2.begin(), data2.end(), negate);
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[n - 1 - i], "Test failed");
+    }
+
+  }
+
+  {
+    std::vector<unsigned char> data1(n);
+    generateCharSequence(n, data1);
+
+    std::vector<unsigned char> data2(data1);
+    std::sort(data1.begin(), data1.end());
+
+    radixSort(data2.begin(), data2.end());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[i], "Test failed");
+    }
+
+  }
+}
+
+
+void checkStableRadixSort() {
+  {
+    std::vector<int> data1;
+    generateIntSequence(n, data1);
+
+    std::vector<int> data2(data1);
+    std::sort(data1.begin(), data1.end());
+
+    stableRadixSort(data2.begin(), data2.end());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[i], "Test failed");
+    }
+
+    stableRadixSort(data2.begin(), data2.end(), Negate());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[n - 1 - i], "Test failed");
+    }
+
+    stableRadixSort(data2.begin(), data2.end(), negate);
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[n - 1 - i], "Test failed");
+    }
+  }
+
+  {
+    std::vector<unsigned char> data1(n);
+    generateCharSequence(n, data1);
+
+    std::vector<unsigned char> data2(data1);
+    std::sort(data1.begin(), data1.end());
+
+    radixSort(data2.begin(), data2.end());
+    for (int i = 0; i < n; ++i) {
+      check(data1[i] == data2[i], "Test failed");
+    }
+
+  }
+}
+
+int main() {
+
+  checkRadixSort();
+  checkStableRadixSort();
+
+  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
