Index: .hgignore
===================================================================
--- .hgignore	(revision 517)
+++ .hgignore	(revision 866)
@@ -23,5 +23,6 @@
 lemon/stamp-h2
 doc/Doxyfile
-cmake/cmake.version
+doc/references.dox
+cmake/version.cmake
 .dirstamp
 .libs/*
Index: .hgtags
===================================================================
--- .hgtags	(revision 992)
+++ .hgtags	(revision 992)
@@ -0,0 +1,5 @@
+3ed8f7c8bed8f51aecdc8395aa11af2f1fa12d9f r1.2
+ffc2d2559fc916e90c3f000582a2d4761d229d44 r1.2.1
+d303bfa8b1edf141856665fb73fddcc6abc33fef r1.2.2
+9e587caed9537aeb01a855749b5919ee3e005911 r1.2.3
+e13061207f85ee5f428855b83b2fe3a3ad62a26c r1.2.4
Index: AUTHORS
===================================================================
--- AUTHORS	(revision 320)
+++ AUTHORS	(revision 924)
@@ -24,3 +24,3 @@
 
 Again, please visit the history of the old LEMON repository for more
-details: http://lemon.cs.elte.hu/svn/lemon/trunk
+details: http://lemon.cs.elte.hu/hg/lemon-0.x
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt	(revision 552)
+++ CMakeLists.txt	(revision 966)
@@ -1,40 +1,127 @@
 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")
 PROJECT(${PROJECT_NAME})
 
+INCLUDE(FindPythonInterp)
+INCLUDE(FindWget)
+
+IF(EXISTS ${PROJECT_SOURCE_DIR}/cmake/version.cmake)
+  INCLUDE(${PROJECT_SOURCE_DIR}/cmake/version.cmake)
+ELSEIF(DEFINED ENV{LEMON_VERSION})
+  SET(LEMON_VERSION $ENV{LEMON_VERSION} CACHE STRING "LEMON version string.")
+ELSE()
+  EXECUTE_PROCESS(
+    COMMAND ${PYTHON_EXECUTABLE} ./scripts/chg-len.py
+    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+    OUTPUT_VARIABLE HG_REVISION_PATH
+    ERROR_QUIET
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+  )
+  EXECUTE_PROCESS(
+    COMMAND hg id -i
+    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+    OUTPUT_VARIABLE HG_REVISION
+    ERROR_QUIET
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+  )
+  IF(HG_REVISION STREQUAL "")
+    SET(HG_REVISION_ID "hg-tip")
+  ELSE()
+    IF(HG_REVISION_PATH STREQUAL "")
+      SET(HG_REVISION_ID ${HG_REVISION})
+    ELSE()
+      SET(HG_REVISION_ID ${HG_REVISION_PATH}.${HG_REVISION})
+    ENDIF()
+  ENDIF()
+  SET(LEMON_VERSION ${HG_REVISION_ID} CACHE STRING "LEMON version string.")
+ENDIF()
+
+SET(PROJECT_VERSION ${LEMON_VERSION})
+
 SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
 
-INCLUDE(FindDoxygen)
-INCLUDE(FindGhostscript)
+FIND_PACKAGE(Doxygen)
+FIND_PACKAGE(Ghostscript)
 FIND_PACKAGE(GLPK 4.33)
-
-ADD_DEFINITIONS(-DHAVE_CONFIG_H)
-
-IF(MSVC)
-  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4250 /wd4355 /wd4800 /wd4996")
-# Suppressed warnings:
-# C4250: 'class1' : inherits 'class2::member' via dominance
-# C4355: 'this' : used in base member initializer list
-# C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning)
-# C4996: 'function': was declared deprecated
-ENDIF(MSVC)
-
-IF(GLPK_FOUND)
-  SET(HAVE_LP TRUE)
-  SET(HAVE_MIP TRUE)
-  SET(HAVE_GLPK TRUE)
-ENDIF(GLPK_FOUND)
+FIND_PACKAGE(CPLEX)
+FIND_PACKAGE(COIN)
+
+IF(DEFINED ENV{LEMON_CXX_WARNING})
+  SET(CXX_WARNING $ENV{LEMON_CXX_WARNING})
+ELSE()
+  IF(CMAKE_COMPILER_IS_GNUCXX)
+    SET(CXX_WARNING "-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 -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas")
+    SET(CMAKE_CXX_FLAGS_DEBUG CACHE STRING "-ggdb")
+    SET(CMAKE_C_FLAGS_DEBUG CACHE STRING "-ggdb")
+  ELSEIF(MSVC)
+    # This part is unnecessary 'casue the same is set by the lemon/core.h.
+    # Still keep it as an example.
+    SET(CXX_WARNING "/wd4250 /wd4355 /wd4503 /wd4800 /wd4996")
+    # Suppressed warnings:
+    # C4250: 'class1' : inherits 'class2::member' via dominance
+    # C4355: 'this' : used in base member initializer list
+    # C4503: 'function' : decorated name length exceeded, name was truncated
+    # C4800: 'type' : forcing value to bool 'true' or 'false'
+    #        (performance warning)
+    # C4996: 'function': was declared deprecated
+  ELSE()
+    SET(CXX_WARNING "-Wall")
+  ENDIF()
+ENDIF()
+SET(LEMON_CXX_WARNING_FLAGS ${CXX_WARNING} CACHE STRING "LEMON warning flags.")
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LEMON_CXX_WARNING_FLAGS}")
+
+SET( CMAKE_CXX_FLAGS_MAINTAINER "-Werror -ggdb -O0" CACHE STRING
+    "Flags used by the C++ compiler during maintainer builds."
+    FORCE )
+SET( CMAKE_C_FLAGS_MAINTAINER "-Werror -O0" CACHE STRING
+    "Flags used by the C compiler during maintainer builds."
+    FORCE )
+SET( CMAKE_EXE_LINKER_FLAGS_MAINTAINER
+    "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
+    "Flags used for linking binaries during maintainer builds."
+    FORCE )
+SET( CMAKE_SHARED_LINKER_FLAGS_MAINTAINER
+    "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
+    "Flags used by the shared libraries linker during maintainer builds."
+    FORCE )
+MARK_AS_ADVANCED(
+    CMAKE_CXX_FLAGS_MAINTAINER
+    CMAKE_C_FLAGS_MAINTAINER
+    CMAKE_EXE_LINKER_FLAGS_MAINTAINER
+    CMAKE_SHARED_LINKER_FLAGS_MAINTAINER )
+
+IF(CMAKE_CONFIGURATION_TYPES)
+  LIST(APPEND CMAKE_CONFIGURATION_TYPES Maintainer)
+  LIST(REMOVE_DUPLICATES CMAKE_CONFIGURATION_TYPES)
+  SET(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING
+      "Add the configurations that we need"
+      FORCE)
+ endif()
+
+IF(NOT CMAKE_BUILD_TYPE)
+  SET(CMAKE_BUILD_TYPE "Release")
+ENDIF()
+
+SET( CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING
+    "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel Maintainer."
+    FORCE )
+
 
 INCLUDE(CheckTypeSize)
 CHECK_TYPE_SIZE("long long" LONG_LONG)
+SET(LEMON_HAVE_LONG_LONG ${HAVE_LONG_LONG})
+
+INCLUDE(FindPythonInterp)
 
 ENABLE_TESTING()
+
+IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
+  ADD_CUSTOM_TARGET(check ALL COMMAND ${CMAKE_CTEST_COMMAND})
+ELSE()
+  ADD_CUSTOM_TARGET(check COMMAND ${CMAKE_CTEST_COMMAND})
+ENDIF()
 
 ADD_SUBDIRECTORY(lemon)
@@ -44,72 +131,87 @@
   ADD_SUBDIRECTORY(doc)
   ADD_SUBDIRECTORY(test)
-ENDIF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
+ENDIF()
+
+CONFIGURE_FILE(
+  ${PROJECT_SOURCE_DIR}/cmake/LEMONConfig.cmake.in
+  ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
+  @ONLY
+)
+IF(UNIX)
+  INSTALL(
+    FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
+    DESTINATION share/lemon/cmake
+  )
+ELSEIF(WIN32)
+  INSTALL(
+    FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
+    DESTINATION cmake
+  )
+ENDIF()
 
 IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
-  IF(WIN32)
-    SET(CPACK_PACKAGE_NAME ${PROJECT_NAME})
-    SET(CPACK_PACKAGE_VENDOR "EGRES")
-    SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
-      "LEMON - Library of Efficient Models and Optimization in Networks")
-    SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
-
-    SET(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
-
-    SET(CPACK_PACKAGE_INSTALL_DIRECTORY
-      "${PROJECT_NAME} ${PROJECT_VERSION}")
-    SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY
-      "${PROJECT_NAME} ${PROJECT_VERSION}")
-
-    SET(CPACK_COMPONENTS_ALL headers library html_documentation bin)
-
-    SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ headers")
-    SET(CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "Dynamic-link library")
-    SET(CPACK_COMPONENT_BIN_DISPLAY_NAME "Command line utilities")
-    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_BIN_DESCRIPTION
-      "Command line utilities")
-    SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DESCRIPTION
-      "Doxygen generated documentation")
-
-    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_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_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")
-    SET(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis/lemon.ico")
-    SET(CPACK_NSIS_MUI_UNIICON "${PROJECT_SOURCE_DIR}/cmake/nsis/uninstall.ico")
-    #SET(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis\\\\installer.bmp")
-    SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\lemon.ico")
-    SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ${PROJECT_NAME}")
-    SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\lemon.cs.elte.hu")
-    SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\lemon.cs.elte.hu")
-    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\\\"
-      ")
-    SET(CPACK_NSIS_DELETE_ICONS_EXTRA "
-      !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
-      Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Documentation.lnk\\\"
-      ")
-
-    INCLUDE(CPack)
-  ENDIF(WIN32)
-ENDIF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
+  SET(CPACK_PACKAGE_NAME ${PROJECT_NAME})
+  SET(CPACK_PACKAGE_VENDOR "EGRES")
+  SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
+    "LEMON - Library for Efficient Modeling and Optimization in Networks")
+  SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
+
+  SET(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
+
+  SET(CPACK_PACKAGE_INSTALL_DIRECTORY
+    "${PROJECT_NAME} ${PROJECT_VERSION}")
+  SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY
+    "${PROJECT_NAME} ${PROJECT_VERSION}")
+
+  SET(CPACK_COMPONENTS_ALL headers library html_documentation bin)
+
+  SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ headers")
+  SET(CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "Dynamic-link library")
+  SET(CPACK_COMPONENT_BIN_DISPLAY_NAME "Command line utilities")
+  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_BIN_DESCRIPTION
+    "Command line utilities")
+  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DESCRIPTION
+    "Doxygen generated documentation")
+
+  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_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_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")
+  SET(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis/lemon.ico")
+  SET(CPACK_NSIS_MUI_UNIICON "${PROJECT_SOURCE_DIR}/cmake/nsis/uninstall.ico")
+  #SET(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis\\\\installer.bmp")
+  SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\lemon.ico")
+  SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ${PROJECT_NAME}")
+  SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\lemon.cs.elte.hu")
+  SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\lemon.cs.elte.hu")
+  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\\\"
+    ")
+  SET(CPACK_NSIS_DELETE_ICONS_EXTRA "
+    !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
+    Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Documentation.lnk\\\"
+    ")
+
+  INCLUDE(CPack)
+ENDIF()
Index: INSTALL
===================================================================
--- INSTALL	(revision 493)
+++ INSTALL	(revision 824)
@@ -28,6 +28,6 @@
 
       This command compiles the non-template part of LEMON into libemon.a
-      file. It also compiles the programs in the tools and demo subdirectories
-      when enabled.
+      file. It also compiles the programs in the tools subdirectory by
+      default.
 
    4. `make check'
@@ -75,12 +75,4 @@
 
   Set the installation prefix to PREFIX. By default it is /usr/local.
-
---enable-demo
-
-   Build the examples in the demo subdirectory.
-
---disable-demo
-
-   Do not build the examples in the demo subdirectory (default).
 
 --enable-tools
@@ -159,2 +151,47 @@
 
    Disable SoPlex support.
+
+--with-coin[=PREFIX]
+
+   Enable support for COIN-OR solvers (CLP and CBC). You should
+   specify the prefix too. (by default, COIN-OR tools install
+   themselves to the source code directory). This command enables the
+   solvers that are actually found.
+
+--with-coin-includedir=DIR
+
+   The directory where the COIN-OR header files are located. This is
+   only useful when the COIN-OR headers and libraries are not under
+   the same prefix (which is unlikely).
+
+--with-coin-libdir=DIR
+
+   The directory where the COIN-OR libraries are located. This is only
+   useful when the COIN-OR headers and libraries are not under the
+   same prefix (which is unlikely).
+
+--without-coin
+
+   Disable COIN-OR support.
+
+
+Makefile Variables
+==================
+
+Some Makefile variables are reserved by the GNU Coding Standards for
+the use of the "user" - the person building the package. For instance,
+CXX and CXXFLAGS are such variables, and have the same meaning as
+explained in the previous section. These variables can be set on the
+command line when invoking `make' like this:
+`make [VARIABLE=VALUE]...'
+
+WARNINGCXXFLAGS is a non-standard Makefile variable introduced by us
+to hold several compiler flags related to warnings. Its default value
+can be overridden when invoking `make'. For example to disable all
+warning flags use `make WARNINGCXXFLAGS='.
+
+In order to turn off a single flag from the default set of warning
+flags, you can use the CXXFLAGS variable, since this is passed after
+WARNINGCXXFLAGS. For example to turn off `-Wold-style-cast' (which is
+used by default when g++ is detected) you can use
+`make CXXFLAGS="-g -O2 -Wno-old-style-cast"'.
Index: LICENSE
===================================================================
--- LICENSE	(revision 553)
+++ LICENSE	(revision 880)
@@ -2,5 +2,5 @@
 copyright/license.
 
-Copyright (C) 2003-2009 Egervary Jeno Kombinatorikus Optimalizalasi
+Copyright (C) 2003-2010 Egervary Jeno Kombinatorikus Optimalizalasi
 Kutatocsoport (Egervary Combinatorial Optimization Research Group,
 EGRES).
Index: Makefile.am
===================================================================
--- Makefile.am	(revision 508)
+++ Makefile.am	(revision 793)
@@ -12,7 +12,11 @@
 	m4/lx_check_glpk.m4 \
 	m4/lx_check_soplex.m4 \
+	m4/lx_check_coin.m4 \
 	CMakeLists.txt \
 	cmake/FindGhostscript.cmake \
+	cmake/FindCPLEX.cmake \
 	cmake/FindGLPK.cmake \
+	cmake/FindCOIN.cmake \
+	cmake/LEMONConfig.cmake.in \
 	cmake/version.cmake.in \
 	cmake/version.cmake \
@@ -40,6 +44,11 @@
 include test/Makefile.am
 include doc/Makefile.am
-include demo/Makefile.am
 include tools/Makefile.am
+include scripts/Makefile.am
+
+DIST_SUBDIRS = demo
+
+demo:
+	$(MAKE) $(AM_MAKEFLAGS) -C demo
 
 MRPROPERFILES = \
@@ -69,3 +78,3 @@
 	bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2
 
-.PHONY: mrproper dist-bz2 distcheck-bz2
+.PHONY: demo mrproper dist-bz2 distcheck-bz2
Index: NEWS
===================================================================
--- NEWS	(revision 496)
+++ NEWS	(revision 991)
@@ -1,2 +1,228 @@
+2013-08-10 Version 1.2.4 released
+
+        Bugfix release.
+
+        #432: Add missing doc/template.h and doc/references.bib to release
+              tarball
+        #433: Support shared library build
+        ----: Update CPLEX lookup
+        ----: Make CBC interface compatible with latest CBC releases
+        ----: Intel C++ compatibility fixes
+        #441: Fix buggy reinitialization in _solver_bits::VarIndex::clear()
+        #444: Bugfix in path copy constructors and assignment operators
+        #447: Bugfix in AllArcLookUp<>
+        #448: Bugfix in adaptor_test.cc
+        #449: Fix clang compilation warnings and errors
+        #440: Fix a bug + remove redundant typedefs in dimacs-solver
+        #453: Avoid GCC 4.7 compiler warnings
+        #445: Fix missing initialization in CplexEnv::CplexEnv()
+        #461: Bugfix in assert.h
+        #470: Fix compilation issues related to various gcc versions
+        #439: Bugfix in biNodeConnected()
+        #469: Bugfix in test/maps_test.cc
+
+2011-11-09 Version 1.2.3 released
+
+        Bugfix release.
+
+        #428: Add missing lemon/lemon.pc.cmake to the release tarball
+        #429: Fix VS warnings
+        #430: Fix LpBase::Constr two-side limit bug
+
+2011-08-08 Version 1.2.2 released
+
+        Bugfix release.
+
+        #392: Bug fix in Dfs::start(s,t)
+        #414: Fix wrong initialization in Preflow
+        #404: Update Doxygen configuration
+        #416: Support tests with valgrind
+        #418: Better Win CodeBlock/MinGW support
+        #419: Backport build environment improvements from the main branch
+              - Build of mip_test and lp_test precede the running of the tests
+              - Also search for coin libs under ${COIN_ROOT_DIR}/lib/coin
+              - Do not look for COIN_VOL libraries
+        #382: Allow lgf file without Arc maps
+        #417: Bug fix in CostScaling
+
+2010-10-21 Version 1.2.1 released
+
+        Bugfix release.
+
+        #366: Fix Pred[Matrix]MapPath::empty()
+        #371: Bug fix in (di)graphCopy()
+              The target graph is cleared before adding nodes and arcs/edges.
+
+        #364: Add missing UndirectedTags
+        #368: Fix the usage of std::numeric_limits<>::min() in Network Simplex
+        #372: Fix a critical bug in preflow
+
+2010-03-19 Version 1.2 released
+
+        This is major feature release
+
+        * New algorithms
+          * Bellman-Ford algorithm (#51)
+          * Minimum mean cycle algorithms (#179)
+            * Karp, Hartman-Orlin and Howard algorithms
+          * New minimum cost flow algorithms (#180)
+            * Cost Scaling algorithms
+            * Capacity Scaling algorithm
+            * Cycle-Canceling algorithms
+          * Planarity related algorithms (#62)
+            * Planarity checking algorithm
+            * Planar embedding algorithm
+            * Schnyder's planar drawing algorithm
+            * Coloring planar graphs with five or six colors
+          * Fractional matching algorithms (#314)
+        * New data structures
+          * StaticDigraph structure (#68)
+          * Several new priority queue structures (#50, #301)
+            * Fibonacci, Radix, Bucket, Pairing, Binomial
+              D-ary and fourary heaps (#301)
+          * Iterable map structures (#73)
+        * Other new tools and functionality
+          * Map utility functions (#320)
+          * Reserve functions are added to ListGraph and SmartGraph (#311)
+          * A resize() function is added to HypercubeGraph (#311)
+          * A count() function is added to CrossRefMap (#302)
+          * Support for multiple targets in Suurballe using fullInit() (#181)
+          * Traits class and named parameters for Suurballe (#323)
+          * Separate reset() and resetParams() functions in NetworkSimplex
+            to handle graph changes (#327)
+          * tolerance() functions are added to HaoOrlin (#306)
+        * Implementation improvements
+          * Improvements in weighted matching algorithms (#314)
+            * Jumpstart initialization
+          * ArcIt iteration is based on out-arc lists instead of in-arc lists
+            in ListDigraph (#311)
+          * Faster add row operation in CbcMip (#203)
+          * Better implementation for split() in ListDigraph (#311)
+          * ArgParser can also throw exception instead of exit(1) (#332)
+        * Miscellaneous
+          * A simple interactive bootstrap script
+          * Doc improvements (#62,#180,#299,#302,#303,#304,#307,#311,#331,#315,
+                #316,#319)
+            * BibTeX references in the doc (#184)
+          * Optionally use valgrind when running tests
+          * Also check ReferenceMapTag in concept checks (#312)
+          * dimacs-solver uses long long type by default.
+        * Several bugfixes (compared to release 1.1):
+          #295: Suppress MSVC warnings using pragmas
+          ----: Various CMAKE related improvements
+                * Remove duplications from doc/CMakeLists.txt
+                * Rename documentation install folder from 'docs' to 'html'
+                * Add tools/CMakeLists.txt to the tarball
+                * Generate and install LEMONConfig.cmake
+                * Change the label of the html project in Visual Studio
+                * Fix the check for the 'long long' type
+                * Put the version string into config.h
+                * Minor CMake improvements
+                * Set the version to 'hg-tip' if everything fails
+          #311: Add missing 'explicit' keywords
+          #302: Fix the implementation and doc of CrossRefMap
+          #308: Remove duplicate list_graph.h entry from source list
+          #307: Bugfix in Preflow and Circulation
+          #305: Bugfix and extension in the rename script
+          #312: Also check ReferenceMapTag in concept checks
+          #250: Bugfix in pathSource() and pathTarget()
+          #321: Use pathCopy(from,to) instead of copyPath(to,from)
+          #322: Distribure LEMONConfig.cmake.in
+          #330: Bug fix in map_extender.h
+          #336: Fix the date field comment of graphToEps() output
+          #323: Bug fix in Suurballe
+          #335: Fix clear() function in ExtendFindEnum
+          #337: Use void* as the LPX object pointer
+          #317: Fix (and improve) error message in mip_test.cc
+                Remove unnecessary OsiCbc dependency
+          #356: Allow multiple executions of weighted matching algorithms (#356)
+
+2009-05-13 Version 1.1 released
+
+        This is the second stable release of the 1.x series. It
+        features a better coverage of the tools available in the 0.x
+        series, a thoroughly reworked LP/MIP interface plus various
+        improvements in the existing tools.
+
+        * Much improved M$ Windows support
+          * Various improvements in the CMAKE build system
+          * Compilation warnings are fixed/suppressed
+        * Support IBM xlC compiler
+        * New algorithms
+          * Connectivity related algorithms (#61)
+          * Euler walks (#65)
+          * Preflow push-relabel max. flow algorithm (#176)
+          * Circulation algorithm (push-relabel based) (#175)
+          * Suurballe algorithm (#47)
+          * Gomory-Hu algorithm (#66)
+          * Hao-Orlin algorithm (#58)
+          * Edmond's maximum cardinality and weighted matching algorithms
+            in general graphs (#48,#265)
+          * Minimum cost arborescence/branching (#60)
+          * Network Simplex min. cost flow algorithm (#234)
+        * New data structures
+          * Full graph structure (#57)
+          * Grid graph structure (#57)
+          * Hypercube graph structure (#57)
+          * Graph adaptors (#67)
+          * ArcSet and EdgeSet classes (#67)
+          * Elevator class (#174)
+        * Other new tools
+          * LP/MIP interface (#44)
+            * Support for GLPK, CPLEX, Soplex, COIN-OR CLP and CBC
+          * Reader for the Nauty file format (#55)
+          * DIMACS readers (#167)
+          * Radix sort algorithms (#72)
+          * RangeIdMap and CrossRefMap (#160)
+        * New command line tools
+          * DIMACS to LGF converter (#182)
+          * lgf-gen - a graph generator (#45)
+          * DIMACS solver utility (#226)
+        * Other code improvements
+          * Lognormal distribution added to Random (#102)
+          * Better (i.e. O(1) time) item counting in SmartGraph (#3)
+          * The standard maps of graphs are guaranteed to be
+            reference maps (#190)
+        * Miscellaneous
+          * Various doc improvements
+          * Improved 0.x -> 1.x converter script
+
+        * Several bugfixes (compared to release 1.0):
+          #170: Bugfix SmartDigraph::split()
+          #171: Bugfix in SmartGraph::restoreSnapshot()
+          #172: Extended test cases for graphs and digraphs
+          #173: Bugfix in Random
+                * operator()s always return a double now
+                * the faulty real<Num>(Num) and real<Num>(Num,Num)
+                  have been removed
+          #187: Remove DijkstraWidestPathOperationTraits
+          #61:  Bugfix in DfsVisit
+          #193: Bugfix in GraphReader::skipSection()
+          #195: Bugfix in ConEdgeIt()
+          #197: Bugfix in heap unionfind
+                * This bug affects Edmond's general matching algorithms
+          #207: Fix 'make install' without 'make html' using CMAKE
+          #208: Suppress or fix VS2008 compilation warnings
+          ----: Update the LEMON icon
+          ----: Enable the component-based installer
+                (in installers made by CPACK)
+          ----: Set the proper version for CMAKE in the tarballs
+                (made by autotools)
+          ----: Minor clarification in the LICENSE file
+          ----: Add missing unistd.h include to time_measure.h
+          #204: Compilation bug fixed in graph_to_eps.h with VS2005
+          #214,#215: windows.h should never be included by LEMON headers
+          #230: Build systems check the availability of 'long long' type
+          #229: Default implementation of Tolerance<> is used for integer types
+          #211,#212: Various fixes for compiling on AIX
+          ----: Improvements in CMAKE config
+                - docs is installed in share/doc/
+                - detects newer versions of Ghostscript
+          #239: Fix missing 'inline' specifier in time_measure.h
+          #274,#280: Install lemon/config.h
+          #275: Prefix macro names with LEMON_ in lemon/config.h
+          ----: Small script for making the release tarballs added
+          ----: Minor improvement in unify-sources.sh (a76f55d7d397)
+
 2009-03-27 LEMON joins to the COIN-OR initiative
 
@@ -8,50 +234,50 @@
 2008-10-13 Version 1.0 released
 
-	This is the first stable release of LEMON. Compared to the 0.x
-	release series, it features a considerably smaller but more
-	matured set of tools. The API has also completely revised and
-	changed in several places.
-
-	* The major name changes compared to the 0.x series (see the
+        This is the first stable release of LEMON. Compared to the 0.x
+        release series, it features a considerably smaller but more
+        matured set of tools. The API has also completely revised and
+        changed in several places.
+
+        * The major name changes compared to the 0.x series (see the
           Migration Guide in the doc for more details)
           * Graph -> Digraph, UGraph -> Graph
           * Edge -> Arc, UEdge -> Edge
-	  * source(UEdge)/target(UEdge) -> u(Edge)/v(Edge)
-	* Other improvements
-	  * Better documentation
-	  * Reviewed and cleaned up codebase
-	  * CMake based build system (along with the autotools based one)
-	* Contents of the library (ported from 0.x)
-	  * Algorithms
-       	    * breadth-first search (bfs.h)
-       	    * depth-first search (dfs.h)
-       	    * Dijkstra's algorithm (dijkstra.h)
-       	    * Kruskal's algorithm (kruskal.h)
-    	  * Data structures
-       	    * graph data structures (list_graph.h, smart_graph.h)
-       	    * path data structures (path.h)
-       	    * binary heap data structure (bin_heap.h)
-       	    * union-find data structures (unionfind.h)
-       	    * miscellaneous property maps (maps.h)
-       	    * two dimensional vector and bounding box (dim2.h)
+          * source(UEdge)/target(UEdge) -> u(Edge)/v(Edge)
+        * Other improvements
+          * Better documentation
+          * Reviewed and cleaned up codebase
+          * CMake based build system (along with the autotools based one)
+        * Contents of the library (ported from 0.x)
+          * Algorithms
+            * breadth-first search (bfs.h)
+            * depth-first search (dfs.h)
+            * Dijkstra's algorithm (dijkstra.h)
+            * Kruskal's algorithm (kruskal.h)
+          * Data structures
+            * graph data structures (list_graph.h, smart_graph.h)
+            * path data structures (path.h)
+            * binary heap data structure (bin_heap.h)
+            * union-find data structures (unionfind.h)
+            * miscellaneous property maps (maps.h)
+            * two dimensional vector and bounding box (dim2.h)
           * Concepts
-       	    * graph structure concepts (concepts/digraph.h, concepts/graph.h,
+            * graph structure concepts (concepts/digraph.h, concepts/graph.h,
               concepts/graph_components.h)
-       	    * concepts for other structures (concepts/heap.h, concepts/maps.h,
-	      concepts/path.h)
-    	  * Tools
-       	    * Mersenne twister random number generator (random.h)
-       	    * tools for measuring cpu and wall clock time (time_measure.h)
-       	    * tools for counting steps and events (counter.h)
-       	    * tool for parsing command line arguments (arg_parser.h)
-       	    * tool for visualizing graphs (graph_to_eps.h)
-       	    * tools for reading and writing data in LEMON Graph Format
+            * concepts for other structures (concepts/heap.h, concepts/maps.h,
+              concepts/path.h)
+          * Tools
+            * Mersenne twister random number generator (random.h)
+            * tools for measuring cpu and wall clock time (time_measure.h)
+            * tools for counting steps and events (counter.h)
+            * tool for parsing command line arguments (arg_parser.h)
+            * tool for visualizing graphs (graph_to_eps.h)
+            * tools for reading and writing data in LEMON Graph Format
               (lgf_reader.h, lgf_writer.h)
             * tools to handle the anomalies of calculations with
-	      floating point numbers (tolerance.h)
+              floating point numbers (tolerance.h)
             * tools to manage RGB colors (color.h)
-    	  * Infrastructure
-       	    * extended assertion handling (assert.h)
-       	    * exception classes and error handling (error.h)
-      	    * concept checking (concept_check.h)
-       	    * commonly used mathematical constants (math.h)
+          * Infrastructure
+            * extended assertion handling (assert.h)
+            * exception classes and error handling (error.h)
+            * concept checking (concept_check.h)
+            * commonly used mathematical constants (math.h)
Index: README
===================================================================
--- README	(revision 318)
+++ README	(revision 848)
@@ -1,5 +1,5 @@
-==================================================================
-LEMON - a Library of Efficient Models and Optimization in Networks
-==================================================================
+=====================================================================
+LEMON - a Library for Efficient Modeling and Optimization in Networks
+=====================================================================
 
 LEMON is an open source library written in C++. It provides
@@ -17,4 +17,8 @@
 
    Copying, distribution and modification conditions and terms.
+
+NEWS
+
+   News and version history.
 
 INSTALL
@@ -34,4 +38,8 @@
    Some example programs to make you easier to get familiar with LEMON.
 
+scripts/
+
+   Scripts that make it easier to develop LEMON.
+
 test/
 
Index: cmake/FindCOIN.cmake
===================================================================
--- cmake/FindCOIN.cmake	(revision 951)
+++ cmake/FindCOIN.cmake	(revision 951)
@@ -0,0 +1,117 @@
+SET(COIN_ROOT_DIR "" CACHE PATH "COIN root directory")
+
+FIND_PATH(COIN_INCLUDE_DIR coin/CoinUtilsConfig.h
+  HINTS ${COIN_ROOT_DIR}/include
+)
+FIND_LIBRARY(COIN_CBC_LIBRARY
+  NAMES Cbc libCbc
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+FIND_LIBRARY(COIN_CBC_SOLVER_LIBRARY
+  NAMES CbcSolver libCbcSolver
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+FIND_LIBRARY(COIN_CGL_LIBRARY
+  NAMES Cgl libCgl
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+FIND_LIBRARY(COIN_CLP_LIBRARY
+  NAMES Clp libClp
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+FIND_LIBRARY(COIN_COIN_UTILS_LIBRARY
+  NAMES CoinUtils libCoinUtils
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+FIND_LIBRARY(COIN_OSI_LIBRARY
+  NAMES Osi libOsi
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+FIND_LIBRARY(COIN_OSI_CBC_LIBRARY
+  NAMES OsiCbc libOsiCbc
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+FIND_LIBRARY(COIN_OSI_CLP_LIBRARY
+  NAMES OsiClp libOsiClp
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+FIND_LIBRARY(COIN_OSI_VOL_LIBRARY
+  NAMES OsiVol libOsiVol
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+FIND_LIBRARY(COIN_VOL_LIBRARY
+  NAMES Vol libVol
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+
+FIND_LIBRARY(COIN_ZLIB_LIBRARY
+  NAMES z libz
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+FIND_LIBRARY(COIN_BZ2_LIBRARY
+  NAMES bz2 libbz2
+  HINTS ${COIN_ROOT_DIR}/lib/coin
+  HINTS ${COIN_ROOT_DIR}/lib
+)
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(COIN DEFAULT_MSG
+  COIN_INCLUDE_DIR
+  COIN_CBC_LIBRARY
+  COIN_CBC_SOLVER_LIBRARY
+  COIN_CGL_LIBRARY
+  COIN_CLP_LIBRARY
+  COIN_COIN_UTILS_LIBRARY
+  COIN_OSI_LIBRARY
+  COIN_OSI_CBC_LIBRARY
+  COIN_OSI_CLP_LIBRARY
+  # COIN_OSI_VOL_LIBRARY
+  # COIN_VOL_LIBRARY
+)
+
+IF(COIN_FOUND)
+  SET(COIN_INCLUDE_DIRS ${COIN_INCLUDE_DIR})
+  SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARY};${COIN_COIN_UTILS_LIBRARY};${COIN_ZLIB_LIBRARY};${COIN_BZ2_LIBRARY}")
+  IF(COIN_ZLIB_LIBRARY)
+    SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARIES};${COIN_ZLIB_LIBRARY}")
+  ENDIF(COIN_ZLIB_LIBRARY)
+   IF(COIN_BZ2_LIBRARY)
+    SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARIES};${COIN_BZ2_LIBRARY}")
+  ENDIF(COIN_BZ2_LIBRARY)
+  SET(COIN_CBC_LIBRARIES "${COIN_CBC_LIBRARY};${COIN_CBC_SOLVER_LIBRARY};${COIN_CGL_LIBRARY};${COIN_OSI_LIBRARY};${COIN_OSI_CBC_LIBRARY};${COIN_OSI_CLP_LIBRARY};${COIN_ZLIB_LIBRARY};${COIN_BZ2_LIBRARY};${COIN_CLP_LIBRARIES}")
+  SET(COIN_LIBRARIES ${COIN_CBC_LIBRARIES})
+ENDIF(COIN_FOUND)
+
+MARK_AS_ADVANCED(
+  COIN_INCLUDE_DIR
+  COIN_CBC_LIBRARY
+  COIN_CBC_SOLVER_LIBRARY
+  COIN_CGL_LIBRARY
+  COIN_CLP_LIBRARY
+  COIN_COIN_UTILS_LIBRARY
+  COIN_OSI_LIBRARY
+  COIN_OSI_CBC_LIBRARY
+  COIN_OSI_CLP_LIBRARY
+  COIN_OSI_VOL_LIBRARY
+  COIN_VOL_LIBRARY
+  COIN_ZLIB_LIBRARY
+  COIN_BZ2_LIBRARY
+)
+
+IF(COIN_FOUND)
+  SET(LEMON_HAVE_LP TRUE)
+  SET(LEMON_HAVE_MIP TRUE)
+  SET(LEMON_HAVE_CLP TRUE)
+  SET(LEMON_HAVE_CBC TRUE)
+ENDIF(COIN_FOUND)
Index: cmake/FindCPLEX.cmake
===================================================================
--- cmake/FindCPLEX.cmake	(revision 950)
+++ cmake/FindCPLEX.cmake	(revision 950)
@@ -0,0 +1,40 @@
+SET(CPLEX_ROOT_DIR "" CACHE PATH "CPLEX root directory")
+
+FIND_PATH(CPLEX_INCLUDE_DIR
+  ilcplex/cplex.h
+  PATHS "C:/ILOG/CPLEX/include"
+  PATHS "/opt/ilog/cplex/include"
+  HINTS ${CPLEX_ROOT_DIR}/include
+)
+FIND_LIBRARY(CPLEX_LIBRARY
+  cplex
+  PATHS "C:/ILOG/CPLEX/lib/msvc7/stat_mda"
+  PATHS "/opt/ilog/cplex/bin"
+  HINTS ${CPLEX_ROOT_DIR}/bin
+  HINTS ${CPLEX_ROOT_DIR}/lib
+)
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(CPLEX DEFAULT_MSG CPLEX_LIBRARY CPLEX_INCLUDE_DIR)
+
+FIND_PATH(CPLEX_BIN_DIR
+  cplex.dll
+  PATHS "C:/ILOG/CPLEX/bin/x86_win32"
+  HINTS ${CPLEX_ROOT_DIR}/bin
+)
+
+IF(CPLEX_FOUND)
+  SET(CPLEX_INCLUDE_DIRS ${CPLEX_INCLUDE_DIR})
+  SET(CPLEX_LIBRARIES ${CPLEX_LIBRARY})
+  IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+    SET(CPLEX_LIBRARIES "${CPLEX_LIBRARIES};m;pthread")
+  ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ENDIF(CPLEX_FOUND)
+
+MARK_AS_ADVANCED(CPLEX_LIBRARY CPLEX_INCLUDE_DIR CPLEX_BIN_DIR)
+
+IF(CPLEX_FOUND)
+  SET(LEMON_HAVE_LP TRUE)
+  SET(LEMON_HAVE_MIP TRUE)
+  SET(LEMON_HAVE_CPLEX TRUE)
+ENDIF(CPLEX_FOUND)
Index: cmake/FindGLPK.cmake
===================================================================
--- cmake/FindGLPK.cmake	(revision 473)
+++ cmake/FindGLPK.cmake	(revision 638)
@@ -1,2 +1,4 @@
+SET(GLPK_ROOT_DIR "" CACHE PATH "GLPK root directory")
+
 SET(GLPK_REGKEY "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Glpk;InstallPath]")
 GET_FILENAME_COMPONENT(GLPK_ROOT_PATH ${GLPK_REGKEY} ABSOLUTE)
@@ -4,14 +6,47 @@
 FIND_PATH(GLPK_INCLUDE_DIR
   glpk.h
-  PATHS ${GLPK_REGKEY}/include)
+  PATHS ${GLPK_REGKEY}/include
+  HINTS ${GLPK_ROOT_DIR}/include
+)
+FIND_LIBRARY(GLPK_LIBRARY
+  glpk
+  PATHS ${GLPK_REGKEY}/lib
+  HINTS ${GLPK_ROOT_DIR}/lib
+)
 
-FIND_LIBRARY(GLPK_LIBRARY
-  NAMES glpk
-  PATHS ${GLPK_REGKEY}/lib)
+IF(GLPK_INCLUDE_DIR AND GLPK_LIBRARY)
+  FILE(READ ${GLPK_INCLUDE_DIR}/glpk.h GLPK_GLPK_H)
+
+  STRING(REGEX MATCH "define[ ]+GLP_MAJOR_VERSION[ ]+[0-9]+" GLPK_MAJOR_VERSION_LINE "${GLPK_GLPK_H}")
+  STRING(REGEX REPLACE "define[ ]+GLP_MAJOR_VERSION[ ]+([0-9]+)" "\\1" GLPK_VERSION_MAJOR "${GLPK_MAJOR_VERSION_LINE}")
+
+  STRING(REGEX MATCH "define[ ]+GLP_MINOR_VERSION[ ]+[0-9]+" GLPK_MINOR_VERSION_LINE "${GLPK_GLPK_H}")
+  STRING(REGEX REPLACE "define[ ]+GLP_MINOR_VERSION[ ]+([0-9]+)" "\\1" GLPK_VERSION_MINOR "${GLPK_MINOR_VERSION_LINE}")
+
+  SET(GLPK_VERSION_STRING "${GLPK_VERSION_MAJOR}.${GLPK_VERSION_MINOR}")
+
+  IF(GLPK_FIND_VERSION)
+    IF(GLPK_FIND_VERSION_COUNT GREATER 2)
+      MESSAGE(SEND_ERROR "unexpected version string")
+    ENDIF(GLPK_FIND_VERSION_COUNT GREATER 2)
+
+    MATH(EXPR GLPK_REQUESTED_VERSION "${GLPK_FIND_VERSION_MAJOR}*100 + ${GLPK_FIND_VERSION_MINOR}")
+    MATH(EXPR GLPK_FOUND_VERSION "${GLPK_VERSION_MAJOR}*100 + ${GLPK_VERSION_MINOR}")
+
+    IF(GLPK_FOUND_VERSION LESS GLPK_REQUESTED_VERSION)
+      SET(GLPK_PROPER_VERSION_FOUND FALSE)
+    ELSE(GLPK_FOUND_VERSION LESS GLPK_REQUESTED_VERSION)
+      SET(GLPK_PROPER_VERSION_FOUND TRUE)
+    ENDIF(GLPK_FOUND_VERSION LESS GLPK_REQUESTED_VERSION)
+  ELSE(GLPK_FIND_VERSION)
+    SET(GLPK_PROPER_VERSION_FOUND TRUE)
+  ENDIF(GLPK_FIND_VERSION)
+ENDIF(GLPK_INCLUDE_DIR AND GLPK_LIBRARY)
 
 INCLUDE(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLPK DEFAULT_MSG GLPK_LIBRARY GLPK_INCLUDE_DIR)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLPK DEFAULT_MSG GLPK_LIBRARY GLPK_INCLUDE_DIR GLPK_PROPER_VERSION_FOUND)
 
 IF(GLPK_FOUND)
+  SET(GLPK_INCLUDE_DIRS ${GLPK_INCLUDE_DIR})
   SET(GLPK_LIBRARIES ${GLPK_LIBRARY})
   SET(GLPK_BIN_DIR ${GLPK_ROOT_PATH}/bin)
@@ -19,2 +54,8 @@
 
 MARK_AS_ADVANCED(GLPK_LIBRARY GLPK_INCLUDE_DIR GLPK_BIN_DIR)
+
+IF(GLPK_FOUND)
+  SET(LEMON_HAVE_LP TRUE)
+  SET(LEMON_HAVE_MIP TRUE)
+  SET(LEMON_HAVE_GLPK TRUE)
+ENDIF(GLPK_FOUND)
Index: cmake/LEMONConfig.cmake.in
===================================================================
--- cmake/LEMONConfig.cmake.in	(revision 675)
+++ cmake/LEMONConfig.cmake.in	(revision 675)
@@ -0,0 +1,13 @@
+SET(LEMON_INCLUDE_DIR "@CMAKE_INSTALL_PREFIX@/include" CACHE PATH "LEMON include directory")
+SET(LEMON_INCLUDE_DIRS "${LEMON_INCLUDE_DIR}")
+
+IF(UNIX)
+  SET(LEMON_LIB_NAME "libemon.a")
+ELSEIF(WIN32)
+  SET(LEMON_LIB_NAME "lemon.lib")
+ENDIF(UNIX)
+
+SET(LEMON_LIBRARY "@CMAKE_INSTALL_PREFIX@/lib/${LEMON_LIB_NAME}" CACHE FILEPATH "LEMON library")
+SET(LEMON_LIBRARIES "${LEMON_LIBRARY}")
+
+MARK_AS_ADVANCED(LEMON_LIBRARY LEMON_INCLUDE_DIR)
Index: cmake/version.cmake.in
===================================================================
--- cmake/version.cmake.in	(revision 478)
+++ cmake/version.cmake.in	(revision 678)
@@ -1,2 +1,1 @@
-SET(PROJECT_NAME "@PACKAGE_NAME@")
-SET(PROJECT_VERSION "@PACKAGE_VERSION@" CACHE STRING "LEMON version string.")
+SET(LEMON_VERSION "@PACKAGE_VERSION@" CACHE STRING "LEMON version string.")
Index: configure.ac
===================================================================
--- configure.ac	(revision 517)
+++ configure.ac	(revision 990)
@@ -3,12 +3,15 @@
 dnl Version information.
 m4_define([lemon_version_number],
-	[m4_normalize(esyscmd([echo ${LEMON_VERSION}]))])
+          [m4_normalize(esyscmd([echo ${LEMON_VERSION}]))])
 dnl m4_define([lemon_version_number], [])
 m4_define([lemon_hg_path], [m4_normalize(esyscmd([./scripts/chg-len.py]))])
-m4_define([lemon_hg_revision], [m4_normalize(esyscmd([hg id -i]))])
+m4_define([lemon_hg_revision], [m4_normalize(esyscmd([hg id -i 2> /dev/null]))])
 m4_define([lemon_version], [ifelse(lemon_version_number(),
-			   [],
-			   [lemon_hg_path().lemon_hg_revision()],
-			   [lemon_version_number()])])
+                           [],
+                           [ifelse(lemon_hg_revision(),
+                           [],
+                           [hg-tip],
+                           [lemon_hg_path().lemon_hg_revision()])],
+                           [lemon_version_number()])])
 
 AC_PREREQ([2.59])
@@ -16,7 +19,9 @@
 AC_CONFIG_AUX_DIR([build-aux])
 AC_CONFIG_MACRO_DIR([m4])
-AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects nostdinc])
+AM_INIT_AUTOMAKE([-Wall foreign subdir-objects nostdinc])
 AC_CONFIG_SRCDIR([lemon/list_graph.h])
 AC_CONFIG_HEADERS([config.h lemon/config.h])
+
+AC_DEFINE([LEMON_VERSION], [lemon_version()], [The version string])
 
 dnl Do compilation tests using the C++ compiler.
@@ -26,5 +31,5 @@
 AC_CHECK_TYPE(long long, [long_long_found=yes], [long_long_found=no])
 if test x"$long_long_found" = x"yes"; then
-  AC_DEFINE([HAVE_LONG_LONG], [1], [Define to 1 if you have long long.])
+  AC_DEFINE([LEMON_HAVE_LONG_LONG], [1], [Define to 1 if you have long long.])
 fi
 
@@ -37,4 +42,5 @@
 
 AC_CHECK_PROG([doxygen_found],[doxygen],[yes],[no])
+AC_CHECK_PROG([python_found],[python],[yes],[no])
 AC_CHECK_PROG([gs_found],[gs],[yes],[no])
 
@@ -60,21 +66,8 @@
 LX_CHECK_CPLEX
 LX_CHECK_SOPLEX
-LX_CHECK_CLP
+LX_CHECK_COIN
 
 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.
-AC_ARG_ENABLE([demo],
-AS_HELP_STRING([--enable-demo], [build the demo programs])
-AS_HELP_STRING([--disable-demo], [do not build the demo programs @<:@default@:>@]),
-              [], [enable_demo=no])
-AC_MSG_CHECKING([whether to build the demo programs])
-if test x"$enable_demo" != x"no"; then
-  AC_MSG_RESULT([yes])
-else
-  AC_MSG_RESULT([no])
-fi
-AM_CONDITIONAL([WANT_DEMO], [test x"$enable_demo" != x"no"])
 
 dnl Disable/enable building the binary tools.
@@ -90,4 +83,19 @@
 fi
 AM_CONDITIONAL([WANT_TOOLS], [test x"$enable_tools" != x"no"])
+
+dnl Support for running test cases using valgrind.
+use_valgrind=no
+AC_ARG_ENABLE([valgrind],
+AS_HELP_STRING([--enable-valgrind], [use valgrind when running tests]),
+              [use_valgrind=yes])
+
+if [[ "$use_valgrind" = "yes" ]]; then
+  AC_CHECK_PROG(HAVE_VALGRIND, valgrind, yes, no)
+
+  if [[ "$HAVE_VALGRIND" = "no" ]]; then
+    AC_MSG_ERROR([Valgrind not found in PATH.])
+  fi
+fi
+AM_CONDITIONAL(USE_VALGRIND, [test "$use_valgrind" = "yes"])
 
 dnl Checks for header files.
@@ -107,10 +115,12 @@
 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)/doc/mainpage.dox.in $(top_srcdir)/lemon/lemon.pc.in $(top_srcdir)/cmake/version.cmake.in'])
 
 AC_CONFIG_FILES([
 Makefile
+demo/Makefile
 cmake/version.cmake
 doc/Doxyfile
+doc/mainpage.dox
 lemon/lemon.pc
 ])
@@ -132,7 +142,8 @@
 echo SOPLEX support................ : $lx_soplex_found
 echo CLP support................... : $lx_clp_found
+echo CBC support................... : $lx_cbc_found
 echo
-echo Build demo programs........... : $enable_demo
 echo Build additional tools........ : $enable_tools
+echo Use valgrind for tests........ : $use_valgrind
 echo
 echo The packace will be installed in
Index: demo/CMakeLists.txt
===================================================================
--- demo/CMakeLists.txt	(revision 549)
+++ demo/CMakeLists.txt	(revision 679)
@@ -4,13 +4,16 @@
 )
 
-LINK_DIRECTORIES(${PROJECT_BINARY_DIR}/lemon)
+LINK_DIRECTORIES(
+  ${PROJECT_BINARY_DIR}/lemon
+)
 
 SET(DEMOS
   arg_parser_demo
   graph_to_eps_demo
-  lgf_demo)
+  lgf_demo
+)
 
 FOREACH(DEMO_NAME ${DEMOS})
   ADD_EXECUTABLE(${DEMO_NAME} ${DEMO_NAME}.cc)
   TARGET_LINK_LIBRARIES(${DEMO_NAME} lemon)
-ENDFOREACH(DEMO_NAME)
+ENDFOREACH()
Index: demo/Makefile.am
===================================================================
--- demo/Makefile.am	(revision 400)
+++ demo/Makefile.am	(revision 564)
@@ -1,16 +1,17 @@
-EXTRA_DIST += \
-	demo/CMakeLists.txt \
-	demo/digraph.lgf
+AM_CXXFLAGS = $(WARNINGCXXFLAGS)
 
-if WANT_DEMO
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir)
+LDADD = $(top_builddir)/lemon/libemon.la
 
-noinst_PROGRAMS += \
-	demo/arg_parser_demo \
-	demo/graph_to_eps_demo \
-	demo/lgf_demo
+EXTRA_DIST = \
+	CMakeLists.txt \
+	digraph.lgf
 
-endif WANT_DEMO
+noinst_PROGRAMS = \
+	arg_parser_demo \
+	graph_to_eps_demo \
+	lgf_demo
 
-demo_arg_parser_demo_SOURCES = demo/arg_parser_demo.cc
-demo_graph_to_eps_demo_SOURCES = demo/graph_to_eps_demo.cc
-demo_lgf_demo_SOURCES = demo/lgf_demo.cc
+arg_parser_demo_SOURCES = arg_parser_demo.cc
+graph_to_eps_demo_SOURCES = graph_to_eps_demo.cc
+lgf_demo_SOURCES = lgf_demo.cc
Index: demo/arg_parser_demo.cc
===================================================================
--- demo/arg_parser_demo.cc	(revision 440)
+++ demo/arg_parser_demo.cc	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -66,7 +66,16 @@
     .other("...");
 
+  // Throw an exception when problems occurs. The default behavior is to
+  // exit(1) on these cases, but this makes Valgrind falsely warn
+  // about memory leaks.
+  ap.throwOnProblems();
+
   // Perform the parsing process
   // (in case of any error it terminates the program)
-  ap.parse();
+  // The try {} construct is necessary only if the ap.trowOnProblems()
+  // setting is in use.
+  try {
+    ap.parse();
+  } catch (ArgParserException &) { return 1; }
 
   // Check each option if it has been given and print its value
Index: demo/graph_to_eps_demo.cc
===================================================================
--- demo/graph_to_eps_demo.cc	(revision 440)
+++ demo/graph_to_eps_demo.cc	(revision 612)
@@ -183,5 +183,5 @@
   ListDigraph::NodeMap<Point> hcoords(h);
 
-  int cols=int(sqrt(double(palette.size())));
+  int cols=int(std::sqrt(double(palette.size())));
   for(int i=0;i<int(paletteW.size());i++) {
     Node n=h.addNode();
Index: doc/CMakeLists.txt
===================================================================
--- doc/CMakeLists.txt	(revision 549)
+++ doc/CMakeLists.txt	(revision 944)
@@ -4,40 +4,71 @@
 SET(abs_top_builddir ${PROJECT_BINARY_DIR})
 
+SET(LEMON_DOC_SOURCE_BROWSER "NO" CACHE STRING "Include source into the doc (YES/NO).")
+
 CONFIGURE_FILE(
   ${PROJECT_SOURCE_DIR}/doc/Doxyfile.in
   ${PROJECT_BINARY_DIR}/doc/Doxyfile
-  @ONLY)
+  @ONLY
+)
 
-IF(DOXYGEN_EXECUTABLE AND GHOSTSCRIPT_EXECUTABLE)
+CONFIGURE_FILE(
+  ${PROJECT_SOURCE_DIR}/doc/mainpage.dox.in
+  ${PROJECT_BINARY_DIR}/doc/mainpage.dox
+  @ONLY
+)
+
+IF(DOXYGEN_EXECUTABLE AND PYTHONINTERP_FOUND AND GHOSTSCRIPT_EXECUTABLE)
   FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/)
+  SET(GHOSTSCRIPT_OPTIONS -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha)
+  ADD_CUSTOM_TARGET(html
+    COMMAND ${CMAKE_COMMAND} -E remove_directory gen-images
+    COMMAND ${CMAKE_COMMAND} -E make_directory gen-images
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/bipartite_matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_matching.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/bipartite_partitions.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_partitions.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/connected_components.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/edge_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/edge_biconnected_components.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/grid_graph.png ${CMAKE_CURRENT_SOURCE_DIR}/images/grid_graph.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/matching.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/node_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/node_biconnected_components.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_1.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_1.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/planar.png ${CMAKE_CURRENT_SOURCE_DIR}/images/planar.eps
+    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/strongly_connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/strongly_connected_components.eps
+    COMMAND ${CMAKE_COMMAND} -E remove_directory html
+    COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/bib2dox.py ${CMAKE_CURRENT_SOURCE_DIR}/references.bib >references.dox
+    COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
+    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  )
+
+  SET_TARGET_PROPERTIES(html PROPERTIES PROJECT_LABEL BUILD_DOC)
+
   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
-      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps
-      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps
-      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
-      COMMAND rm -rf html
-      COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
-      WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+    INSTALL(
+      DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
+      DESTINATION share/doc/lemon/html
+      COMPONENT html_documentation
+    )
   ELSEIF(WIN32)
-    ADD_CUSTOM_TARGET(html
-      COMMAND if exist gen-images rmdir /s /q gen-images
-      COMMAND mkdir gen-images
-      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
-      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps
-      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps
-      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
-      COMMAND if exist html rmdir /s /q html
-      COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
-      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
+    )
+  ENDIF()
+
+ENDIF()
+
+IF(WGET_FOUND)
+ADD_CUSTOM_TARGET(update-external-tags
+  COMMAND ${CMAKE_COMMAND} -E make_directory dl
+  # COMMAND ${CMAKE_COMMAND} -E copy libstdc++.tag dl
+  COMMAND ${WGET_EXECUTABLE} wget -P dl -N libstdc++.tag.tmp http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/libstdc++.tag
+  COMMAND ${CMAKE_COMMAND} -E rename dl/libstdc++.tag libstdc++.tag
+  COMMAND ${CMAKE_COMMAND} -E remove dl/libstdc++.tag
+  COMMAND ${CMAKE_COMMAND} -E remove_directory dl
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  )
+ENDIF()
Index: doc/Doxyfile.in
===================================================================
--- doc/Doxyfile.in	(revision 367)
+++ doc/Doxyfile.in	(revision 944)
@@ -1,3 +1,3 @@
-# Doxyfile 1.5.7.1
+# Doxyfile 1.7.3
 
 #---------------------------------------------------------------------------
@@ -5,6 +5,8 @@
 #---------------------------------------------------------------------------
 DOXYFILE_ENCODING      = UTF-8
-PROJECT_NAME           = @PACKAGE_NAME@
-PROJECT_NUMBER         = @PACKAGE_VERSION@
+PROJECT_NAME           = 
+PROJECT_NUMBER         = 
+PROJECT_BRIEF          =
+PROJECT_LOGO           =
 OUTPUT_DIRECTORY       = 
 CREATE_SUBDIRS         = NO
@@ -22,5 +24,4 @@
 QT_AUTOBRIEF           = NO
 MULTILINE_CPP_IS_BRIEF = NO
-DETAILS_AT_TOP         = YES
 INHERIT_DOCS           = NO
 SEPARATE_MEMBER_PAGES  = NO
@@ -31,4 +32,5 @@
 OPTIMIZE_FOR_FORTRAN   = NO
 OPTIMIZE_OUTPUT_VHDL   = NO
+EXTENSION_MAPPING      =
 BUILTIN_STL_SUPPORT    = YES
 CPP_CLI_SUPPORT        = NO
@@ -56,9 +58,12 @@
 HIDE_SCOPE_NAMES       = YES
 SHOW_INCLUDE_FILES     = YES
+FORCE_LOCAL_INCLUDES   = NO
 INLINE_INFO            = YES
 SORT_MEMBER_DOCS       = NO
 SORT_BRIEF_DOCS        = NO
+SORT_MEMBERS_CTORS_1ST = NO
 SORT_GROUP_NAMES       = NO
 SORT_BY_SCOPE_NAME     = NO
+STRICT_PROTO_MATCHING  = NO
 GENERATE_TODOLIST      = YES
 GENERATE_TESTLIST      = YES
@@ -72,5 +77,5 @@
 SHOW_NAMESPACES        = YES
 FILE_VERSION_FILTER    = 
-LAYOUT_FILE            = DoxygenLayout.xml
+LAYOUT_FILE            = "@abs_top_srcdir@/doc/DoxygenLayout.xml"
 #---------------------------------------------------------------------------
 # configuration options related to warning and progress messages
@@ -92,5 +97,7 @@
                          "@abs_top_srcdir@/demo" \
                          "@abs_top_srcdir@/tools" \
-                         "@abs_top_srcdir@/test/test_tools.h"
+                         "@abs_top_srcdir@/test/test_tools.h" \
+                         "@abs_top_builddir@/doc/mainpage.dox" \
+                         "@abs_top_builddir@/doc/references.dox"
 INPUT_ENCODING         = UTF-8
 FILE_PATTERNS          = *.h \
@@ -112,8 +119,9 @@
 FILTER_PATTERNS        = 
 FILTER_SOURCE_FILES    = NO
+FILTER_SOURCE_PATTERNS =
 #---------------------------------------------------------------------------
 # configuration options related to source browsing
 #---------------------------------------------------------------------------
-SOURCE_BROWSER         = NO
+SOURCE_BROWSER         = @LEMON_DOC_SOURCE_BROWSER@
 INLINE_SOURCES         = NO
 STRIP_CODE_COMMENTS    = YES
@@ -138,9 +146,15 @@
 HTML_FOOTER            = 
 HTML_STYLESHEET        = 
+HTML_COLORSTYLE_HUE    = 220
+HTML_COLORSTYLE_SAT    = 100
+HTML_COLORSTYLE_GAMMA  = 80
+HTML_TIMESTAMP         = YES
 HTML_ALIGN_MEMBERS     = YES
-HTML_DYNAMIC_SECTIONS  = NO
+HTML_DYNAMIC_SECTIONS  = YES
 GENERATE_DOCSET        = NO
 DOCSET_FEEDNAME        = "Doxygen generated docs"
 DOCSET_BUNDLE_ID       = org.doxygen.Project
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+DOCSET_PUBLISHER_NAME  = Publisher
 GENERATE_HTMLHELP      = NO
 CHM_FILE               = 
@@ -154,10 +168,22 @@
 QHP_NAMESPACE          = org.doxygen.Project
 QHP_VIRTUAL_FOLDER     = doc
+QHP_CUST_FILTER_NAME   =
+QHP_CUST_FILTER_ATTRS  =
+QHP_SECT_FILTER_ATTRS  =
 QHG_LOCATION           = 
+GENERATE_ECLIPSEHELP   = NO
+ECLIPSE_DOC_ID         = org.doxygen.Project
 DISABLE_INDEX          = NO
 ENUM_VALUES_PER_LINE   = 4
 GENERATE_TREEVIEW      = NO
+USE_INLINE_TREES       = NO
 TREEVIEW_WIDTH         = 250
+EXT_LINKS_IN_WINDOW    = NO
 FORMULA_FONTSIZE       = 10
+FORMULA_TRANSPARENT    = YES
+USE_MATHJAX            = NO
+MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
+SEARCHENGINE           = YES
+SERVER_BASED_SEARCH    = NO
 #---------------------------------------------------------------------------
 # configuration options related to the LaTeX output
@@ -176,4 +202,5 @@
 LATEX_BATCHMODE        = NO
 LATEX_HIDE_INDICES     = NO
+LATEX_SOURCE_CODE      = NO
 #---------------------------------------------------------------------------
 # configuration options related to the RTF output
@@ -224,7 +251,7 @@
 SKIP_FUNCTION_MACROS   = YES
 #---------------------------------------------------------------------------
-# Configuration::additions related to external references   
-#---------------------------------------------------------------------------
-TAGFILES               = "@abs_top_srcdir@/doc/libstdc++.tag = http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/  "
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES               = "@abs_top_builddir@/doc/libstdc++.tag = http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/  "
 GENERATE_TAGFILE       = html/lemon.tag
 ALLEXTERNALS           = NO
@@ -238,4 +265,5 @@
 HIDE_UNDOC_RELATIONS   = YES
 HAVE_DOT               = YES
+DOT_NUM_THREADS        = 0
 DOT_FONTNAME           = FreeSans
 DOT_FONTSIZE           = 10
@@ -255,4 +283,5 @@
 DOT_PATH               = 
 DOTFILE_DIRS           = 
+MSCFILE_DIRS           =
 DOT_GRAPH_MAX_NODES    = 50
 MAX_DOT_GRAPH_DEPTH    = 0
@@ -261,6 +290,2 @@
 GENERATE_LEGEND        = YES
 DOT_CLEANUP            = YES
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine   
-#---------------------------------------------------------------------------
-SEARCHENGINE           = NO
Index: doc/DoxygenLayout.xml
===================================================================
--- doc/DoxygenLayout.xml	(revision 316)
+++ doc/DoxygenLayout.xml	(revision 906)
@@ -3,22 +3,22 @@
   <navindex>
     <tab type="mainpage" visible="yes" title=""/>
-    <tab type="modules" visible="yes" title=""/>
+    <tab type="modules" visible="yes" title="" intro=""/>
     <tab type="classes" visible="yes" title="">
-      <tab type="classes" visible="yes" title=""/>
-      <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/> 
-      <tab type="hierarchy" visible="yes" title=""/>
-      <tab type="classmembers" visible="yes" title=""/>
+      <tab type="classes" visible="yes" title="" intro=""/>
+      <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
+      <tab type="hierarchy" visible="yes" title="" intro=""/>
+      <tab type="classmembers" visible="yes" title="" intro=""/>
     </tab>
     <tab type="namespaces" visible="yes" title="">
-      <tab type="namespaces" visible="yes" title=""/>
-      <tab type="namespacemembers" visible="yes" title=""/>
+      <tab type="namespaces" visible="yes" title="" intro=""/>
+      <tab type="namespacemembers" visible="yes" title="" intro=""/>
     </tab>
     <tab type="files" visible="yes" title="">
-      <tab type="files" visible="yes" title=""/>
-      <tab type="globals" visible="yes" title=""/>
+      <tab type="files" visible="yes" title="" intro=""/>
+      <tab type="globals" visible="yes" title="" intro=""/>
     </tab>
-    <tab type="dirs" visible="yes" title=""/>
-    <tab type="examples" visible="yes" title=""/>  
-    <tab type="pages" visible="yes" title=""/>
+    <tab type="dirs" visible="yes" title="" intro=""/>
+    <tab type="examples" visible="yes" title="" intro=""/>
+    <tab type="pages" visible="yes" title="" intro=""/>
   </navindex>
 
Index: doc/Makefile.am
===================================================================
--- doc/Makefile.am	(revision 337)
+++ doc/Makefile.am	(revision 948)
@@ -9,6 +9,9 @@
 	doc/mainpage.dox \
 	doc/migration.dox \
+	doc/min_cost_flow.dox \
 	doc/named-param.dox \
 	doc/namespaces.dox \
+	doc/references.bib \
+	doc/template.h \
 	doc/html \
 	doc/CMakeLists.txt
@@ -22,6 +25,17 @@
 	nodeshape_4.eps
 
+DOC_EPS_IMAGES27 = \
+	bipartite_matching.eps \
+	bipartite_partitions.eps \
+	connected_components.eps \
+	edge_biconnected_components.eps \
+	matching.eps \
+	node_biconnected_components.eps \
+	planar.eps \
+	strongly_connected_components.eps
+
 DOC_EPS_IMAGES = \
-	$(DOC_EPS_IMAGES18)
+	$(DOC_EPS_IMAGES18) \
+	$(DOC_EPS_IMAGES27)
 
 DOC_PNG_IMAGES = \
@@ -46,5 +60,28 @@
 	fi
 
-html-local: $(DOC_PNG_IMAGES)
+$(DOC_EPS_IMAGES27:%.eps=doc/gen-images/%.png): doc/gen-images/%.png: doc/images/%.eps
+	-mkdir doc/gen-images
+	if test ${gs_found} = yes; then \
+	  $(GS_COMMAND) -sDEVICE=pngalpha -r27 -sOutputFile=$@ $<; \
+	else \
+	  echo; \
+	  echo "Ghostscript not found."; \
+	  echo; \
+	  exit 1; \
+	fi
+
+references.dox: doc/references.bib
+	if test ${python_found} = yes; then \
+	  cd doc; \
+	  python @abs_top_srcdir@/scripts/bib2dox.py @abs_top_builddir@/$< >$@; \
+	  cd ..; \
+	else \
+	  echo; \
+	  echo "Python not found."; \
+	  echo; \
+	  exit 1; \
+	fi
+
+html-local: $(DOC_PNG_IMAGES) references.dox
 	if test ${doxygen_found} = yes; then \
 	  cd doc; \
@@ -71,9 +108,9 @@
 install-html-local: doc/html
 	@$(NORMAL_INSTALL)
-	$(mkinstalldirs) $(DESTDIR)$(htmldir)/docs
+	$(mkinstalldirs) $(DESTDIR)$(htmldir)/html
 	for p in doc/html/*.{html,css,png,map,gif,tag} ; do \
 	  f="`echo $$p | sed -e 's|^.*/||'`"; \
-	  echo " $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/docs/$$f"; \
-	  $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/docs/$$f; \
+	  echo " $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f"; \
+	  $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f; \
 	done
 
@@ -82,6 +119,6 @@
 	for p in doc/html/*.{html,css,png,map,gif,tag} ; do \
 	  f="`echo $$p | sed -e 's|^.*/||'`"; \
-	  echo " rm -f $(DESTDIR)$(htmldir)/docs/$$f"; \
-	  rm -f $(DESTDIR)$(htmldir)/docs/$$f; \
+	  echo " rm -f $(DESTDIR)$(htmldir)/html/$$f"; \
+	  rm -f $(DESTDIR)$(htmldir)/html/$$f; \
 	done
 
Index: doc/groups.dox
===================================================================
--- doc/groups.dox	(revision 559)
+++ doc/groups.dox	(revision 884)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -139,14 +139,4 @@
 
 /**
-@defgroup semi_adaptors Semi-Adaptor Classes for Graphs
-@ingroup graphs
-\brief Graph types between real graphs and graph adaptors.
-
-This group contains some graph types between real graphs and graph adaptors.
-These classes wrap graphs to give new functionality as the adaptors do it.
-On the other hand they are not light-weight structures as the adaptors.
-*/
-
-/**
 @defgroup maps Maps
 @ingroup datas
@@ -237,12 +227,4 @@
 
 /**
-@defgroup matrices Matrices
-@ingroup datas
-\brief Two dimensional data storages implemented in LEMON.
-
-This group contains two dimensional data storages implemented in LEMON.
-*/
-
-/**
 @defgroup paths Path Structures
 @ingroup datas
@@ -257,5 +239,26 @@
 any kind of path structure.
 
-\sa lemon::concepts::Path
+\sa \ref concepts::Path "Path concept"
+*/
+
+/**
+@defgroup heaps Heap Structures
+@ingroup datas
+\brief %Heap structures implemented in LEMON.
+
+This group contains the heap structures implemented in LEMON.
+
+LEMON provides several heap classes. They are efficient implementations
+of the abstract data type \e priority \e queue. They store items with
+specified values called \e priorities in such a way that finding and
+removing the item with minimum priority are efficient.
+The basic operations are adding and erasing items, changing the priority
+of an item, etc.
+
+Heaps are crucial in several algorithms, such as Dijkstra and Prim.
+The heap implementations have the same interface, thus any of them can be
+used easily in such algorithms.
+
+\sa \ref concepts::Heap "Heap concept"
 */
 
@@ -270,4 +273,18 @@
 
 /**
+@defgroup geomdat Geometric Data Structures
+@ingroup auxdat
+\brief Geometric data structures implemented in LEMON.
+
+This group contains geometric data structures implemented in LEMON.
+
+ - \ref lemon::dim2::Point "dim2::Point" implements a two dimensional
+   vector with the usual operations.
+ - \ref lemon::dim2::Box "dim2::Box" can be used to determine the
+   rectangular bounding box of a set of \ref lemon::dim2::Point
+   "dim2::Point"'s.
+*/
+
+/**
 @defgroup algs Algorithms
 \brief This group contains the several algorithms
@@ -284,5 +301,6 @@
 
 This group contains the common graph search algorithms, namely
-\e breadth-first \e search (BFS) and \e depth-first \e search (DFS).
+\e breadth-first \e search (BFS) and \e depth-first \e search (DFS)
+\ref clrs01algorithms.
 */
 
@@ -292,5 +310,6 @@
 \brief Algorithms for finding shortest paths.
 
-This group contains the algorithms for finding shortest paths in digraphs.
+This group contains the algorithms for finding shortest paths in digraphs
+\ref clrs01algorithms.
 
  - \ref Dijkstra algorithm for finding shortest paths from a source node
@@ -300,8 +319,4 @@
    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.
@@ -309,4 +324,13 @@
 
 /**
+@defgroup spantree Minimum Spanning Tree Algorithms
+@ingroup algs
+\brief Algorithms for finding minimum cost spanning trees and arborescences.
+
+This group contains the algorithms for finding minimum cost spanning
+trees and arborescences \ref clrs01algorithms.
+*/
+
+/**
 @defgroup max_flow Maximum Flow Algorithms
 @ingroup algs
@@ -314,32 +338,31 @@
 
 This group contains the algorithms for finding maximum flows and
-feasible circulations.
+feasible circulations \ref clrs01algorithms, \ref amo93networkflows.
 
 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
+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
+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 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.
-*/
-
-/**
-@defgroup min_cost_flow Minimum Cost Flow Algorithms
+\f[ \max\sum_{sv\in A} f(sv) - \sum_{vs\in A} f(vs) \f]
+\f[ \sum_{uv\in A} f(uv) = \sum_{vu\in A} f(vu)
+    \quad \forall u\in V\setminus\{s,t\} \f]
+\f[ 0 \leq f(uv) \leq cap(uv) \quad \forall uv\in A \f]
+
+\ref Preflow is an efficient implementation of Goldberg-Tarjan's
+preflow push-relabel algorithm \ref goldberg88newapproach for finding
+maximum flows. It also provides functions to query the minimum cut,
+which is the dual problem of maximum flow.
+
+\ref Circulation is a preflow push-relabel algorithm implemented directly
+for finding feasible circulations, which is a somewhat different problem,
+but it is strongly related to maximum flow.
+For more information, see \ref Circulation.
+*/
+
+/**
+@defgroup min_cost_flow_algs Minimum Cost Flow Algorithms
 @ingroup algs
 
@@ -347,32 +370,23 @@
 
 This group contains 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.
+circulations \ref amo93networkflows. For more information about this
+problem and its dual solution, see \ref min_cost_flow
+"Minimum Cost Flow Problem".
+
+LEMON contains several algorithms for this problem.
+ - \ref NetworkSimplex Primal Network Simplex algorithm with various
+   pivot strategies \ref dantzig63linearprog, \ref kellyoneill91netsimplex.
+ - \ref CostScaling Cost Scaling algorithm based on push/augment and
+   relabel operations \ref goldberg90approximation, \ref goldberg97efficient,
+   \ref bunnagel98efficient.
+ - \ref CapacityScaling Capacity Scaling algorithm based on the successive
+   shortest path method \ref edmondskarp72theoretical.
+ - \ref CycleCanceling Cycle-Canceling algorithms, two of which are
+   strongly polynomial \ref klein67primal, \ref goldberg89cyclecanceling.
+
+In general NetworkSimplex is the most efficient implementation,
+but in special cases other algorithms could be faster.
+For example, if the total supply and/or capacities are rather small,
+CapacityScaling is usually the fastest algorithm (without effective scaling).
 */
 
@@ -392,5 +406,5 @@
 
 \f[ \min_{X \subset V, X\not\in \{\emptyset, V\}}
-    \sum_{uv\in A, u\in X, v\not\in X}cap(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:
@@ -398,6 +412,4 @@
 - \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 GomoryHu "Gomory-Hu tree computation" for calculating
   all-pairs minimum cut in undirected graphs.
@@ -408,25 +420,38 @@
 
 /**
-@defgroup graph_prop Connectivity and Other Graph Properties
-@ingroup algs
-\brief Algorithms for discovering the graph properties
-
-This group contains the algorithms for discovering the graph properties
-like connectivity, bipartiteness, euler property, simplicity etc.
-
-\image html edge_biconnected_components.png
-\image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
-*/
-
-/**
-@defgroup planar Planarity Embedding and Drawing
-@ingroup algs
-\brief Algorithms for planarity checking, embedding and drawing
-
-This group contains the algorithms for planarity checking,
-embedding and drawing.
-
-\image html planar.png
-\image latex planar.eps "Plane graph" width=\textwidth
+@defgroup min_mean_cycle Minimum Mean Cycle Algorithms
+@ingroup algs
+\brief Algorithms for finding minimum mean cycles.
+
+This group contains the algorithms for finding minimum mean cycles
+\ref clrs01algorithms, \ref amo93networkflows.
+
+The \e minimum \e mean \e cycle \e problem is to find a directed cycle
+of minimum mean length (cost) in a digraph.
+The mean length of a cycle is the average length of its arcs, i.e. the
+ratio between the total length of the cycle and the number of arcs on it.
+
+This problem has an important connection to \e conservative \e length
+\e functions, too. A length function on the arcs of a digraph is called
+conservative if and only if there is no directed cycle of negative total
+length. For an arbitrary length function, the negative of the minimum
+cycle mean is the smallest \f$\epsilon\f$ value so that increasing the
+arc lengths uniformly by \f$\epsilon\f$ results in a conservative length
+function.
+
+LEMON contains three algorithms for solving the minimum mean cycle problem:
+- \ref KarpMmc Karp's original algorithm \ref amo93networkflows,
+  \ref dasdan98minmeancycle.
+- \ref HartmannOrlinMmc Hartmann-Orlin's algorithm, which is an improved
+  version of Karp's algorithm \ref dasdan98minmeancycle.
+- \ref HowardMmc Howard's policy iteration algorithm
+  \ref dasdan98minmeancycle.
+
+In practice, the \ref HowardMmc "Howard" algorithm proved to be by far the
+most efficient one, though the best known theoretical bound on its running
+time is exponential.
+Both \ref KarpMmc "Karp" and \ref HartmannOrlinMmc "Hartmann-Orlin" algorithms
+run in time O(ne) and use space O(n<sup>2</sup>+e), but the latter one is
+typically faster due to the applied early termination scheme.
 */
 
@@ -436,7 +461,8 @@
 \brief Algorithms for finding matchings in graphs and bipartite graphs.
 
-This group contains algorithm objects and functions to calculate
+This group contains the algorithms for calculating
 matchings in graphs and bipartite graphs. The general matching problem is
-finding a subset of the arcs which does not shares common endpoints.
+finding a subset of the edges for which each node has at most one incident
+edge.
 
 There are several different algorithms for calculate matchings in
@@ -448,14 +474,4 @@
 
 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.
@@ -465,16 +481,38 @@
   Edmond's blossom shrinking algorithm for calculating maximum weighted
   perfect matching in general graphs.
-
-\image html bipartite_matching.png
-\image latex bipartite_matching.eps "Bipartite Matching" width=\textwidth
-*/
-
-/**
-@defgroup spantree Minimum Spanning Tree Algorithms
-@ingroup algs
-\brief Algorithms for finding a minimum cost spanning tree in a graph.
-
-This group contains the algorithms for finding a minimum cost spanning
-tree in a graph.
+- \ref MaxFractionalMatching Push-relabel algorithm for calculating
+  maximum cardinality fractional matching in general graphs.
+- \ref MaxWeightedFractionalMatching Augmenting path algorithm for calculating
+  maximum weighted fractional matching in general graphs.
+- \ref MaxWeightedPerfectFractionalMatching
+  Augmenting path algorithm for calculating maximum weighted
+  perfect fractional matching in general graphs.
+
+\image html matching.png
+\image latex matching.eps "Min Cost Perfect Matching" width=\textwidth
+*/
+
+/**
+@defgroup graph_properties Connectivity and Other Graph Properties
+@ingroup algs
+\brief Algorithms for discovering the graph properties
+
+This group contains the algorithms for discovering the graph properties
+like connectivity, bipartiteness, euler property, simplicity etc.
+
+\image html connected_components.png
+\image latex connected_components.eps "Connected components" width=\textwidth
+*/
+
+/**
+@defgroup planar Planarity Embedding and Drawing
+@ingroup algs
+\brief Algorithms for planarity checking, embedding and drawing
+
+This group contains the algorithms for planarity checking,
+embedding and drawing.
+
+\image html planar.png
+\image latex planar.eps "Plane graph" width=\textwidth
 */
 
@@ -486,13 +524,4 @@
 This group contains some algorithms implemented in LEMON
 in order to make it easier to implement complex algorithms.
-*/
-
-/**
-@defgroup approx Approximation Algorithms
-@ingroup algs
-\brief Approximation algorithms.
-
-This group contains the approximation and heuristic algorithms
-implemented in LEMON.
 */
 
@@ -507,28 +536,14 @@
 
 /**
-@defgroup lp_group Lp and Mip Solvers
+@defgroup lp_group LP and MIP Solvers
 @ingroup gen_opt_group
-\brief Lp and Mip solver interfaces for LEMON.
-
-This group contains Lp and Mip solver interfaces for LEMON. The
-various LP solvers could be used in the same manner with this
-interface.
-*/
-
-/**
-@defgroup lp_utils Tools for Lp and Mip Solvers
-@ingroup lp_group
-\brief Helper tools to the Lp and Mip solvers.
-
-This group adds some helper tools to general optimization framework
-implemented in LEMON.
-*/
-
-/**
-@defgroup metah Metaheuristics
-@ingroup gen_opt_group
-\brief Metaheuristics for LEMON library.
-
-This group contains some metaheuristic optimization tools.
+\brief LP and MIP solver interfaces for LEMON.
+
+This group contains LP and MIP solver interfaces for LEMON.
+Various LP solvers could be used in the same manner with this
+high-level interface.
+
+The currently supported solvers are \ref glpk, \ref clp, \ref cbc,
+\ref cplex, \ref soplex.
 */
 
@@ -603,5 +618,5 @@
 
 /**
-@defgroup dimacs_group DIMACS format
+@defgroup dimacs_group DIMACS Format
 @ingroup io_group
 \brief Read and write files in DIMACS format
@@ -652,6 +667,6 @@
 \brief Skeleton and concept checking classes for graph structures
 
-This group contains the skeletons and concept checking classes of LEMON's
-graph structures and helper classes used to implement these.
+This group contains the skeletons and concept checking classes of
+graph structures.
 */
 
@@ -665,4 +680,13 @@
 
 /**
+@defgroup tools Standalone Utility Applications
+
+Some utility applications are listed here.
+
+The standard compilation procedure (<tt>./configure;make</tt>) will compile
+them, as well.
+*/
+
+/**
 \anchor demoprograms
 
@@ -672,15 +696,6 @@
 the \c demo subdirectory of the source tree.
 
-It order to compile them, use <tt>--enable-demo</tt> configure option when
-build the library.
-*/
-
-/**
-@defgroup tools Standalone Utility Applications
-
-Some utility applications are listed here.
-
-The standard compilation procedure (<tt>./configure;make</tt>) will compile
-them, as well.
+In order to compile them, use the <tt>make demo</tt> or the
+<tt>make check</tt> commands.
 */
 
Index: doc/images/bipartite_matching.eps
===================================================================
--- doc/images/bipartite_matching.eps	(revision 586)
+++ doc/images/bipartite_matching.eps	(revision 586)
@@ -0,0 +1,586 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%BoundingBox: 15 18 829 570
+%%HiResBoundingBox: 15.1913 18.4493 828.078 569.438
+%%Creator: Karbon14 EPS Exportfilter 0.5
+%%CreationDate: (04/15/06 15:20:26)
+%%For: (Balazs Dezso) ()
+%%Title: ()
+
+/N {newpath} def
+/C {closepath} def
+/m {moveto} def
+/c {curveto} def
+/l {lineto} def
+/s {stroke} def
+/f {fill} def
+/w {setlinewidth} def
+/d {setdash} def
+/r {setrgbcolor} def
+/S {gsave} def
+/R {grestore} def
+
+N
+251.402 32.047 m
+532.945 293.946 814.484 555.844 814.484 555.844 c
+[] 0 d 1 0 0 r 3.92814 w s
+
+N
+749.012 32.047 m
+742.465 293.946 735.918 555.844 735.918 555.844 c
+[] 0 d 0 0 0 r 1.96407 w s
+
+N
+539.492 32.047 m
+637.703 293.946 735.918 555.844 735.918 555.844 c
+[] 0 d 0 0 0 r 1.96407 w s
+
+N
+172.832 32.047 m
+454.375 293.946 735.918 555.844 735.918 555.844 c
+[] 0 d 0 0 0 r 1.96407 w s
+
+N
+107.355 32.047 m
+421.637 293.946 735.918 555.844 735.918 555.844 c
+[] 0 d 1 0 0 r 3.92814 w s
+
+N
+644.25 555.844 m
+696.633 293.946 749.012 32.047 749.012 32.047 c
+[] 0 d 0 0 0 r 1.96407 w s
+
+N
+474.016 555.844 m
+611.516 293.946 749.012 32.047 749.012 32.047 c
+[] 0 d 1 0 0 r 3.92814 w s
+
+N
+683.535 32.047 m
+663.894 293.946 644.25 555.844 644.25 555.844 c
+[] 0 d 0 0 0 r 1.96407 w s
+
+N
+120.453 555.844 m
+401.992 293.946 683.535 32.047 683.535 32.047 c
+[] 0 d 0 0 0 r 1.96407 w s
+
+N
+28.7853 555.844 m
+356.16 293.946 683.535 32.047 683.535 32.047 c
+[] 0 d 1 0 0 r 3.92814 w s
+
+N
+539.492 32.047 m
+546.039 293.946 552.586 555.844 552.586 555.844 c
+[] 0 d 1 0 0 r 3.92814 w s
+
+N
+316.875 32.047 m
+349.613 293.946 382.351 555.844 382.351 555.844 c
+[] 0 d 1 0 0 r 3.92814 w s
+
+N
+107.355 32.047 m
+244.855 293.946 382.351 555.844 382.351 555.844 c
+[] 0 d 0 0 0 r 1.96407 w s
+
+N
+290.687 555.844 m
+375.805 293.946 460.922 32.047 460.922 32.047 c
+[] 0 d 1 0 0 r 3.92814 w s
+
+N
+120.453 555.844 m
+290.687 293.946 460.922 32.047 460.922 32.047 c
+[] 0 d 0 0 0 r 1.96407 w s
+
+N
+172.832 32.047 m
+146.64 293.946 120.453 555.844 120.453 555.844 c
+[] 0 d 1 0 0 r 3.92814 w s
+
+N
+15.6913 555.844 m
+15.6913 555.844 l
+15.6913 548.614 21.5553 542.75 28.7853 542.75 c
+36.0163 542.75 41.8833 548.614 41.8833 555.844 c
+41.8833 563.075 36.0163 568.938 28.7853 568.938 c
+21.5553 568.938 15.6913 563.075 15.6913 555.844 c
+15.6913 555.844 l
+C
+S 0 0 0 r f R
+
+N
+16.8833 555.844 m
+16.8833 555.844 l
+16.8833 549.27 22.2113 543.942 28.7853 543.942 c
+35.3593 543.942 40.6913 549.27 40.6913 555.844 c
+40.6913 562.418 35.3593 567.747 28.7853 567.747 c
+22.2113 567.747 16.8833 562.418 16.8833 555.844 c
+16.8833 555.844 l
+C
+S 1 0.5 1 r f R
+
+N
+107.355 555.844 m
+107.355 555.844 l
+107.355 548.614 113.223 542.75 120.453 542.75 c
+127.683 542.75 133.547 548.614 133.547 555.844 c
+133.547 563.075 127.683 568.938 120.453 568.938 c
+113.223 568.938 107.355 563.075 107.355 555.844 c
+107.355 555.844 l
+C
+S 0 0 0 r f R
+
+N
+108.547 555.844 m
+108.547 555.844 l
+108.547 549.27 113.879 543.942 120.453 543.942 c
+127.027 543.942 132.355 549.27 132.355 555.844 c
+132.355 562.418 127.027 567.747 120.453 567.747 c
+113.879 567.747 108.547 562.418 108.547 555.844 c
+108.547 555.844 l
+C
+S 1 0 1 r f R
+
+N
+199.019 555.844 m
+199.019 555.844 l
+199.019 548.614 204.887 542.75 212.117 542.75 c
+219.348 542.75 225.211 548.614 225.211 555.844 c
+225.211 563.075 219.348 568.938 212.117 568.938 c
+204.887 568.938 199.019 563.075 199.019 555.844 c
+199.019 555.844 l
+C
+S 0 0 0 r f R
+
+N
+200.211 555.844 m
+200.211 555.844 l
+200.211 549.27 205.543 543.942 212.117 543.942 c
+218.691 543.942 224.019 549.27 224.019 555.844 c
+224.019 562.418 218.691 567.747 212.117 567.747 c
+205.543 567.747 200.211 562.418 200.211 555.844 c
+200.211 555.844 l
+C
+S 1 0.5 1 r f R
+
+N
+277.59 555.844 m
+277.59 555.844 l
+277.59 548.614 283.457 542.75 290.687 542.75 c
+297.918 542.75 303.781 548.614 303.781 555.844 c
+303.781 563.075 297.918 568.938 290.687 568.938 c
+283.457 568.938 277.59 563.075 277.59 555.844 c
+277.59 555.844 l
+C
+S 0 0 0 r f R
+
+N
+278.781 555.844 m
+278.781 555.844 l
+278.781 549.27 284.113 543.942 290.687 543.942 c
+297.262 543.942 302.59 549.27 302.59 555.844 c
+302.59 562.418 297.262 567.747 290.687 567.747 c
+284.113 567.747 278.781 562.418 278.781 555.844 c
+278.781 555.844 l
+C
+S 1 0 1 r f R
+
+N
+369.258 555.844 m
+369.258 555.844 l
+369.258 548.614 375.121 542.75 382.351 542.75 c
+389.582 542.75 395.445 548.614 395.445 555.844 c
+395.445 563.075 389.582 568.938 382.351 568.938 c
+375.121 568.938 369.258 563.075 369.258 555.844 c
+369.258 555.844 l
+C
+S 0 0 0 r f R
+
+N
+370.445 555.844 m
+370.445 555.844 l
+370.445 549.27 375.777 543.942 382.351 543.942 c
+388.926 543.942 394.258 549.27 394.258 555.844 c
+394.258 562.418 388.926 567.747 382.351 567.747 c
+375.777 567.747 370.445 562.418 370.445 555.844 c
+370.445 555.844 l
+C
+S 1 0 1 r f R
+
+N
+460.922 555.844 m
+460.922 555.844 l
+460.922 548.614 466.785 542.75 474.016 542.75 c
+481.246 542.75 487.109 548.614 487.109 555.844 c
+487.109 563.075 481.246 568.938 474.016 568.938 c
+466.785 568.938 460.922 563.075 460.922 555.844 c
+460.922 555.844 l
+C
+S 0 0 0 r f R
+
+N
+462.113 555.844 m
+462.113 555.844 l
+462.113 549.27 467.441 543.942 474.016 543.942 c
+480.59 543.942 485.922 549.27 485.922 555.844 c
+485.922 562.418 480.59 567.747 474.016 567.747 c
+467.441 567.747 462.113 562.418 462.113 555.844 c
+462.113 555.844 l
+C
+S 1 0.5 1 r f R
+
+N
+539.492 555.844 m
+539.492 555.844 l
+539.492 548.614 545.355 542.75 552.586 542.75 c
+559.816 542.75 565.68 548.614 565.68 555.844 c
+565.68 563.075 559.816 568.938 552.586 568.938 c
+545.355 568.938 539.492 563.075 539.492 555.844 c
+539.492 555.844 l
+C
+S 0 0 0 r f R
+
+N
+540.683 555.844 m
+540.683 555.844 l
+540.683 549.27 546.012 543.942 552.586 543.942 c
+559.16 543.942 564.492 549.27 564.492 555.844 c
+564.492 562.418 559.16 567.747 552.586 567.747 c
+546.012 567.747 540.683 562.418 540.683 555.844 c
+540.683 555.844 l
+C
+S 1 0 1 r f R
+
+N
+631.156 555.844 m
+631.156 555.844 l
+631.156 548.614 637.019 542.75 644.25 542.75 c
+651.48 542.75 657.348 548.614 657.348 555.844 c
+657.348 563.075 651.48 568.938 644.25 568.938 c
+637.019 568.938 631.156 563.075 631.156 555.844 c
+631.156 555.844 l
+C
+S 0 0 0 r f R
+
+N
+632.348 555.844 m
+632.348 555.844 l
+632.348 549.27 637.676 543.942 644.25 543.942 c
+650.824 543.942 656.156 549.27 656.156 555.844 c
+656.156 562.418 650.824 567.747 644.25 567.747 c
+637.676 567.747 632.348 562.418 632.348 555.844 c
+632.348 555.844 l
+C
+S 1 0.5 1 r f R
+
+N
+722.82 555.844 m
+722.82 555.844 l
+722.82 548.614 728.687 542.75 735.918 542.75 c
+743.149 542.75 749.012 548.614 749.012 555.844 c
+749.012 563.075 743.149 568.938 735.918 568.938 c
+728.687 568.938 722.82 563.075 722.82 555.844 c
+722.82 555.844 l
+C
+S 0 0 0 r f R
+
+N
+724.012 555.844 m
+724.012 555.844 l
+724.012 549.27 729.344 543.942 735.918 543.942 c
+742.492 543.942 747.82 549.27 747.82 555.844 c
+747.82 562.418 742.492 567.747 735.918 567.747 c
+729.344 567.747 724.012 562.418 724.012 555.844 c
+724.012 555.844 l
+C
+S 1 0 1 r f R
+
+N
+801.391 555.844 m
+801.391 555.844 l
+801.391 548.614 807.254 542.75 814.484 542.75 c
+821.715 542.75 827.578 548.614 827.578 555.844 c
+827.578 563.075 821.715 568.938 814.484 568.938 c
+807.254 568.938 801.391 563.075 801.391 555.844 c
+801.391 555.844 l
+C
+S 0 0 0 r f R
+
+N
+802.582 555.844 m
+802.582 555.844 l
+802.582 549.27 807.91 543.942 814.484 543.942 c
+821.059 543.942 826.387 549.27 826.387 555.844 c
+826.387 562.418 821.059 567.747 814.484 567.747 c
+807.91 567.747 802.582 562.418 802.582 555.844 c
+802.582 555.844 l
+C
+S 1 0 1 r f R
+
+N
+15.6913 32.047 m
+15.6913 32.047 l
+15.6913 24.8165 21.5553 18.9493 28.7853 18.9493 c
+36.0163 18.9493 41.8833 24.8165 41.8833 32.047 c
+41.8833 39.2775 36.0163 45.1407 28.7853 45.1407 c
+21.5553 45.1407 15.6913 39.2775 15.6913 32.047 c
+15.6913 32.047 l
+C
+S 0 0 0 r f R
+
+N
+16.8833 32.047 m
+16.8833 32.047 l
+16.8833 25.4728 22.2113 20.1407 28.7853 20.1407 c
+35.3593 20.1407 40.6913 25.4728 40.6913 32.047 c
+40.6913 38.6212 35.3593 43.9493 28.7853 43.9493 c
+22.2113 43.9493 16.8833 38.6212 16.8833 32.047 c
+16.8833 32.047 l
+C
+S 0.5 0.5 1 r f R
+
+N
+94.2623 32.047 m
+94.2623 32.047 l
+94.2623 24.8165 100.125 18.9493 107.355 18.9493 c
+114.586 18.9493 120.453 24.8165 120.453 32.047 c
+120.453 39.2775 114.586 45.1407 107.355 45.1407 c
+100.125 45.1407 94.2623 39.2775 94.2623 32.047 c
+94.2623 32.047 l
+C
+S 0 0 0 r f R
+
+N
+95.4533 32.047 m
+95.4533 32.047 l
+95.4533 25.4728 100.781 20.1407 107.355 20.1407 c
+113.93 20.1407 119.262 25.4728 119.262 32.047 c
+119.262 38.6212 113.93 43.9493 107.355 43.9493 c
+100.781 43.9493 95.4533 38.6212 95.4533 32.047 c
+95.4533 32.047 l
+C
+S 0.5 0.5 1 r f R
+
+N
+159.734 32.047 m
+159.734 32.047 l
+159.734 24.8165 165.601 18.9493 172.832 18.9493 c
+180.062 18.9493 185.926 24.8165 185.926 32.047 c
+185.926 39.2775 180.062 45.1407 172.832 45.1407 c
+165.601 45.1407 159.734 39.2775 159.734 32.047 c
+159.734 32.047 l
+C
+S 0 0 0 r f R
+
+N
+160.926 32.047 m
+160.926 32.047 l
+160.926 25.4728 166.258 20.1407 172.832 20.1407 c
+179.406 20.1407 184.734 25.4728 184.734 32.047 c
+184.734 38.6212 179.406 43.9493 172.832 43.9493 c
+166.258 43.9493 160.926 38.6212 160.926 32.047 c
+160.926 32.047 l
+C
+S 0.5 0.5 1 r f R
+
+N
+238.305 32.047 m
+238.305 32.047 l
+238.305 24.8165 244.172 18.9493 251.402 18.9493 c
+258.633 18.9493 264.496 24.8165 264.496 32.047 c
+264.496 39.2775 258.633 45.1407 251.402 45.1407 c
+244.172 45.1407 238.305 39.2775 238.305 32.047 c
+238.305 32.047 l
+C
+S 0 0 0 r f R
+
+N
+239.496 32.047 m
+239.496 32.047 l
+239.496 25.4728 244.828 20.1407 251.402 20.1407 c
+257.976 20.1407 263.305 25.4728 263.305 32.047 c
+263.305 38.6212 257.976 43.9493 251.402 43.9493 c
+244.828 43.9493 239.496 38.6212 239.496 32.047 c
+239.496 32.047 l
+C
+S 0.5 0.5 1 r f R
+
+N
+303.781 32.047 m
+303.781 32.047 l
+303.781 24.8165 309.644 18.9493 316.875 18.9493 c
+324.105 18.9493 329.973 24.8165 329.973 32.047 c
+329.973 39.2775 324.105 45.1407 316.875 45.1407 c
+309.644 45.1407 303.781 39.2775 303.781 32.047 c
+303.781 32.047 l
+C
+S 0 0 0 r f R
+
+N
+304.973 32.047 m
+304.973 32.047 l
+304.973 25.4728 310.301 20.1407 316.875 20.1407 c
+323.449 20.1407 328.781 25.4728 328.781 32.047 c
+328.781 38.6212 323.449 43.9493 316.875 43.9493 c
+310.301 43.9493 304.973 38.6212 304.973 32.047 c
+304.973 32.047 l
+C
+S 0.5 0.5 1 r f R
+
+N
+382.351 32.047 m
+382.351 32.047 l
+382.351 24.8165 388.215 18.9493 395.445 18.9493 c
+402.676 18.9493 408.543 24.8165 408.543 32.047 c
+408.543 39.2775 402.676 45.1407 395.445 45.1407 c
+388.215 45.1407 382.351 39.2775 382.351 32.047 c
+382.351 32.047 l
+C
+S 0 0 0 r f R
+
+N
+383.543 32.047 m
+383.543 32.047 l
+383.543 25.4728 388.871 20.1407 395.445 20.1407 c
+402.019 20.1407 407.351 25.4728 407.351 32.047 c
+407.351 38.6212 402.019 43.9493 395.445 43.9493 c
+388.871 43.9493 383.543 38.6212 383.543 32.047 c
+383.543 32.047 l
+C
+S 0.5 0.5 1 r f R
+
+N
+447.828 32.047 m
+447.828 32.047 l
+447.828 24.8165 453.691 18.9493 460.922 18.9493 c
+468.152 18.9493 474.016 24.8165 474.016 32.047 c
+474.016 39.2775 468.152 45.1407 460.922 45.1407 c
+453.691 45.1407 447.828 39.2775 447.828 32.047 c
+447.828 32.047 l
+C
+S 0 0 0 r f R
+
+N
+449.016 32.047 m
+449.016 32.047 l
+449.016 25.4728 454.348 20.1407 460.922 20.1407 c
+467.496 20.1407 472.824 25.4728 472.824 32.047 c
+472.824 38.6212 467.496 43.9493 460.922 43.9493 c
+454.348 43.9493 449.016 38.6212 449.016 32.047 c
+449.016 32.047 l
+C
+S 0.5 0.5 1 r f R
+
+N
+526.394 32.047 m
+526.394 32.047 l
+526.394 24.8165 532.262 18.9493 539.492 18.9493 c
+546.723 18.9493 552.586 24.8165 552.586 32.047 c
+552.586 39.2775 546.723 45.1407 539.492 45.1407 c
+532.262 45.1407 526.394 39.2775 526.394 32.047 c
+526.394 32.047 l
+C
+S 0 0 0 r f R
+
+N
+527.586 32.047 m
+527.586 32.047 l
+527.586 25.4728 532.918 20.1407 539.492 20.1407 c
+546.066 20.1407 551.394 25.4728 551.394 32.047 c
+551.394 38.6212 546.066 43.9493 539.492 43.9493 c
+532.918 43.9493 527.586 38.6212 527.586 32.047 c
+527.586 32.047 l
+C
+S 0.5 0.5 1 r f R
+
+N
+591.871 32.047 m
+591.871 32.047 l
+591.871 24.8165 597.734 18.9493 604.965 18.9493 c
+612.195 18.9493 618.062 24.8165 618.062 32.047 c
+618.062 39.2775 612.195 45.1407 604.965 45.1407 c
+597.734 45.1407 591.871 39.2775 591.871 32.047 c
+591.871 32.047 l
+C
+S 0 0 0 r f R
+
+N
+593.062 32.047 m
+593.062 32.047 l
+593.062 25.4728 598.39 20.1407 604.965 20.1407 c
+611.539 20.1407 616.871 25.4728 616.871 32.047 c
+616.871 38.6212 611.539 43.9493 604.965 43.9493 c
+598.39 43.9493 593.062 38.6212 593.062 32.047 c
+593.062 32.047 l
+C
+S 0.5 0.5 1 r f R
+
+N
+670.441 32.047 m
+670.441 32.047 l
+670.441 24.8165 676.305 18.9493 683.535 18.9493 c
+690.766 18.9493 696.633 24.8165 696.633 32.047 c
+696.633 39.2775 690.766 45.1407 683.535 45.1407 c
+676.305 45.1407 670.441 39.2775 670.441 32.047 c
+670.441 32.047 l
+C
+S 0 0 0 r f R
+
+N
+671.633 32.047 m
+671.633 32.047 l
+671.633 25.4728 676.961 20.1407 683.535 20.1407 c
+690.109 20.1407 695.441 25.4728 695.441 32.047 c
+695.441 38.6212 690.109 43.9493 683.535 43.9493 c
+676.961 43.9493 671.633 38.6212 671.633 32.047 c
+671.633 32.047 l
+C
+S 0 0 1 r f R
+
+N
+735.918 32.047 m
+735.918 32.047 l
+735.918 24.8165 741.781 18.9493 749.012 18.9493 c
+756.242 18.9493 762.106 24.8165 762.106 32.047 c
+762.106 39.2775 756.242 45.1407 749.012 45.1407 c
+741.781 45.1407 735.918 39.2775 735.918 32.047 c
+735.918 32.047 l
+C
+S 0 0 0 r f R
+
+N
+737.105 32.047 m
+737.105 32.047 l
+737.105 25.4728 742.437 20.1407 749.012 20.1407 c
+755.586 20.1407 760.914 25.4728 760.914 32.047 c
+760.914 38.6212 755.586 43.9493 749.012 43.9493 c
+742.437 43.9493 737.105 38.6212 737.105 32.047 c
+737.105 32.047 l
+C
+S 0 0 1 r f R
+
+N
+801.391 32.047 m
+801.391 32.047 l
+801.391 24.8165 807.254 18.9493 814.484 18.9493 c
+821.715 18.9493 827.578 24.8165 827.578 32.047 c
+827.578 39.2775 821.715 45.1407 814.484 45.1407 c
+807.254 45.1407 801.391 39.2775 801.391 32.047 c
+801.391 32.047 l
+C
+S 0 0 0 r f R
+
+N
+802.582 32.047 m
+802.582 32.047 l
+802.582 25.4728 807.91 20.1407 814.484 20.1407 c
+821.059 20.1407 826.387 25.4728 826.387 32.047 c
+826.387 38.6212 821.059 43.9493 814.484 43.9493 c
+807.91 43.9493 802.582 38.6212 802.582 32.047 c
+802.582 32.047 l
+C
+S 0.5 0.5 1 r f R
+
+%%EOF
Index: doc/images/bipartite_partitions.eps
===================================================================
--- doc/images/bipartite_partitions.eps	(revision 587)
+++ doc/images/bipartite_partitions.eps	(revision 587)
@@ -0,0 +1,114 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: LEMON, graphToEps()
+%%CreationDate: Tue Nov 15 16:51:43 2005
+%%BoundingBox: 0 0 842 596
+%%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
+/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
+     setrgbcolor 1.1 div sq fill
+   } bind def
+/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
+     setrgbcolor 1.1 div di 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
+90 rotate
+0 -842 translate
+71.6378 15 translate
+0.389093 dup scale
+90 rotate
+1197.47 -613.138 translate
+%Edges:
+gsave
+513.857 -446.322 296.569 -487.43 79.2808 -528.539 0 0 0 2 lb
+513.857 -446.322 575.52 -315.655 637.183 -184.989 0 0 0 2 lb
+393.468 566.711 494.771 434.577 596.074 302.442 0 0 0 2 lb
+393.468 566.711 155.625 579.925 -82.2171 593.138 0 0 0 2 lb
+393.468 566.711 251.056 450.726 108.644 334.741 0 0 0 2 lb
+869.153 52.8539 732.613 177.648 596.074 302.442 0 0 0 2 lb
+869.153 52.8539 753.168 -66.0676 637.183 -184.989 0 0 0 2 lb
+-82.2171 593.138 -91.0261 346.487 -99.8351 99.8351 0 0 0 2 lb
+-663.61 546.157 -753.168 394.936 -842.726 243.715 0 0 0 2 lb
+-663.61 546.157 -574.052 437.513 -484.494 328.869 0 0 0 2 lb
+-1077.63 161.498 -960.178 202.606 -842.726 243.715 0 0 0 2 lb
+-1077.63 161.498 -968.987 66.0674 -860.344 -29.3633 0 0 0 2 lb
+-1177.47 -234.906 -1029.18 -381.722 -880.898 -528.539 0 0 0 2 lb
+-1177.47 -234.906 -1018.91 -132.135 -860.344 -29.3633 0 0 0 2 lb
+-880.898 -528.539 -744.359 -387.595 -607.82 -246.651 0 0 0 2 lb
+-499.175 -499.175 -355.295 -475.685 -211.415 -452.194 0 0 0 2 lb
+-499.175 -499.175 -553.498 -372.913 -607.82 -246.651 0 0 0 2 lb
+-499.175 -499.175 -386.587 -315.087 -274 -131 0 0 0 2 lb
+79.2808 -528.539 -66.0671 -490.366 -211.415 -452.194 0 0 0 2 lb
+637.183 -184.989 421.363 -253.993 205.543 -322.996 0 0 0 2 lb
+205.543 -322.996 162.966 -226.097 120.389 -129.198 0 0 0 2 lb
+399.34 88.0898 259.865 -20.5541 120.389 -129.198 0 0 0 2 lb
+399.34 88.0898 253.992 211.415 108.644 334.741 0 0 0 2 lb
+-842.726 243.715 -471.281 171.775 -99.8351 99.8351 0 0 0 2 lb
+-842.726 243.715 -558.363 56.3575 -274 -131 0 0 0 2 lb
+-860.344 -29.3633 -734.082 -138.007 -607.82 -246.651 0 0 0 2 lb
+-211.415 -452.194 -45.513 -290.696 120.389 -129.198 0 0 0 2 lb
+-99.8351 99.8351 4.40445 217.288 108.644 334.741 0 0 0 2 lb
+-99.8351 99.8351 -292.165 214.352 -484.494 328.869 0 0 0 2 lb
+120.389 -129.198 -76.8055 -130.099 -274 -131 0 0 0 2 lb
+grestore
+%Nodes:
+gsave
+-274 -131 20 1 0 0 nc
+-607.82 -246.651 20 1 0 0 nc
+-484.494 328.869 20 0 0 1 nc
+108.644 334.741 20 0 0 1 nc
+120.389 -129.198 20 0 0 1 nc
+-99.8351 99.8351 20 1 0 0 nc
+-211.415 -452.194 20 1 0 0 nc
+-860.344 -29.3633 20 0 0 1 nc
+-842.726 243.715 20 0 0 1 nc
+399.34 88.0898 20 1 0 0 nc
+205.543 -322.996 20 1 0 0 nc
+637.183 -184.989 20 0 0 1 nc
+79.2808 -528.539 20 0 0 1 nc
+-499.175 -499.175 20 0 0 1 nc
+-880.898 -528.539 20 0 0 1 nc
+-1177.47 -234.906 20 1 0 0 nc
+-1077.63 161.498 20 1 0 0 nc
+-663.61 546.157 20 1 0 0 nc
+-82.2171 593.138 20 0 0 1 nc
+596.074 302.442 20 0 0 1 nc
+869.153 52.8539 20 1 0 0 nc
+393.468 566.711 20 1 0 0 nc
+513.857 -446.322 20 1 0 0 nc
+grestore
+grestore
+showpage
Index: doc/images/connected_components.eps
===================================================================
--- doc/images/connected_components.eps	(revision 587)
+++ doc/images/connected_components.eps	(revision 587)
@@ -0,0 +1,159 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: LEMON, graphToEps()
+%%CreationDate: Fri Nov  4 13:47:12 2005
+%%BoundingBox: 0 0 842 596
+%%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
+/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
+     setrgbcolor 1.1 div sq fill
+   } bind def
+/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
+     setrgbcolor 1.1 div di 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
+90 rotate
+0 -842 translate
+71.0944 15 translate
+0.434694 dup scale
+90 rotate
+860.856 -588.349 translate
+%Edges:
+gsave
+574.035 177.301 622.149 225.748 670.264 274.195 0 0 0 2 lb
+694.579 115.483 682.421 194.839 670.264 274.195 0 0 0 2 lb
+280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 0 2 lb
+280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 0 2 lb
+212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 0 2 lb
+286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 0 2 lb
+286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 0 2 lb
+438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 0 2 lb
+438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 0 2 lb
+397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 0 2 lb
+366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 0 2 lb
+271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 0 2 lb
+271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 0 2 lb
+277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 0 2 lb
+-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0 0 2 lb
+-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0 2 lb
+-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0 2 lb
+-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0 2 lb
+906.312 201.403 946.592 42.798 986.873 -115.807 0 0 0 2 lb
+906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 0 2 lb
+986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 0 2 lb
+-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0 0 0 2 lb
+422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 0 2 lb
+422.945 521.129 376.371 417.911 329.797 314.692 0 0 0 2 lb
+422.945 521.129 474.554 276.928 526.164 32.7279 0 0 0 2 lb
+-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 0 2 lb
+329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 0 2 lb
+-67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 0 2 lb
+762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 0 2 lb
+762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 0 2 lb
+526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 0 2 lb
+730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 0 2 lb
+415.393 -289.516 173.71 -318.468 -67.9734 -347.42 0 0 0 2 lb
+-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 0 2 lb
+-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 0 2 lb
+-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 0 2 lb
+-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 0 2 lb
+-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 0 2 lb
+-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 0 2 lb
+-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 0 2 lb
+-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 0 2 lb
+116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 0 2 lb
+-262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 0 2 lb
+-262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 0 2 lb
+-13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 0 2 lb
+-180.397 245.045 -142.256 345.099 -132.697 451.748 0 0 0 2 lb
+-180.397 245.045 -170.838 351.694 -132.697 451.748 0 0 0 2 lb
+-416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 0 2 lb
+-416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 0 2 lb
+-132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 0 2 lb
+670.264 274.195 629.188 409.347 588.113 544.499 0 0 0 2 lb
+670.264 274.195 797.466 341.771 924.667 409.347 0 0 0 2 lb
+588.113 544.499 756.39 476.923 924.667 409.347 0 0 0 2 lb
+-689.204 -237.261 -614.799 -102.648 -567.302 43.6423 0 0 0 2 lb
+-689.204 -237.261 -641.707 -90.9706 -567.302 43.6423 0 0 0 2 lb
+grestore
+%Nodes:
+gsave
+-567.302 43.6423 20 0 0 0 nc
+-689.204 -237.261 20 0 0 0 nc
+924.667 409.347 20 1 0 0 nc
+588.113 544.499 20 1 0 0 nc
+670.264 274.195 20 1 0 0 nc
+-371.2 568.349 20 0 1 0 nc
+-132.697 451.748 20 0 1 0 nc
+-416.25 345.746 20 0 1 0 nc
+-180.397 245.045 20 0 1 0 nc
+-13.4452 133.743 20 0 1 0 nc
+-262.548 107.243 20 0 1 0 nc
+201.208 38.3422 20 0 1 0 nc
+116.407 -173.66 20 0 1 0 nc
+-26.6953 -19.9585 20 0 1 0 nc
+-539.894 -262.64 20 0 0 1 nc
+-323.543 -433.964 20 0 0 1 nc
+-309.657 -57.9033 20 0 0 1 nc
+-67.9734 -347.42 20 0 0 1 nc
+415.393 -289.516 20 0 0 1 nc
+730.084 -307.139 20 0 0 1 nc
+526.164 32.7279 20 0 0 1 nc
+762.812 -17.6227 20 0 0 1 nc
+-67.9734 319.727 20 0 0 1 nc
+329.797 314.692 20 0 0 1 nc
+-5.03507 561.41 20 0 0 1 nc
+422.945 521.129 20 0 0 1 nc
+-470.779 158.605 20 0 0 1 nc
+986.873 -115.807 20 0 0 1 nc
+906.312 201.403 20 0 0 1 nc
+-767.847 113.289 20 0 0 1 nc
+-579.033 445.603 20 0 0 1 nc
+-840.856 -246.718 20 0 0 1 nc
+206.221 -205.967 20 1 1 0 nc
+277.311 -252.33 20 1 1 0 nc
+271.13 -175.058 20 1 1 0 nc
+366.947 -110.15 20 1 1 0 nc
+397.855 -196.694 20 1 1 0 nc
+438.037 -88.514 20 1 1 0 nc
+286.584 -48.3327 20 1 1 0 nc
+212.403 -23.6057 20 1 1 0 nc
+280.402 10.3938 20 1 1 0 nc
+694.579 115.483 20 1 0 0 nc
+574.035 177.301 20 1 0 0 nc
+grestore
+grestore
+showpage
Index: doc/images/edge_biconnected_components.eps
===================================================================
--- doc/images/edge_biconnected_components.eps	(revision 587)
+++ doc/images/edge_biconnected_components.eps	(revision 587)
@@ -0,0 +1,159 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: LEMON, graphToEps()
+%%CreationDate: Fri Nov  4 13:47:12 2005
+%%BoundingBox: 0 0 842 596
+%%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
+/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
+     setrgbcolor 1.1 div sq fill
+   } bind def
+/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
+     setrgbcolor 1.1 div di 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
+90 rotate
+0 -842 translate
+71.0944 15 translate
+0.434694 dup scale
+90 rotate
+860.856 -588.349 translate
+%Edges:
+gsave
+574.035 177.301 622.149 225.748 670.264 274.195 1 0 0 2 lb
+694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 2 lb
+280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 1 2 lb
+280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 1 2 lb
+212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 1 2 lb
+286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 1 2 lb
+286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 1 2 lb
+438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 1 2 lb
+438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 1 2 lb
+397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 1 2 lb
+366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 1 2 lb
+271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 1 2 lb
+271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 1 2 lb
+277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 1 2 lb
+-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 1 0 0 2 lb
+-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 1 2 lb
+-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 1 2 lb
+-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 1 2 lb
+906.312 201.403 946.592 42.798 986.873 -115.807 0 0 1 2 lb
+906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 1 2 lb
+986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 1 2 lb
+-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 1 0 0 2 lb
+422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 1 2 lb
+422.945 521.129 376.371 417.911 329.797 314.692 0 0 1 2 lb
+422.945 521.129 474.554 276.928 526.164 32.7279 0 0 1 2 lb
+-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 1 2 lb
+329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 1 2 lb
+-67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 1 2 lb
+762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 1 2 lb
+762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 1 2 lb
+526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 1 2 lb
+730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 1 2 lb
+415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0 0 2 lb
+-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 1 2 lb
+-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 1 2 lb
+-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 1 2 lb
+-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 1 2 lb
+-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 1 2 lb
+-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 1 2 lb
+-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 1 2 lb
+-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 1 2 lb
+116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 1 2 lb
+-262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 1 2 lb
+-262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 1 2 lb
+-13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 1 2 lb
+-180.397 245.045 -142.256 345.099 -132.697 451.748 0 0 1 2 lb
+-180.397 245.045 -170.838 351.694 -132.697 451.748 0 0 1 2 lb
+-416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 1 2 lb
+-416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 1 2 lb
+-132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 1 2 lb
+670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 2 lb
+670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 2 lb
+588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 2 lb
+-689.204 -237.261 -614.799 -102.648 -567.302 43.6423 0 0 1 2 lb
+-689.204 -237.261 -641.707 -90.9706 -567.302 43.6423 0 0 1 2 lb
+grestore
+%Nodes:
+gsave
+-567.302 43.6423 20 0 0 0 nc
+-689.204 -237.261 20 0 0 0 nc
+924.667 409.347 20 0 0 1 nc
+588.113 544.499 20 0 0 1 nc
+670.264 274.195 20 0 0 1 nc
+-371.2 568.349 20 1 1 0 nc
+-132.697 451.748 20 1 1 0 nc
+-416.25 345.746 20 1 1 0 nc
+-180.397 245.045 20 1 1 0 nc
+-13.4452 133.743 20 1 1 0 nc
+-262.548 107.243 20 1 1 0 nc
+201.208 38.3422 20 1 1 0 nc
+116.407 -173.66 20 1 1 0 nc
+-26.6953 -19.9585 20 1 1 0 nc
+-539.894 -262.64 20 0 0.5 0 nc
+-323.543 -433.964 20 0 0.5 0 nc
+-309.657 -57.9033 20 0 0.5 0 nc
+-67.9734 -347.42 20 0 0.5 0 nc
+415.393 -289.516 20 0.5 0 0 nc
+730.084 -307.139 20 0.5 0 0 nc
+526.164 32.7279 20 0.5 0 0 nc
+762.812 -17.6227 20 0.5 0 0 nc
+-67.9734 319.727 20 0.5 0 0 nc
+329.797 314.692 20 0.5 0 0 nc
+-5.03507 561.41 20 0.5 0 0 nc
+422.945 521.129 20 0.5 0 0 nc
+-470.779 158.605 20 0 1 1 nc
+986.873 -115.807 20 0.5 0 0 nc
+906.312 201.403 20 0.5 0 0 nc
+-767.847 113.289 20 0 1 1 nc
+-579.033 445.603 20 0 1 1 nc
+-840.856 -246.718 20 1 0 1 nc
+206.221 -205.967 20 0 0 0.5 nc
+277.311 -252.33 20 0 0 0.5 nc
+271.13 -175.058 20 0 0 0.5 nc
+366.947 -110.15 20 0 0 0.5 nc
+397.855 -196.694 20 0 0 0.5 nc
+438.037 -88.514 20 0 0 0.5 nc
+286.584 -48.3327 20 0 0 0.5 nc
+212.403 -23.6057 20 0 0 0.5 nc
+280.402 10.3938 20 0 0 0.5 nc
+694.579 115.483 20 1 0 0 nc
+574.035 177.301 20 0 1 0 nc
+grestore
+grestore
+showpage
Index: doc/images/matching.eps
===================================================================
--- doc/images/matching.eps	(revision 865)
+++ doc/images/matching.eps	(revision 865)
@@ -0,0 +1,130 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: LEMON, graphToEps()
+%%CreationDate: Sun Mar 14 09:08:34 2010
+%%BoundingBox: -353 -264 559 292
+%%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
+/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
+     setrgbcolor 1.1 div sq fill
+   } bind def
+/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
+     setrgbcolor 1.1 div di fill
+   } bind def
+/nfemale { 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
+  newpath 5 index 5 index moveto 5 index 5 index 5 index 3.01 mul sub
+  lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub moveto
+  5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto stroke
+  5 index 5 index 5 index c fill
+  setrgbcolor 1.1 div c fill
+  } bind def
+/nmale {
+  0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
+  newpath 5 index 5 index moveto
+  5 index 4 index 1 mul 1.5 mul add
+  5 index 5 index 3 sqrt 1.5 mul mul add
+  1 index 1 index lineto
+  1 index 1 index 7 index sub moveto
+  1 index 1 index lineto
+  exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub lineto
+  stroke
+  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
+%Arcs:
+gsave
+140.321 266.249 -327.729 150.06 0 0 0 4.99223 l
+82.1207 -238.726 -245.288 -110.743 0 0 0 4.99223 l
+336.635 -229.036 533.603 13.109 0 0 0 4.99223 l
+53.8598 -45.8071 -245.288 -110.743 0 0 0 4.99223 l
+-75.5617 118.579 -327.729 150.06 0 0 0 4.99223 l
+-327.729 150.06 -245.288 -110.743 1 0 0 11.9813 l
+533.603 13.109 218.184 -84.2955 0 0 0 4.99223 l
+39.87 175.035 141.163 67.2575 0 0 0 4.99223 l
+53.8598 -45.8071 -75.5617 118.579 0 0 0 4.99223 l
+-102.406 -141.267 82.1207 -238.726 0 0 0 4.99223 l
+399.144 166.894 533.603 13.109 1 0 0 11.9813 l
+39.87 175.035 140.321 266.249 1 0 0 11.9813 l
+399.144 166.894 140.321 266.249 0 0 0 4.99223 l
+399.144 166.894 141.163 67.2575 0 0 0 4.99223 l
+53.8598 -45.8071 204.765 -173.77 0 0 0 4.99223 l
+82.1207 -238.726 204.765 -173.77 0 0 0 4.99223 l
+258.227 61.658 399.144 166.894 0 0 0 4.99223 l
+53.8598 -45.8071 -102.406 -141.267 1 0 0 11.9813 l
+175.073 -37.4477 141.163 67.2575 0 0 0 4.99223 l
+258.227 61.658 380 0 0 0 0 4.99223 l
+34.6739 40.8267 -75.5617 118.579 1 0 0 11.9813 l
+380 0 533.603 13.109 0 0 0 4.99223 l
+175.073 -37.4477 380 0 0 0 0 4.99223 l
+218.184 -84.2955 204.765 -173.77 0 0 0 4.99223 l
+53.8598 -45.8071 34.6739 40.8267 0 0 0 4.99223 l
+167.905 -213.988 82.1207 -238.726 1 0 0 11.9813 l
+336.635 -229.036 204.765 -173.77 1 0 0 11.9813 l
+336.635 -229.036 167.905 -213.988 0 0 0 4.99223 l
+329.08 -26.3098 218.184 -84.2955 0 0 0 4.99223 l
+39.87 175.035 -75.5617 118.579 0 0 0 4.99223 l
+53.8598 -45.8071 175.073 -37.4477 0 0 0 4.99223 l
+34.6739 40.8267 141.163 67.2575 0 0 0 4.99223 l
+258.227 61.658 141.163 67.2575 1 0 0 11.9813 l
+175.073 -37.4477 218.184 -84.2955 1 0 0 11.9813 l
+380 0 329.08 -26.3098 1 0 0 11.9813 l
+grestore
+%Nodes:
+gsave
+-245.288 -110.743 14.9767 1 1 1 nc
+204.765 -173.77 14.9767 1 1 1 nc
+-327.729 150.06 14.9767 1 1 1 nc
+-75.5617 118.579 14.9767 1 1 1 nc
+218.184 -84.2955 14.9767 1 1 1 nc
+140.321 266.249 14.9767 1 1 1 nc
+141.163 67.2575 14.9767 1 1 1 nc
+82.1207 -238.726 14.9767 1 1 1 nc
+329.08 -26.3098 14.9767 1 1 1 nc
+-102.406 -141.267 14.9767 1 1 1 nc
+533.603 13.109 14.9767 1 1 1 nc
+167.905 -213.988 14.9767 1 1 1 nc
+336.635 -229.036 14.9767 1 1 1 nc
+380 0 14.9767 1 1 1 nc
+399.144 166.894 14.9767 1 1 1 nc
+34.6739 40.8267 14.9767 1 1 1 nc
+39.87 175.035 14.9767 1 1 1 nc
+175.073 -37.4477 14.9767 1 1 1 nc
+53.8598 -45.8071 14.9767 1 1 1 nc
+258.227 61.658 14.9767 1 1 1 nc
+grestore
+grestore
+showpage
Index: doc/images/node_biconnected_components.eps
===================================================================
--- doc/images/node_biconnected_components.eps	(revision 587)
+++ doc/images/node_biconnected_components.eps	(revision 587)
@@ -0,0 +1,159 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: LEMON, graphToEps()
+%%CreationDate: Fri Nov  4 13:47:12 2005
+%%BoundingBox: 0 0 842 596
+%%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
+/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
+     setrgbcolor 1.1 div sq fill
+   } bind def
+/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
+     setrgbcolor 1.1 div di 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
+90 rotate
+0 -842 translate
+71.0944 15 translate
+0.434694 dup scale
+90 rotate
+860.856 -588.349 translate
+%Edges:
+gsave
+574.035 177.301 622.149 225.748 670.264 274.195 0 1 0 5 lb
+694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 5 lb
+280.402 10.3938 246.402 -6.60595 212.403 -23.6057 1 1 0.5 5 lb
+280.402 10.3938 283.493 -18.9695 286.584 -48.3327 1 1 0.5 5 lb
+212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 1 1 0.5 5 lb
+286.584 -48.3327 326.765 -79.2414 366.947 -110.15 1 0.5 1 5 lb
+286.584 -48.3327 278.857 -111.695 271.13 -175.058 1 0.5 1 5 lb
+438.037 -88.514 417.946 -142.604 397.855 -196.694 0.5 0.5 1 5 lb
+438.037 -88.514 402.492 -99.332 366.947 -110.15 0.5 0.5 1 5 lb
+397.855 -196.694 382.401 -153.422 366.947 -110.15 0.5 0.5 1 5 lb
+366.947 -110.15 319.038 -142.604 271.13 -175.058 1 0.5 1 5 lb
+271.13 -175.058 274.221 -213.694 277.311 -252.33 0.5 1 1 5 lb
+271.13 -175.058 238.675 -190.512 206.221 -205.967 0.5 1 1 5 lb
+277.311 -252.33 241.766 -229.149 206.221 -205.967 0.5 1 1 5 lb
+-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0.5 0 5 lb
+-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0.5 5 lb
+-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0.5 5 lb
+-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0.5 5 lb
+906.312 201.403 946.592 42.798 986.873 -115.807 0 0.5 0.5 5 lb
+906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0.5 0.5 5 lb
+986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0.5 0.5 5 lb
+-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0.5 0.5 0 5 lb
+422.945 521.129 208.955 541.269 -5.03507 561.41 0.5 0 0.5 5 lb
+422.945 521.129 376.371 417.911 329.797 314.692 0.5 0 0.5 5 lb
+422.945 521.129 474.554 276.928 526.164 32.7279 0.5 0 0.5 5 lb
+-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0.5 0 0.5 5 lb
+329.797 314.692 130.912 317.209 -67.9734 319.727 0.5 0 0.5 5 lb
+-67.9734 319.727 229.095 176.227 526.164 32.7279 0.5 0 0.5 5 lb
+762.812 -17.6227 644.488 7.5526 526.164 32.7279 0.5 0.5 0.5 5 lb
+762.812 -17.6227 746.448 -162.381 730.084 -307.139 0.5 0.5 0.5 5 lb
+526.164 32.7279 470.779 -128.394 415.393 -289.516 0.5 0.5 0.5 5 lb
+730.084 -307.139 572.738 -298.327 415.393 -289.516 0.5 0.5 0.5 5 lb
+415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0.5 0.5 5 lb
+-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0.5 1 0.5 5 lb
+-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0.5 1 0.5 5 lb
+-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0.5 1 0.5 5 lb
+-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0.5 1 0.5 5 lb
+-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 1 1 0 5 lb
+-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 1 1 0 5 lb
+-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 1 0 1 5 lb
+-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 1 0 1 5 lb
+116.407 -173.66 158.808 -67.6589 201.208 38.3422 1 1 0 5 lb
+-262.548 107.243 -137.997 120.493 -13.4452 133.743 1 0 1 5 lb
+-262.548 107.243 -221.472 176.144 -180.397 245.045 1 0 1 5 lb
+-13.4452 133.743 -96.9211 189.394 -180.397 245.045 1 0 1 5 lb
+-180.397 245.045 -140.307 344.649 -132.697 451.748 0 1 1 5 lb
+-180.397 245.045 -172.787 352.144 -132.697 451.748 0 1 1 5 lb
+-416.25 345.746 -274.474 398.747 -132.697 451.748 0.5 0 0 5 lb
+-416.25 345.746 -393.725 457.048 -371.2 568.349 0.5 0 0 5 lb
+-132.697 451.748 -251.948 510.048 -371.2 568.349 0.5 0 0 5 lb
+670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 5 lb
+670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 5 lb
+588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 5 lb
+-689.204 -237.261 -612.964 -103.444 -567.302 43.6423 0 0 0 5 lb
+-689.204 -237.261 -643.542 -90.1744 -567.302 43.6423 0 0 0 5 lb
+grestore
+%Nodes:
+gsave
+-567.302 43.6423 20 0 0 1 nc
+-689.204 -237.261 20 0 0 1 nc
+924.667 409.347 20 0 0 1 nc
+588.113 544.499 20 0 0 1 nc
+670.264 274.195 20 1 0 0 nc
+-371.2 568.349 20 0 0 1 nc
+-132.697 451.748 20 1 0 0 nc
+-416.25 345.746 20 0 0 1 nc
+-180.397 245.045 20 1 0 0 nc
+-13.4452 133.743 20 0 0 1 nc
+-262.548 107.243 20 0 0 1 nc
+201.208 38.3422 20 0 0 1 nc
+116.407 -173.66 20 0 0 1 nc
+-26.6953 -19.9585 20 1 0 0 nc
+-539.894 -262.64 20 0 0 1 nc
+-323.543 -433.964 20 0 0 1 nc
+-309.657 -57.9033 20 1 0 0 nc
+-67.9734 -347.42 20 1 0 0 nc
+415.393 -289.516 20 1 0 0 nc
+730.084 -307.139 20 0 0 1 nc
+526.164 32.7279 20 1 0 0 nc
+762.812 -17.6227 20 1 0 0 nc
+-67.9734 319.727 20 0 0 1 nc
+329.797 314.692 20 0 0 1 nc
+-5.03507 561.41 20 0 0 1 nc
+422.945 521.129 20 0 0 1 nc
+-470.779 158.605 20 1 0 0 nc
+986.873 -115.807 20 0 0 1 nc
+906.312 201.403 20 0 0 1 nc
+-767.847 113.289 20 1 0 0 nc
+-579.033 445.603 20 0 0 1 nc
+-840.856 -246.718 20 0 0 1 nc
+206.221 -205.967 20 0 0 1 nc
+277.311 -252.33 20 0 0 1 nc
+271.13 -175.058 20 1 0 0 nc
+366.947 -110.15 20 1 0 0 nc
+397.855 -196.694 20 0 0 1 nc
+438.037 -88.514 20 0 0 1 nc
+286.584 -48.3327 20 1 0 0 nc
+212.403 -23.6057 20 0 0 1 nc
+280.402 10.3938 20 0 0 1 nc
+694.579 115.483 20 0 0 1 nc
+574.035 177.301 20 0 0 1 nc
+grestore
+grestore
+showpage
Index: doc/images/planar.eps
===================================================================
--- doc/images/planar.eps	(revision 827)
+++ doc/images/planar.eps	(revision 827)
@@ -0,0 +1,181 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: LEMON, graphToEps()
+%%CreationDate: Fri Oct 19 18:32:32 2007
+%%BoundingBox: 0 0 596 842
+%%DocumentPaperSizes: a4
+%%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
+/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
+     setrgbcolor 1.1 div sq fill
+   } bind def
+/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
+     setrgbcolor 1.1 div di fill
+   } bind def
+/nfemale { 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
+  newpath 5 index 5 index moveto 5 index 5 index 5 index 3.01 mul sub
+  lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub moveto
+  5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto stroke
+  5 index 5 index 5 index c fill
+  setrgbcolor 1.1 div c fill
+  } bind def
+/nmale {
+  0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
+  newpath 5 index 5 index moveto
+  5 index 4 index 1 mul 1.5 mul add
+  5 index 5 index 3 sqrt 1.5 mul mul add
+  1 index 1 index lineto
+  1 index 1 index 7 index sub moveto
+  1 index 1 index lineto
+  exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub lineto
+  stroke
+  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
+15 138.307 translate
+12.7843 dup scale
+90 rotate
+0.608112 -43.6081 translate
+%Edges:
+gsave
+9 31 9.5 30.5 10 30 0 0 0 0.091217 lb
+9 31 5.5 34.5 2 38 0 0 0 0.091217 lb
+9 31 25.5 16 42 1 0 0 0 0.091217 lb
+3 40 23 20.5 43 1 0 0 0 0.091217 lb
+3 40 22.5 20.5 42 1 0 0 0 0.091217 lb
+3 40 2.5 40.5 2 41 0 0 0 0.091217 lb
+13 25 10.5 24.5 8 24 0 0 0 0.091217 lb
+13 25 12 27 11 29 0 0 0 0.091217 lb
+3 4 2.5 3 2 2 0 0 0 0.091217 lb
+3 4 4.5 3 6 2 0 0 0 0.091217 lb
+6 25 7 24.5 8 24 0 0 0 0.091217 lb
+6 25 6 24.5 6 24 0 0 0 0.091217 lb
+34 2 33.5 2 33 2 0 0 0 0.091217 lb
+34 2 35 2 36 2 0 0 0 0.091217 lb
+6 8 16 9 26 10 0 0 0 0.091217 lb
+6 8 6 10.5 6 13 0 0 0 0.091217 lb
+6 8 6 7.5 6 7 0 0 0 0.091217 lb
+26 10 27.5 8.5 29 7 0 0 0 0.091217 lb
+26 10 27.5 9 29 8 0 0 0 0.091217 lb
+10 30 10.5 29.5 11 29 0 0 0 0.091217 lb
+8 24 7 23.5 6 23 0 0 0 0.091217 lb
+8 24 8 24.5 8 25 0 0 0 0.091217 lb
+33 2 32.5 2 32 2 0 0 0 0.091217 lb
+29 7 17.5 7 6 7 0 0 0 0.091217 lb
+2 2 1.5 22 1 42 0 0 0 0.091217 lb
+2 2 3.5 2 5 2 0 0 0 0.091217 lb
+21 15 13.5 14.5 6 14 0 0 0 0.091217 lb
+21 15 21 15.5 21 16 0 0 0 0.091217 lb
+1 42 0.5 42.5 0 43 0 0 0 0.091217 lb
+1 42 1.5 41.5 2 41 0 0 0 0.091217 lb
+6 15 6 15.5 6 16 0 0 0 0.091217 lb
+6 15 6 14.5 6 14 0 0 0 0.091217 lb
+43 1 22 0.5 1 0 0 0 0 0.091217 lb
+31 2 18.5 2 6 2 0 0 0 0.091217 lb
+31 2 31.5 2 32 2 0 0 0 0.091217 lb
+6 24 6 23.5 6 23 0 0 0 0.091217 lb
+6 16 6 16.5 6 17 0 0 0 0.091217 lb
+6 23 6 20 6 17 0 0 0 0.091217 lb
+6 2 5.5 2 5 2 0 0 0 0.091217 lb
+6 2 6 4.5 6 7 0 0 0 0.091217 lb
+0 43 0.5 21.5 1 0 0 0 0 0.091217 lb
+1 1 19.5 1.5 38 2 0 0 0 0.091217 lb
+1 1 1 0.5 1 0 0 0 0 0.091217 lb
+2 38 5.5 31.5 9 25 0 0 0 0.091217 lb
+25 13 15.5 13 6 13 0 0 0 0.091217 lb
+25 13 15.5 13.5 6 14 0 0 0 0.091217 lb
+8 25 8.5 25 9 25 0 0 0 0.091217 lb
+11 29 24.5 15.5 38 2 0 0 0 0.091217 lb
+6 17 11.5 18 17 19 0 0 0 0.091217 lb
+16 23 26.5 12.5 37 2 0 0 0 0.091217 lb
+16 23 18.5 19.5 21 16 0 0 0 0.091217 lb
+36 2 36.5 2 37 2 0 0 0 0.091217 lb
+36 2 32.5 5 29 8 0 0 0 0.091217 lb
+6 13 6 13.5 6 14 0 0 0 0.091217 lb
+37 2 37.5 2 38 2 0 0 0 0.091217 lb
+21 16 19 17.5 17 19 0 0 0 0.091217 lb
+grestore
+%Nodes:
+gsave
+29 8 0.304556 1 1 1 nc
+2 41 0.304556 1 1 1 nc
+6 7 0.304556 1 1 1 nc
+5 2 0.304556 1 1 1 nc
+17 19 0.304556 1 1 1 nc
+21 16 0.304556 1 1 1 nc
+1 0 0.304556 1 1 1 nc
+9 25 0.304556 1 1 1 nc
+6 14 0.304556 1 1 1 nc
+42 1 0.304556 1 1 1 nc
+38 2 0.304556 1 1 1 nc
+37 2 0.304556 1 1 1 nc
+6 13 0.304556 1 1 1 nc
+36 2 0.304556 1 1 1 nc
+16 23 0.304556 1 1 1 nc
+6 17 0.304556 1 1 1 nc
+11 29 0.304556 1 1 1 nc
+8 25 0.304556 1 1 1 nc
+32 2 0.304556 1 1 1 nc
+25 13 0.304556 1 1 1 nc
+2 38 0.304556 1 1 1 nc
+1 1 0.304556 1 1 1 nc
+0 43 0.304556 1 1 1 nc
+6 2 0.304556 1 1 1 nc
+6 23 0.304556 1 1 1 nc
+6 16 0.304556 1 1 1 nc
+6 24 0.304556 1 1 1 nc
+31 2 0.304556 1 1 1 nc
+43 1 0.304556 1 1 1 nc
+6 15 0.304556 1 1 1 nc
+1 42 0.304556 1 1 1 nc
+21 15 0.304556 1 1 1 nc
+2 2 0.304556 1 1 1 nc
+29 7 0.304556 1 1 1 nc
+33 2 0.304556 1 1 1 nc
+8 24 0.304556 1 1 1 nc
+10 30 0.304556 1 1 1 nc
+26 10 0.304556 1 1 1 nc
+6 8 0.304556 1 1 1 nc
+34 2 0.304556 1 1 1 nc
+6 25 0.304556 1 1 1 nc
+3 4 0.304556 1 1 1 nc
+13 25 0.304556 1 1 1 nc
+3 40 0.304556 1 1 1 nc
+9 31 0.304556 1 1 1 nc
+grestore
+grestore
+showpage
Index: doc/images/strongly_connected_components.eps
===================================================================
--- doc/images/strongly_connected_components.eps	(revision 587)
+++ doc/images/strongly_connected_components.eps	(revision 587)
@@ -0,0 +1,180 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Creator: LEMON, graphToEps()
+%%CreationDate: Fri Nov  4 13:47:12 2005
+%%BoundingBox: 0 0 842 596
+%%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
+/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
+     setrgbcolor 1.1 div sq fill
+   } bind def
+/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
+     setrgbcolor 1.1 div di fill
+   } bind def
+/arrl 10 def
+/arrw 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
+90 rotate
+0 -842 translate
+77.1122 15 translate
+0.585745 dup scale
+90 rotate
+695.963 -397.916 translate
+%Edges:
+gsave
+2 setlinewidth 0 0 1 setrgbcolor newpath
+218.178 27.2723 moveto
+192.373 -40.1551 188.622 -49.9556 169.228 -100.631 curveto stroke
+newpath 164.939 -111.838 moveto 165.492 -99.2013 lineto 172.964 -102.061 lineto closepath fill
+2 setlinewidth 0 0 1 setrgbcolor newpath
+44.8044 15.5841 moveto
+119.293 20.6059 129.775 21.3125 186.25 25.1199 curveto stroke
+newpath 198.223 25.927 moveto 186.519 21.1289 lineto 185.981 29.1108 lineto closepath fill
+2 setlinewidth 1 0 0 setrgbcolor newpath
+218.178 27.2723 moveto
+285.395 -87.4449 290.763 -96.6058 348.102 -194.464 curveto stroke
+newpath 354.169 -204.818 moveto 344.651 -196.487 lineto 351.554 -192.442 lineto closepath fill
+2 setlinewidth 0 0 1 setrgbcolor newpath
+157.79 -130.517 moveto
+108.71 -67.0521 102.27 -58.7243 64.3804 -9.72954 curveto stroke
+newpath 57.0394 -0.236898 moveto 67.5446 -7.28254 lineto 61.2162 -12.1765 lineto closepath fill
+2 setlinewidth 1 0 0 setrgbcolor newpath
+-105.193 -261.035 moveto
+-35.6576 -132.801 -30.5923 -123.459 29.5506 -12.5464 curveto stroke
+newpath 35.2708 -1.99743 moveto 33.0669 -14.4531 lineto 26.0343 -10.6397 lineto closepath fill
+2 setlinewidth 0 0 1 setrgbcolor newpath
+-465.576 -42.8564 moveto
+-559.078 -25.5413 -569.47 -23.6169 -644.498 -9.72286 curveto stroke
+newpath -656.297 -7.5378 moveto -643.77 -5.78973 lineto -645.226 -13.656 lineto closepath fill
+2 setlinewidth 0 0 1 setrgbcolor newpath
+-574.666 -153.893 moveto
+-528.842 -107.252 -521.515 -99.794 -488.002 -65.683 curveto stroke
+newpath -479.592 -57.123 moveto -485.149 -68.4863 lineto -490.856 -62.8797 lineto closepath fill
+2 setlinewidth 1 0 0 setrgbcolor newpath
+-490.901 120.777 moveto
+-480.122 51.1328 -478.519 40.7713 -470.47 -11.2329 curveto stroke
+newpath -468.635 -23.0917 moveto -474.423 -11.8447 lineto -466.517 -10.6212 lineto closepath fill
+2 setlinewidth 0 0 1 setrgbcolor newpath
+-675.963 -3.89604 moveto
+-632.116 -68.8235 -626.228 -77.5422 -592.575 -127.374 curveto stroke
+newpath -585.859 -137.319 moveto -595.89 -129.612 lineto -589.26 -125.135 lineto closepath fill
+2 setlinewidth 0 0 1 setrgbcolor newpath
+-490.901 120.777 moveto
+-435.445 215.844 -430.107 224.995 -384.3 303.522 curveto stroke
+newpath -378.253 313.887 moveto -380.845 301.507 lineto -387.755 305.537 lineto closepath fill
+2 setlinewidth 0 0 1 setrgbcolor newpath
+-266.879 114.933 moveto
+-367.067 117.547 -377.642 117.822 -458.912 119.943 curveto stroke
+newpath -470.908 120.255 moveto -458.807 123.941 lineto -459.016 115.944 lineto closepath fill
+2 setlinewidth 0 0 1 setrgbcolor newpath
+-368.176 331.163 moveto
+-322.511 233.685 -318.018 224.095 -280.454 143.911 curveto stroke
+newpath -275.364 133.044 moveto -284.076 142.214 lineto -276.832 145.608 lineto closepath fill
+2 setlinewidth 1 0 0 setrgbcolor newpath
+-266.879 114.933 moveto
+-224.004 235.52 -220.448 245.52 -184.094 347.765 curveto stroke
+newpath -180.074 359.072 moveto -180.325 346.425 lineto -187.863 349.105 lineto closepath fill
+2 setlinewidth 0 0 1 setrgbcolor newpath
+-251.294 -335.059 moveto
+-189.25 -303.624 -179.902 -298.887 -133.738 -275.498 curveto stroke
+newpath -123.034 -270.074 moveto -131.93 -279.066 lineto -135.546 -271.93 lineto closepath fill
+2 setlinewidth 0 0 1 setrgbcolor newpath
+-389.604 -136.361 moveto
+-327.15 -226.083 -321.098 -234.777 -269.576 -308.795 curveto stroke
+newpath -262.72 -318.644 moveto -272.859 -311.081 lineto -266.293 -306.51 lineto closepath fill
+2 setlinewidth 1 0 0 setrgbcolor newpath
+5.84406 175.322 moveto
+-76.0754 267.926 -83.1051 275.873 -152.172 353.948 curveto stroke
+newpath -160.122 362.936 moveto -149.176 356.598 lineto -155.168 351.298 lineto closepath fill
+2 setlinewidth 0 0 1 setrgbcolor newpath
+169.478 311.683 moveto
+96.8003 251.119 88.6819 244.353 30.4273 195.808 curveto stroke
+newpath 21.2086 188.126 moveto 27.8666 198.881 lineto 32.988 192.735 lineto closepath fill
+2 setlinewidth 0 0 1 setrgbcolor newpath
+342.851 111.037 moveto
+263.766 202.563 256.831 210.589 190.4 287.47 curveto stroke
+newpath 182.554 296.55 moveto 193.427 290.085 lineto 187.373 284.855 lineto closepath fill
+2 setlinewidth 0 0 1 setrgbcolor newpath
+5.84406 175.322 moveto
+163.16 145.314 173.605 143.321 311.418 117.033 curveto stroke
+newpath 323.205 114.784 moveto 310.668 113.104 lineto 312.167 120.962 lineto closepath fill
+2 setlinewidth 0 0 1 setrgbcolor newpath
+342.851 111.037 moveto
+497.255 2.58683 505.964 -3.53033 643.932 -100.436 curveto stroke
+newpath 653.752 -107.334 moveto 641.633 -103.71 lineto 646.231 -97.163 lineto closepath fill
+2 setlinewidth 0 0 1 setrgbcolor newpath
+364.28 -222.074 moveto
+354.298 -66.9063 353.616 -56.2971 344.905 79.1029 curveto stroke
+newpath 344.135 91.0781 moveto 348.897 79.3597 lineto 340.914 78.8461 lineto closepath fill
+2 setlinewidth 0 0 1 setrgbcolor newpath
+670.118 -118.829 moveto
+528.037 -166.793 517.967 -170.192 394.599 -211.839 curveto stroke
+newpath 383.229 -215.677 moveto 393.32 -208.049 lineto 395.878 -215.629 lineto closepath fill
+2 setlinewidth 1 0 0 setrgbcolor newpath
+-105.193 -261.035 moveto
+118.401 -242.479 129.015 -241.598 332.39 -224.721 curveto stroke
+newpath 344.348 -223.728 moveto 332.72 -228.707 lineto 332.059 -220.734 lineto closepath fill
+2 setlinewidth 0 0 1 setrgbcolor newpath
+-105.193 -261.035 moveto
+-160.867 -161.176 -166.028 -151.918 -212.336 -68.858 curveto stroke
+newpath -218.179 -58.3769 moveto -208.842 -66.9102 lineto -215.829 -70.8058 lineto closepath fill
+2 setlinewidth 0 0 1 setrgbcolor newpath
+-227.918 -40.9084 moveto
+-298.35 -82.4884 -307.42 -87.8432 -362.048 -120.093 curveto stroke
+newpath -372.381 -126.193 moveto -364.081 -116.648 lineto -360.014 -123.537 lineto closepath fill
+grestore
+%Nodes:
+gsave
+-389.604 -136.361 20 0 1 0 nc
+-227.918 -40.9084 20 0 1 0 nc
+-105.193 -261.035 20 0 1 0 nc
+364.28 -222.074 20 1 1 0 nc
+670.118 -118.829 20 1 1 0 nc
+342.851 111.037 20 1 1 0 nc
+5.84406 175.322 20 1 1 0 nc
+169.478 311.683 20 1 1 0 nc
+-173.374 377.916 20 1 0 1 nc
+-251.294 -335.059 20 0 1 0 nc
+-266.879 114.933 20 0 0 0 nc
+-368.176 331.163 20 0 0 0 nc
+-490.901 120.777 20 0 0 0 nc
+-574.666 -153.893 20 1 0 0 nc
+-675.963 -3.89604 20 1 0 0 nc
+-465.576 -42.8564 20 1 0 0 nc
+44.8044 15.5841 20 0 0 1 nc
+157.79 -130.517 20 0 0 1 nc
+218.178 27.2723 20 0 0 1 nc
+grestore
+grestore
+showpage
Index: doc/lgf.dox
===================================================================
--- doc/lgf.dox	(revision 440)
+++ doc/lgf.dox	(revision 927)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2011
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -64,9 +64,9 @@
 \endcode
 
-The \c \@arcs section is very similar to the \c \@nodes section,
-it again starts with a header line describing the names of the maps,
-but the \c "label" map is not obligatory here. The following lines
-describe the arcs. The first two tokens of each line are
-the source and the target node of the arc, respectively, then come the map
+The \c \@arcs section is very similar to the \c \@nodes section, it
+again starts with a header line describing the names of the maps, but
+the \c "label" map is not obligatory here. The following lines
+describe the arcs. The first two tokens of each line are the source
+and the target node of the arc, respectively, then come the map
 values. The source and target tokens must be node labels.
 
@@ -79,8 +79,19 @@
 \endcode
 
+If there is no map in the \c \@arcs section at all, then it must be
+indicated by a sole '-' sign in the first line.
+
+\code
+ @arcs
+         -
+ 1   2
+ 1   3
+ 2   3
+\endcode
+
 The \c \@edges is just a synonym of \c \@arcs. The \@arcs section can
 also store the edge set of an undirected graph. In such case there is
 a conventional method for store arc maps in the file, if two columns
-has the same caption with \c '+' and \c '-' prefix, then these columns
+have the same caption with \c '+' and \c '-' prefix, then these columns
 can be regarded as the values of an arc map.
 
Index: c/mainpage.dox
===================================================================
--- doc/mainpage.dox	(revision 559)
+++ 	(revision )
@@ -1,56 +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.
- *
- */
-
-/**
-\mainpage LEMON Documentation
-
-\section intro Introduction
-
-\subsection whatis What is LEMON
-
-LEMON stands for
-<b>L</b>ibrary of <b>E</b>fficient <b>M</b>odels
-and <b>O</b>ptimization in <b>N</b>etworks.
-It is a C++ template
-library aimed at combinatorial optimization tasks which
-often involve in working
-with graphs.
-
-<b>
-LEMON is an <a class="el" href="http://opensource.org/">open&nbsp;source</a>
-project.
-You are free to use it in your commercial or
-non-commercial applications under very permissive
-\ref license "license terms".
-</b>
-
-\subsection howtoread How to read the documentation
-
-If you want to get a quick start and see the most important features then
-take a look at our \ref quicktour
-"Quick Tour to LEMON" which will guide you along.
-
-If you already feel like using our library, see the
-<a class="el" href="http://lemon.cs.elte.hu/pub/tutorial/">LEMON Tutorial</a>.
-
-If you know what you are looking for then try to find it under the
-<a class="el" href="modules.html">Modules</a> section.
-
-If you are a user of the old (0.x) series of LEMON, please check out the
-\ref migration "Migration Guide" for the backward incompatibilities.
-*/
Index: doc/mainpage.dox.in
===================================================================
--- doc/mainpage.dox.in	(revision 908)
+++ doc/mainpage.dox.in	(revision 908)
@@ -0,0 +1,61 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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.
+ *
+ */
+
+/**
+\mainpage @PACKAGE_NAME@ @PACKAGE_VERSION@ Documentation
+
+\section intro Introduction
+
+<b>LEMON</b> stands for <i><b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
+and <b>O</b>ptimization in <b>N</b>etworks</i>.
+It is a C++ template library providing efficient implementations of common
+data structures and algorithms with focus on combinatorial optimization
+tasks connected mainly with graphs and networks.
+
+<b>
+LEMON is an <a class="el" href="http://opensource.org/">open&nbsp;source</a>
+project.
+You are free to use it in your commercial or
+non-commercial applications under very permissive
+\ref license "license terms".
+</b>
+
+The project is maintained by the
+<a href="http://www.cs.elte.hu/egres/">Egerv&aacute;ry Research Group on
+Combinatorial Optimization</a> \ref egres
+at the Operations Research Department of the
+<a href="http://www.elte.hu/en/">E&ouml;tv&ouml;s Lor&aacute;nd University</a>,
+Budapest, Hungary.
+LEMON is also a member of the <a href="http://www.coin-or.org/">COIN-OR</a>
+initiative \ref coinor.
+
+\section howtoread How to Read the Documentation
+
+If you would like to get to know the library, see
+<a class="el" href="http://lemon.cs.elte.hu/pub/tutorial/">LEMON Tutorial</a>.
+
+If you are interested in starting to use the library, see the <a class="el"
+href="http://lemon.cs.elte.hu/trac/lemon/wiki/InstallGuide/">Installation
+Guide</a>.
+
+If you know what you are looking for, then try to find it under the
+<a class="el" href="modules.html">Modules</a> section.
+
+If you are a user of the old (0.x) series of LEMON, please check out the
+\ref migration "Migration Guide" for the backward incompatibilities.
+*/
Index: doc/min_cost_flow.dox
===================================================================
--- doc/min_cost_flow.dox	(revision 877)
+++ doc/min_cost_flow.dox	(revision 877)
@@ -0,0 +1,153 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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.
+ *
+ */
+
+namespace lemon {
+
+/**
+\page min_cost_flow Minimum Cost Flow Problem
+
+\section mcf_def Definition (GEQ form)
+
+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 (lower and upper bounds)
+and arc costs \ref amo93networkflows.
+
+Formally, let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$,
+\f$upper: A\rightarrow\mathbf{R}\cup\{+\infty\}\f$ denote the lower and
+upper bounds for the flow values on the arcs, for which
+\f$lower(uv) \leq upper(uv)\f$ must hold for all \f$uv\in A\f$,
+\f$cost: A\rightarrow\mathbf{R}\f$ denotes the cost per unit flow
+on the arcs and \f$sup: V\rightarrow\mathbf{R}\f$ denotes the
+signed supply values of the nodes.
+If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
+supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
+\f$-sup(u)\f$ demand.
+A minimum cost flow is an \f$f: A\rightarrow\mathbf{R}\f$ solution
+of the following optimization problem.
+
+\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
+\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \geq
+    sup(u) \quad \forall u\in V \f]
+\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
+
+The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
+zero or negative in order to have a feasible solution (since the sum
+of the expressions on the left-hand side of the inequalities is zero).
+It means that the total demand must be greater or equal to the total
+supply and all the supplies have to be carried out from the supply nodes,
+but there could be demands that are not satisfied.
+If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand
+constraints have to be satisfied with equality, i.e. all demands
+have to be satisfied and all supplies have to be used.
+
+
+\section mcf_algs Algorithms
+
+LEMON contains several algorithms for solving this problem, for more
+information see \ref min_cost_flow_algs "Minimum Cost Flow Algorithms".
+
+A feasible solution for this problem can be found using \ref Circulation.
+
+
+\section mcf_dual Dual Solution
+
+The dual solution of the minimum cost flow problem is represented by
+node potentials \f$\pi: V\rightarrow\mathbf{R}\f$.
+An \f$f: A\rightarrow\mathbf{R}\f$ primal feasible solution is optimal
+if and only if for some \f$\pi: V\rightarrow\mathbf{R}\f$ node potentials
+the following \e complementary \e slackness optimality conditions hold.
+
+ - For all \f$uv\in A\f$ arcs:
+   - if \f$cost^\pi(uv)>0\f$, then \f$f(uv)=lower(uv)\f$;
+   - if \f$lower(uv)<f(uv)<upper(uv)\f$, then \f$cost^\pi(uv)=0\f$;
+   - if \f$cost^\pi(uv)<0\f$, then \f$f(uv)=upper(uv)\f$.
+ - For all \f$u\in V\f$ nodes:
+   - \f$\pi(u)\leq 0\f$;
+   - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
+     then \f$\pi(u)=0\f$.
+
+Here \f$cost^\pi(uv)\f$ denotes the \e reduced \e cost of the arc
+\f$uv\in A\f$ with respect to the potential function \f$\pi\f$, i.e.
+\f[ cost^\pi(uv) = cost(uv) + \pi(u) - \pi(v).\f]
+
+All algorithms provide dual solution (node potentials), as well,
+if an optimal flow is found.
+
+
+\section mcf_eq Equality Form
+
+The above \ref mcf_def "definition" is actually more general than the
+usual formulation of the minimum cost flow problem, in which strict
+equalities are required in the supply/demand contraints.
+
+\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
+\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) =
+    sup(u) \quad \forall u\in V \f]
+\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
+
+However if the sum of the supply values is zero, then these two problems
+are equivalent.
+The \ref min_cost_flow_algs "algorithms" in LEMON support the general
+form, so if you need the equality form, you have to ensure this additional
+contraint manually.
+
+
+\section mcf_leq Opposite Inequalites (LEQ Form)
+
+Another possible definition of the minimum cost flow problem is
+when there are <em>"less or equal"</em> (LEQ) supply/demand constraints,
+instead of the <em>"greater or equal"</em> (GEQ) constraints.
+
+\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
+\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \leq
+    sup(u) \quad \forall u\in V \f]
+\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
+
+It means that the total demand must be less or equal to the
+total supply (i.e. \f$\sum_{u\in V} sup(u)\f$ must be zero or
+positive) and all the demands have to be satisfied, but there
+could be supplies that are not carried out from the supply
+nodes.
+The equality form is also a special case of this form, of course.
+
+You could easily transform this case to the \ref mcf_def "GEQ form"
+of the problem by reversing the direction of the arcs and taking the
+negative of the supply values (e.g. using \ref ReverseDigraph and
+\ref NegMap adaptors).
+However \ref NetworkSimplex algorithm also supports this form directly
+for the sake of convenience.
+
+Note that the optimality conditions for this supply constraint type are
+slightly differ from the conditions that are discussed for the GEQ form,
+namely the potentials have to be non-negative instead of non-positive.
+An \f$f: A\rightarrow\mathbf{R}\f$ feasible solution of this problem
+is optimal if and only if for some \f$\pi: V\rightarrow\mathbf{R}\f$
+node potentials the following conditions hold.
+
+ - For all \f$uv\in A\f$ arcs:
+   - if \f$cost^\pi(uv)>0\f$, then \f$f(uv)=lower(uv)\f$;
+   - if \f$lower(uv)<f(uv)<upper(uv)\f$, then \f$cost^\pi(uv)=0\f$;
+   - if \f$cost^\pi(uv)<0\f$, then \f$f(uv)=upper(uv)\f$.
+ - For all \f$u\in V\f$ nodes:
+   - \f$\pi(u)\geq 0\f$;
+   - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
+     then \f$\pi(u)=0\f$.
+
+*/
+}
Index: doc/references.bib
===================================================================
--- doc/references.bib	(revision 755)
+++ doc/references.bib	(revision 755)
@@ -0,0 +1,301 @@
+%%%%% Defining LEMON %%%%%
+
+@misc{lemon,
+  key =          {LEMON},
+  title =        {{LEMON} -- {L}ibrary for {E}fficient {M}odeling and
+                  {O}ptimization in {N}etworks},
+  howpublished = {\url{http://lemon.cs.elte.hu/}},
+  year =         2009
+}
+
+@misc{egres,
+  key =          {EGRES},
+  title =        {{EGRES} -- {E}gerv{\'a}ry {R}esearch {G}roup on
+                  {C}ombinatorial {O}ptimization},
+  url =          {http://www.cs.elte.hu/egres/}
+}
+
+@misc{coinor,
+  key =          {COIN-OR},
+  title =        {{COIN-OR} -- {C}omputational {I}nfrastructure for
+                  {O}perations {R}esearch},
+  url =          {http://www.coin-or.org/}
+}
+
+
+%%%%% Other libraries %%%%%%
+
+@misc{boost,
+  key =          {Boost},
+  title =        {{B}oost {C++} {L}ibraries},
+  url =          {http://www.boost.org/}
+}
+
+@book{bglbook,
+  author =       {Jeremy G. Siek and Lee-Quan Lee and Andrew
+                  Lumsdaine},
+  title =        {The Boost Graph Library: User Guide and Reference
+                  Manual},
+  publisher =    {Addison-Wesley},
+  year =         2002
+}
+
+@misc{leda,
+  key =          {LEDA},
+  title =        {{LEDA} -- {L}ibrary of {E}fficient {D}ata {T}ypes and
+                  {A}lgorithms},
+  url =          {http://www.algorithmic-solutions.com/}
+}
+
+@book{ledabook,
+  author =       {Kurt Mehlhorn and Stefan N{\"a}her},
+  title =        {{LEDA}: {A} platform for combinatorial and geometric
+                  computing},
+  isbn =         {0-521-56329-1},
+  publisher =    {Cambridge University Press},
+  address =      {New York, NY, USA},
+  year =         1999
+}
+
+
+%%%%% Tools that LEMON depends on %%%%%
+
+@misc{cmake,
+  key =          {CMake},
+  title =        {{CMake} -- {C}ross {P}latform {M}ake},
+  url =          {http://www.cmake.org/}
+}
+
+@misc{doxygen,
+  key =          {Doxygen},
+  title =        {{Doxygen} -- {S}ource code documentation generator
+                  tool},
+  url =          {http://www.doxygen.org/}
+}
+
+
+%%%%% LP/MIP libraries %%%%%
+
+@misc{glpk,
+  key =          {GLPK},
+  title =        {{GLPK} -- {GNU} {L}inear {P}rogramming {K}it},
+  url =          {http://www.gnu.org/software/glpk/}
+}
+
+@misc{clp,
+  key =          {Clp},
+  title =        {{Clp} -- {Coin-Or} {L}inear {P}rogramming},
+  url =          {http://projects.coin-or.org/Clp/}
+}
+
+@misc{cbc,
+  key =          {Cbc},
+  title =        {{Cbc} -- {Coin-Or} {B}ranch and {C}ut},
+  url =          {http://projects.coin-or.org/Cbc/}
+}
+
+@misc{cplex,
+  key =          {CPLEX},
+  title =        {{ILOG} {CPLEX}},
+  url =          {http://www.ilog.com/}
+}
+
+@misc{soplex,
+  key =          {SoPlex},
+  title =        {{SoPlex} -- {T}he {S}equential {O}bject-{O}riented
+                  {S}implex},
+  url =          {http://soplex.zib.de/}
+}
+
+
+%%%%% General books %%%%%
+
+@book{amo93networkflows,
+  author =       {Ravindra K. Ahuja and Thomas L. Magnanti and James
+                  B. Orlin},
+  title =        {Network Flows: Theory, Algorithms, and Applications},
+  publisher =    {Prentice-Hall, Inc.},
+  year =         1993,
+  month =        feb,
+  isbn =         {978-0136175490}
+}
+
+@book{schrijver03combinatorial,
+  author =       {Alexander Schrijver},
+  title =        {Combinatorial Optimization: Polyhedra and Efficiency},
+  publisher =    {Springer-Verlag},
+  year =         2003,
+  isbn =         {978-3540443896}
+}
+
+@book{clrs01algorithms,
+  author =       {Thomas H. Cormen and Charles E. Leiserson and Ronald
+                  L. Rivest and Clifford Stein},
+  title =        {Introduction to Algorithms},
+  publisher =    {The MIT Press},
+  year =         2001,
+  edition =      {2nd}
+}
+
+@book{stroustrup00cpp,
+  author =       {Bjarne Stroustrup},
+  title =        {The C++ Programming Language},
+  edition =      {3rd},
+  publisher =    {Addison-Wesley Professional},
+  isbn =         0201700735,
+  month =        {February},
+  year =         2000
+}
+
+
+%%%%% Maximum flow algorithms %%%%%
+
+@article{edmondskarp72theoretical,
+  author =       {Jack Edmonds and Richard M. Karp},
+  title =        {Theoretical improvements in algorithmic efficiency
+                  for network flow problems},
+  journal =      {Journal of the ACM},
+  year =         1972,
+  volume =       19,
+  number =       2,
+  pages =        {248-264}
+}
+
+@article{goldberg88newapproach,
+  author =       {Andrew V. Goldberg and Robert E. Tarjan},
+  title =        {A new approach to the maximum flow problem},
+  journal =      {Journal of the ACM},
+  year =         1988,
+  volume =       35,
+  number =       4,
+  pages =        {921-940}
+}
+
+@article{dinic70algorithm,
+  author =       {E. A. Dinic},
+  title =        {Algorithm for solution of a problem of maximum flow
+                  in a network with power estimation},
+  journal =      {Soviet Math. Doklady},
+  year =         1970,
+  volume =       11,
+  pages =        {1277-1280}
+}
+
+@article{goldberg08partial,
+  author =       {Andrew V. Goldberg},
+  title =        {The Partial Augment-Relabel Algorithm for the
+                  Maximum Flow Problem},
+  journal =      {16th Annual European Symposium on Algorithms},
+  year =         2008,
+  pages =        {466-477}
+}
+
+@article{sleator83dynamic,
+  author =       {Daniel D. Sleator and Robert E. Tarjan},
+  title =        {A data structure for dynamic trees},
+  journal =      {Journal of Computer and System Sciences},
+  year =         1983,
+  volume =       26,
+  number =       3,
+  pages =        {362-391}
+}
+
+
+%%%%% Minimum mean cycle algorithms %%%%%
+
+@article{karp78characterization,
+  author =       {Richard M. Karp},
+  title =        {A characterization of the minimum cycle mean in a
+                  digraph},
+  journal =      {Discrete Math.},
+  year =         1978,
+  volume =       23,
+  pages =        {309-311}
+}
+
+@article{dasdan98minmeancycle,
+  author =       {Ali Dasdan and Rajesh K. Gupta},
+  title =        {Faster Maximum and Minimum Mean Cycle Alogrithms for
+                  System Performance Analysis},
+  journal =      {IEEE Transactions on Computer-Aided Design of
+                  Integrated Circuits and Systems},
+  year =         1998,
+  volume =       17,
+  number =       10,
+  pages =        {889-899}
+}
+
+
+%%%%% Minimum cost flow algorithms %%%%%
+
+@article{klein67primal,
+  author =       {Morton Klein},
+  title =        {A primal method for minimal cost flows with
+                  applications to the assignment and transportation
+                  problems},
+  journal =      {Management Science},
+  year =         1967,
+  volume =       14,
+  pages =        {205-220}
+}
+
+@article{goldberg89cyclecanceling,
+  author =       {Andrew V. Goldberg and Robert E. Tarjan},
+  title =        {Finding minimum-cost circulations by canceling
+                  negative cycles},
+  journal =      {Journal of the ACM},
+  year =         1989,
+  volume =       36,
+  number =       4,
+  pages =        {873-886}
+}
+
+@article{goldberg90approximation,
+  author =       {Andrew V. Goldberg and Robert E. Tarjan},
+  title =        {Finding Minimum-Cost Circulations by Successive
+                  Approximation},
+  journal =      {Mathematics of Operations Research},
+  year =         1990,
+  volume =       15,
+  number =       3,
+  pages =        {430-466}
+}
+
+@article{goldberg97efficient,
+  author =       {Andrew V. Goldberg},
+  title =        {An Efficient Implementation of a Scaling
+                  Minimum-Cost Flow Algorithm},
+  journal =      {Journal of Algorithms},
+  year =         1997,
+  volume =       22,
+  number =       1,
+  pages =        {1-29}
+}
+
+@article{bunnagel98efficient,
+  author =       {Ursula B{\"u}nnagel and Bernhard Korte and Jens
+                  Vygen},
+  title =        {Efficient implementation of the {G}oldberg-{T}arjan
+                  minimum-cost flow algorithm},
+  journal =      {Optimization Methods and Software},
+  year =         1998,
+  volume =       10,
+  pages =        {157-174}
+}
+
+@book{dantzig63linearprog,
+  author =       {George B. Dantzig},
+  title =        {Linear Programming and Extensions},
+  publisher =    {Princeton University Press},
+  year =         1963
+}
+
+@mastersthesis{kellyoneill91netsimplex,
+  author =       {Damian J. Kelly and Garrett M. O'Neill},
+  title =        {The Minimum Cost Flow Problem and The Network
+                  Simplex Method},
+  school =       {University College},
+  address =      {Dublin, Ireland},
+  year =         1991,
+  month =        sep,
+}
Index: lemon/CMakeLists.txt
===================================================================
--- lemon/CMakeLists.txt	(revision 549)
+++ lemon/CMakeLists.txt	(revision 946)
@@ -7,4 +7,10 @@
   ${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake
   ${CMAKE_CURRENT_BINARY_DIR}/config.h
+)
+
+CONFIGURE_FILE(
+  ${CMAKE_CURRENT_SOURCE_DIR}/lemon.pc.cmake
+  ${CMAKE_CURRENT_BINARY_DIR}/lemon.pc
+  @ONLY
 )
 
@@ -19,20 +25,40 @@
 )
 
-IF(HAVE_GLPK)
+IF(LEMON_HAVE_GLPK)
   SET(LEMON_SOURCES ${LEMON_SOURCES} glpk.cc)
-  INCLUDE_DIRECTORIES(${GLPK_INCLUDE_DIR})
+  INCLUDE_DIRECTORIES(${GLPK_INCLUDE_DIRS})
   IF(WIN32)
     INSTALL(FILES ${GLPK_BIN_DIR}/glpk.dll DESTINATION bin)
     INSTALL(FILES ${GLPK_BIN_DIR}/libltdl3.dll DESTINATION bin)
     INSTALL(FILES ${GLPK_BIN_DIR}/zlib1.dll DESTINATION bin)
-  ENDIF(WIN32)
-ENDIF(HAVE_GLPK)
+  ENDIF()
+ENDIF()
+
+IF(LEMON_HAVE_CPLEX)
+  SET(LEMON_SOURCES ${LEMON_SOURCES} cplex.cc)
+  INCLUDE_DIRECTORIES(${CPLEX_INCLUDE_DIRS})
+ENDIF()
+
+IF(LEMON_HAVE_CLP)
+  SET(LEMON_SOURCES ${LEMON_SOURCES} clp.cc)
+  INCLUDE_DIRECTORIES(${COIN_INCLUDE_DIRS})
+ENDIF()
+
+IF(LEMON_HAVE_CBC)
+  SET(LEMON_SOURCES ${LEMON_SOURCES} cbc.cc)
+  INCLUDE_DIRECTORIES(${COIN_INCLUDE_DIRS})
+ENDIF()
 
 ADD_LIBRARY(lemon ${LEMON_SOURCES})
+IF(UNIX)
+  SET_TARGET_PROPERTIES(lemon PROPERTIES OUTPUT_NAME emon)
+ENDIF()
 
 INSTALL(
   TARGETS lemon
   ARCHIVE DESTINATION lib
-  COMPONENT library)
+  LIBRARY DESTINATION lib
+  COMPONENT library
+)
 
 INSTALL(
@@ -40,3 +66,16 @@
   DESTINATION include/lemon
   COMPONENT headers
-  FILES_MATCHING PATTERN "*.h")
+  FILES_MATCHING PATTERN "*.h"
+)
+
+INSTALL(
+  FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h
+  DESTINATION include/lemon
+  COMPONENT headers
+)
+
+INSTALL(
+  FILES ${CMAKE_CURRENT_BINARY_DIR}/lemon.pc
+  DESTINATION lib/pkgconfig
+)
+
Index: lemon/Makefile.am
===================================================================
--- lemon/Makefile.am	(revision 550)
+++ lemon/Makefile.am	(revision 944)
@@ -1,5 +1,7 @@
 EXTRA_DIST += \
 	lemon/lemon.pc.in \
-	lemon/CMakeLists.txt
+	lemon/lemon.pc.cmake \
+	lemon/CMakeLists.txt \
+	lemon/config.h.cmake
 
 pkgconfig_DATA += lemon/lemon.pc
@@ -13,7 +15,8 @@
 	lemon/lp_base.cc \
 	lemon/lp_skeleton.cc \
-        lemon/random.cc \
+	lemon/random.cc \
 	lemon/bits/windows.cc
 
+nodist_lemon_HEADERS = lemon/config.h	
 
 lemon_libemon_la_CXXFLAGS = \
@@ -22,5 +25,6 @@
 	$(CPLEX_CFLAGS) \
 	$(SOPLEX_CXXFLAGS) \
-	$(CLP_CXXFLAGS)
+	$(CLP_CXXFLAGS) \
+	$(CBC_CXXFLAGS)
 
 lemon_libemon_la_LDFLAGS = \
@@ -28,5 +32,6 @@
 	$(CPLEX_LIBS) \
 	$(SOPLEX_LIBS) \
-	$(CLP_LIBS)
+	$(CLP_LIBS) \
+	$(CBC_LIBS)
 
 if HAVE_GLPK
@@ -46,10 +51,19 @@
 endif
 
+if HAVE_CBC
+lemon_libemon_la_SOURCES += lemon/cbc.cc
+endif
+
 lemon_HEADERS += \
 	lemon/adaptors.h \
 	lemon/arg_parser.h \
 	lemon/assert.h \
+	lemon/bellman_ford.h \
 	lemon/bfs.h \
 	lemon/bin_heap.h \
+	lemon/binomial_heap.h \
+	lemon/bucket_heap.h \
+	lemon/capacity_scaling.h \
+	lemon/cbc.h \
 	lemon/circulation.h \
 	lemon/clp.h \
@@ -57,8 +71,11 @@
 	lemon/concept_check.h \
 	lemon/connectivity.h \
+	lemon/core.h \
+	lemon/cost_scaling.h \
 	lemon/counter.h \
-	lemon/core.h \
 	lemon/cplex.h \
+	lemon/cycle_canceling.h \
 	lemon/dfs.h \
+	lemon/dheap.h \
 	lemon/dijkstra.h \
 	lemon/dim2.h \
@@ -68,4 +85,6 @@
 	lemon/error.h \
 	lemon/euler.h \
+	lemon/fib_heap.h \
+	lemon/fractional_matching.h \
 	lemon/full_graph.h \
 	lemon/glpk.h \
@@ -73,5 +92,8 @@
 	lemon/graph_to_eps.h \
 	lemon/grid_graph.h \
+	lemon/hartmann_orlin_mmc.h \
+	lemon/howard_mmc.h \
 	lemon/hypercube_graph.h \
+	lemon/karp_mmc.h \
 	lemon/kruskal.h \
 	lemon/hao_orlin.h \
@@ -82,16 +104,21 @@
 	lemon/lp_base.h \
 	lemon/lp_skeleton.h \
-	lemon/list_graph.h \
 	lemon/maps.h \
+	lemon/matching.h \
 	lemon/math.h \
-	lemon/max_matching.h \
 	lemon/min_cost_arborescence.h \
 	lemon/nauty_reader.h \
+	lemon/network_simplex.h \
+	lemon/pairing_heap.h \
 	lemon/path.h \
+	lemon/planarity.h \
 	lemon/preflow.h \
+	lemon/quad_heap.h \
+	lemon/radix_heap.h \
 	lemon/radix_sort.h \
 	lemon/random.h \
 	lemon/smart_graph.h \
 	lemon/soplex.h \
+	lemon/static_graph.h \
 	lemon/suurballe.h \
 	lemon/time_measure.h \
@@ -103,5 +130,4 @@
 	lemon/bits/alteration_notifier.h \
 	lemon/bits/array_map.h \
-	lemon/bits/base_extender.h \
 	lemon/bits/bezier.h \
 	lemon/bits/default_map.h \
Index: lemon/adaptors.h
===================================================================
--- lemon/adaptors.h	(revision 559)
+++ lemon/adaptors.h	(revision 964)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -110,11 +110,9 @@
     template <typename V>
     class NodeMap : public DGR::template NodeMap<V> {
+      typedef typename DGR::template NodeMap<V> Parent;
+
     public:
-
-      typedef typename DGR::template NodeMap<V> Parent;
-
       explicit NodeMap(const Adaptor& adaptor)
         : Parent(*adaptor._digraph) {}
-
       NodeMap(const Adaptor& adaptor, const V& value)
         : Parent(*adaptor._digraph, value) { }
@@ -135,11 +133,9 @@
     template <typename V>
     class ArcMap : public DGR::template ArcMap<V> {
+      typedef typename DGR::template ArcMap<V> Parent;
+
     public:
-
-      typedef typename DGR::template ArcMap<V> Parent;
-
       explicit ArcMap(const DigraphAdaptorBase<DGR>& adaptor)
         : Parent(*adaptor._digraph) {}
-
       ArcMap(const DigraphAdaptorBase<DGR>& adaptor, const V& value)
         : Parent(*adaptor._digraph, value) {}
@@ -256,6 +252,7 @@
     template <typename V>
     class NodeMap : public GR::template NodeMap<V> {
+      typedef typename GR::template NodeMap<V> Parent;
+
     public:
-      typedef typename GR::template NodeMap<V> Parent;
       explicit NodeMap(const GraphAdaptorBase<GR>& adapter)
         : Parent(*adapter._graph) {}
@@ -278,6 +275,7 @@
     template <typename V>
     class ArcMap : public GR::template ArcMap<V> {
+      typedef typename GR::template ArcMap<V> Parent;
+
     public:
-      typedef typename GR::template ArcMap<V> Parent;
       explicit ArcMap(const GraphAdaptorBase<GR>& adapter)
         : Parent(*adapter._graph) {}
@@ -299,6 +297,7 @@
     template <typename V>
     class EdgeMap : public GR::template EdgeMap<V> {
+      typedef typename GR::template EdgeMap<V> Parent;
+
     public:
-      typedef typename GR::template EdgeMap<V> Parent;
       explicit EdgeMap(const GraphAdaptorBase<GR>& adapter)
         : Parent(*adapter._graph) {}
@@ -322,7 +321,7 @@
   template <typename DGR>
   class ReverseDigraphBase : public DigraphAdaptorBase<DGR> {
+    typedef DigraphAdaptorBase<DGR> Parent;
   public:
     typedef DGR Digraph;
-    typedef DigraphAdaptorBase<DGR> Parent;
   protected:
     ReverseDigraphBase() : Parent() { }
@@ -361,4 +360,7 @@
   /// by adding or removing nodes or arcs, unless the \c GR template
   /// parameter is set to be \c const.
+  ///
+  /// This class provides item counting in the same time as the adapted
+  /// digraph structure.
   ///
   /// \tparam DGR The type of the adapted digraph.
@@ -375,8 +377,8 @@
     public DigraphAdaptorExtender<ReverseDigraphBase<DGR> > {
 #endif
+    typedef DigraphAdaptorExtender<ReverseDigraphBase<DGR> > Parent;
   public:
     /// The type of the adapted digraph.
     typedef DGR Digraph;
-    typedef DigraphAdaptorExtender<ReverseDigraphBase<DGR> > Parent;
   protected:
     ReverseDigraph() { }
@@ -404,4 +406,5 @@
   template <typename DGR, typename NF, typename AF, bool ch = true>
   class SubDigraphBase : public DigraphAdaptorBase<DGR> {
+    typedef DigraphAdaptorBase<DGR> Parent;
   public:
     typedef DGR Digraph;
@@ -410,5 +413,4 @@
 
     typedef SubDigraphBase Adaptor;
-    typedef DigraphAdaptorBase<DGR> Parent;
   protected:
     NF* _node_filter;
@@ -420,5 +422,5 @@
       Parent::initialize(digraph);
       _node_filter = &node_filter;
-      _arc_filter = &arc_filter;      
+      _arc_filter = &arc_filter;
     }
 
@@ -507,11 +509,12 @@
 
     template <typename V>
-    class NodeMap 
-      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>, 
-	      LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
+    class NodeMap
+      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
+              LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
+      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
+        LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
+
     public:
       typedef V Value;
-      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
-	    LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
 
       NodeMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor)
@@ -533,11 +536,12 @@
 
     template <typename V>
-    class ArcMap 
+    class ArcMap
       : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
-	      LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
+              LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
+      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
+        LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> Parent;
+
     public:
       typedef V Value;
-      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
-        LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> Parent;
 
       ArcMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor)
@@ -563,4 +567,5 @@
   class SubDigraphBase<DGR, NF, AF, false>
     : public DigraphAdaptorBase<DGR> {
+    typedef DigraphAdaptorBase<DGR> Parent;
   public:
     typedef DGR Digraph;
@@ -569,5 +574,4 @@
 
     typedef SubDigraphBase Adaptor;
-    typedef DigraphAdaptorBase<Digraph> Parent;
   protected:
     NF* _node_filter;
@@ -579,5 +583,5 @@
       Parent::initialize(digraph);
       _node_filter = &node_filter;
-      _arc_filter = &arc_filter;      
+      _arc_filter = &arc_filter;
     }
 
@@ -648,11 +652,12 @@
 
     template <typename V>
-    class NodeMap 
+    class NodeMap
       : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
           LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
+      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
+        LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
+
     public:
       typedef V Value;
-      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>, 
-        LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
 
       NodeMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor)
@@ -674,11 +679,12 @@
 
     template <typename V>
-    class ArcMap 
+    class ArcMap
       : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
           LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
+      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
+        LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> Parent;
+
     public:
       typedef V Value;
-      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
-          LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> Parent;
 
       ArcMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor)
@@ -716,4 +722,6 @@
   /// by adding or removing nodes or arcs, unless the \c GR template
   /// parameter is set to be \c const.
+  ///
+  /// This class provides only linear time counting for nodes and arcs.
   ///
   /// \tparam DGR The type of the adapted digraph.
@@ -864,4 +872,5 @@
   template <typename GR, typename NF, typename EF, bool ch = true>
   class SubGraphBase : public GraphAdaptorBase<GR> {
+    typedef GraphAdaptorBase<GR> Parent;
   public:
     typedef GR Graph;
@@ -870,5 +879,4 @@
 
     typedef SubGraphBase Adaptor;
-    typedef GraphAdaptorBase<GR> Parent;
   protected:
 
@@ -1014,11 +1022,12 @@
 
     template <typename V>
-    class NodeMap 
+    class NodeMap
       : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
           LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> {
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
+
     public:
       typedef V Value;
-      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 
-        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
 
       NodeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor)
@@ -1040,11 +1049,12 @@
 
     template <typename V>
-    class ArcMap 
+    class ArcMap
       : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
           LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> {
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
+
     public:
       typedef V Value;
-      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 
-        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
 
       ArcMap(const SubGraphBase<GR, NF, EF, ch>& adaptor)
@@ -1066,11 +1076,12 @@
 
     template <typename V>
-    class EdgeMap 
+    class EdgeMap
       : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
         LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> {
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
+
     public:
       typedef V Value;
-      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 
-        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
 
       EdgeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor)
@@ -1097,4 +1108,5 @@
   class SubGraphBase<GR, NF, EF, false>
     : public GraphAdaptorBase<GR> {
+    typedef GraphAdaptorBase<GR> Parent;
   public:
     typedef GR Graph;
@@ -1103,10 +1115,9 @@
 
     typedef SubGraphBase Adaptor;
-    typedef GraphAdaptorBase<GR> Parent;
   protected:
     NF* _node_filter;
     EF* _edge_filter;
-    SubGraphBase() 
-	  : Parent(), _node_filter(0), _edge_filter(0) { }
+    SubGraphBase()
+          : Parent(), _node_filter(0), _edge_filter(0) { }
 
     void initialize(GR& graph, NF& node_filter, EF& edge_filter) {
@@ -1209,11 +1220,12 @@
 
     template <typename V>
-    class NodeMap 
+    class NodeMap
       : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
           LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> {
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
+
     public:
       typedef V Value;
-      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 
-        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
 
       NodeMap(const SubGraphBase<GR, NF, EF, false>& adaptor)
@@ -1235,11 +1247,12 @@
 
     template <typename V>
-    class ArcMap 
+    class ArcMap
       : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
           LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> {
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
+
     public:
       typedef V Value;
-      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 
-        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
 
       ArcMap(const SubGraphBase<GR, NF, EF, false>& adaptor)
@@ -1261,11 +1274,12 @@
 
     template <typename V>
-    class EdgeMap 
+    class EdgeMap
       : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
         LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> {
+      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>,
+        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
+
     public:
       typedef V Value;
-      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 
-		  LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
 
       EdgeMap(const SubGraphBase<GR, NF, EF, false>& adaptor)
@@ -1305,4 +1319,6 @@
   /// by adding or removing nodes or edges, unless the \c GR template
   /// parameter is set to be \c const.
+  ///
+  /// This class provides only linear time counting for nodes, edges and arcs.
   ///
   /// \tparam GR The type of the adapted graph.
@@ -1356,5 +1372,5 @@
     /// and edge filter maps.
     SubGraph(GR& graph, NF& node_filter, EF& edge_filter) {
-      initialize(graph, node_filter, edge_filter);
+      this->initialize(graph, node_filter, edge_filter);
     }
 
@@ -1462,4 +1478,6 @@
   /// by adding or removing nodes or arcs/edges, unless the \c GR template
   /// parameter is set to be \c const.
+  ///
+  /// This class provides only linear time item counting.
   ///
   /// \tparam GR The type of the adapted digraph or graph.
@@ -1486,4 +1504,8 @@
                      true> > {
 #endif
+    typedef DigraphAdaptorExtender<
+      SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, Const<bool, true> >,
+                     true> > Parent;
+
   public:
 
@@ -1491,8 +1513,4 @@
     typedef NF NodeFilterMap;
 
-    typedef DigraphAdaptorExtender<
-      SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, Const<bool, true> >, 
-                     true> > Parent;
-
     typedef typename Parent::Node Node;
 
@@ -1508,5 +1526,5 @@
     /// Creates a subgraph for the given digraph or graph with the
     /// given node filter map.
-    FilterNodes(GR& graph, NF& node_filter) 
+    FilterNodes(GR& graph, NF& node_filter)
       : Parent(), const_true_map()
     {
@@ -1546,15 +1564,18 @@
                     typename enable_if<UndirectedTagIndicator<GR> >::type> :
     public GraphAdaptorExtender<
-      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >, 
+      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >,
                    true> > {
 
-  public:
+    typedef GraphAdaptorExtender<
+      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >,
+                   true> > Parent;
+
+  public:
+
     typedef GR Graph;
     typedef NF NodeFilterMap;
-    typedef GraphAdaptorExtender<
-      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >, 
-                   true> > Parent;
 
     typedef typename Parent::Node Node;
+
   protected:
     ConstMap<typename GR::Edge, Const<bool, true> > const_true_map;
@@ -1607,4 +1628,6 @@
   /// by adding or removing nodes or arcs, unless the \c GR template
   /// parameter is set to be \c const.
+  ///
+  /// This class provides only linear time counting for nodes and arcs.
   ///
   /// \tparam DGR The type of the adapted digraph.
@@ -1630,13 +1653,14 @@
                      AF, false> > {
 #endif
-  public:
+    typedef DigraphAdaptorExtender<
+      SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >,
+                     AF, false> > Parent;
+
+  public:
+
     /// The type of the adapted digraph.
     typedef DGR Digraph;
     /// The type of the arc filter map.
     typedef AF ArcFilterMap;
-
-    typedef DigraphAdaptorExtender<
-      SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >, 
-                     AF, false> > Parent;
 
     typedef typename Parent::Arc Arc;
@@ -1716,4 +1740,6 @@
   /// by adding or removing nodes or edges, unless the \c GR template
   /// parameter is set to be \c const.
+  ///
+  /// This class provides only linear time counting for nodes, edges and arcs.
   ///
   /// \tparam GR The type of the adapted graph.
@@ -1736,8 +1762,13 @@
   class FilterEdges :
     public GraphAdaptorExtender<
-      SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true> >, 
+      SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true> >,
                    EF, false> > {
 #endif
-  public:
+    typedef GraphAdaptorExtender<
+      SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true > >,
+                   EF, false> > Parent;
+
+  public:
+
     /// The type of the adapted graph.
     typedef GR Graph;
@@ -1745,8 +1776,4 @@
     typedef EF EdgeFilterMap;
 
-    typedef GraphAdaptorExtender<
-      SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true > >, 
-                   EF, false> > Parent;
-
     typedef typename Parent::Edge Edge;
 
@@ -1764,5 +1791,5 @@
     /// Creates a subgraph for the given graph with the given edge
     /// filter map.
-    FilterEdges(GR& graph, EF& edge_filter) 
+    FilterEdges(GR& graph, EF& edge_filter)
       : Parent(), const_true_map() {
       Parent::initialize(graph, const_true_map, edge_filter);
@@ -1826,29 +1853,29 @@
     typedef typename Digraph::Node Node;
 
-    class Arc : public Edge {
+    class Arc {
       friend class UndirectorBase;
     protected:
+      Edge _edge;
       bool _forward;
 
-      Arc(const Edge& edge, bool forward) :
-        Edge(edge), _forward(forward) {}
+      Arc(const Edge& edge, bool forward)
+        : _edge(edge), _forward(forward) {}
 
     public:
       Arc() {}
 
-      Arc(Invalid) : Edge(INVALID), _forward(true) {}
+      Arc(Invalid) : _edge(INVALID), _forward(true) {}
+
+      operator const Edge&() const { return _edge; }
 
       bool operator==(const Arc &other) const {
-        return _forward == other._forward &&
-          static_cast<const Edge&>(*this) == static_cast<const Edge&>(other);
+        return _forward == other._forward && _edge == other._edge;
       }
       bool operator!=(const Arc &other) const {
-        return _forward != other._forward ||
-          static_cast<const Edge&>(*this) != static_cast<const Edge&>(other);
+        return _forward != other._forward || _edge != other._edge;
       }
       bool operator<(const Arc &other) const {
         return _forward < other._forward ||
-          (_forward == other._forward &&
-           static_cast<const Edge&>(*this) < static_cast<const Edge&>(other));
+          (_forward == other._forward && _edge < other._edge);
       }
     };
@@ -1863,5 +1890,5 @@
 
     void first(Arc& a) const {
-      _digraph->first(a);
+      _digraph->first(a._edge);
       a._forward = true;
     }
@@ -1871,5 +1898,5 @@
         a._forward = false;
       } else {
-        _digraph->next(a);
+        _digraph->next(a._edge);
         a._forward = true;
       }
@@ -1885,9 +1912,9 @@
 
     void firstOut(Arc& a, const Node& n) const {
-      _digraph->firstIn(a, n);
-      if( static_cast<const Edge&>(a) != INVALID ) {
+      _digraph->firstIn(a._edge, n);
+      if (a._edge != INVALID ) {
         a._forward = false;
       } else {
-        _digraph->firstOut(a, n);
+        _digraph->firstOut(a._edge, n);
         a._forward = true;
       }
@@ -1895,22 +1922,22 @@
     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);
+        Node n = _digraph->target(a._edge);
+        _digraph->nextIn(a._edge);
+        if (a._edge == INVALID) {
+          _digraph->firstOut(a._edge, n);
           a._forward = true;
         }
       }
       else {
-        _digraph->nextOut(a);
+        _digraph->nextOut(a._edge);
       }
     }
 
     void firstIn(Arc &a, const Node &n) const {
-      _digraph->firstOut(a, n);
-      if (static_cast<const Edge&>(a) != INVALID ) {
+      _digraph->firstOut(a._edge, n);
+      if (a._edge != INVALID ) {
         a._forward = false;
       } else {
-        _digraph->firstIn(a, n);
+        _digraph->firstIn(a._edge, n);
         a._forward = true;
       }
@@ -1918,13 +1945,13 @@
     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);
+        Node n = _digraph->source(a._edge);
+        _digraph->nextOut(a._edge);
+        if (a._edge == INVALID ) {
+          _digraph->firstIn(a._edge, n);
           a._forward = true;
         }
       }
       else {
-        _digraph->nextIn(a);
+        _digraph->nextIn(a._edge);
       }
     }
@@ -1959,16 +1986,13 @@
 
     Node source(const Arc &a) const {
-      return a._forward ? _digraph->source(a) : _digraph->target(a);
+      return a._forward ? _digraph->source(a._edge) : _digraph->target(a._edge);
     }
 
     Node target(const Arc &a) const {
-      return a._forward ? _digraph->target(a) : _digraph->source(a);
+      return a._forward ? _digraph->target(a._edge) : _digraph->source(a._edge);
     }
 
     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);
     }
 
@@ -2075,5 +2099,5 @@
 
       ArcMapBase(const UndirectorBase<DGR>& adaptor, const V& value)
-        : _forward(*adaptor._digraph, value), 
+        : _forward(*adaptor._digraph, value),
           _backward(*adaptor._digraph, value) {}
 
@@ -2112,8 +2136,8 @@
     template <typename V>
     class NodeMap : public DGR::template NodeMap<V> {
+      typedef typename DGR::template NodeMap<V> Parent;
+
     public:
-
       typedef V Value;
-      typedef typename DGR::template NodeMap<Value> Parent;
 
       explicit NodeMap(const UndirectorBase<DGR>& adaptor)
@@ -2138,9 +2162,9 @@
     template <typename V>
     class ArcMap
-      : public SubMapExtender<UndirectorBase<DGR>, ArcMapBase<V> >
-    {
+      : public SubMapExtender<UndirectorBase<DGR>, ArcMapBase<V> > {
+      typedef SubMapExtender<UndirectorBase<DGR>, ArcMapBase<V> > Parent;
+
     public:
       typedef V Value;
-      typedef SubMapExtender<Adaptor, ArcMapBase<V> > Parent;
 
       explicit ArcMap(const UndirectorBase<DGR>& adaptor)
@@ -2164,8 +2188,8 @@
     template <typename V>
     class EdgeMap : public Digraph::template ArcMap<V> {
+      typedef typename Digraph::template ArcMap<V> Parent;
+
     public:
-
       typedef V Value;
-      typedef typename Digraph::template ArcMap<V> Parent;
 
       explicit EdgeMap(const UndirectorBase<DGR>& adaptor)
@@ -2194,4 +2218,7 @@
     EdgeNotifier& notifier(Edge) const { return _digraph->notifier(Edge()); }
 
+    typedef EdgeNotifier ArcNotifier;
+    ArcNotifier& notifier(Arc) const { return _digraph->notifier(Edge()); }
+
   protected:
 
@@ -2218,4 +2245,7 @@
   /// by adding or removing nodes or edges, unless the \c GR template
   /// parameter is set to be \c const.
+  ///
+  /// This class provides item counting in the same time as the adapted
+  /// digraph structure.
   ///
   /// \tparam DGR The type of the adapted digraph.
@@ -2236,8 +2266,8 @@
     public GraphAdaptorExtender<UndirectorBase<DGR> > {
 #endif
+    typedef GraphAdaptorExtender<UndirectorBase<DGR> > Parent;
   public:
     /// The type of the adapted digraph.
     typedef DGR Digraph;
-    typedef GraphAdaptorExtender<UndirectorBase<DGR> > Parent;
   protected:
     Undirector() { }
@@ -2248,5 +2278,5 @@
     /// Creates an undirected graph from the given digraph.
     Undirector(DGR& digraph) {
-      initialize(digraph);
+      this->initialize(digraph);
     }
 
@@ -2447,7 +2477,7 @@
     template <typename V>
     class NodeMap : public GR::template NodeMap<V> {
+      typedef typename GR::template NodeMap<V> Parent;
+
     public:
-
-      typedef typename GR::template NodeMap<V> Parent;
 
       explicit NodeMap(const OrienterBase<GR, DM>& adapter)
@@ -2472,7 +2502,7 @@
     template <typename V>
     class ArcMap : public GR::template EdgeMap<V> {
+      typedef typename Graph::template EdgeMap<V> Parent;
+
     public:
-
-      typedef typename Graph::template EdgeMap<V> Parent;
 
       explicit ArcMap(const OrienterBase<GR, DM>& adapter)
@@ -2521,4 +2551,7 @@
   /// by adding or removing nodes or arcs, unless the \c GR template
   /// parameter is set to be \c const.
+  ///
+  /// This class provides item counting in the same time as the adapted
+  /// graph structure.
   ///
   /// \tparam GR The type of the adapted graph.
@@ -2544,4 +2577,5 @@
     public DigraphAdaptorExtender<OrienterBase<GR, DM> > {
 #endif
+    typedef DigraphAdaptorExtender<OrienterBase<GR, DM> > Parent;
   public:
 
@@ -2551,8 +2585,9 @@
     typedef DM DirectionMap;
 
-    typedef DigraphAdaptorExtender<OrienterBase<GR, DM> > Parent;
     typedef typename Parent::Arc Arc;
+
   protected:
     Orienter() { }
+
   public:
 
@@ -2663,4 +2698,6 @@
   /// This class conforms to the \ref concepts::Digraph "Digraph" concept.
   ///
+  /// This class provides only linear time counting for nodes and arcs.
+  ///
   /// \tparam DGR The type of the adapted digraph.
   /// It must conform to the \ref concepts::Digraph "Digraph" concept.
@@ -2692,5 +2729,5 @@
            typename FM = CM,
            typename TL = Tolerance<typename CM::Value> >
-  class ResidualDigraph 
+  class ResidualDigraph
     : public SubDigraph<
         Undirector<const DGR>,
@@ -2749,5 +2786,5 @@
     ResidualDigraph(const DGR& digraph, const CM& capacity,
                     FM& flow, const TL& tolerance = Tolerance())
-      : Parent(), _capacity(&capacity), _flow(&flow), 
+      : Parent(), _capacity(&capacity), _flow(&flow),
         _graph(digraph), _node_filter(),
         _forward_filter(capacity, flow, tolerance),
@@ -2831,5 +2868,5 @@
 
       /// Constructor
-      ResidualCapacity(const ResidualDigraph<DGR, CM, FM, TL>& adaptor) 
+      ResidualCapacity(const ResidualDigraph<DGR, CM, FM, TL>& adaptor)
         : _adaptor(&adaptor) {}
 
@@ -2864,8 +2901,9 @@
   template <typename DGR>
   class SplitNodesBase {
+    typedef DigraphAdaptorBase<const DGR> Parent;
+
   public:
 
     typedef DGR Digraph;
-    typedef DigraphAdaptorBase<const DGR> Parent;
     typedef SplitNodesBase Adaptor;
 
@@ -3226,9 +3264,9 @@
     template <typename V>
     class NodeMap
-      : public SubMapExtender<SplitNodesBase<DGR>, NodeMapBase<V> >
-    {
+      : public SubMapExtender<SplitNodesBase<DGR>, NodeMapBase<V> > {
+      typedef SubMapExtender<SplitNodesBase<DGR>, NodeMapBase<V> > Parent;
+
     public:
       typedef V Value;
-      typedef SubMapExtender<SplitNodesBase<DGR>, NodeMapBase<Value> > Parent;
 
       NodeMap(const SplitNodesBase<DGR>& adaptor)
@@ -3252,9 +3290,9 @@
     template <typename V>
     class ArcMap
-      : public SubMapExtender<SplitNodesBase<DGR>, ArcMapBase<V> >
-    {
+      : public SubMapExtender<SplitNodesBase<DGR>, ArcMapBase<V> > {
+      typedef SubMapExtender<SplitNodesBase<DGR>, ArcMapBase<V> > Parent;
+
     public:
       typedef V Value;
-      typedef SubMapExtender<SplitNodesBase<DGR>, ArcMapBase<Value> > Parent;
 
       ArcMap(const SplitNodesBase<DGR>& adaptor)
@@ -3309,4 +3347,7 @@
   /// in the adaptor.
   ///
+  /// This class provides item counting in the same time as the adapted
+  /// digraph structure.
+  ///
   /// \tparam DGR The type of the adapted digraph.
   /// It must conform to the \ref concepts::Digraph "Digraph" concept.
@@ -3322,7 +3363,8 @@
     : public DigraphAdaptorExtender<SplitNodesBase<const DGR> > {
 #endif
+    typedef DigraphAdaptorExtender<SplitNodesBase<const DGR> > Parent;
+
   public:
     typedef DGR Digraph;
-    typedef DigraphAdaptorExtender<SplitNodesBase<const DGR> > Parent;
 
     typedef typename DGR::Node DigraphNode;
@@ -3406,5 +3448,5 @@
     /// to get a node map of the split digraph.
     /// Its value type is inherited from the first node map type (\c IN).
-    /// \tparam IN The type of the node map for the in-nodes. 
+    /// \tparam IN The type of the node map for the in-nodes.
     /// \tparam OUT The type of the node map for the out-nodes.
     template <typename IN, typename OUT>
Index: lemon/arg_parser.cc
===================================================================
--- lemon/arg_parser.cc	(revision 440)
+++ lemon/arg_parser.cc	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -21,12 +21,21 @@
 namespace lemon {
 
+  void ArgParser::_terminate(ArgParserException::Reason reason) const
+  {
+    if(_exit_on_problems)
+      exit(1);
+    else throw(ArgParserException(reason));
+  }
+
+
   void ArgParser::_showHelp(void *p)
   {
     (static_cast<ArgParser*>(p))->showHelp();
-    exit(1);
+    (static_cast<ArgParser*>(p))->_terminate(ArgParserException::HELP);
   }
 
   ArgParser::ArgParser(int argc, const char * const *argv)
-    :_argc(argc), _argv(argv), _command_name(argv[0]) {
+    :_argc(argc), _argv(argv), _command_name(argv[0]),
+    _exit_on_problems(true) {
     funcOption("-help","Print a short help message",_showHelp,this);
     synonym("help","-help");
@@ -343,5 +352,5 @@
         i!=_others_help.end();++i) showHelp(i);
     for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i) showHelp(i);
-    exit(1);
+    _terminate(ArgParserException::HELP);
   }
 
@@ -352,5 +361,5 @@
     std::cerr << "\nType '" << _command_name <<
       " --help' to obtain a short summary on the usage.\n\n";
-    exit(1);
+    _terminate(ArgParserException::UNKNOWN_OPT);
   }
 
@@ -415,5 +424,5 @@
       std::cerr << "\nType '" << _command_name <<
         " --help' to obtain a short summary on the usage.\n\n";
-      exit(1);
+      _terminate(ArgParserException::INVALID_OPT);
     }
   }
Index: lemon/arg_parser.h
===================================================================
--- lemon/arg_parser.h	(revision 440)
+++ lemon/arg_parser.h	(revision 880)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -35,4 +35,49 @@
 namespace lemon {
 
+  ///Exception used by ArgParser
+
+  ///Exception used by ArgParser.
+  ///
+  class ArgParserException : public Exception {
+  public:
+    /// Reasons for failure
+
+    /// Reasons for failure.
+    ///
+    enum Reason {
+      HELP,         ///< <tt>--help</tt> option was given.
+      UNKNOWN_OPT,  ///< Unknown option was given.
+      INVALID_OPT   ///< Invalid combination of options.
+    };
+
+  private:
+    Reason _reason;
+
+  public:
+    ///Constructor
+    ArgParserException(Reason r) throw() : _reason(r) {}
+    ///Virtual destructor
+    virtual ~ArgParserException() throw() {}
+    ///A short description of the exception
+    virtual const char* what() const throw() {
+      switch(_reason)
+        {
+        case HELP:
+          return "lemon::ArgParseException: ask for help";
+          break;
+        case UNKNOWN_OPT:
+          return "lemon::ArgParseException: unknown option";
+          break;
+        case INVALID_OPT:
+          return "lemon::ArgParseException: invalid combination of options";
+          break;
+        }
+      return "";
+    }
+    ///Return the reason for the failure
+    Reason reason() const {return _reason; }
+  };
+
+
   ///Command line arguments parser
 
@@ -116,4 +161,8 @@
                     const std::string &help,
                     void (*func)(void *),void *data);
+
+    bool _exit_on_problems;
+
+    void _terminate(ArgParserException::Reason reason) const;
 
   public:
@@ -381,4 +430,9 @@
     const std::vector<std::string> &files() const { return _file_args; }
 
+    ///Throw instead of exit in case of problems
+    void throwOnProblems()
+    {
+      _exit_on_problems=false;
+    }
   };
 }
Index: lemon/assert.h
===================================================================
--- lemon/assert.h	(revision 440)
+++ lemon/assert.h	(revision 977)
@@ -200,5 +200,5 @@
                              ::lemon::_assert_bits::cstringify(msg),    \
                              #exp), 0)))
-#    if LEMON_ENABLE_DEBUG
+#    if defined LEMON_ENABLE_DEBUG
 #      define LEMON_DEBUG(exp, msg)                                     \
          (static_cast<void> (!!(exp) ? 0 : (                            \
Index: lemon/bellman_ford.h
===================================================================
--- lemon/bellman_ford.h	(revision 881)
+++ lemon/bellman_ford.h	(revision 881)
@@ -0,0 +1,1115 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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_BELLMAN_FORD_H
+#define LEMON_BELLMAN_FORD_H
+
+/// \ingroup shortest_path
+/// \file
+/// \brief Bellman-Ford algorithm.
+
+#include <lemon/list_graph.h>
+#include <lemon/bits/path_dump.h>
+#include <lemon/core.h>
+#include <lemon/error.h>
+#include <lemon/maps.h>
+#include <lemon/path.h>
+
+#include <limits>
+
+namespace lemon {
+
+  /// \brief Default OperationTraits for the BellmanFord algorithm class.
+  ///
+  /// This operation traits class defines all computational operations
+  /// and constants that are used in the Bellman-Ford algorithm.
+  /// The default implementation is based on the \c numeric_limits class.
+  /// If the numeric type does not have infinity value, then the maximum
+  /// value is used as extremal infinity value.
+  template <
+    typename V,
+    bool has_inf = std::numeric_limits<V>::has_infinity>
+  struct BellmanFordDefaultOperationTraits {
+    /// \e
+    typedef V Value;
+    /// \brief Gives back the zero value of the type.
+    static Value zero() {
+      return static_cast<Value>(0);
+    }
+    /// \brief Gives back the positive infinity value of the type.
+    static Value infinity() {
+      return std::numeric_limits<Value>::infinity();
+    }
+    /// \brief Gives back the sum of the given two elements.
+    static Value plus(const Value& left, const Value& right) {
+      return left + right;
+    }
+    /// \brief Gives back \c true only if the first value is less than
+    /// the second.
+    static bool less(const Value& left, const Value& right) {
+      return left < right;
+    }
+  };
+
+  template <typename V>
+  struct BellmanFordDefaultOperationTraits<V, false> {
+    typedef V Value;
+    static Value zero() {
+      return static_cast<Value>(0);
+    }
+    static Value infinity() {
+      return std::numeric_limits<Value>::max();
+    }
+    static Value plus(const Value& left, const Value& right) {
+      if (left == infinity() || right == infinity()) return infinity();
+      return left + right;
+    }
+    static bool less(const Value& left, const Value& right) {
+      return left < right;
+    }
+  };
+
+  /// \brief Default traits class of BellmanFord class.
+  ///
+  /// Default traits class of BellmanFord class.
+  /// \param GR The type of the digraph.
+  /// \param LEN The type of the length map.
+  template<typename GR, typename LEN>
+  struct BellmanFordDefaultTraits {
+    /// The type of the digraph the algorithm runs on.
+    typedef GR Digraph;
+
+    /// \brief The type of the map that stores the arc lengths.
+    ///
+    /// The type of the map that stores the arc lengths.
+    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+    typedef LEN LengthMap;
+
+    /// The type of the arc lengths.
+    typedef typename LEN::Value Value;
+
+    /// \brief Operation traits for Bellman-Ford algorithm.
+    ///
+    /// It defines the used operations and the infinity value for the
+    /// given \c Value type.
+    /// \see BellmanFordDefaultOperationTraits
+    typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
+
+    /// \brief The type of the map that stores the last arcs of the
+    /// shortest paths.
+    ///
+    /// The type of the map that stores the last
+    /// arcs of the shortest paths.
+    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename GR::template NodeMap<typename GR::Arc> PredMap;
+
+    /// \brief Instantiates a \c PredMap.
+    ///
+    /// This function instantiates a \ref PredMap.
+    /// \param g is the digraph to which we would like to define the
+    /// \ref PredMap.
+    static PredMap *createPredMap(const GR& g) {
+      return new PredMap(g);
+    }
+
+    /// \brief The type of the map that stores the distances of the nodes.
+    ///
+    /// The type of the map that stores the distances of the nodes.
+    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename GR::template NodeMap<typename LEN::Value> DistMap;
+
+    /// \brief Instantiates a \c DistMap.
+    ///
+    /// This function instantiates a \ref DistMap.
+    /// \param g is the digraph to which we would like to define the
+    /// \ref DistMap.
+    static DistMap *createDistMap(const GR& g) {
+      return new DistMap(g);
+    }
+
+  };
+
+  /// \brief %BellmanFord algorithm class.
+  ///
+  /// \ingroup shortest_path
+  /// This class provides an efficient implementation of the Bellman-Ford
+  /// algorithm. The maximum time complexity of the algorithm is
+  /// <tt>O(ne)</tt>.
+  ///
+  /// The Bellman-Ford algorithm solves the single-source shortest path
+  /// problem when the arcs can have negative lengths, but the digraph
+  /// should not contain directed cycles with negative total length.
+  /// If all arc costs are non-negative, consider to use the Dijkstra
+  /// algorithm instead, since it is more efficient.
+  ///
+  /// The arc lengths are passed to the algorithm using a
+  /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any
+  /// kind of length. The type of the length values is determined by the
+  /// \ref concepts::ReadMap::Value "Value" type of the length map.
+  ///
+  /// There is also a \ref bellmanFord() "function-type interface" for the
+  /// Bellman-Ford algorithm, which is convenient in the simplier cases and
+  /// it can be used easier.
+  ///
+  /// \tparam GR The type of the digraph the algorithm runs on.
+  /// The default type is \ref ListDigraph.
+  /// \tparam LEN A \ref concepts::ReadMap "readable" arc map that specifies
+  /// the lengths of the arcs. The default map type is
+  /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm. By default, it is \ref BellmanFordDefaultTraits
+  /// "BellmanFordDefaultTraits<GR, LEN>".
+  /// In most cases, this parameter should not be set directly,
+  /// consider to use the named template parameters instead.
+#ifdef DOXYGEN
+  template <typename GR, typename LEN, typename TR>
+#else
+  template <typename GR=ListDigraph,
+            typename LEN=typename GR::template ArcMap<int>,
+            typename TR=BellmanFordDefaultTraits<GR,LEN> >
+#endif
+  class BellmanFord {
+  public:
+
+    ///The type of the underlying digraph.
+    typedef typename TR::Digraph Digraph;
+
+    /// \brief The type of the arc lengths.
+    typedef typename TR::LengthMap::Value Value;
+    /// \brief The type of the map that stores the arc lengths.
+    typedef typename TR::LengthMap LengthMap;
+    /// \brief The type of the map that stores the last
+    /// arcs of the shortest paths.
+    typedef typename TR::PredMap PredMap;
+    /// \brief The type of the map that stores the distances of the nodes.
+    typedef typename TR::DistMap DistMap;
+    /// The type of the paths.
+    typedef PredMapPath<Digraph, PredMap> Path;
+    ///\brief The \ref BellmanFordDefaultOperationTraits
+    /// "operation traits class" of the algorithm.
+    typedef typename TR::OperationTraits OperationTraits;
+
+    ///The \ref BellmanFordDefaultTraits "traits class" of the algorithm.
+    typedef TR Traits;
+
+  private:
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::OutArcIt OutArcIt;
+
+    // Pointer to the underlying digraph.
+    const Digraph *_gr;
+    // Pointer to the length map
+    const LengthMap *_length;
+    // Pointer to the map of predecessors arcs.
+    PredMap *_pred;
+    // Indicates if _pred is locally allocated (true) or not.
+    bool _local_pred;
+    // Pointer to the map of distances.
+    DistMap *_dist;
+    // Indicates if _dist is locally allocated (true) or not.
+    bool _local_dist;
+
+    typedef typename Digraph::template NodeMap<bool> MaskMap;
+    MaskMap *_mask;
+
+    std::vector<Node> _process;
+
+    // Creates the maps if necessary.
+    void create_maps() {
+      if(!_pred) {
+        _local_pred = true;
+        _pred = Traits::createPredMap(*_gr);
+      }
+      if(!_dist) {
+        _local_dist = true;
+        _dist = Traits::createDistMap(*_gr);
+      }
+      if(!_mask) {
+        _mask = new MaskMap(*_gr);
+      }
+    }
+
+  public :
+
+    typedef BellmanFord Create;
+
+    /// \name Named Template Parameters
+
+    ///@{
+
+    template <class T>
+    struct SetPredMapTraits : public Traits {
+      typedef T PredMap;
+      static PredMap *createPredMap(const Digraph&) {
+        LEMON_ASSERT(false, "PredMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c PredMap type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting
+    /// \c PredMap type.
+    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    template <class T>
+    struct SetPredMap
+      : public BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > {
+      typedef BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > Create;
+    };
+
+    template <class T>
+    struct SetDistMapTraits : public Traits {
+      typedef T DistMap;
+      static DistMap *createDistMap(const Digraph&) {
+        LEMON_ASSERT(false, "DistMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c DistMap type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting
+    /// \c DistMap type.
+    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    template <class T>
+    struct SetDistMap
+      : public BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > {
+      typedef BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > Create;
+    };
+
+    template <class T>
+    struct SetOperationTraitsTraits : public Traits {
+      typedef T OperationTraits;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c OperationTraits type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting
+    /// \c OperationTraits type.
+    /// For more information, see \ref BellmanFordDefaultOperationTraits.
+    template <class T>
+    struct SetOperationTraits
+      : public BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits<T> > {
+      typedef BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits<T> >
+      Create;
+    };
+
+    ///@}
+
+  protected:
+
+    BellmanFord() {}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param g The digraph the algorithm runs on.
+    /// \param length The length map used by the algorithm.
+    BellmanFord(const Digraph& g, const LengthMap& length) :
+      _gr(&g), _length(&length),
+      _pred(0), _local_pred(false),
+      _dist(0), _local_dist(false), _mask(0) {}
+
+    ///Destructor.
+    ~BellmanFord() {
+      if(_local_pred) delete _pred;
+      if(_local_dist) delete _dist;
+      if(_mask) delete _mask;
+    }
+
+    /// \brief Sets the length map.
+    ///
+    /// Sets the length map.
+    /// \return <tt>(*this)</tt>
+    BellmanFord &lengthMap(const LengthMap &map) {
+      _length = &map;
+      return *this;
+    }
+
+    /// \brief Sets the map that stores the predecessor arcs.
+    ///
+    /// Sets the map that stores the predecessor arcs.
+    /// 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>
+    BellmanFord &predMap(PredMap &map) {
+      if(_local_pred) {
+        delete _pred;
+        _local_pred=false;
+      }
+      _pred = &map;
+      return *this;
+    }
+
+    /// \brief Sets the map that stores the distances of the nodes.
+    ///
+    /// 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()
+    /// or \ref init(), an instance will be allocated automatically.
+    /// The destructor deallocates this automatically allocated map,
+    /// of course.
+    /// \return <tt>(*this)</tt>
+    BellmanFord &distMap(DistMap &map) {
+      if(_local_dist) {
+        delete _dist;
+        _local_dist=false;
+      }
+      _dist = &map;
+      return *this;
+    }
+
+    /// \name Execution Control
+    /// The simplest way to execute the Bellman-Ford algorithm is to use
+    /// one of the member functions called \ref run().\n
+    /// If you need better control on the execution, you have to call
+    /// \ref init() first, then you can add several source nodes
+    /// with \ref addSource(). Finally the actual path computation can be
+    /// performed with \ref start(), \ref checkedStart() or
+    /// \ref limitedStart().
+
+    ///@{
+
+    /// \brief Initializes the internal data structures.
+    ///
+    /// Initializes the internal data structures. The optional parameter
+    /// is the initial distance of each node.
+    void init(const Value value = OperationTraits::infinity()) {
+      create_maps();
+      for (NodeIt it(*_gr); it != INVALID; ++it) {
+        _pred->set(it, INVALID);
+        _dist->set(it, value);
+      }
+      _process.clear();
+      if (OperationTraits::less(value, OperationTraits::infinity())) {
+        for (NodeIt it(*_gr); it != INVALID; ++it) {
+          _process.push_back(it);
+          _mask->set(it, true);
+        }
+      } else {
+        for (NodeIt it(*_gr); it != INVALID; ++it) {
+          _mask->set(it, false);
+        }
+      }
+    }
+
+    /// \brief Adds a new source node.
+    ///
+    /// This function adds a new source node. The optional second parameter
+    /// is the initial distance of the node.
+    void addSource(Node source, Value dst = OperationTraits::zero()) {
+      _dist->set(source, dst);
+      if (!(*_mask)[source]) {
+        _process.push_back(source);
+        _mask->set(source, true);
+      }
+    }
+
+    /// \brief Executes one round from the Bellman-Ford algorithm.
+    ///
+    /// If the algoritm calculated the distances in the previous round
+    /// exactly for the paths of at most \c k arcs, then this function
+    /// will calculate the distances exactly for the paths of at most
+    /// <tt>k+1</tt> arcs. Performing \c k iterations using this function
+    /// calculates the shortest path distances exactly for the paths
+    /// consisting of at most \c k arcs.
+    ///
+    /// \warning The paths with limited arc number cannot be retrieved
+    /// easily with \ref path() or \ref predArc() functions. If you also
+    /// need the shortest paths and not only the distances, you should
+    /// store the \ref predMap() "predecessor map" after each iteration
+    /// and build the path manually.
+    ///
+    /// \return \c true when the algorithm have not found more shorter
+    /// paths.
+    ///
+    /// \see ActiveIt
+    bool processNextRound() {
+      for (int i = 0; i < int(_process.size()); ++i) {
+        _mask->set(_process[i], false);
+      }
+      std::vector<Node> nextProcess;
+      std::vector<Value> values(_process.size());
+      for (int i = 0; i < int(_process.size()); ++i) {
+        values[i] = (*_dist)[_process[i]];
+      }
+      for (int i = 0; i < int(_process.size()); ++i) {
+        for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
+          Node target = _gr->target(it);
+          Value relaxed = OperationTraits::plus(values[i], (*_length)[it]);
+          if (OperationTraits::less(relaxed, (*_dist)[target])) {
+            _pred->set(target, it);
+            _dist->set(target, relaxed);
+            if (!(*_mask)[target]) {
+              _mask->set(target, true);
+              nextProcess.push_back(target);
+            }
+          }
+        }
+      }
+      _process.swap(nextProcess);
+      return _process.empty();
+    }
+
+    /// \brief Executes one weak round from the Bellman-Ford algorithm.
+    ///
+    /// If the algorithm calculated the distances in the previous round
+    /// at least for the paths of at most \c k arcs, then this function
+    /// will calculate the distances at least for the paths of at most
+    /// <tt>k+1</tt> arcs.
+    /// This function does not make it possible to calculate the shortest
+    /// path distances exactly for paths consisting of at most \c k arcs,
+    /// this is why it is called weak round.
+    ///
+    /// \return \c true when the algorithm have not found more shorter
+    /// paths.
+    ///
+    /// \see ActiveIt
+    bool processNextWeakRound() {
+      for (int i = 0; i < int(_process.size()); ++i) {
+        _mask->set(_process[i], false);
+      }
+      std::vector<Node> nextProcess;
+      for (int i = 0; i < int(_process.size()); ++i) {
+        for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
+          Node target = _gr->target(it);
+          Value relaxed =
+            OperationTraits::plus((*_dist)[_process[i]], (*_length)[it]);
+          if (OperationTraits::less(relaxed, (*_dist)[target])) {
+            _pred->set(target, it);
+            _dist->set(target, relaxed);
+            if (!(*_mask)[target]) {
+              _mask->set(target, true);
+              nextProcess.push_back(target);
+            }
+          }
+        }
+      }
+      _process.swap(nextProcess);
+      return _process.empty();
+    }
+
+    /// \brief Executes the algorithm.
+    ///
+    /// Executes the algorithm.
+    ///
+    /// This method runs the Bellman-Ford algorithm from the root node(s)
+    /// in order to compute the shortest path to each node.
+    ///
+    /// The algorithm computes
+    /// - the shortest path tree (forest),
+    /// - the distance of each node from the root(s).
+    ///
+    /// \pre init() must be called and at least one root node should be
+    /// added with addSource() before using this function.
+    void start() {
+      int num = countNodes(*_gr) - 1;
+      for (int i = 0; i < num; ++i) {
+        if (processNextWeakRound()) break;
+      }
+    }
+
+    /// \brief Executes the algorithm and checks the negative cycles.
+    ///
+    /// Executes the algorithm and checks the negative cycles.
+    ///
+    /// This method runs the Bellman-Ford algorithm from the root node(s)
+    /// in order to compute the shortest path to each node and also checks
+    /// if the digraph contains cycles with negative total length.
+    ///
+    /// The algorithm computes
+    /// - the shortest path tree (forest),
+    /// - the distance of each node from the root(s).
+    ///
+    /// \return \c false if there is a negative cycle in the digraph.
+    ///
+    /// \pre init() must be called and at least one root node should be
+    /// added with addSource() before using this function.
+    bool checkedStart() {
+      int num = countNodes(*_gr);
+      for (int i = 0; i < num; ++i) {
+        if (processNextWeakRound()) return true;
+      }
+      return _process.empty();
+    }
+
+    /// \brief Executes the algorithm with arc number limit.
+    ///
+    /// Executes the algorithm with arc number limit.
+    ///
+    /// This method runs the Bellman-Ford algorithm from the root node(s)
+    /// in order to compute the shortest path distance for each node
+    /// using only the paths consisting of at most \c num arcs.
+    ///
+    /// The algorithm computes
+    /// - the limited distance of each node from the root(s),
+    /// - the predecessor arc for each node.
+    ///
+    /// \warning The paths with limited arc number cannot be retrieved
+    /// easily with \ref path() or \ref predArc() functions. If you also
+    /// need the shortest paths and not only the distances, you should
+    /// store the \ref predMap() "predecessor map" after each iteration
+    /// and build the path manually.
+    ///
+    /// \pre init() must be called and at least one root node should be
+    /// added with addSource() before using this function.
+    void limitedStart(int num) {
+      for (int i = 0; i < num; ++i) {
+        if (processNextRound()) break;
+      }
+    }
+
+    /// \brief Runs the algorithm from the given root node.
+    ///
+    /// This method runs the Bellman-Ford algorithm from the given root
+    /// node \c s in order to compute the shortest path to each node.
+    ///
+    /// The algorithm computes
+    /// - the shortest path tree (forest),
+    /// - the distance of each node from the root(s).
+    ///
+    /// \note bf.run(s) is just a shortcut of the following code.
+    /// \code
+    ///   bf.init();
+    ///   bf.addSource(s);
+    ///   bf.start();
+    /// \endcode
+    void run(Node s) {
+      init();
+      addSource(s);
+      start();
+    }
+
+    /// \brief Runs the algorithm from the given root node with arc
+    /// number limit.
+    ///
+    /// This method runs the Bellman-Ford algorithm from the given root
+    /// node \c s in order to compute the shortest path distance for each
+    /// node using only the paths consisting of at most \c num arcs.
+    ///
+    /// The algorithm computes
+    /// - the limited distance of each node from the root(s),
+    /// - the predecessor arc for each node.
+    ///
+    /// \warning The paths with limited arc number cannot be retrieved
+    /// easily with \ref path() or \ref predArc() functions. If you also
+    /// need the shortest paths and not only the distances, you should
+    /// store the \ref predMap() "predecessor map" after each iteration
+    /// and build the path manually.
+    ///
+    /// \note bf.run(s, num) is just a shortcut of the following code.
+    /// \code
+    ///   bf.init();
+    ///   bf.addSource(s);
+    ///   bf.limitedStart(num);
+    /// \endcode
+    void run(Node s, int num) {
+      init();
+      addSource(s);
+      limitedStart(num);
+    }
+
+    ///@}
+
+    /// \brief LEMON iterator for getting the active nodes.
+    ///
+    /// This class provides a common style LEMON iterator that traverses
+    /// the active nodes of the Bellman-Ford algorithm after the last
+    /// phase. These nodes should be checked in the next phase to
+    /// find augmenting arcs outgoing from them.
+    class ActiveIt {
+    public:
+
+      /// \brief Constructor.
+      ///
+      /// Constructor for getting the active nodes of the given BellmanFord
+      /// instance.
+      ActiveIt(const BellmanFord& algorithm) : _algorithm(&algorithm)
+      {
+        _index = _algorithm->_process.size() - 1;
+      }
+
+      /// \brief Invalid constructor.
+      ///
+      /// Invalid constructor.
+      ActiveIt(Invalid) : _algorithm(0), _index(-1) {}
+
+      /// \brief Conversion to \c Node.
+      ///
+      /// Conversion to \c Node.
+      operator Node() const {
+        return _index >= 0 ? _algorithm->_process[_index] : INVALID;
+      }
+
+      /// \brief Increment operator.
+      ///
+      /// Increment operator.
+      ActiveIt& operator++() {
+        --_index;
+        return *this;
+      }
+
+      bool operator==(const ActiveIt& it) const {
+        return static_cast<Node>(*this) == static_cast<Node>(it);
+      }
+      bool operator!=(const ActiveIt& it) const {
+        return static_cast<Node>(*this) != static_cast<Node>(it);
+      }
+      bool operator<(const ActiveIt& it) const {
+        return static_cast<Node>(*this) < static_cast<Node>(it);
+      }
+
+    private:
+      const BellmanFord* _algorithm;
+      int _index;
+    };
+
+    /// \name Query Functions
+    /// The result of the Bellman-Ford algorithm can be obtained using these
+    /// functions.\n
+    /// Either \ref run() or \ref init() should be called before using them.
+
+    ///@{
+
+    /// \brief The shortest path to the given node.
+    ///
+    /// Gives back the shortest path to the given node from the root(s).
+    ///
+    /// \warning \c t should be reached from the root(s).
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    Path path(Node t) const
+    {
+      return Path(*_gr, *_pred, t);
+    }
+
+    /// \brief The distance of the given node from the root(s).
+    ///
+    /// Returns the distance of the given 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 init() must be called before
+    /// using this function.
+    Value dist(Node v) const { return (*_dist)[v]; }
+
+    /// \brief Returns the 'previous arc' of the shortest path tree for
+    /// the given node.
+    ///
+    /// This function returns the 'previous arc' of the shortest path
+    /// tree for node \c v, i.e. it returns the last arc of 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 predNode() and \ref predMap().
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    Arc predArc(Node v) const { return (*_pred)[v]; }
+
+    /// \brief Returns the 'previous node' of the shortest path tree for
+    /// the given node.
+    ///
+    /// This function returns the 'previous node' of the shortest path
+    /// tree for node \c v, i.e. it returns the last but one node of
+    /// 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() and \ref predMap().
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    Node predNode(Node v) const {
+      return (*_pred)[v] == INVALID ? INVALID : _gr->source((*_pred)[v]);
+    }
+
+    /// \brief Returns a const reference to the node map that stores the
+    /// distances of the nodes.
+    ///
+    /// Returns a const reference to the node map that stores the distances
+    /// of the nodes calculated by the algorithm.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    const DistMap &distMap() const { return *_dist;}
+
+    /// \brief Returns a const reference to the node map that stores the
+    /// predecessor arcs.
+    ///
+    /// Returns a const reference to the node map that stores the predecessor
+    /// arcs, which form the shortest path tree (forest).
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    const PredMap &predMap() const { return *_pred; }
+
+    /// \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() or \ref init() must be called before
+    /// using this function.
+    bool reached(Node v) const {
+      return (*_dist)[v] != OperationTraits::infinity();
+    }
+
+    /// \brief Gives back a negative cycle.
+    ///
+    /// This function gives back a directed cycle with negative total
+    /// length if the algorithm has already found one.
+    /// Otherwise it gives back an empty path.
+    lemon::Path<Digraph> negativeCycle() const {
+      typename Digraph::template NodeMap<int> state(*_gr, -1);
+      lemon::Path<Digraph> cycle;
+      for (int i = 0; i < int(_process.size()); ++i) {
+        if (state[_process[i]] != -1) continue;
+        for (Node v = _process[i]; (*_pred)[v] != INVALID;
+             v = _gr->source((*_pred)[v])) {
+          if (state[v] == i) {
+            cycle.addFront((*_pred)[v]);
+            for (Node u = _gr->source((*_pred)[v]); u != v;
+                 u = _gr->source((*_pred)[u])) {
+              cycle.addFront((*_pred)[u]);
+            }
+            return cycle;
+          }
+          else if (state[v] >= 0) {
+            break;
+          }
+          state[v] = i;
+        }
+      }
+      return cycle;
+    }
+
+    ///@}
+  };
+
+  /// \brief Default traits class of bellmanFord() function.
+  ///
+  /// Default traits class of bellmanFord() function.
+  /// \tparam GR The type of the digraph.
+  /// \tparam LEN The type of the length map.
+  template <typename GR, typename LEN>
+  struct BellmanFordWizardDefaultTraits {
+    /// The type of the digraph the algorithm runs on.
+    typedef GR Digraph;
+
+    /// \brief The type of the map that stores the arc lengths.
+    ///
+    /// The type of the map that stores the arc lengths.
+    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
+    typedef LEN LengthMap;
+
+    /// The type of the arc lengths.
+    typedef typename LEN::Value Value;
+
+    /// \brief Operation traits for Bellman-Ford algorithm.
+    ///
+    /// It defines the used operations and the infinity value for the
+    /// given \c Value type.
+    /// \see BellmanFordDefaultOperationTraits
+    typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
+
+    /// \brief The type of the map that stores the last
+    /// arcs of the shortest paths.
+    ///
+    /// The type of the map that stores the last arcs of the shortest paths.
+    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename GR::template NodeMap<typename GR::Arc> PredMap;
+
+    /// \brief Instantiates a \c PredMap.
+    ///
+    /// This function instantiates a \ref PredMap.
+    /// \param g is the digraph to which we would like to define the
+    /// \ref PredMap.
+    static PredMap *createPredMap(const GR &g) {
+      return new PredMap(g);
+    }
+
+    /// \brief The type of the map that stores the distances of the nodes.
+    ///
+    /// The type of the map that stores the distances of the nodes.
+    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    typedef typename GR::template NodeMap<Value> DistMap;
+
+    /// \brief Instantiates a \c DistMap.
+    ///
+    /// This function instantiates a \ref DistMap.
+    /// \param g is the digraph to which we would like to define the
+    /// \ref DistMap.
+    static DistMap *createDistMap(const GR &g) {
+      return new DistMap(g);
+    }
+
+    ///The type of the shortest paths.
+
+    ///The type of the shortest paths.
+    ///It must meet the \ref concepts::Path "Path" concept.
+    typedef lemon::Path<Digraph> Path;
+  };
+
+  /// \brief Default traits class used by BellmanFordWizard.
+  ///
+  /// Default traits class used by BellmanFordWizard.
+  /// \tparam GR The type of the digraph.
+  /// \tparam LEN The type of the length map.
+  template <typename GR, typename LEN>
+  class BellmanFordWizardBase
+    : public BellmanFordWizardDefaultTraits<GR, LEN> {
+
+    typedef BellmanFordWizardDefaultTraits<GR, LEN> Base;
+  protected:
+    // Type of the nodes in the digraph.
+    typedef typename Base::Digraph::Node Node;
+
+    // Pointer to the underlying digraph.
+    void *_graph;
+    // Pointer to the length map
+    void *_length;
+    // Pointer to the map of predecessors arcs.
+    void *_pred;
+    // Pointer to the map of distances.
+    void *_dist;
+    //Pointer to the shortest path to the target node.
+    void *_path;
+    //Pointer to the distance of the target node.
+    void *_di;
+
+    public:
+    /// Constructor.
+
+    /// This constructor does not require parameters, it initiates
+    /// all of the attributes to default values \c 0.
+    BellmanFordWizardBase() :
+      _graph(0), _length(0), _pred(0), _dist(0), _path(0), _di(0) {}
+
+    /// Constructor.
+
+    /// This constructor requires two parameters,
+    /// others are initiated to \c 0.
+    /// \param gr The digraph the algorithm runs on.
+    /// \param len The length map.
+    BellmanFordWizardBase(const GR& gr,
+                          const LEN& len) :
+      _graph(reinterpret_cast<void*>(const_cast<GR*>(&gr))),
+      _length(reinterpret_cast<void*>(const_cast<LEN*>(&len))),
+      _pred(0), _dist(0), _path(0), _di(0) {}
+
+  };
+
+  /// \brief Auxiliary class for the function-type interface of the
+  /// \ref BellmanFord "Bellman-Ford" algorithm.
+  ///
+  /// This auxiliary class is created to implement the
+  /// \ref bellmanFord() "function-type interface" of the
+  /// \ref BellmanFord "Bellman-Ford" algorithm.
+  /// It does not have own \ref run() method, it uses the
+  /// functions and features of the plain \ref BellmanFord.
+  ///
+  /// This class should only be used through the \ref bellmanFord()
+  /// function, which makes it easier to use the algorithm.
+  ///
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm.
+  template<class TR>
+  class BellmanFordWizard : public TR {
+    typedef TR Base;
+
+    typedef typename TR::Digraph Digraph;
+
+    typedef typename Digraph::Node Node;
+    typedef typename Digraph::NodeIt NodeIt;
+    typedef typename Digraph::Arc Arc;
+    typedef typename Digraph::OutArcIt ArcIt;
+
+    typedef typename TR::LengthMap LengthMap;
+    typedef typename LengthMap::Value Value;
+    typedef typename TR::PredMap PredMap;
+    typedef typename TR::DistMap DistMap;
+    typedef typename TR::Path Path;
+
+  public:
+    /// Constructor.
+    BellmanFordWizard() : TR() {}
+
+    /// \brief Constructor that requires parameters.
+    ///
+    /// Constructor that requires parameters.
+    /// These parameters will be the default values for the traits class.
+    /// \param gr The digraph the algorithm runs on.
+    /// \param len The length map.
+    BellmanFordWizard(const Digraph& gr, const LengthMap& len)
+      : TR(gr, len) {}
+
+    /// \brief Copy constructor
+    BellmanFordWizard(const TR &b) : TR(b) {}
+
+    ~BellmanFordWizard() {}
+
+    /// \brief Runs the Bellman-Ford algorithm from the given source node.
+    ///
+    /// This method runs the Bellman-Ford algorithm from the given source
+    /// node in order to compute the shortest path to each node.
+    void run(Node s) {
+      BellmanFord<Digraph,LengthMap,TR>
+        bf(*reinterpret_cast<const Digraph*>(Base::_graph),
+           *reinterpret_cast<const LengthMap*>(Base::_length));
+      if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
+      if (Base::_dist) bf.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
+      bf.run(s);
+    }
+
+    /// \brief Runs the Bellman-Ford algorithm to find the shortest path
+    /// between \c s and \c t.
+    ///
+    /// This method runs the Bellman-Ford algorithm from node \c s
+    /// in order to compute the shortest path to node \c t.
+    /// Actually, it computes the shortest path to each node, but using
+    /// this function you can retrieve the distance and the shortest path
+    /// for a single target node easier.
+    ///
+    /// \return \c true if \c t is reachable form \c s.
+    bool run(Node s, Node t) {
+      BellmanFord<Digraph,LengthMap,TR>
+        bf(*reinterpret_cast<const Digraph*>(Base::_graph),
+           *reinterpret_cast<const LengthMap*>(Base::_length));
+      if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
+      if (Base::_dist) bf.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
+      bf.run(s);
+      if (Base::_path) *reinterpret_cast<Path*>(Base::_path) = bf.path(t);
+      if (Base::_di) *reinterpret_cast<Value*>(Base::_di) = bf.dist(t);
+      return bf.reached(t);
+    }
+
+    template<class T>
+    struct SetPredMapBase : public Base {
+      typedef T PredMap;
+      static PredMap *createPredMap(const Digraph &) { return 0; };
+      SetPredMapBase(const TR &b) : TR(b) {}
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// the predecessor map.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting
+    /// the map that stores the predecessor arcs of the nodes.
+    template<class T>
+    BellmanFordWizard<SetPredMapBase<T> > predMap(const T &t) {
+      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
+      return BellmanFordWizard<SetPredMapBase<T> >(*this);
+    }
+
+    template<class T>
+    struct SetDistMapBase : public Base {
+      typedef T DistMap;
+      static DistMap *createDistMap(const Digraph &) { return 0; };
+      SetDistMapBase(const TR &b) : TR(b) {}
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// the distance map.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting
+    /// the map that stores the distances of the nodes calculated
+    /// by the algorithm.
+    template<class T>
+    BellmanFordWizard<SetDistMapBase<T> > distMap(const T &t) {
+      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
+      return BellmanFordWizard<SetDistMapBase<T> >(*this);
+    }
+
+    template<class T>
+    struct SetPathBase : public Base {
+      typedef T Path;
+      SetPathBase(const TR &b) : TR(b) {}
+    };
+
+    /// \brief \ref named-func-param "Named parameter" for getting
+    /// the shortest path to the target node.
+    ///
+    /// \ref named-func-param "Named parameter" for getting
+    /// the shortest path to the target node.
+    template<class T>
+    BellmanFordWizard<SetPathBase<T> > path(const T &t)
+    {
+      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
+      return BellmanFordWizard<SetPathBase<T> >(*this);
+    }
+
+    /// \brief \ref named-func-param "Named parameter" for getting
+    /// the distance of the target node.
+    ///
+    /// \ref named-func-param "Named parameter" for getting
+    /// the distance of the target node.
+    BellmanFordWizard dist(const Value &d)
+    {
+      Base::_di=reinterpret_cast<void*>(const_cast<Value*>(&d));
+      return *this;
+    }
+
+  };
+
+  /// \brief Function type interface for the \ref BellmanFord "Bellman-Ford"
+  /// algorithm.
+  ///
+  /// \ingroup shortest_path
+  /// Function type interface for the \ref BellmanFord "Bellman-Ford"
+  /// algorithm.
+  ///
+  /// This function also has several \ref named-templ-func-param
+  /// "named parameters", they are declared as the members of class
+  /// \ref BellmanFordWizard.
+  /// The following examples show how to use these parameters.
+  /// \code
+  ///   // Compute shortest path from node s to each node
+  ///   bellmanFord(g,length).predMap(preds).distMap(dists).run(s);
+  ///
+  ///   // Compute shortest path from s to t
+  ///   bool reached = bellmanFord(g,length).path(p).dist(d).run(s,t);
+  /// \endcode
+  /// \warning Don't forget to put the \ref BellmanFordWizard::run() "run()"
+  /// to the end of the parameter list.
+  /// \sa BellmanFordWizard
+  /// \sa BellmanFord
+  template<typename GR, typename LEN>
+  BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >
+  bellmanFord(const GR& digraph,
+              const LEN& length)
+  {
+    return BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >(digraph, length);
+  }
+
+} //END OF NAMESPACE LEMON
+
+#endif
+
Index: lemon/bfs.h
===================================================================
--- lemon/bfs.h	(revision 492)
+++ lemon/bfs.h	(revision 954)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -48,5 +48,5 @@
     ///The type of the map that stores the predecessor
     ///arcs of the shortest paths.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
     ///Instantiates a \c PredMap.
@@ -63,5 +63,6 @@
 
     ///The type of the map that indicates which nodes are processed.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    ///By default, it is a NullMap.
     typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
     ///Instantiates a \c ProcessedMap.
@@ -82,5 +83,6 @@
 
     ///The type of the map that indicates which nodes are reached.
-    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    ///It must conform to
+    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     typedef typename Digraph::template NodeMap<bool> ReachedMap;
     ///Instantiates a \c ReachedMap.
@@ -97,5 +99,5 @@
 
     ///The type of the map that stores the distances of the nodes.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     typedef typename Digraph::template NodeMap<int> DistMap;
     ///Instantiates a \c DistMap.
@@ -121,4 +123,9 @@
   ///\tparam GR The type of the digraph the algorithm runs on.
   ///The default type is \ref ListDigraph.
+  ///\tparam TR The traits class that defines various types used by the
+  ///algorithm. By default, it is \ref BfsDefaultTraits
+  ///"BfsDefaultTraits<GR>".
+  ///In most cases, this parameter should not be set directly,
+  ///consider to use the named template parameters instead.
 #ifdef DOXYGEN
   template <typename GR,
@@ -226,5 +233,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///\c PredMap type.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetPredMap : public Bfs< Digraph, SetPredMapTraits<T> > {
@@ -246,5 +253,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///\c DistMap type.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetDistMap : public Bfs< Digraph, SetDistMapTraits<T> > {
@@ -266,5 +273,6 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///\c ReachedMap type.
-    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    ///It must conform to
+    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     template <class T>
     struct SetReachedMap : public Bfs< Digraph, SetReachedMapTraits<T> > {
@@ -286,5 +294,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///\c ProcessedMap type.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetProcessedMap : public Bfs< Digraph, SetProcessedMapTraits<T> > {
@@ -414,6 +422,6 @@
     ///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
+    ///If you need better control on the execution, you have to call
+    ///\ref init() first, 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.
@@ -701,10 +709,6 @@
     ///Runs the algorithm to visit all nodes in the digraph.
 
-    ///This method runs the %BFS algorithm in order to
-    ///compute the shortest path to each node.
-    ///
-    ///The algorithm computes
-    ///- the shortest path tree (forest),
-    ///- the distance of each node from the root(s).
+    ///This method runs the %BFS algorithm in order to visit all nodes
+    ///in the digraph.
     ///
     ///\note <tt>b.run(s)</tt> is just a shortcut of the following code.
@@ -738,7 +742,7 @@
     ///@{
 
-    ///The shortest path to a node.
-
-    ///Returns the shortest path to a node.
+    ///The shortest path to the given node.
+
+    ///Returns the shortest path to the given node from the root(s).
     ///
     ///\warning \c t should be reached from the root(s).
@@ -748,7 +752,7 @@
     Path path(Node t) const { return Path(*G, *_pred, t); }
 
-    ///The distance of a node from the root(s).
-
-    ///Returns the distance of a node from the root(s).
+    ///The distance of the given node from the root(s).
+
+    ///Returns the distance of the given node from the root(s).
     ///
     ///\warning If node \c v is not reached from the root(s), then
@@ -759,6 +763,7 @@
     int dist(Node v) const { return (*_dist)[v]; }
 
-    ///Returns the 'previous arc' of the shortest path tree for a node.
-
+    ///\brief Returns the 'previous arc' of the shortest path tree for
+    ///the given node.
+    ///
     ///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
@@ -767,5 +772,5 @@
     ///
     ///The shortest path tree used here is equal to the shortest path
-    ///tree used in \ref predNode().
+    ///tree used in \ref predNode() and \ref predMap().
     ///
     ///\pre Either \ref run(Node) "run()" or \ref init()
@@ -773,13 +778,14 @@
     Arc predArc(Node v) const { return (*_pred)[v];}
 
-    ///Returns the 'previous node' of the shortest path tree for a node.
-
+    ///\brief Returns the 'previous node' of the shortest path tree for
+    ///the given node.
+    ///
     ///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 a root to \c v. It is \c INVALID
+    ///of 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().
+    ///tree used in \ref predArc() and \ref predMap().
     ///
     ///\pre Either \ref run(Node) "run()" or \ref init()
@@ -802,5 +808,5 @@
     ///
     ///Returns a const reference to the node map that stores the predecessor
-    ///arcs, which form the shortest path tree.
+    ///arcs, which form the shortest path tree (forest).
     ///
     ///\pre Either \ref run(Node) "run()" or \ref init()
@@ -808,5 +814,5 @@
     const PredMap &predMap() const { return *_pred;}
 
-    ///Checks if a node is reached from the root(s).
+    ///Checks if the given node is reached from the root(s).
 
     ///Returns \c true if \c v is reached from the root(s).
@@ -834,5 +840,5 @@
     ///The type of the map that stores the predecessor
     ///arcs of the shortest paths.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
     ///Instantiates a PredMap.
@@ -849,6 +855,6 @@
 
     ///The type of the map that indicates which nodes are processed.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
-    ///By default it is a NullMap.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    ///By default, it is a NullMap.
     typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
     ///Instantiates a ProcessedMap.
@@ -869,5 +875,6 @@
 
     ///The type of the map that indicates which nodes are reached.
-    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    ///It must conform to
+    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     typedef typename Digraph::template NodeMap<bool> ReachedMap;
     ///Instantiates a ReachedMap.
@@ -884,5 +891,5 @@
 
     ///The type of the map that stores the distances of the nodes.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     typedef typename Digraph::template NodeMap<int> DistMap;
     ///Instantiates a DistMap.
@@ -899,5 +906,5 @@
 
     ///The type of the shortest paths.
-    ///It must meet the \ref concepts::Path "Path" concept.
+    ///It must conform to the \ref concepts::Path "Path" concept.
     typedef lemon::Path<Digraph> Path;
   };
@@ -905,10 +912,6 @@
   /// Default traits class used by BfsWizard
 
-  /// To make it easier to use Bfs algorithm
-  /// we have created a wizard class.
-  /// This \ref BfsWizard class needs default traits,
-  /// as well as the \ref Bfs class.
-  /// The \ref BfsWizardBase is a class to be the default traits of the
-  /// \ref BfsWizard class.
+  /// Default traits class used by BfsWizard.
+  /// \tparam GR The type of the digraph.
   template<class GR>
   class BfsWizardBase : public BfsWizardDefaultTraits<GR>
@@ -938,5 +941,5 @@
     /// Constructor.
 
-    /// This constructor does not require parameters, therefore it initiates
+    /// This constructor does not require parameters, it initiates
     /// all of the attributes to \c 0.
     BfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
@@ -963,4 +966,7 @@
   /// This class should only be used through the \ref bfs() function,
   /// which makes it easier to use the algorithm.
+  ///
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm.
   template<class TR>
   class BfsWizard : public TR
@@ -968,5 +974,4 @@
     typedef TR Base;
 
-    ///The type of the digraph the algorithm runs on.
     typedef typename TR::Digraph Digraph;
 
@@ -976,14 +981,8 @@
     typedef typename Digraph::OutArcIt OutArcIt;
 
-    ///\brief The type of the map that stores the predecessor
-    ///arcs of the shortest paths.
     typedef typename TR::PredMap PredMap;
-    ///\brief The type of the map that stores the distances of the nodes.
     typedef typename TR::DistMap DistMap;
-    ///\brief The type of the map that indicates which nodes are reached.
     typedef typename TR::ReachedMap ReachedMap;
-    ///\brief The type of the map that indicates which nodes are processed.
     typedef typename TR::ProcessedMap ProcessedMap;
-    ///The type of the shortest paths
     typedef typename TR::Path Path;
 
@@ -1055,6 +1054,6 @@
     ///Runs BFS algorithm to visit all nodes in the digraph.
 
-    ///This method runs BFS algorithm in order to compute
-    ///the shortest path to each node.
+    ///This method runs BFS algorithm in order to visit all nodes
+    ///in the digraph.
     void run()
     {
@@ -1068,9 +1067,10 @@
       SetPredMapBase(const TR &b) : TR(b) {}
     };
-    ///\brief \ref named-func-param "Named parameter"
-    ///for setting PredMap object.
-    ///
-    ///\ref named-func-param "Named parameter"
-    ///for setting PredMap object.
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the predecessor map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that stores the predecessor arcs of the nodes.
     template<class T>
     BfsWizard<SetPredMapBase<T> > predMap(const T &t)
@@ -1086,9 +1086,10 @@
       SetReachedMapBase(const TR &b) : TR(b) {}
     };
-    ///\brief \ref named-func-param "Named parameter"
-    ///for setting ReachedMap object.
-    ///
-    /// \ref named-func-param "Named parameter"
-    ///for setting ReachedMap object.
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the reached map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that indicates which nodes are reached.
     template<class T>
     BfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
@@ -1104,9 +1105,11 @@
       SetDistMapBase(const TR &b) : TR(b) {}
     };
-    ///\brief \ref named-func-param "Named parameter"
-    ///for setting DistMap object.
-    ///
-    /// \ref named-func-param "Named parameter"
-    ///for setting DistMap object.
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the distance map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that stores the distances of the nodes calculated
+    ///by the algorithm.
     template<class T>
     BfsWizard<SetDistMapBase<T> > distMap(const T &t)
@@ -1122,9 +1125,10 @@
       SetProcessedMapBase(const TR &b) : TR(b) {}
     };
-    ///\brief \ref named-func-param "Named parameter"
-    ///for setting ProcessedMap object.
-    ///
-    /// \ref named-func-param "Named parameter"
-    ///for setting ProcessedMap object.
+
+    ///\brief \ref named-func-param "Named parameter" for setting
+    ///the processed map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that indicates which nodes are processed.
     template<class T>
     BfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
@@ -1248,4 +1252,5 @@
       }
       _Visitor& visitor;
+      Constraints() {}
     };
   };
@@ -1265,5 +1270,6 @@
     ///
     /// The type of the map that indicates which nodes are reached.
-    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    /// It must conform to
+    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     typedef typename Digraph::template NodeMap<bool> ReachedMap;
 
@@ -1303,9 +1309,9 @@
   /// does not observe the BFS events. If you want to observe the BFS
   /// events, you should implement your own visitor class.
-  /// \tparam TR Traits class to set various data types used by the
-  /// algorithm. The default traits class is
-  /// \ref BfsVisitDefaultTraits "BfsVisitDefaultTraits<GR>".
-  /// See \ref BfsVisitDefaultTraits for the documentation of
-  /// a BFS visit traits class.
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm. By default, it is \ref BfsVisitDefaultTraits
+  /// "BfsVisitDefaultTraits<GR>".
+  /// In most cases, this parameter should not be set directly,
+  /// consider to use the named template parameters instead.
 #ifdef DOXYGEN
   template <typename GR, typename VS, typename TR>
@@ -1426,6 +1432,6 @@
     /// 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
+    /// If you need better control on the execution, you have to call
+    /// \ref init() first, 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.
@@ -1699,10 +1705,6 @@
     /// \brief Runs the algorithm to visit all nodes in the digraph.
     ///
-    /// This method runs the %BFS algorithm in order to
-    /// compute the shortest path to each node.
-    ///
-    /// The algorithm computes
-    /// - the shortest path tree (forest),
-    /// - the distance of each node from the root(s).
+    /// This method runs the %BFS algorithm in order to visit all nodes
+    /// in the digraph.
     ///
     /// \note <tt>b.run(s)</tt> is just a shortcut of the following code.
@@ -1736,5 +1738,5 @@
     ///@{
 
-    /// \brief Checks if a node is reached from the root(s).
+    /// \brief Checks if the given node is reached from the root(s).
     ///
     /// Returns \c true if \c v is reached from the root(s).
Index: lemon/bin_heap.h
===================================================================
--- lemon/bin_heap.h	(revision 559)
+++ lemon/bin_heap.h	(revision 711)
@@ -20,7 +20,7 @@
 #define LEMON_BIN_HEAP_H
 
-///\ingroup auxdat
+///\ingroup heaps
 ///\file
-///\brief Binary Heap implementation.
+///\brief Binary heap implementation.
 
 #include <vector>
@@ -30,43 +30,39 @@
 namespace lemon {
 
-  ///\ingroup auxdat
+  /// \ingroup heaps
   ///
-  ///\brief A Binary Heap implementation.
+  /// \brief Binary heap data structure.
   ///
-  ///This class implements the \e binary \e heap data structure. 
-  /// 
-  ///A \e heap is a data structure for storing items with specified values
-  ///called \e priorities in such a way that finding the item with minimum
-  ///priority is efficient. \c Comp specifies the ordering of the priorities.
-  ///In a heap one can change the priority of an item, add or erase an
-  ///item, etc.
+  /// This class implements the \e binary \e heap data structure.
+  /// It fully conforms to the \ref concepts::Heap "heap concept".
   ///
-  ///\tparam PR Type of the priority of the items.
-  ///\tparam IM A read and writable item map with int values, used internally
-  ///to handle the cross references.
-  ///\tparam Comp A functor class for the ordering of the priorities.
-  ///The default is \c std::less<PR>.
-  ///
-  ///\sa FibHeap
-  ///\sa Dijkstra
-  template <typename PR, typename IM, typename Comp = std::less<PR> >
+  /// \tparam PR Type of the priorities of the items.
+  /// \tparam IM A read-writable item map with \c int values, used
+  /// internally to handle the cross references.
+  /// \tparam CMP A functor class for comparing the priorities.
+  /// The default is \c std::less<PR>.
+#ifdef DOXYGEN
+  template <typename PR, typename IM, typename CMP>
+#else
+  template <typename PR, typename IM, typename CMP = std::less<PR> >
+#endif
   class BinHeap {
-
   public:
-    ///\e
+
+    /// Type of the item-int map.
     typedef IM ItemIntMap;
-    ///\e
+    /// Type of the priorities.
     typedef PR Prio;
-    ///\e
+    /// Type of the items stored in the heap.
     typedef typename ItemIntMap::Key Item;
-    ///\e
+    /// Type of the item-priority pairs.
     typedef std::pair<Item,Prio> Pair;
-    ///\e
-    typedef Comp Compare;
-
-    /// \brief Type to represent the items states.
-    ///
-    /// Each Item element have a state associated to it. It may be "in heap",
-    /// "pre heap" or "post heap". The latter two are indifferent from the
+    /// Functor type for comparing the priorities.
+    typedef CMP Compare;
+
+    /// \brief Type to represent the states of the items.
+    ///
+    /// Each item has a state associated to it. It can be "in heap",
+    /// "pre-heap" or "post-heap". The latter two are indifferent from the
     /// heap's point of view, but may be useful to the user.
     ///
@@ -74,7 +70,7 @@
     /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
     enum State {
-      IN_HEAP = 0,    ///< \e
-      PRE_HEAP = -1,  ///< \e
-      POST_HEAP = -2  ///< \e
+      IN_HEAP = 0,    ///< = 0.
+      PRE_HEAP = -1,  ///< = -1.
+      POST_HEAP = -2  ///< = -2.
     };
 
@@ -85,40 +81,41 @@
 
   public:
-    /// \brief The constructor.
-    ///
-    /// The constructor.
-    /// \param map should be given to the constructor, since it is used
-    /// internally to handle the cross references. The value of the map
-    /// must be \c PRE_HEAP (<tt>-1</tt>) for every item.
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
     explicit BinHeap(ItemIntMap &map) : _iim(map) {}
 
-    /// \brief The constructor.
-    ///
-    /// The constructor.
-    /// \param map should be given to the constructor, since it is used
-    /// internally to handle the cross references. The value of the map
-    /// should be PRE_HEAP (-1) for each element.
-    ///
-    /// \param comp The comparator function object.
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    /// \param comp The function object used for comparing the priorities.
     BinHeap(ItemIntMap &map, const Compare &comp)
       : _iim(map), _comp(comp) {}
 
 
-    /// The number of items stored in the heap.
-    ///
-    /// \brief Returns the number of items stored in the heap.
+    /// \brief The number of items stored in the heap.
+    ///
+    /// This function returns the number of items stored in the heap.
     int size() const { return _data.size(); }
 
-    /// \brief Checks if the heap stores no items.
-    ///
-    /// Returns \c true if and only if the heap stores no items.
+    /// \brief Check if the heap is empty.
+    ///
+    /// This function returns \c true if the heap is empty.
     bool empty() const { return _data.empty(); }
 
-    /// \brief Make empty this heap.
-    ///
-    /// Make empty this heap. It does not change the cross reference map.
-    /// If you want to reuse what is not surely empty you should first clear
-    /// the heap and after that you should set the cross reference map for
-    /// each item to \c PRE_HEAP.
+    /// \brief Make the heap empty.
+    ///
+    /// This functon makes the heap empty.
+    /// It does not change the cross reference map. If you want to reuse
+    /// a heap that is not surely empty, you should first clear it and
+    /// then you should set the cross reference map to \c PRE_HEAP
+    /// for each item.
     void clear() {
       _data.clear();
@@ -128,10 +125,10 @@
     static int parent(int i) { return (i-1)/2; }
 
-    static int second_child(int i) { return 2*i+2; }
+    static int secondChild(int i) { return 2*i+2; }
     bool less(const Pair &p1, const Pair &p2) const {
       return _comp(p1.second, p2.second);
     }
 
-    int bubble_up(int hole, Pair p) {
+    int bubbleUp(int hole, Pair p) {
       int par = parent(hole);
       while( hole>0 && less(p,_data[par]) ) {
@@ -144,6 +141,6 @@
     }
 
-    int bubble_down(int hole, Pair p, int length) {
-      int child = second_child(hole);
+    int bubbleDown(int hole, Pair p, int length) {
+      int child = secondChild(hole);
       while(child < length) {
         if( less(_data[child-1], _data[child]) ) {
@@ -154,5 +151,5 @@
         move(_data[child], hole);
         hole = child;
-        child = second_child(hole);
+        child = secondChild(hole);
       }
       child--;
@@ -172,42 +169,45 @@
 
   public:
+
     /// \brief Insert a pair of item and priority into the heap.
     ///
-    /// Adds \c p.first to the heap with priority \c p.second.
+    /// This function inserts \c p.first to the heap with priority
+    /// \c p.second.
     /// \param p The pair to insert.
+    /// \pre \c p.first must not be stored in the heap.
     void push(const Pair &p) {
       int n = _data.size();
       _data.resize(n+1);
-      bubble_up(n, p);
-    }
-
-    /// \brief Insert an item into the heap with the given heap.
-    ///
-    /// Adds \c i to the heap with priority \c p.
+      bubbleUp(n, p);
+    }
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// This function inserts the given item into the heap with the
+    /// given priority.
     /// \param i The item to insert.
     /// \param p The priority of the item.
+    /// \pre \e i must not be stored in the heap.
     void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
 
-    /// \brief Returns the item with minimum priority relative to \c Compare.
-    ///
-    /// This method returns the item with minimum priority relative to \c
-    /// Compare.
-    /// \pre The heap must be nonempty.
+    /// \brief Return the item having minimum priority.
+    ///
+    /// This function returns the item having minimum priority.
+    /// \pre The heap must be non-empty.
     Item top() const {
       return _data[0].first;
     }
 
-    /// \brief Returns the minimum priority relative to \c Compare.
-    ///
-    /// It returns the minimum priority relative to \c Compare.
-    /// \pre The heap must be nonempty.
+    /// \brief The minimum priority.
+    ///
+    /// This function returns the minimum priority.
+    /// \pre The heap must be non-empty.
     Prio prio() const {
       return _data[0].second;
     }
 
-    /// \brief Deletes the item with minimum priority relative to \c Compare.
-    ///
-    /// This method deletes the item with minimum priority relative to \c
-    /// Compare from the heap.
+    /// \brief Remove the item having minimum priority.
+    ///
+    /// This function removes the item having minimum priority.
     /// \pre The heap must be non-empty.
     void pop() {
@@ -215,14 +215,15 @@
       _iim.set(_data[0].first, POST_HEAP);
       if (n > 0) {
-        bubble_down(0, _data[n], n);
+        bubbleDown(0, _data[n], n);
       }
       _data.pop_back();
     }
 
-    /// \brief Deletes \c i from the heap.
-    ///
-    /// This method deletes item \c i from the heap.
-    /// \param i The item to erase.
-    /// \pre The item should be in the heap.
+    /// \brief Remove the given item from the heap.
+    ///
+    /// This function removes the given item from the heap if it is
+    /// already stored.
+    /// \param i The item to delete.
+    /// \pre \e i must be in the heap.
     void erase(const Item &i) {
       int h = _iim[i];
@@ -230,6 +231,6 @@
       _iim.set(_data[h].first, POST_HEAP);
       if( h < n ) {
-        if ( bubble_up(h, _data[n]) == h) {
-          bubble_down(h, _data[n], n);
+        if ( bubbleUp(h, _data[n]) == h) {
+          bubbleDown(h, _data[n], n);
         }
       }
@@ -237,10 +238,9 @@
     }
 
-
-    /// \brief Returns the priority of \c i.
-    ///
-    /// This function returns the priority of item \c i.
-    /// \param i The item.
-    /// \pre \c i must be in the heap.
+    /// \brief The priority of the given item.
+    ///
+    /// This function returns the priority of the given item.
+    /// \param i The item.
+    /// \pre \e i must be in the heap.
     Prio operator[](const Item &i) const {
       int idx = _iim[i];
@@ -248,9 +248,10 @@
     }
 
-    /// \brief \c i gets to the heap with priority \c p independently
-    /// if \c i was already there.
-    ///
-    /// This method calls \ref push(\c i, \c p) if \c i is not stored
-    /// in the heap and sets the priority of \c i to \c p otherwise.
+    /// \brief Set the priority of an item or insert it, if it is
+    /// not stored in the heap.
+    ///
+    /// This method sets the priority of the given item if it is
+    /// already stored in the heap. Otherwise it inserts the given
+    /// item into the heap with the given priority.
     /// \param i The item.
     /// \param p The priority.
@@ -261,42 +262,40 @@
       }
       else if( _comp(p, _data[idx].second) ) {
-        bubble_up(idx, Pair(i,p));
+        bubbleUp(idx, Pair(i,p));
       }
       else {
-        bubble_down(idx, Pair(i,p), _data.size());
-      }
-    }
-
-    /// \brief Decreases the priority of \c i to \c p.
-    ///
-    /// This method decreases the priority of item \c i to \c p.
+        bubbleDown(idx, Pair(i,p), _data.size());
+      }
+    }
+
+    /// \brief Decrease the priority of an item to the given value.
+    ///
+    /// This function decreases the priority of an item to the given value.
     /// \param i The item.
     /// \param p The priority.
-    /// \pre \c i must be stored in the heap with priority at least \c
-    /// p relative to \c Compare.
+    /// \pre \e i must be stored in the heap with priority at least \e p.
     void decrease(const Item &i, const Prio &p) {
       int idx = _iim[i];
-      bubble_up(idx, Pair(i,p));
-    }
-
-    /// \brief Increases the priority of \c i to \c p.
-    ///
-    /// This method sets the priority of item \c i to \c p.
+      bubbleUp(idx, Pair(i,p));
+    }
+
+    /// \brief Increase the priority of an item to the given value.
+    ///
+    /// This function increases the priority of an item to the given value.
     /// \param i The item.
     /// \param p The priority.
-    /// \pre \c i must be stored in the heap with priority at most \c
-    /// p relative to \c Compare.
+    /// \pre \e i must be stored in the heap with priority at most \e p.
     void increase(const Item &i, const Prio &p) {
       int idx = _iim[i];
-      bubble_down(idx, Pair(i,p), _data.size());
-    }
-
-    /// \brief Returns if \c item is in, has already been in, or has
-    /// never been in the heap.
-    ///
-    /// This method returns PRE_HEAP if \c item has never been in the
-    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
-    /// otherwise. In the latter case it is possible that \c item will
-    /// get back to the heap again.
+      bubbleDown(idx, Pair(i,p), _data.size());
+    }
+
+    /// \brief Return the state of an item.
+    ///
+    /// This method returns \c PRE_HEAP if the given item has never
+    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
+    /// and \c POST_HEAP otherwise.
+    /// In the latter case it is possible that the item will get back
+    /// to the heap again.
     /// \param i The item.
     State state(const Item &i) const {
@@ -307,9 +306,9 @@
     }
 
-    /// \brief Sets the state of the \c item in the heap.
-    ///
-    /// Sets the state of the \c item in the heap. It can be used to
-    /// manually clear the heap when it is important to achive the
-    /// better time complexity.
+    /// \brief Set the state of an item in the heap.
+    ///
+    /// This function sets the state of the given item in the heap.
+    /// It can be used to manually clear the heap when it is important
+    /// to achive better time complexity.
     /// \param i The item.
     /// \param st The state. It should not be \c IN_HEAP.
@@ -328,10 +327,11 @@
     }
 
-    /// \brief Replaces an item in the heap.
-    ///
-    /// The \c i item is replaced with \c j item. The \c i item should
-    /// be in the heap, while the \c j should be out of the heap. The
-    /// \c i item will out of the heap and \c j will be in the heap
-    /// with the same prioriority as prevoiusly the \c i item.
+    /// \brief Replace an item in the heap.
+    ///
+    /// This function replaces item \c i with item \c j.
+    /// Item \c i must be in the heap, while \c j must be out of the heap.
+    /// After calling this method, item \c i will be out of the
+    /// heap and \c j will be in the heap with the same prioriority
+    /// as item \c i had before.
     void replace(const Item& i, const Item& j) {
       int idx = _iim[i];
Index: lemon/binomial_heap.h
===================================================================
--- lemon/binomial_heap.h	(revision 877)
+++ lemon/binomial_heap.h	(revision 877)
@@ -0,0 +1,445 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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_BINOMIAL_HEAP_H
+#define LEMON_BINOMIAL_HEAP_H
+
+///\file
+///\ingroup heaps
+///\brief Binomial Heap implementation.
+
+#include <vector>
+#include <utility>
+#include <functional>
+#include <lemon/math.h>
+#include <lemon/counter.h>
+
+namespace lemon {
+
+  /// \ingroup heaps
+  ///
+  ///\brief Binomial heap data structure.
+  ///
+  /// This class implements the \e binomial \e heap data structure.
+  /// It fully conforms to the \ref concepts::Heap "heap concept".
+  ///
+  /// The methods \ref increase() and \ref erase() are not efficient
+  /// in a binomial heap. In case of many calls of these operations,
+  /// it is better to use other heap structure, e.g. \ref BinHeap
+  /// "binary heap".
+  ///
+  /// \tparam PR Type of the priorities of the items.
+  /// \tparam IM A read-writable item map with \c int values, used
+  /// internally to handle the cross references.
+  /// \tparam CMP A functor class for comparing the priorities.
+  /// The default is \c std::less<PR>.
+#ifdef DOXYGEN
+  template <typename PR, typename IM, typename CMP>
+#else
+  template <typename PR, typename IM, typename CMP = std::less<PR> >
+#endif
+  class BinomialHeap {
+  public:
+    /// Type of the item-int map.
+    typedef IM ItemIntMap;
+    /// Type of the priorities.
+    typedef PR Prio;
+    /// Type of the items stored in the heap.
+    typedef typename ItemIntMap::Key Item;
+    /// Functor type for comparing the priorities.
+    typedef CMP Compare;
+
+    /// \brief Type to represent the states of the items.
+    ///
+    /// Each item has a state associated to it. It can be "in heap",
+    /// "pre-heap" or "post-heap". The latter two are indifferent from the
+    /// heap's point of view, but may be useful to the user.
+    ///
+    /// The item-int map must be initialized in such way that it assigns
+    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
+    enum State {
+      IN_HEAP = 0,    ///< = 0.
+      PRE_HEAP = -1,  ///< = -1.
+      POST_HEAP = -2  ///< = -2.
+    };
+
+  private:
+    class Store;
+
+    std::vector<Store> _data;
+    int _min, _head;
+    ItemIntMap &_iim;
+    Compare _comp;
+    int _num_items;
+
+  public:
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    explicit BinomialHeap(ItemIntMap &map)
+      : _min(0), _head(-1), _iim(map), _num_items(0) {}
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    /// \param comp The function object used for comparing the priorities.
+    BinomialHeap(ItemIntMap &map, const Compare &comp)
+      : _min(0), _head(-1), _iim(map), _comp(comp), _num_items(0) {}
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// This function returns the number of items stored in the heap.
+    int size() const { return _num_items; }
+
+    /// \brief Check if the heap is empty.
+    ///
+    /// This function returns \c true if the heap is empty.
+    bool empty() const { return _num_items==0; }
+
+    /// \brief Make the heap empty.
+    ///
+    /// This functon makes the heap empty.
+    /// It does not change the cross reference map. If you want to reuse
+    /// a heap that is not surely empty, you should first clear it and
+    /// then you should set the cross reference map to \c PRE_HEAP
+    /// for each item.
+    void clear() {
+      _data.clear(); _min=0; _num_items=0; _head=-1;
+    }
+
+    /// \brief Set the priority of an item or insert it, if it is
+    /// not stored in the heap.
+    ///
+    /// This method sets the priority of the given item if it is
+    /// already stored in the heap. Otherwise it inserts the given
+    /// item into the heap with the given priority.
+    /// \param item The item.
+    /// \param value The priority.
+    void set (const Item& item, const Prio& value) {
+      int i=_iim[item];
+      if ( i >= 0 && _data[i].in ) {
+        if ( _comp(value, _data[i].prio) ) decrease(item, value);
+        if ( _comp(_data[i].prio, value) ) increase(item, value);
+      } else push(item, value);
+    }
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// This function inserts the given item into the heap with the
+    /// given priority.
+    /// \param item The item to insert.
+    /// \param value The priority of the item.
+    /// \pre \e item must not be stored in the heap.
+    void push (const Item& item, const Prio& value) {
+      int i=_iim[item];
+      if ( i<0 ) {
+        int s=_data.size();
+        _iim.set( item,s );
+        Store st;
+        st.name=item;
+        st.prio=value;
+        _data.push_back(st);
+        i=s;
+      }
+      else {
+        _data[i].parent=_data[i].right_neighbor=_data[i].child=-1;
+        _data[i].degree=0;
+        _data[i].in=true;
+        _data[i].prio=value;
+      }
+
+      if( 0==_num_items ) {
+        _head=i;
+        _min=i;
+      } else {
+        merge(i);
+        if( _comp(_data[i].prio, _data[_min].prio) ) _min=i;
+      }
+      ++_num_items;
+    }
+
+    /// \brief Return the item having minimum priority.
+    ///
+    /// This function returns the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    Item top() const { return _data[_min].name; }
+
+    /// \brief The minimum priority.
+    ///
+    /// This function returns the minimum priority.
+    /// \pre The heap must be non-empty.
+    Prio prio() const { return _data[_min].prio; }
+
+    /// \brief The priority of the given item.
+    ///
+    /// This function returns the priority of the given item.
+    /// \param item The item.
+    /// \pre \e item must be in the heap.
+    const Prio& operator[](const Item& item) const {
+      return _data[_iim[item]].prio;
+    }
+
+    /// \brief Remove the item having minimum priority.
+    ///
+    /// This function removes the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      _data[_min].in=false;
+
+      int head_child=-1;
+      if ( _data[_min].child!=-1 ) {
+        int child=_data[_min].child;
+        int neighb;
+        while( child!=-1 ) {
+          neighb=_data[child].right_neighbor;
+          _data[child].parent=-1;
+          _data[child].right_neighbor=head_child;
+          head_child=child;
+          child=neighb;
+        }
+      }
+
+      if ( _data[_head].right_neighbor==-1 ) {
+        // there was only one root
+        _head=head_child;
+      }
+      else {
+        // there were more roots
+        if( _head!=_min )  { unlace(_min); }
+        else { _head=_data[_head].right_neighbor; }
+        merge(head_child);
+      }
+      _min=findMin();
+      --_num_items;
+    }
+
+    /// \brief Remove the given item from the heap.
+    ///
+    /// This function removes the given item from the heap if it is
+    /// already stored.
+    /// \param item The item to delete.
+    /// \pre \e item must be in the heap.
+    void erase (const Item& item) {
+      int i=_iim[item];
+      if ( i >= 0 && _data[i].in ) {
+        decrease( item, _data[_min].prio-1 );
+        pop();
+      }
+    }
+
+    /// \brief Decrease the priority of an item to the given value.
+    ///
+    /// This function decreases the priority of an item to the given value.
+    /// \param item The item.
+    /// \param value The priority.
+    /// \pre \e item must be stored in the heap with priority at least \e value.
+    void decrease (Item item, const Prio& value) {
+      int i=_iim[item];
+      int p=_data[i].parent;
+      _data[i].prio=value;
+
+      while( p!=-1 && _comp(value, _data[p].prio) ) {
+        _data[i].name=_data[p].name;
+        _data[i].prio=_data[p].prio;
+        _data[p].name=item;
+        _data[p].prio=value;
+        _iim[_data[i].name]=i;
+        i=p;
+        p=_data[p].parent;
+      }
+      _iim[item]=i;
+      if ( _comp(value, _data[_min].prio) ) _min=i;
+    }
+
+    /// \brief Increase the priority of an item to the given value.
+    ///
+    /// This function increases the priority of an item to the given value.
+    /// \param item The item.
+    /// \param value The priority.
+    /// \pre \e item must be stored in the heap with priority at most \e value.
+    void increase (Item item, const Prio& value) {
+      erase(item);
+      push(item, value);
+    }
+
+    /// \brief Return the state of an item.
+    ///
+    /// This method returns \c PRE_HEAP if the given item has never
+    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
+    /// and \c POST_HEAP otherwise.
+    /// In the latter case it is possible that the item will get back
+    /// to the heap again.
+    /// \param item The item.
+    State state(const Item &item) const {
+      int i=_iim[item];
+      if( i>=0 ) {
+        if ( _data[i].in ) i=0;
+        else i=-2;
+      }
+      return State(i);
+    }
+
+    /// \brief Set the state of an item in the heap.
+    ///
+    /// This function sets the state of the given item in the heap.
+    /// It can be used to manually clear the heap when it is important
+    /// to achive better time complexity.
+    /// \param i The item.
+    /// \param st The state. It should not be \c IN_HEAP.
+    void state(const Item& i, State st) {
+      switch (st) {
+      case POST_HEAP:
+      case PRE_HEAP:
+        if (state(i) == IN_HEAP) {
+          erase(i);
+        }
+        _iim[i] = st;
+        break;
+      case IN_HEAP:
+        break;
+      }
+    }
+
+  private:
+
+    // Find the minimum of the roots
+    int findMin() {
+      if( _head!=-1 ) {
+        int min_loc=_head, min_val=_data[_head].prio;
+        for( int x=_data[_head].right_neighbor; x!=-1;
+             x=_data[x].right_neighbor ) {
+          if( _comp( _data[x].prio,min_val ) ) {
+            min_val=_data[x].prio;
+            min_loc=x;
+          }
+        }
+        return min_loc;
+      }
+      else return -1;
+    }
+
+    // Merge the heap with another heap starting at the given position
+    void merge(int a) {
+      if( _head==-1 || a==-1 ) return;
+      if( _data[a].right_neighbor==-1 &&
+          _data[a].degree<=_data[_head].degree ) {
+        _data[a].right_neighbor=_head;
+        _head=a;
+      } else {
+        interleave(a);
+      }
+      if( _data[_head].right_neighbor==-1 ) return;
+
+      int x=_head;
+      int x_prev=-1, x_next=_data[x].right_neighbor;
+      while( x_next!=-1 ) {
+        if( _data[x].degree!=_data[x_next].degree ||
+            ( _data[x_next].right_neighbor!=-1 &&
+              _data[_data[x_next].right_neighbor].degree==_data[x].degree ) ) {
+          x_prev=x;
+          x=x_next;
+        }
+        else {
+          if( _comp(_data[x_next].prio,_data[x].prio) ) {
+            if( x_prev==-1 ) {
+              _head=x_next;
+            } else {
+              _data[x_prev].right_neighbor=x_next;
+            }
+            fuse(x,x_next);
+            x=x_next;
+          }
+          else {
+            _data[x].right_neighbor=_data[x_next].right_neighbor;
+            fuse(x_next,x);
+          }
+        }
+        x_next=_data[x].right_neighbor;
+      }
+    }
+
+    // Interleave the elements of the given list into the list of the roots
+    void interleave(int a) {
+      int p=_head, q=a;
+      int curr=_data.size();
+      _data.push_back(Store());
+
+      while( p!=-1 || q!=-1 ) {
+        if( q==-1 || ( p!=-1 && _data[p].degree<_data[q].degree ) ) {
+          _data[curr].right_neighbor=p;
+          curr=p;
+          p=_data[p].right_neighbor;
+        }
+        else {
+          _data[curr].right_neighbor=q;
+          curr=q;
+          q=_data[q].right_neighbor;
+        }
+      }
+
+      _head=_data.back().right_neighbor;
+      _data.pop_back();
+    }
+
+    // Lace node a under node b
+    void fuse(int a, int b) {
+      _data[a].parent=b;
+      _data[a].right_neighbor=_data[b].child;
+      _data[b].child=a;
+
+      ++_data[b].degree;
+    }
+
+    // Unlace node a (if it has siblings)
+    void unlace(int a) {
+      int neighb=_data[a].right_neighbor;
+      int other=_head;
+
+      while( _data[other].right_neighbor!=a )
+        other=_data[other].right_neighbor;
+      _data[other].right_neighbor=neighb;
+    }
+
+  private:
+
+    class Store {
+      friend class BinomialHeap;
+
+      Item name;
+      int parent;
+      int right_neighbor;
+      int child;
+      int degree;
+      bool in;
+      Prio prio;
+
+      Store() : parent(-1), right_neighbor(-1), child(-1), degree(0),
+        in(true) {}
+    };
+  };
+
+} //namespace lemon
+
+#endif //LEMON_BINOMIAL_HEAP_H
+
Index: lemon/bits/array_map.h
===================================================================
--- lemon/bits/array_map.h	(revision 492)
+++ lemon/bits/array_map.h	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -48,5 +48,5 @@
   public:
     // The graph type.
-    typedef _Graph Graph;
+    typedef _Graph GraphType;
     // The item type.
     typedef _Item Item;
@@ -64,11 +64,15 @@
     typedef _Value& Reference;
 
+    // The map type.
+    typedef ArrayMap Map;
+
     // The notifier type.
     typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier;
 
+  private:
+
     // The MapBase of the Map which imlements the core regisitry function.
     typedef typename Notifier::ObserverBase Parent;
 
-  private:
     typedef std::allocator<Value> Allocator;
 
@@ -78,5 +82,5 @@
     //
     // Graph initialized map constructor.
-    explicit ArrayMap(const Graph& graph) {
+    explicit ArrayMap(const GraphType& graph) {
       Parent::attach(graph.notifier(Item()));
       allocate_memory();
@@ -92,5 +96,5 @@
     //
     // It constructs a map and initialize all of the the map.
-    ArrayMap(const Graph& graph, const Value& value) {
+    ArrayMap(const GraphType& graph, const Value& value) {
       Parent::attach(graph.notifier(Item()));
       allocate_memory();
Index: mon/bits/base_extender.h
===================================================================
--- lemon/bits/base_extender.h	(revision 440)
+++ 	(revision )
@@ -1,494 +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_BITS_BASE_EXTENDER_H
-#define LEMON_BITS_BASE_EXTENDER_H
-
-#include <lemon/core.h>
-#include <lemon/error.h>
-
-#include <lemon/bits/map_extender.h>
-#include <lemon/bits/default_map.h>
-
-#include <lemon/concept_check.h>
-#include <lemon/concepts/maps.h>
-
-//\ingroup digraphbits
-//\file
-//\brief Extenders for the graph types
-namespace lemon {
-
-  // \ingroup digraphbits
-  //
-  // \brief BaseDigraph to BaseGraph extender
-  template <typename Base>
-  class UndirDigraphExtender : public Base {
-
-  public:
-
-    typedef Base Parent;
-    typedef typename Parent::Arc Edge;
-    typedef typename Parent::Node Node;
-
-    typedef True UndirectedTag;
-
-    class Arc : public Edge {
-      friend class UndirDigraphExtender;
-
-    protected:
-      bool forward;
-
-      Arc(const Edge &ue, bool _forward) :
-        Edge(ue), forward(_forward) {}
-
-    public:
-      Arc() {}
-
-      // Invalid arc constructor
-      Arc(Invalid i) : Edge(i), forward(true) {}
-
-      bool operator==(const Arc &that) const {
-        return forward==that.forward && Edge(*this)==Edge(that);
-      }
-      bool operator!=(const Arc &that) const {
-        return forward!=that.forward || Edge(*this)!=Edge(that);
-      }
-      bool operator<(const Arc &that) const {
-        return forward<that.forward ||
-          (!(that.forward<forward) && Edge(*this)<Edge(that));
-      }
-    };
-
-    // First node of the edge
-    Node u(const Edge &e) const {
-      return Parent::source(e);
-    }
-
-    // Source of the given arc
-    Node source(const Arc &e) const {
-      return e.forward ? Parent::source(e) : Parent::target(e);
-    }
-
-    // Second node of the edge
-    Node v(const Edge &e) const {
-      return Parent::target(e);
-    }
-
-    // Target of the given arc
-    Node target(const Arc &e) const {
-      return e.forward ? Parent::target(e) : Parent::source(e);
-    }
-
-    // \brief Directed arc from an edge.
-    //
-    // Returns a directed arc corresponding to the specified edge.
-    // If the given bool is true, the first node of the given edge and
-    // the source node of the returned arc are the same.
-    static Arc direct(const Edge &e, bool d) {
-      return Arc(e, d);
-    }
-
-    // Returns whether the given directed arc has the same orientation
-    // as the corresponding edge.
-    static bool direction(const Arc &a) { return a.forward; }
-
-    using Parent::first;
-    using Parent::next;
-
-    void first(Arc &e) const {
-      Parent::first(e);
-      e.forward=true;
-    }
-
-    void next(Arc &e) const {
-      if( e.forward ) {
-        e.forward = false;
-      }
-      else {
-        Parent::next(e);
-        e.forward = true;
-      }
-    }
-
-    void firstOut(Arc &e, const Node &n) const {
-      Parent::firstIn(e,n);
-      if( Edge(e) != INVALID ) {
-        e.forward = false;
-      }
-      else {
-        Parent::firstOut(e,n);
-        e.forward = true;
-      }
-    }
-    void nextOut(Arc &e) const {
-      if( ! e.forward ) {
-        Node n = Parent::target(e);
-        Parent::nextIn(e);
-        if( Edge(e) == INVALID ) {
-          Parent::firstOut(e, n);
-          e.forward = true;
-        }
-      }
-      else {
-        Parent::nextOut(e);
-      }
-    }
-
-    void firstIn(Arc &e, const Node &n) const {
-      Parent::firstOut(e,n);
-      if( Edge(e) != INVALID ) {
-        e.forward = false;
-      }
-      else {
-        Parent::firstIn(e,n);
-        e.forward = true;
-      }
-    }
-    void nextIn(Arc &e) const {
-      if( ! e.forward ) {
-        Node n = Parent::source(e);
-        Parent::nextOut(e);
-        if( Edge(e) == INVALID ) {
-          Parent::firstIn(e, n);
-          e.forward = true;
-        }
-      }
-      else {
-        Parent::nextIn(e);
-      }
-    }
-
-    void firstInc(Edge &e, bool &d, const Node &n) const {
-      d = true;
-      Parent::firstOut(e, n);
-      if (e != INVALID) return;
-      d = false;
-      Parent::firstIn(e, n);
-    }
-
-    void nextInc(Edge &e, bool &d) const {
-      if (d) {
-        Node s = Parent::source(e);
-        Parent::nextOut(e);
-        if (e != INVALID) return;
-        d = false;
-        Parent::firstIn(e, s);
-      } else {
-        Parent::nextIn(e);
-      }
-    }
-
-    Node nodeFromId(int ix) const {
-      return Parent::nodeFromId(ix);
-    }
-
-    Arc arcFromId(int ix) const {
-      return direct(Parent::arcFromId(ix >> 1), bool(ix & 1));
-    }
-
-    Edge edgeFromId(int ix) const {
-      return Parent::arcFromId(ix);
-    }
-
-    int id(const Node &n) const {
-      return Parent::id(n);
-    }
-
-    int id(const Edge &e) const {
-      return Parent::id(e);
-    }
-
-    int id(const Arc &e) const {
-      return 2 * Parent::id(e) + int(e.forward);
-    }
-
-    int maxNodeId() const {
-      return Parent::maxNodeId();
-    }
-
-    int maxArcId() const {
-      return 2 * Parent::maxArcId() + 1;
-    }
-
-    int maxEdgeId() const {
-      return Parent::maxArcId();
-    }
-
-    int arcNum() const {
-      return 2 * Parent::arcNum();
-    }
-
-    int edgeNum() const {
-      return Parent::arcNum();
-    }
-
-    Arc findArc(Node s, Node t, Arc p = INVALID) const {
-      if (p == INVALID) {
-        Edge arc = Parent::findArc(s, t);
-        if (arc != INVALID) return direct(arc, true);
-        arc = Parent::findArc(t, s);
-        if (arc != INVALID) return direct(arc, false);
-      } else if (direction(p)) {
-        Edge arc = Parent::findArc(s, t, p);
-        if (arc != INVALID) return direct(arc, true);
-        arc = Parent::findArc(t, s);
-        if (arc != INVALID) return direct(arc, false);
-      } else {
-        Edge arc = Parent::findArc(t, s, p);
-        if (arc != INVALID) return direct(arc, false);
-      }
-      return INVALID;
-    }
-
-    Edge findEdge(Node s, Node t, Edge p = INVALID) const {
-      if (s != t) {
-        if (p == INVALID) {
-          Edge arc = Parent::findArc(s, t);
-          if (arc != INVALID) return arc;
-          arc = Parent::findArc(t, s);
-          if (arc != INVALID) return arc;
-        } else if (Parent::s(p) == s) {
-          Edge arc = Parent::findArc(s, t, p);
-          if (arc != INVALID) return arc;
-          arc = Parent::findArc(t, s);
-          if (arc != INVALID) return arc;
-        } else {
-          Edge arc = Parent::findArc(t, s, p);
-          if (arc != INVALID) return arc;
-        }
-      } else {
-        return Parent::findArc(s, t, p);
-      }
-      return INVALID;
-    }
-  };
-
-  template <typename Base>
-  class BidirBpGraphExtender : public Base {
-  public:
-    typedef Base Parent;
-    typedef BidirBpGraphExtender Digraph;
-
-    typedef typename Parent::Node Node;
-    typedef typename Parent::Edge Edge;
-
-
-    using Parent::first;
-    using Parent::next;
-
-    using Parent::id;
-
-    class Red : public Node {
-      friend class BidirBpGraphExtender;
-    public:
-      Red() {}
-      Red(const Node& node) : Node(node) {
-        LEMON_DEBUG(Parent::red(node) || node == INVALID,
-                    typename Parent::NodeSetError());
-      }
-      Red& operator=(const Node& node) {
-        LEMON_DEBUG(Parent::red(node) || node == INVALID,
-                    typename Parent::NodeSetError());
-        Node::operator=(node);
-        return *this;
-      }
-      Red(Invalid) : Node(INVALID) {}
-      Red& operator=(Invalid) {
-        Node::operator=(INVALID);
-        return *this;
-      }
-    };
-
-    void first(Red& node) const {
-      Parent::firstRed(static_cast<Node&>(node));
-    }
-    void next(Red& node) const {
-      Parent::nextRed(static_cast<Node&>(node));
-    }
-
-    int id(const Red& node) const {
-      return Parent::redId(node);
-    }
-
-    class Blue : public Node {
-      friend class BidirBpGraphExtender;
-    public:
-      Blue() {}
-      Blue(const Node& node) : Node(node) {
-        LEMON_DEBUG(Parent::blue(node) || node == INVALID,
-                    typename Parent::NodeSetError());
-      }
-      Blue& operator=(const Node& node) {
-        LEMON_DEBUG(Parent::blue(node) || node == INVALID,
-                    typename Parent::NodeSetError());
-        Node::operator=(node);
-        return *this;
-      }
-      Blue(Invalid) : Node(INVALID) {}
-      Blue& operator=(Invalid) {
-        Node::operator=(INVALID);
-        return *this;
-      }
-    };
-
-    void first(Blue& node) const {
-      Parent::firstBlue(static_cast<Node&>(node));
-    }
-    void next(Blue& node) const {
-      Parent::nextBlue(static_cast<Node&>(node));
-    }
-
-    int id(const Blue& node) const {
-      return Parent::redId(node);
-    }
-
-    Node source(const Edge& arc) const {
-      return red(arc);
-    }
-    Node target(const Edge& arc) const {
-      return blue(arc);
-    }
-
-    void firstInc(Edge& arc, bool& dir, const Node& node) const {
-      if (Parent::red(node)) {
-        Parent::firstFromRed(arc, node);
-        dir = true;
-      } else {
-        Parent::firstFromBlue(arc, node);
-        dir = static_cast<Edge&>(arc) == INVALID;
-      }
-    }
-    void nextInc(Edge& arc, bool& dir) const {
-      if (dir) {
-        Parent::nextFromRed(arc);
-      } else {
-        Parent::nextFromBlue(arc);
-        if (arc == INVALID) dir = true;
-      }
-    }
-
-    class Arc : public Edge {
-      friend class BidirBpGraphExtender;
-    protected:
-      bool forward;
-
-      Arc(const Edge& arc, bool _forward)
-        : Edge(arc), forward(_forward) {}
-
-    public:
-      Arc() {}
-      Arc (Invalid) : Edge(INVALID), forward(true) {}
-      bool operator==(const Arc& i) const {
-        return Edge::operator==(i) && forward == i.forward;
-      }
-      bool operator!=(const Arc& i) const {
-        return Edge::operator!=(i) || forward != i.forward;
-      }
-      bool operator<(const Arc& i) const {
-        return Edge::operator<(i) ||
-          (!(i.forward<forward) && Edge(*this)<Edge(i));
-      }
-    };
-
-    void first(Arc& arc) const {
-      Parent::first(static_cast<Edge&>(arc));
-      arc.forward = true;
-    }
-
-    void next(Arc& arc) const {
-      if (!arc.forward) {
-        Parent::next(static_cast<Edge&>(arc));
-      }
-      arc.forward = !arc.forward;
-    }
-
-    void firstOut(Arc& arc, const Node& node) const {
-      if (Parent::red(node)) {
-        Parent::firstFromRed(arc, node);
-        arc.forward = true;
-      } else {
-        Parent::firstFromBlue(arc, node);
-        arc.forward = static_cast<Edge&>(arc) == INVALID;
-      }
-    }
-    void nextOut(Arc& arc) const {
-      if (arc.forward) {
-        Parent::nextFromRed(arc);
-      } else {
-        Parent::nextFromBlue(arc);
-        arc.forward = static_cast<Edge&>(arc) == INVALID;
-      }
-    }
-
-    void firstIn(Arc& arc, const Node& node) const {
-      if (Parent::blue(node)) {
-        Parent::firstFromBlue(arc, node);
-        arc.forward = true;
-      } else {
-        Parent::firstFromRed(arc, node);
-        arc.forward = static_cast<Edge&>(arc) == INVALID;
-      }
-    }
-    void nextIn(Arc& arc) const {
-      if (arc.forward) {
-        Parent::nextFromBlue(arc);
-      } else {
-        Parent::nextFromRed(arc);
-        arc.forward = static_cast<Edge&>(arc) == INVALID;
-      }
-    }
-
-    Node source(const Arc& arc) const {
-      return arc.forward ? Parent::red(arc) : Parent::blue(arc);
-    }
-    Node target(const Arc& arc) const {
-      return arc.forward ? Parent::blue(arc) : Parent::red(arc);
-    }
-
-    int id(const Arc& arc) const {
-      return (Parent::id(static_cast<const Edge&>(arc)) << 1) +
-        (arc.forward ? 0 : 1);
-    }
-    Arc arcFromId(int ix) const {
-      return Arc(Parent::fromEdgeId(ix >> 1), (ix & 1) == 0);
-    }
-    int maxArcId() const {
-      return (Parent::maxEdgeId() << 1) + 1;
-    }
-
-    bool direction(const Arc& arc) const {
-      return arc.forward;
-    }
-
-    Arc direct(const Edge& arc, bool dir) const {
-      return Arc(arc, dir);
-    }
-
-    int arcNum() const {
-      return 2 * Parent::edgeNum();
-    }
-
-    int edgeNum() const {
-      return Parent::edgeNum();
-    }
-
-
-  };
-}
-
-#endif
Index: lemon/bits/bezier.h
===================================================================
--- lemon/bits/bezier.h	(revision 440)
+++ lemon/bits/bezier.h	(revision 963)
@@ -160,5 +160,5 @@
     const Point d=(a+b)/2;
     const Point e=(b+c)/2;
-    const Point f=(d+e)/2;
+    // const Point f=(d+e)/2;
     R f1=_f(Bezier3(p1,a,d,e),_d);
     R f2=_f(Bezier3(e,d,c,p4),_d);
Index: lemon/bits/default_map.h
===================================================================
--- lemon/bits/default_map.h	(revision 535)
+++ lemon/bits/default_map.h	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -98,5 +98,5 @@
 
 
-#if defined HAVE_LONG_LONG
+#if defined LEMON_HAVE_LONG_LONG
 
   // long long
@@ -154,13 +154,14 @@
   class DefaultMap
     : public DefaultMapSelector<_Graph, _Item, _Value>::Map {
+    typedef typename DefaultMapSelector<_Graph, _Item, _Value>::Map Parent;
+
   public:
-    typedef typename DefaultMapSelector<_Graph, _Item, _Value>::Map Parent;
     typedef DefaultMap<_Graph, _Item, _Value> Map;
 
-    typedef typename Parent::Graph Graph;
+    typedef typename Parent::GraphType GraphType;
     typedef typename Parent::Value Value;
 
-    explicit DefaultMap(const Graph& graph) : Parent(graph) {}
-    DefaultMap(const Graph& graph, const Value& value)
+    explicit DefaultMap(const GraphType& graph) : Parent(graph) {}
+    DefaultMap(const GraphType& graph, const Value& value)
       : Parent(graph, value) {}
 
Index: lemon/bits/edge_set_extender.h
===================================================================
--- lemon/bits/edge_set_extender.h	(revision 559)
+++ lemon/bits/edge_set_extender.h	(revision 966)
@@ -1,7 +1,7 @@
-/* -*- C++ -*-
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
  *
- * This file is a part of LEMON, a generic C++ optimization library
+ * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -35,7 +35,8 @@
   template <typename Base>
   class ArcSetExtender : public Base {
+    typedef Base Parent;
+
   public:
 
-    typedef Base Parent;
     typedef ArcSetExtender Digraph;
 
@@ -63,9 +64,9 @@
     Node oppositeNode(const Node &n, const Arc &e) const {
       if (n == Parent::source(e))
-	return Parent::target(e);
+        return Parent::target(e);
       else if(n==Parent::target(e))
-	return Parent::source(e);
+        return Parent::source(e);
       else
-	return INVALID;
+        return INVALID;
     }
 
@@ -91,5 +92,5 @@
     // Iterable extensions
 
-    class NodeIt : public Node { 
+    class NodeIt : public Node {
       const Digraph* digraph;
     public:
@@ -100,19 +101,19 @@
 
       explicit NodeIt(const Digraph& _graph) : digraph(&_graph) {
-	_graph.first(static_cast<Node&>(*this));
-      }
-
-      NodeIt(const Digraph& _graph, const Node& node) 
-	: Node(node), digraph(&_graph) {}
-
-      NodeIt& operator++() { 
-	digraph->next(*this);
-	return *this; 
-      }
-
-    };
-
-
-    class ArcIt : public Arc { 
+        _graph.first(static_cast<Node&>(*this));
+      }
+
+      NodeIt(const Digraph& _graph, const Node& node)
+        : Node(node), digraph(&_graph) {}
+
+      NodeIt& operator++() {
+        digraph->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class ArcIt : public Arc {
       const Digraph* digraph;
     public:
@@ -123,19 +124,19 @@
 
       explicit ArcIt(const Digraph& _graph) : digraph(&_graph) {
-	_graph.first(static_cast<Arc&>(*this));
-      }
-
-      ArcIt(const Digraph& _graph, const Arc& e) : 
-	Arc(e), digraph(&_graph) { }
-
-      ArcIt& operator++() { 
-	digraph->next(*this);
-	return *this; 
-      }
-
-    };
-
-
-    class OutArcIt : public Arc { 
+        _graph.first(static_cast<Arc&>(*this));
+      }
+
+      ArcIt(const Digraph& _graph, const Arc& e) :
+        Arc(e), digraph(&_graph) { }
+
+      ArcIt& operator++() {
+        digraph->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class OutArcIt : public Arc {
       const Digraph* digraph;
     public:
@@ -145,21 +146,21 @@
       OutArcIt(Invalid i) : Arc(i) { }
 
-      OutArcIt(const Digraph& _graph, const Node& node) 
-	: digraph(&_graph) {
-	_graph.firstOut(*this, node);
-      }
-
-      OutArcIt(const Digraph& _graph, const Arc& arc) 
-	: Arc(arc), digraph(&_graph) {}
-
-      OutArcIt& operator++() { 
-	digraph->nextOut(*this);
-	return *this; 
-      }
-
-    };
-
-
-    class InArcIt : public Arc { 
+      OutArcIt(const Digraph& _graph, const Node& node)
+        : digraph(&_graph) {
+        _graph.firstOut(*this, node);
+      }
+
+      OutArcIt(const Digraph& _graph, const Arc& arc)
+        : Arc(arc), digraph(&_graph) {}
+
+      OutArcIt& operator++() {
+        digraph->nextOut(*this);
+        return *this;
+      }
+
+    };
+
+
+    class InArcIt : public Arc {
       const Digraph* digraph;
     public:
@@ -169,15 +170,15 @@
       InArcIt(Invalid i) : Arc(i) { }
 
-      InArcIt(const Digraph& _graph, const Node& node) 
-	: digraph(&_graph) {
-	_graph.firstIn(*this, node);
-      }
-
-      InArcIt(const Digraph& _graph, const Arc& arc) : 
-	Arc(arc), digraph(&_graph) {}
-
-      InArcIt& operator++() { 
-	digraph->nextIn(*this);
-	return *this; 
+      InArcIt(const Digraph& _graph, const Node& node)
+        : digraph(&_graph) {
+        _graph.firstIn(*this, node);
+      }
+
+      InArcIt(const Digraph& _graph, const Arc& arc) :
+        Arc(arc), digraph(&_graph) {}
+
+      InArcIt& operator++() {
+        digraph->nextIn(*this);
+        return *this;
       }
 
@@ -215,19 +216,18 @@
 
     // Mappable extension
-    
+
     template <typename _Value>
-    class ArcMap 
+    class ArcMap
       : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
-    public:
-      typedef ArcSetExtender Digraph;
       typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
 
-      explicit ArcMap(const Digraph& _g) 
-	: Parent(_g) {}
-      ArcMap(const Digraph& _g, const _Value& _v) 
-	: Parent(_g, _v) {}
+    public:
+      explicit ArcMap(const Digraph& _g)
+        : Parent(_g) {}
+      ArcMap(const Digraph& _g, const _Value& _v)
+        : Parent(_g, _v) {}
 
       ArcMap& operator=(const ArcMap& cmap) {
-	return operator=<ArcMap>(cmap);
+        return operator=<ArcMap>(cmap);
       }
 
@@ -235,5 +235,5 @@
       ArcMap& operator=(const CMap& cmap) {
         Parent::operator=(cmap);
-	return *this;
+        return *this;
       }
 
@@ -248,5 +248,5 @@
       return arc;
     }
-    
+
     void clear() {
       notifier(Arc()).clear();
@@ -275,9 +275,11 @@
   template <typename Base>
   class EdgeSetExtender : public Base {
+    typedef Base Parent;
 
   public:
 
-    typedef Base Parent;
-    typedef EdgeSetExtender Digraph;
+    typedef EdgeSetExtender Graph;
+
+    typedef True UndirectedTag;
 
     typedef typename Parent::Node Node;
@@ -285,5 +287,4 @@
     typedef typename Parent::Edge Edge;
 
-
     int maxId(Node) const {
       return Parent::maxNodeId();
@@ -312,9 +313,9 @@
     Node oppositeNode(const Node &n, const Edge &e) const {
       if( n == Parent::u(e))
-	return Parent::v(e);
+        return Parent::v(e);
       else if( n == Parent::v(e))
-	return Parent::u(e);
+        return Parent::u(e);
       else
-	return INVALID;
+        return INVALID;
     }
 
@@ -340,5 +341,5 @@
 
     using Parent::notifier;
-    
+
     ArcNotifier& notifier(Arc) const {
       return arc_notifier;
@@ -350,6 +351,6 @@
 
 
-    class NodeIt : public Node { 
-      const Digraph* digraph;
+    class NodeIt : public Node {
+      const Graph* graph;
     public:
 
@@ -358,21 +359,21 @@
       NodeIt(Invalid i) : Node(i) { }
 
-      explicit NodeIt(const Digraph& _graph) : digraph(&_graph) {
-	_graph.first(static_cast<Node&>(*this));
-      }
-
-      NodeIt(const Digraph& _graph, const Node& node) 
-	: Node(node), digraph(&_graph) {}
-
-      NodeIt& operator++() { 
-	digraph->next(*this);
-	return *this; 
-      }
-
-    };
-
-
-    class ArcIt : public Arc { 
-      const Digraph* digraph;
+      explicit NodeIt(const Graph& _graph) : graph(&_graph) {
+        _graph.first(static_cast<Node&>(*this));
+      }
+
+      NodeIt(const Graph& _graph, const Node& node)
+        : Node(node), graph(&_graph) {}
+
+      NodeIt& operator++() {
+        graph->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class ArcIt : public Arc {
+      const Graph* graph;
     public:
 
@@ -381,21 +382,21 @@
       ArcIt(Invalid i) : Arc(i) { }
 
-      explicit ArcIt(const Digraph& _graph) : digraph(&_graph) {
-	_graph.first(static_cast<Arc&>(*this));
-      }
-
-      ArcIt(const Digraph& _graph, const Arc& e) : 
-	Arc(e), digraph(&_graph) { }
-
-      ArcIt& operator++() { 
-	digraph->next(*this);
-	return *this; 
-      }
-
-    };
-
-
-    class OutArcIt : public Arc { 
-      const Digraph* digraph;
+      explicit ArcIt(const Graph& _graph) : graph(&_graph) {
+        _graph.first(static_cast<Arc&>(*this));
+      }
+
+      ArcIt(const Graph& _graph, const Arc& e) :
+        Arc(e), graph(&_graph) { }
+
+      ArcIt& operator++() {
+        graph->next(*this);
+        return *this;
+      }
+
+    };
+
+
+    class OutArcIt : public Arc {
+      const Graph* graph;
     public:
 
@@ -404,22 +405,22 @@
       OutArcIt(Invalid i) : Arc(i) { }
 
-      OutArcIt(const Digraph& _graph, const Node& node) 
-	: digraph(&_graph) {
-	_graph.firstOut(*this, node);
-      }
-
-      OutArcIt(const Digraph& _graph, const Arc& arc) 
-	: Arc(arc), digraph(&_graph) {}
-
-      OutArcIt& operator++() { 
-	digraph->nextOut(*this);
-	return *this; 
-      }
-
-    };
-
-
-    class InArcIt : public Arc { 
-      const Digraph* digraph;
+      OutArcIt(const Graph& _graph, const Node& node)
+        : graph(&_graph) {
+        _graph.firstOut(*this, node);
+      }
+
+      OutArcIt(const Graph& _graph, const Arc& arc)
+        : Arc(arc), graph(&_graph) {}
+
+      OutArcIt& operator++() {
+        graph->nextOut(*this);
+        return *this;
+      }
+
+    };
+
+
+    class InArcIt : public Arc {
+      const Graph* graph;
     public:
 
@@ -428,22 +429,22 @@
       InArcIt(Invalid i) : Arc(i) { }
 
-      InArcIt(const Digraph& _graph, const Node& node) 
-	: digraph(&_graph) {
-	_graph.firstIn(*this, node);
-      }
-
-      InArcIt(const Digraph& _graph, const Arc& arc) : 
-	Arc(arc), digraph(&_graph) {}
-
-      InArcIt& operator++() { 
-	digraph->nextIn(*this);
-	return *this; 
-      }
-
-    };
-
-
-    class EdgeIt : public Parent::Edge { 
-      const Digraph* digraph;
+      InArcIt(const Graph& _graph, const Node& node)
+        : graph(&_graph) {
+        _graph.firstIn(*this, node);
+      }
+
+      InArcIt(const Graph& _graph, const Arc& arc) :
+        Arc(arc), graph(&_graph) {}
+
+      InArcIt& operator++() {
+        graph->nextIn(*this);
+        return *this;
+      }
+
+    };
+
+
+    class EdgeIt : public Parent::Edge {
+      const Graph* graph;
     public:
 
@@ -452,14 +453,14 @@
       EdgeIt(Invalid i) : Edge(i) { }
 
-      explicit EdgeIt(const Digraph& _graph) : digraph(&_graph) {
-	_graph.first(static_cast<Edge&>(*this));
-      }
-
-      EdgeIt(const Digraph& _graph, const Edge& e) : 
-	Edge(e), digraph(&_graph) { }
-
-      EdgeIt& operator++() { 
-	digraph->next(*this);
-	return *this; 
+      explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
+        _graph.first(static_cast<Edge&>(*this));
+      }
+
+      EdgeIt(const Graph& _graph, const Edge& e) :
+        Edge(e), graph(&_graph) { }
+
+      EdgeIt& operator++() {
+        graph->next(*this);
+        return *this;
       }
 
@@ -468,5 +469,5 @@
     class IncEdgeIt : public Parent::Edge {
       friend class EdgeSetExtender;
-      const Digraph* digraph;
+      const Graph* graph;
       bool direction;
     public:
@@ -476,16 +477,16 @@
       IncEdgeIt(Invalid i) : Edge(i), direction(false) { }
 
-      IncEdgeIt(const Digraph& _graph, const Node &n) : digraph(&_graph) {
-	_graph.firstInc(*this, direction, n);
-      }
-
-      IncEdgeIt(const Digraph& _graph, const Edge &ue, const Node &n)
-	: digraph(&_graph), Edge(ue) {
-	direction = (_graph.source(ue) == n);
+      IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) {
+        _graph.firstInc(*this, direction, n);
+      }
+
+      IncEdgeIt(const Graph& _graph, const Edge &ue, const Node &n)
+        : graph(&_graph), Edge(ue) {
+        direction = (_graph.source(ue) == n);
       }
 
       IncEdgeIt& operator++() {
-	digraph->nextInc(*this, direction);
-	return *this; 
+        graph->nextInc(*this, direction);
+        return *this;
       }
     };
@@ -523,5 +524,5 @@
     // Returns the base node of the iterator
     Node baseNode(const IncEdgeIt &e) const {
-      return e.direction ? u(e) : v(e);
+      return e.direction ? this->u(e) : this->v(e);
     }
     // Running node of the iterator
@@ -529,22 +530,21 @@
     // Returns the running node of the iterator
     Node runningNode(const IncEdgeIt &e) const {
-      return e.direction ? v(e) : u(e);
+      return e.direction ? this->v(e) : this->u(e);
     }
 
 
     template <typename _Value>
-    class ArcMap 
-      : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
-    public:
-      typedef EdgeSetExtender Digraph;
-      typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
-
-      ArcMap(const Digraph& _g) 
-	: Parent(_g) {}
-      ArcMap(const Digraph& _g, const _Value& _v) 
-	: Parent(_g, _v) {}
+    class ArcMap
+      : public MapExtender<DefaultMap<Graph, Arc, _Value> > {
+      typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
+
+    public:
+      explicit ArcMap(const Graph& _g)
+        : Parent(_g) {}
+      ArcMap(const Graph& _g, const _Value& _v)
+        : Parent(_g, _v) {}
 
       ArcMap& operator=(const ArcMap& cmap) {
-	return operator=<ArcMap>(cmap);
+        return operator=<ArcMap>(cmap);
       }
 
@@ -552,5 +552,5 @@
       ArcMap& operator=(const CMap& cmap) {
         Parent::operator=(cmap);
-	return *this;
+        return *this;
       }
 
@@ -559,18 +559,17 @@
 
     template <typename _Value>
-    class EdgeMap 
-      : public MapExtender<DefaultMap<Digraph, Edge, _Value> > {
-    public:
-      typedef EdgeSetExtender Digraph;
-      typedef MapExtender<DefaultMap<Digraph, Edge, _Value> > Parent;
-
-      EdgeMap(const Digraph& _g) 
-	: Parent(_g) {}
-
-      EdgeMap(const Digraph& _g, const _Value& _v) 
-	: Parent(_g, _v) {}
+    class EdgeMap
+      : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
+      typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
+
+    public:
+      explicit EdgeMap(const Graph& _g)
+        : Parent(_g) {}
+
+      EdgeMap(const Graph& _g, const _Value& _v)
+        : Parent(_g, _v) {}
 
       EdgeMap& operator=(const EdgeMap& cmap) {
-	return operator=<EdgeMap>(cmap);
+        return operator=<EdgeMap>(cmap);
       }
 
@@ -578,5 +577,5 @@
       EdgeMap& operator=(const CMap& cmap) {
         Parent::operator=(cmap);
-	return *this;
+        return *this;
       }
 
@@ -595,5 +594,5 @@
       return edge;
     }
-    
+
     void clear() {
       notifier(Arc()).clear();
@@ -621,5 +620,5 @@
       arc_notifier.clear();
     }
-    
+
   };
 
Index: lemon/bits/graph_adaptor_extender.h
===================================================================
--- lemon/bits/graph_adaptor_extender.h	(revision 455)
+++ lemon/bits/graph_adaptor_extender.h	(revision 927)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2011
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -23,13 +23,12 @@
 #include <lemon/error.h>
 
-#include <lemon/bits/default_map.h>
-
 namespace lemon {
 
   template <typename _Digraph>
   class DigraphAdaptorExtender : public _Digraph {
+    typedef _Digraph Parent;
+
   public:
 
-    typedef _Digraph Parent;
     typedef _Digraph Digraph;
     typedef DigraphAdaptorExtender Adaptor;
@@ -176,9 +175,12 @@
   template <typename _Graph>
   class GraphAdaptorExtender : public _Graph {
+    typedef _Graph Parent;
+
   public:
 
-    typedef _Graph Parent;
     typedef _Graph Graph;
     typedef GraphAdaptorExtender Adaptor;
+
+    typedef True UndirectedTag;
 
     typedef typename Parent::Node Node;
Index: lemon/bits/graph_extender.h
===================================================================
--- lemon/bits/graph_extender.h	(revision 440)
+++ lemon/bits/graph_extender.h	(revision 964)
@@ -38,7 +38,8 @@
   template <typename Base>
   class DigraphExtender : public Base {
+    typedef Base Parent;
+
   public:
 
-    typedef Base Parent;
     typedef DigraphExtender Digraph;
 
@@ -56,9 +57,9 @@
     }
 
-    Node fromId(int id, Node) const {
+    static Node fromId(int id, Node) {
       return Parent::nodeFromId(id);
     }
 
-    Arc fromId(int id, Arc) const {
+    static Arc fromId(int id, Arc) {
       return Parent::arcFromId(id);
     }
@@ -219,8 +220,7 @@
     class NodeMap
       : public MapExtender<DefaultMap<Digraph, Node, _Value> > {
-    public:
-      typedef DigraphExtender Digraph;
       typedef MapExtender<DefaultMap<Digraph, Node, _Value> > Parent;
 
+    public:
       explicit NodeMap(const Digraph& digraph)
         : Parent(digraph) {}
@@ -244,8 +244,7 @@
     class ArcMap
       : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
-    public:
-      typedef DigraphExtender Digraph;
       typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
 
+    public:
       explicit ArcMap(const Digraph& digraph)
         : Parent(digraph) {}
@@ -331,7 +330,8 @@
   template <typename Base>
   class GraphExtender : public Base {
+    typedef Base Parent;
+
   public:
 
-    typedef Base Parent;
     typedef GraphExtender Graph;
 
@@ -356,13 +356,13 @@
     }
 
-    Node fromId(int id, Node) const {
+    static Node fromId(int id, Node) {
       return Parent::nodeFromId(id);
     }
 
-    Arc fromId(int id, Arc) const {
+    static Arc fromId(int id, Arc) {
       return Parent::arcFromId(id);
     }
 
-    Edge fromId(int id, Edge) const {
+    static Edge fromId(int id, Edge) {
       return Parent::edgeFromId(id);
     }
@@ -588,5 +588,5 @@
     // Returns the base node of the iterator
     Node baseNode(const IncEdgeIt &edge) const {
-      return edge._direction ? u(edge) : v(edge);
+      return edge._direction ? this->u(edge) : this->v(edge);
     }
     // Running node of the iterator
@@ -594,5 +594,5 @@
     // Returns the running node of the iterator
     Node runningNode(const IncEdgeIt &edge) const {
-      return edge._direction ? v(edge) : u(edge);
+      return edge._direction ? this->v(edge) : this->u(edge);
     }
 
@@ -602,9 +602,8 @@
     class NodeMap
       : public MapExtender<DefaultMap<Graph, Node, _Value> > {
-    public:
-      typedef GraphExtender Graph;
       typedef MapExtender<DefaultMap<Graph, Node, _Value> > Parent;
 
-      NodeMap(const Graph& graph)
+    public:
+      explicit NodeMap(const Graph& graph)
         : Parent(graph) {}
       NodeMap(const Graph& graph, const _Value& value)
@@ -627,9 +626,8 @@
     class ArcMap
       : public MapExtender<DefaultMap<Graph, Arc, _Value> > {
-    public:
-      typedef GraphExtender Graph;
       typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
 
-      ArcMap(const Graph& graph)
+    public:
+      explicit ArcMap(const Graph& graph)
         : Parent(graph) {}
       ArcMap(const Graph& graph, const _Value& value)
@@ -652,9 +650,8 @@
     class EdgeMap
       : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
-    public:
-      typedef GraphExtender Graph;
       typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
 
-      EdgeMap(const Graph& graph)
+    public:
+      explicit EdgeMap(const Graph& graph)
         : Parent(graph) {}
 
Index: lemon/bits/map_extender.h
===================================================================
--- lemon/bits/map_extender.h	(revision 440)
+++ lemon/bits/map_extender.h	(revision 802)
@@ -37,15 +37,18 @@
   template <typename _Map>
   class MapExtender : public _Map {
-  public:
-
     typedef _Map Parent;
+    typedef typename Parent::GraphType GraphType;
+
+  public:
+
     typedef MapExtender Map;
-
-
-    typedef typename Parent::Graph Graph;
     typedef typename Parent::Key Item;
 
     typedef typename Parent::Key Key;
     typedef typename Parent::Value Value;
+    typedef typename Parent::Reference Reference;
+    typedef typename Parent::ConstReference ConstReference;
+
+    typedef typename Parent::ReferenceMapTag ReferenceMapTag;
 
     class MapIt;
@@ -57,8 +60,8 @@
   public:
 
-    MapExtender(const Graph& graph)
+    MapExtender(const GraphType& graph)
       : Parent(graph) {}
 
-    MapExtender(const Graph& graph, const Value& value)
+    MapExtender(const GraphType& graph, const Value& value)
       : Parent(graph, value) {}
 
@@ -76,22 +79,63 @@
   public:
     class MapIt : public Item {
-    public:
-
-      typedef Item Parent;
+      typedef Item Parent;
+
+    public:
+
       typedef typename Map::Value Value;
 
-      MapIt() {}
-
-      MapIt(Invalid i) : Parent(i) { }
-
-      explicit MapIt(Map& _map) : map(_map) {
-        map.notifier()->first(*this);
+      MapIt() : map(NULL) {}
+
+      MapIt(Invalid i) : Parent(i), map(NULL) {}
+
+      explicit MapIt(Map& _map) : map(&_map) {
+        map->notifier()->first(*this);
       }
 
       MapIt(const Map& _map, const Item& item)
+        : Parent(item), map(&_map) {}
+
+      MapIt& operator++() {
+        map->notifier()->next(*this);
+        return *this;
+      }
+
+      typename MapTraits<Map>::ConstReturnValue operator*() const {
+        return (*map)[*this];
+      }
+
+      typename MapTraits<Map>::ReturnValue operator*() {
+        return (*map)[*this];
+      }
+
+      void set(const Value& value) {
+        map->set(*this, value);
+      }
+
+    protected:
+      Map* map;
+
+    };
+
+    class ConstMapIt : public Item {
+      typedef Item Parent;
+
+    public:
+
+      typedef typename Map::Value Value;
+
+      ConstMapIt() : map(NULL) {}
+
+      ConstMapIt(Invalid i) : Parent(i), map(NULL) {}
+
+      explicit ConstMapIt(Map& _map) : map(&_map) {
+        map->notifier()->first(*this);
+      }
+
+      ConstMapIt(const Map& _map, const Item& item)
         : Parent(item), map(_map) {}
 
-      MapIt& operator++() {
-        map.notifier()->next(*this);
+      ConstMapIt& operator++() {
+        map->notifier()->next(*this);
         return *this;
       }
@@ -101,71 +145,31 @@
       }
 
-      typename MapTraits<Map>::ReturnValue operator*() {
-        return map[*this];
-      }
-
-      void set(const Value& value) {
-        map.set(*this, value);
-      }
-
-    protected:
-      Map& map;
-
-    };
-
-    class ConstMapIt : public Item {
-    public:
-
-      typedef Item Parent;
-
-      typedef typename Map::Value Value;
-
-      ConstMapIt() {}
-
-      ConstMapIt(Invalid i) : Parent(i) { }
-
-      explicit ConstMapIt(Map& _map) : map(_map) {
-        map.notifier()->first(*this);
-      }
-
-      ConstMapIt(const Map& _map, const Item& item)
-        : Parent(item), map(_map) {}
-
-      ConstMapIt& operator++() {
-        map.notifier()->next(*this);
-        return *this;
-      }
-
-      typename MapTraits<Map>::ConstReturnValue operator*() const {
-        return map[*this];
-      }
-
-    protected:
-      const Map& map;
+    protected:
+      const Map* map;
     };
 
     class ItemIt : public Item {
-    public:
-
-      typedef Item Parent;
-
-      ItemIt() {}
-
-      ItemIt(Invalid i) : Parent(i) { }
-
-      explicit ItemIt(Map& _map) : map(_map) {
-        map.notifier()->first(*this);
+      typedef Item Parent;
+
+    public:
+      ItemIt() : map(NULL) {}
+
+
+      ItemIt(Invalid i) : Parent(i), map(NULL) {}
+
+      explicit ItemIt(Map& _map) : map(&_map) {
+        map->notifier()->first(*this);
       }
 
       ItemIt(const Map& _map, const Item& item)
-        : Parent(item), map(_map) {}
+        : Parent(item), map(&_map) {}
 
       ItemIt& operator++() {
-        map.notifier()->next(*this);
-        return *this;
-      }
-
-    protected:
-      const Map& map;
+        map->notifier()->next(*this);
+        return *this;
+      }
+
+    protected:
+      const Map* map;
 
     };
@@ -177,15 +181,18 @@
   template <typename _Graph, typename _Map>
   class SubMapExtender : public _Map {
-  public:
-
     typedef _Map Parent;
+    typedef _Graph GraphType;
+
+  public:
+
     typedef SubMapExtender Map;
-
-    typedef _Graph Graph;
-
     typedef typename Parent::Key Item;
 
     typedef typename Parent::Key Key;
     typedef typename Parent::Value Value;
+    typedef typename Parent::Reference Reference;
+    typedef typename Parent::ConstReference ConstReference;
+
+    typedef typename Parent::ReferenceMapTag ReferenceMapTag;
 
     class MapIt;
@@ -197,8 +204,8 @@
   public:
 
-    SubMapExtender(const Graph& _graph)
+    SubMapExtender(const GraphType& _graph)
       : Parent(_graph), graph(_graph) {}
 
-    SubMapExtender(const Graph& _graph, const Value& _value)
+    SubMapExtender(const GraphType& _graph, const Value& _value)
       : Parent(_graph, _value), graph(_graph) {}
 
@@ -220,96 +227,96 @@
   public:
     class MapIt : public Item {
-    public:
-
-      typedef Item Parent;
+      typedef Item Parent;
+
+    public:
       typedef typename Map::Value Value;
 
-      MapIt() {}
-
-      MapIt(Invalid i) : Parent(i) { }
-
-      explicit MapIt(Map& _map) : map(_map) {
-        map.graph.first(*this);
+      MapIt() : map(NULL) {}
+
+      MapIt(Invalid i) : Parent(i), map(NULL) { }
+
+      explicit MapIt(Map& _map) : map(&_map) {
+        map->graph.first(*this);
       }
 
       MapIt(const Map& _map, const Item& item)
-        : Parent(item), map(_map) {}
+        : Parent(item), map(&_map) {}
 
       MapIt& operator++() {
-        map.graph.next(*this);
+        map->graph.next(*this);
         return *this;
       }
 
       typename MapTraits<Map>::ConstReturnValue operator*() const {
-        return map[*this];
+        return (*map)[*this];
       }
 
       typename MapTraits<Map>::ReturnValue operator*() {
-        return map[*this];
+        return (*map)[*this];
       }
 
       void set(const Value& value) {
-        map.set(*this, value);
-      }
-
-    protected:
-      Map& map;
+        map->set(*this, value);
+      }
+
+    protected:
+      Map* map;
 
     };
 
     class ConstMapIt : public Item {
-    public:
-
-      typedef Item Parent;
+      typedef Item Parent;
+
+    public:
 
       typedef typename Map::Value Value;
 
-      ConstMapIt() {}
-
-      ConstMapIt(Invalid i) : Parent(i) { }
-
-      explicit ConstMapIt(Map& _map) : map(_map) {
-        map.graph.first(*this);
+      ConstMapIt() : map(NULL) {}
+
+      ConstMapIt(Invalid i) : Parent(i), map(NULL) { }
+
+      explicit ConstMapIt(Map& _map) : map(&_map) {
+        map->graph.first(*this);
       }
 
       ConstMapIt(const Map& _map, const Item& item)
-        : Parent(item), map(_map) {}
+        : Parent(item), map(&_map) {}
 
       ConstMapIt& operator++() {
-        map.graph.next(*this);
+        map->graph.next(*this);
         return *this;
       }
 
       typename MapTraits<Map>::ConstReturnValue operator*() const {
-        return map[*this];
-      }
-
-    protected:
-      const Map& map;
+        return (*map)[*this];
+      }
+
+    protected:
+      const Map* map;
     };
 
     class ItemIt : public Item {
-    public:
-
-      typedef Item Parent;
-
-      ItemIt() {}
-
-      ItemIt(Invalid i) : Parent(i) { }
-
-      explicit ItemIt(Map& _map) : map(_map) {
-        map.graph.first(*this);
+      typedef Item Parent;
+
+    public:
+      ItemIt() : map(NULL) {}
+
+
+      ItemIt(Invalid i) : Parent(i), map(NULL) { }
+
+      explicit ItemIt(Map& _map) : map(&_map) {
+        map->graph.first(*this);
       }
 
       ItemIt(const Map& _map, const Item& item)
-        : Parent(item), map(_map) {}
+        : Parent(item), map(&_map) {}
 
       ItemIt& operator++() {
-        map.graph.next(*this);
-        return *this;
-      }
-
-    protected:
-      const Map& map;
+        map->graph.next(*this);
+        return *this;
+      }
+
+    protected:
+      const Map* map;
 
     };
@@ -317,5 +324,5 @@
   private:
 
-    const Graph& graph;
+    const GraphType& graph;
 
   };
Index: lemon/bits/path_dump.h
===================================================================
--- lemon/bits/path_dump.h	(revision 529)
+++ lemon/bits/path_dump.h	(revision 927)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2011
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -50,5 +50,5 @@
 
     bool empty() const {
-      return predMap[target] != INVALID;
+      return predMap[target] == INVALID;
     }
 
@@ -124,5 +124,5 @@
 
     bool empty() const {
-      return source != target;
+      return predMatrixMap(source, target) == INVALID;
     }
 
Index: lemon/bits/solver_bits.h
===================================================================
--- lemon/bits/solver_bits.h	(revision 519)
+++ lemon/bits/solver_bits.h	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -45,4 +45,5 @@
       void clear() {
         first_item = -1;
+        last_item = -1;
         first_free_item = -1;
         items.clear();
Index: lemon/bits/traits.h
===================================================================
--- lemon/bits/traits.h	(revision 440)
+++ lemon/bits/traits.h	(revision 616)
@@ -30,40 +30,42 @@
   struct InvalidType {};
 
-  template <typename _Graph, typename _Item>
+  template <typename GR, typename _Item>
   class ItemSetTraits {};
 
 
-  template <typename Graph, typename Enable = void>
+  template <typename GR, typename Enable = void>
   struct NodeNotifierIndicator {
     typedef InvalidType Type;
   };
-  template <typename Graph>
+  template <typename GR>
   struct NodeNotifierIndicator<
-    Graph,
-    typename enable_if<typename Graph::NodeNotifier::Notifier, void>::type
-  > {
-    typedef typename Graph::NodeNotifier Type;
-  };
-
-  template <typename _Graph>
-  class ItemSetTraits<_Graph, typename _Graph::Node> {
+    GR,
+    typename enable_if<typename GR::NodeNotifier::Notifier, void>::type
+  > {
+    typedef typename GR::NodeNotifier Type;
+  };
+
+  template <typename GR>
+  class ItemSetTraits<GR, typename GR::Node> {
   public:
 
-    typedef _Graph Graph;
-
-    typedef typename Graph::Node Item;
-    typedef typename Graph::NodeIt ItemIt;
-
-    typedef typename NodeNotifierIndicator<Graph>::Type ItemNotifier;
-
-    template <typename _Value>
-    class Map : public Graph::template NodeMap<_Value> {
+    typedef GR Graph;
+    typedef GR Digraph;
+
+    typedef typename GR::Node Item;
+    typedef typename GR::NodeIt ItemIt;
+
+    typedef typename NodeNotifierIndicator<GR>::Type ItemNotifier;
+
+    template <typename V>
+    class Map : public GR::template NodeMap<V> {
+      typedef typename GR::template NodeMap<V> Parent;
+
     public:
-      typedef typename Graph::template NodeMap<_Value> Parent;
-      typedef typename Graph::template NodeMap<_Value> Type;
+      typedef typename GR::template NodeMap<V> Type;
       typedef typename Parent::Value Value;
 
-      Map(const Graph& _digraph) : Parent(_digraph) {}
-      Map(const Graph& _digraph, const Value& _value)
+      Map(const GR& _digraph) : Parent(_digraph) {}
+      Map(const GR& _digraph, const Value& _value)
         : Parent(_digraph, _value) {}
 
@@ -72,36 +74,38 @@
   };
 
-  template <typename Graph, typename Enable = void>
+  template <typename GR, typename Enable = void>
   struct ArcNotifierIndicator {
     typedef InvalidType Type;
   };
-  template <typename Graph>
+  template <typename GR>
   struct ArcNotifierIndicator<
-    Graph,
-    typename enable_if<typename Graph::ArcNotifier::Notifier, void>::type
-  > {
-    typedef typename Graph::ArcNotifier Type;
-  };
-
-  template <typename _Graph>
-  class ItemSetTraits<_Graph, typename _Graph::Arc> {
+    GR,
+    typename enable_if<typename GR::ArcNotifier::Notifier, void>::type
+  > {
+    typedef typename GR::ArcNotifier Type;
+  };
+
+  template <typename GR>
+  class ItemSetTraits<GR, typename GR::Arc> {
   public:
 
-    typedef _Graph Graph;
-
-    typedef typename Graph::Arc Item;
-    typedef typename Graph::ArcIt ItemIt;
-
-    typedef typename ArcNotifierIndicator<Graph>::Type ItemNotifier;
-
-    template <typename _Value>
-    class Map : public Graph::template ArcMap<_Value> {
+    typedef GR Graph;
+    typedef GR Digraph;
+
+    typedef typename GR::Arc Item;
+    typedef typename GR::ArcIt ItemIt;
+
+    typedef typename ArcNotifierIndicator<GR>::Type ItemNotifier;
+
+    template <typename V>
+    class Map : public GR::template ArcMap<V> {
+      typedef typename GR::template ArcMap<V> Parent;
+
     public:
-      typedef typename Graph::template ArcMap<_Value> Parent;
-      typedef typename Graph::template ArcMap<_Value> Type;
+      typedef typename GR::template ArcMap<V> Type;
       typedef typename Parent::Value Value;
 
-      Map(const Graph& _digraph) : Parent(_digraph) {}
-      Map(const Graph& _digraph, const Value& _value)
+      Map(const GR& _digraph) : Parent(_digraph) {}
+      Map(const GR& _digraph, const Value& _value)
         : Parent(_digraph, _value) {}
     };
@@ -109,36 +113,38 @@
   };
 
-  template <typename Graph, typename Enable = void>
+  template <typename GR, typename Enable = void>
   struct EdgeNotifierIndicator {
     typedef InvalidType Type;
   };
-  template <typename Graph>
+  template <typename GR>
   struct EdgeNotifierIndicator<
-    Graph,
-    typename enable_if<typename Graph::EdgeNotifier::Notifier, void>::type
-  > {
-    typedef typename Graph::EdgeNotifier Type;
-  };
-
-  template <typename _Graph>
-  class ItemSetTraits<_Graph, typename _Graph::Edge> {
+    GR,
+    typename enable_if<typename GR::EdgeNotifier::Notifier, void>::type
+  > {
+    typedef typename GR::EdgeNotifier Type;
+  };
+
+  template <typename GR>
+  class ItemSetTraits<GR, typename GR::Edge> {
   public:
 
-    typedef _Graph Graph;
-
-    typedef typename Graph::Edge Item;
-    typedef typename Graph::EdgeIt ItemIt;
-
-    typedef typename EdgeNotifierIndicator<Graph>::Type ItemNotifier;
-
-    template <typename _Value>
-    class Map : public Graph::template EdgeMap<_Value> {
+    typedef GR Graph;
+    typedef GR Digraph;
+
+    typedef typename GR::Edge Item;
+    typedef typename GR::EdgeIt ItemIt;
+
+    typedef typename EdgeNotifierIndicator<GR>::Type ItemNotifier;
+
+    template <typename V>
+    class Map : public GR::template EdgeMap<V> {
+      typedef typename GR::template EdgeMap<V> Parent;
+
     public:
-      typedef typename Graph::template EdgeMap<_Value> Parent;
-      typedef typename Graph::template EdgeMap<_Value> Type;
+      typedef typename GR::template EdgeMap<V> Type;
       typedef typename Parent::Value Value;
 
-      Map(const Graph& _digraph) : Parent(_digraph) {}
-      Map(const Graph& _digraph, const Value& _value)
+      Map(const GR& _digraph) : Parent(_digraph) {}
+      Map(const GR& _digraph, const Value& _value)
         : Parent(_digraph, _value) {}
     };
@@ -205,91 +211,91 @@
   // Indicators for the tags
 
-  template <typename Graph, typename Enable = void>
+  template <typename GR, typename Enable = void>
   struct NodeNumTagIndicator {
     static const bool value = false;
   };
 
-  template <typename Graph>
+  template <typename GR>
   struct NodeNumTagIndicator<
-    Graph,
-    typename enable_if<typename Graph::NodeNumTag, void>::type
-  > {
-    static const bool value = true;
-  };
-
-  template <typename Graph, typename Enable = void>
+    GR,
+    typename enable_if<typename GR::NodeNumTag, void>::type
+  > {
+    static const bool value = true;
+  };
+
+  template <typename GR, typename Enable = void>
   struct ArcNumTagIndicator {
     static const bool value = false;
   };
 
-  template <typename Graph>
+  template <typename GR>
   struct ArcNumTagIndicator<
-    Graph,
-    typename enable_if<typename Graph::ArcNumTag, void>::type
-  > {
-    static const bool value = true;
-  };
-
-  template <typename Graph, typename Enable = void>
+    GR,
+    typename enable_if<typename GR::ArcNumTag, void>::type
+  > {
+    static const bool value = true;
+  };
+
+  template <typename GR, typename Enable = void>
   struct EdgeNumTagIndicator {
     static const bool value = false;
   };
 
-  template <typename Graph>
+  template <typename GR>
   struct EdgeNumTagIndicator<
-    Graph,
-    typename enable_if<typename Graph::EdgeNumTag, void>::type
-  > {
-    static const bool value = true;
-  };
-
-  template <typename Graph, typename Enable = void>
+    GR,
+    typename enable_if<typename GR::EdgeNumTag, void>::type
+  > {
+    static const bool value = true;
+  };
+
+  template <typename GR, typename Enable = void>
   struct FindArcTagIndicator {
     static const bool value = false;
   };
 
-  template <typename Graph>
+  template <typename GR>
   struct FindArcTagIndicator<
-    Graph,
-    typename enable_if<typename Graph::FindArcTag, void>::type
-  > {
-    static const bool value = true;
-  };
-
-  template <typename Graph, typename Enable = void>
+    GR,
+    typename enable_if<typename GR::FindArcTag, void>::type
+  > {
+    static const bool value = true;
+  };
+
+  template <typename GR, typename Enable = void>
   struct FindEdgeTagIndicator {
     static const bool value = false;
   };
 
-  template <typename Graph>
+  template <typename GR>
   struct FindEdgeTagIndicator<
-    Graph,
-    typename enable_if<typename Graph::FindEdgeTag, void>::type
-  > {
-    static const bool value = true;
-  };
-
-  template <typename Graph, typename Enable = void>
+    GR,
+    typename enable_if<typename GR::FindEdgeTag, void>::type
+  > {
+    static const bool value = true;
+  };
+
+  template <typename GR, typename Enable = void>
   struct UndirectedTagIndicator {
     static const bool value = false;
   };
 
-  template <typename Graph>
+  template <typename GR>
   struct UndirectedTagIndicator<
-    Graph,
-    typename enable_if<typename Graph::UndirectedTag, void>::type
-  > {
-    static const bool value = true;
-  };
-
-  template <typename Graph, typename Enable = void>
+    GR,
+    typename enable_if<typename GR::UndirectedTag, void>::type
+  > {
+    static const bool value = true;
+  };
+
+  template <typename GR, typename Enable = void>
   struct BuildTagIndicator {
     static const bool value = false;
   };
 
-  template <typename Graph>
+  template <typename GR>
   struct BuildTagIndicator<
-    Graph,
-    typename enable_if<typename Graph::BuildTag, void>::type
+    GR,
+    typename enable_if<typename GR::BuildTag, void>::type
   > {
     static const bool value = true;
Index: lemon/bits/vector_map.h
===================================================================
--- lemon/bits/vector_map.h	(revision 492)
+++ lemon/bits/vector_map.h	(revision 617)
@@ -57,5 +57,5 @@
 
     // The graph type of the map.
-    typedef _Graph Graph;
+    typedef _Graph GraphType;
     // The item type of the map.
     typedef _Item Item;
@@ -73,6 +73,4 @@
     // The map type.
     typedef VectorMap Map;
-    // The base class of the map.
-    typedef typename Notifier::ObserverBase Parent;
 
     // The reference type of the map;
@@ -81,4 +79,10 @@
     typedef typename Container::const_reference ConstReference;
 
+  private:
+
+    // The base class of the map.
+    typedef typename Notifier::ObserverBase Parent;
+
+  public:
 
     // \brief Constructor to attach the new map into the notifier.
@@ -86,5 +90,5 @@
     // It constructs a map and attachs it into the notifier.
     // It adds all the items of the graph to the map.
-    VectorMap(const Graph& graph) {
+    VectorMap(const GraphType& graph) {
       Parent::attach(graph.notifier(Item()));
       container.resize(Parent::notifier()->maxId() + 1);
@@ -95,5 +99,5 @@
     // It constructs a map uses a given value to initialize the map.
     // It adds all the items of the graph to the map.
-    VectorMap(const Graph& graph, const Value& value) {
+    VectorMap(const GraphType& graph, const Value& value) {
       Parent::attach(graph.notifier(Item()));
       container.resize(Parent::notifier()->maxId() + 1, value);
Index: lemon/bits/windows.cc
===================================================================
--- lemon/bits/windows.cc	(revision 483)
+++ lemon/bits/windows.cc	(revision 927)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2011
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -41,5 +41,7 @@
 #include <unistd.h>
 #include <ctime>
+#ifndef WIN32
 #include <sys/times.h>
+#endif
 #include <sys/time.h>
 #endif
@@ -97,5 +99,5 @@
       GetSystemTime(&time);
       char buf1[11], buf2[9], buf3[5];
-	  if (GetDateFormat(MY_LOCALE, 0, &time,
+          if (GetDateFormat(MY_LOCALE, 0, &time,
                         ("ddd MMM dd"), buf1, 11) &&
           GetTimeFormat(MY_LOCALE, 0, &time,
Index: lemon/bucket_heap.h
===================================================================
--- lemon/bucket_heap.h	(revision 877)
+++ lemon/bucket_heap.h	(revision 877)
@@ -0,0 +1,594 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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_BUCKET_HEAP_H
+#define LEMON_BUCKET_HEAP_H
+
+///\ingroup heaps
+///\file
+///\brief Bucket heap implementation.
+
+#include <vector>
+#include <utility>
+#include <functional>
+
+namespace lemon {
+
+  namespace _bucket_heap_bits {
+
+    template <bool MIN>
+    struct DirectionTraits {
+      static bool less(int left, int right) {
+        return left < right;
+      }
+      static void increase(int& value) {
+        ++value;
+      }
+    };
+
+    template <>
+    struct DirectionTraits<false> {
+      static bool less(int left, int right) {
+        return left > right;
+      }
+      static void increase(int& value) {
+        --value;
+      }
+    };
+
+  }
+
+  /// \ingroup heaps
+  ///
+  /// \brief Bucket heap data structure.
+  ///
+  /// This class implements the \e bucket \e heap data structure.
+  /// It practically conforms to the \ref concepts::Heap "heap concept",
+  /// but it has some limitations.
+  ///
+  /// The bucket heap is a very simple structure. It can store only
+  /// \c int priorities and it maintains a list of items for each priority
+  /// in the range <tt>[0..C)</tt>. So it should only be used when the
+  /// priorities are small. It is not intended to use as a Dijkstra heap.
+  ///
+  /// \tparam IM A read-writable item map with \c int values, used
+  /// internally to handle the cross references.
+  /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
+  /// The default is \e min-heap. If this parameter is set to \c false,
+  /// then the comparison is reversed, so the top(), prio() and pop()
+  /// functions deal with the item having maximum priority instead of the
+  /// minimum.
+  ///
+  /// \sa SimpleBucketHeap
+  template <typename IM, bool MIN = true>
+  class BucketHeap {
+
+  public:
+
+    /// Type of the item-int map.
+    typedef IM ItemIntMap;
+    /// Type of the priorities.
+    typedef int Prio;
+    /// Type of the items stored in the heap.
+    typedef typename ItemIntMap::Key Item;
+    /// Type of the item-priority pairs.
+    typedef std::pair<Item,Prio> Pair;
+
+  private:
+
+    typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
+
+  public:
+
+    /// \brief Type to represent the states of the items.
+    ///
+    /// Each item has a state associated to it. It can be "in heap",
+    /// "pre-heap" or "post-heap". The latter two are indifferent from the
+    /// heap's point of view, but may be useful to the user.
+    ///
+    /// The item-int map must be initialized in such way that it assigns
+    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
+    enum State {
+      IN_HEAP = 0,    ///< = 0.
+      PRE_HEAP = -1,  ///< = -1.
+      POST_HEAP = -2  ///< = -2.
+    };
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    explicit BucketHeap(ItemIntMap &map) : _iim(map), _minimum(0) {}
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// This function returns the number of items stored in the heap.
+    int size() const { return _data.size(); }
+
+    /// \brief Check if the heap is empty.
+    ///
+    /// This function returns \c true if the heap is empty.
+    bool empty() const { return _data.empty(); }
+
+    /// \brief Make the heap empty.
+    ///
+    /// This functon makes the heap empty.
+    /// It does not change the cross reference map. If you want to reuse
+    /// a heap that is not surely empty, you should first clear it and
+    /// then you should set the cross reference map to \c PRE_HEAP
+    /// for each item.
+    void clear() {
+      _data.clear(); _first.clear(); _minimum = 0;
+    }
+
+  private:
+
+    void relocateLast(int idx) {
+      if (idx + 1 < int(_data.size())) {
+        _data[idx] = _data.back();
+        if (_data[idx].prev != -1) {
+          _data[_data[idx].prev].next = idx;
+        } else {
+          _first[_data[idx].value] = idx;
+        }
+        if (_data[idx].next != -1) {
+          _data[_data[idx].next].prev = idx;
+        }
+        _iim[_data[idx].item] = idx;
+      }
+      _data.pop_back();
+    }
+
+    void unlace(int idx) {
+      if (_data[idx].prev != -1) {
+        _data[_data[idx].prev].next = _data[idx].next;
+      } else {
+        _first[_data[idx].value] = _data[idx].next;
+      }
+      if (_data[idx].next != -1) {
+        _data[_data[idx].next].prev = _data[idx].prev;
+      }
+    }
+
+    void lace(int idx) {
+      if (int(_first.size()) <= _data[idx].value) {
+        _first.resize(_data[idx].value + 1, -1);
+      }
+      _data[idx].next = _first[_data[idx].value];
+      if (_data[idx].next != -1) {
+        _data[_data[idx].next].prev = idx;
+      }
+      _first[_data[idx].value] = idx;
+      _data[idx].prev = -1;
+    }
+
+  public:
+
+    /// \brief Insert a pair of item and priority into the heap.
+    ///
+    /// This function inserts \c p.first to the heap with priority
+    /// \c p.second.
+    /// \param p The pair to insert.
+    /// \pre \c p.first must not be stored in the heap.
+    void push(const Pair& p) {
+      push(p.first, p.second);
+    }
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// This function inserts the given item into the heap with the
+    /// given priority.
+    /// \param i The item to insert.
+    /// \param p The priority of the item.
+    /// \pre \e i must not be stored in the heap.
+    void push(const Item &i, const Prio &p) {
+      int idx = _data.size();
+      _iim[i] = idx;
+      _data.push_back(BucketItem(i, p));
+      lace(idx);
+      if (Direction::less(p, _minimum)) {
+        _minimum = p;
+      }
+    }
+
+    /// \brief Return the item having minimum priority.
+    ///
+    /// This function returns the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    Item top() const {
+      while (_first[_minimum] == -1) {
+        Direction::increase(_minimum);
+      }
+      return _data[_first[_minimum]].item;
+    }
+
+    /// \brief The minimum priority.
+    ///
+    /// This function returns the minimum priority.
+    /// \pre The heap must be non-empty.
+    Prio prio() const {
+      while (_first[_minimum] == -1) {
+        Direction::increase(_minimum);
+      }
+      return _minimum;
+    }
+
+    /// \brief Remove the item having minimum priority.
+    ///
+    /// This function removes the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      while (_first[_minimum] == -1) {
+        Direction::increase(_minimum);
+      }
+      int idx = _first[_minimum];
+      _iim[_data[idx].item] = -2;
+      unlace(idx);
+      relocateLast(idx);
+    }
+
+    /// \brief Remove the given item from the heap.
+    ///
+    /// This function removes the given item from the heap if it is
+    /// already stored.
+    /// \param i The item to delete.
+    /// \pre \e i must be in the heap.
+    void erase(const Item &i) {
+      int idx = _iim[i];
+      _iim[_data[idx].item] = -2;
+      unlace(idx);
+      relocateLast(idx);
+    }
+
+    /// \brief The priority of the given item.
+    ///
+    /// This function returns the priority of the given item.
+    /// \param i The item.
+    /// \pre \e i must be in the heap.
+    Prio operator[](const Item &i) const {
+      int idx = _iim[i];
+      return _data[idx].value;
+    }
+
+    /// \brief Set the priority of an item or insert it, if it is
+    /// not stored in the heap.
+    ///
+    /// This method sets the priority of the given item if it is
+    /// already stored in the heap. Otherwise it inserts the given
+    /// item into the heap with the given priority.
+    /// \param i The item.
+    /// \param p The priority.
+    void set(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      if (idx < 0) {
+        push(i, p);
+      } else if (Direction::less(p, _data[idx].value)) {
+        decrease(i, p);
+      } else {
+        increase(i, p);
+      }
+    }
+
+    /// \brief Decrease the priority of an item to the given value.
+    ///
+    /// This function decreases the priority of an item to the given value.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be stored in the heap with priority at least \e p.
+    void decrease(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      unlace(idx);
+      _data[idx].value = p;
+      if (Direction::less(p, _minimum)) {
+        _minimum = p;
+      }
+      lace(idx);
+    }
+
+    /// \brief Increase the priority of an item to the given value.
+    ///
+    /// This function increases the priority of an item to the given value.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be stored in the heap with priority at most \e p.
+    void increase(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      unlace(idx);
+      _data[idx].value = p;
+      lace(idx);
+    }
+
+    /// \brief Return the state of an item.
+    ///
+    /// This method returns \c PRE_HEAP if the given item has never
+    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
+    /// and \c POST_HEAP otherwise.
+    /// In the latter case it is possible that the item will get back
+    /// to the heap again.
+    /// \param i The item.
+    State state(const Item &i) const {
+      int idx = _iim[i];
+      if (idx >= 0) idx = 0;
+      return State(idx);
+    }
+
+    /// \brief Set the state of an item in the heap.
+    ///
+    /// This function sets the state of the given item in the heap.
+    /// It can be used to manually clear the heap when it is important
+    /// to achive better time complexity.
+    /// \param i The item.
+    /// \param st The state. It should not be \c IN_HEAP.
+    void state(const Item& i, State st) {
+      switch (st) {
+      case POST_HEAP:
+      case PRE_HEAP:
+        if (state(i) == IN_HEAP) {
+          erase(i);
+        }
+        _iim[i] = st;
+        break;
+      case IN_HEAP:
+        break;
+      }
+    }
+
+  private:
+
+    struct BucketItem {
+      BucketItem(const Item& _item, int _value)
+        : item(_item), value(_value) {}
+
+      Item item;
+      int value;
+
+      int prev, next;
+    };
+
+    ItemIntMap& _iim;
+    std::vector<int> _first;
+    std::vector<BucketItem> _data;
+    mutable int _minimum;
+
+  }; // class BucketHeap
+
+  /// \ingroup heaps
+  ///
+  /// \brief Simplified bucket heap data structure.
+  ///
+  /// This class implements a simplified \e bucket \e heap data
+  /// structure. It does not provide some functionality, but it is
+  /// faster and simpler than BucketHeap. The main difference is
+  /// that BucketHeap stores a doubly-linked list for each key while
+  /// this class stores only simply-linked lists. It supports erasing
+  /// only for the item having minimum priority and it does not support
+  /// key increasing and decreasing.
+  ///
+  /// Note that this implementation does not conform to the
+  /// \ref concepts::Heap "heap concept" due to the lack of some
+  /// functionality.
+  ///
+  /// \tparam IM A read-writable item map with \c int values, used
+  /// internally to handle the cross references.
+  /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
+  /// The default is \e min-heap. If this parameter is set to \c false,
+  /// then the comparison is reversed, so the top(), prio() and pop()
+  /// functions deal with the item having maximum priority instead of the
+  /// minimum.
+  ///
+  /// \sa BucketHeap
+  template <typename IM, bool MIN = true >
+  class SimpleBucketHeap {
+
+  public:
+
+    /// Type of the item-int map.
+    typedef IM ItemIntMap;
+    /// Type of the priorities.
+    typedef int Prio;
+    /// Type of the items stored in the heap.
+    typedef typename ItemIntMap::Key Item;
+    /// Type of the item-priority pairs.
+    typedef std::pair<Item,Prio> Pair;
+
+  private:
+
+    typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
+
+  public:
+
+    /// \brief Type to represent the states of the items.
+    ///
+    /// Each item has a state associated to it. It can be "in heap",
+    /// "pre-heap" or "post-heap". The latter two are indifferent from the
+    /// heap's point of view, but may be useful to the user.
+    ///
+    /// The item-int map must be initialized in such way that it assigns
+    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
+    enum State {
+      IN_HEAP = 0,    ///< = 0.
+      PRE_HEAP = -1,  ///< = -1.
+      POST_HEAP = -2  ///< = -2.
+    };
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    explicit SimpleBucketHeap(ItemIntMap &map)
+      : _iim(map), _free(-1), _num(0), _minimum(0) {}
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// This function returns the number of items stored in the heap.
+    int size() const { return _num; }
+
+    /// \brief Check if the heap is empty.
+    ///
+    /// This function returns \c true if the heap is empty.
+    bool empty() const { return _num == 0; }
+
+    /// \brief Make the heap empty.
+    ///
+    /// This functon makes the heap empty.
+    /// It does not change the cross reference map. If you want to reuse
+    /// a heap that is not surely empty, you should first clear it and
+    /// then you should set the cross reference map to \c PRE_HEAP
+    /// for each item.
+    void clear() {
+      _data.clear(); _first.clear(); _free = -1; _num = 0; _minimum = 0;
+    }
+
+    /// \brief Insert a pair of item and priority into the heap.
+    ///
+    /// This function inserts \c p.first to the heap with priority
+    /// \c p.second.
+    /// \param p The pair to insert.
+    /// \pre \c p.first must not be stored in the heap.
+    void push(const Pair& p) {
+      push(p.first, p.second);
+    }
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// This function inserts the given item into the heap with the
+    /// given priority.
+    /// \param i The item to insert.
+    /// \param p The priority of the item.
+    /// \pre \e i must not be stored in the heap.
+    void push(const Item &i, const Prio &p) {
+      int idx;
+      if (_free == -1) {
+        idx = _data.size();
+        _data.push_back(BucketItem(i));
+      } else {
+        idx = _free;
+        _free = _data[idx].next;
+        _data[idx].item = i;
+      }
+      _iim[i] = idx;
+      if (p >= int(_first.size())) _first.resize(p + 1, -1);
+      _data[idx].next = _first[p];
+      _first[p] = idx;
+      if (Direction::less(p, _minimum)) {
+        _minimum = p;
+      }
+      ++_num;
+    }
+
+    /// \brief Return the item having minimum priority.
+    ///
+    /// This function returns the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    Item top() const {
+      while (_first[_minimum] == -1) {
+        Direction::increase(_minimum);
+      }
+      return _data[_first[_minimum]].item;
+    }
+
+    /// \brief The minimum priority.
+    ///
+    /// This function returns the minimum priority.
+    /// \pre The heap must be non-empty.
+    Prio prio() const {
+      while (_first[_minimum] == -1) {
+        Direction::increase(_minimum);
+      }
+      return _minimum;
+    }
+
+    /// \brief Remove the item having minimum priority.
+    ///
+    /// This function removes the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      while (_first[_minimum] == -1) {
+        Direction::increase(_minimum);
+      }
+      int idx = _first[_minimum];
+      _iim[_data[idx].item] = -2;
+      _first[_minimum] = _data[idx].next;
+      _data[idx].next = _free;
+      _free = idx;
+      --_num;
+    }
+
+    /// \brief The priority of the given item.
+    ///
+    /// This function returns the priority of the given item.
+    /// \param i The item.
+    /// \pre \e i must be in the heap.
+    /// \warning This operator is not a constant time function because
+    /// it scans the whole data structure to find the proper value.
+    Prio operator[](const Item &i) const {
+      for (int k = 0; k < int(_first.size()); ++k) {
+        int idx = _first[k];
+        while (idx != -1) {
+          if (_data[idx].item == i) {
+            return k;
+          }
+          idx = _data[idx].next;
+        }
+      }
+      return -1;
+    }
+
+    /// \brief Return the state of an item.
+    ///
+    /// This method returns \c PRE_HEAP if the given item has never
+    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
+    /// and \c POST_HEAP otherwise.
+    /// In the latter case it is possible that the item will get back
+    /// to the heap again.
+    /// \param i The item.
+    State state(const Item &i) const {
+      int idx = _iim[i];
+      if (idx >= 0) idx = 0;
+      return State(idx);
+    }
+
+  private:
+
+    struct BucketItem {
+      BucketItem(const Item& _item)
+        : item(_item) {}
+
+      Item item;
+      int next;
+    };
+
+    ItemIntMap& _iim;
+    std::vector<int> _first;
+    std::vector<BucketItem> _data;
+    int _free, _num;
+    mutable int _minimum;
+
+  }; // class SimpleBucketHeap
+
+}
+
+#endif
Index: lemon/capacity_scaling.h
===================================================================
--- lemon/capacity_scaling.h	(revision 1004)
+++ lemon/capacity_scaling.h	(revision 1004)
@@ -0,0 +1,991 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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_CAPACITY_SCALING_H
+#define LEMON_CAPACITY_SCALING_H
+
+/// \ingroup min_cost_flow_algs
+///
+/// \file
+/// \brief Capacity Scaling algorithm for finding a minimum cost flow.
+
+#include <vector>
+#include <limits>
+#include <lemon/core.h>
+#include <lemon/maps.h>
+#include <lemon/bin_heap.h>
+
+namespace lemon {
+
+  /// \brief Default traits class of CapacityScaling algorithm.
+  ///
+  /// Default traits class of CapacityScaling algorithm.
+  /// \tparam GR Digraph type.
+  /// \tparam V The number type used for flow amounts, capacity bounds
+  /// and supply values. By default it is \c int.
+  /// \tparam C The number type used for costs and potentials.
+  /// By default it is the same as \c V.
+  template <typename GR, typename V = int, typename C = V>
+  struct CapacityScalingDefaultTraits
+  {
+    /// The type of the digraph
+    typedef GR Digraph;
+    /// The type of the flow amounts, capacity bounds and supply values
+    typedef V Value;
+    /// The type of the arc costs
+    typedef C Cost;
+
+    /// \brief The type of the heap used for internal Dijkstra computations.
+    ///
+    /// The type of the heap used for internal Dijkstra computations.
+    /// It must conform to the \ref lemon::concepts::Heap "Heap" concept,
+    /// its priority type must be \c Cost and its cross reference type
+    /// must be \ref RangeMap "RangeMap<int>".
+    typedef BinHeap<Cost, RangeMap<int> > Heap;
+  };
+
+  /// \addtogroup min_cost_flow_algs
+  /// @{
+
+  /// \brief Implementation of the Capacity Scaling algorithm for
+  /// finding a \ref min_cost_flow "minimum cost flow".
+  ///
+  /// \ref CapacityScaling implements the capacity scaling version
+  /// of the successive shortest path algorithm for finding a
+  /// \ref min_cost_flow "minimum cost flow" \ref amo93networkflows,
+  /// \ref edmondskarp72theoretical. It is an efficient dual
+  /// solution method.
+  ///
+  /// Most of the parameters of the problem (except for the digraph)
+  /// can be given using separate functions, and the algorithm can be
+  /// executed using the \ref run() function. If some parameters are not
+  /// specified, then default values will be used.
+  ///
+  /// \tparam GR The digraph type the algorithm runs on.
+  /// \tparam V The number type used for flow amounts, capacity bounds
+  /// and supply values in the algorithm. By default, it is \c int.
+  /// \tparam C The number type used for costs and potentials in the
+  /// algorithm. By default, it is the same as \c V.
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm. By default, it is \ref CapacityScalingDefaultTraits
+  /// "CapacityScalingDefaultTraits<GR, V, C>".
+  /// In most cases, this parameter should not be set directly,
+  /// consider to use the named template parameters instead.
+  ///
+  /// \warning Both number types must be signed and all input data must
+  /// be integer.
+  /// \warning This algorithm does not support negative costs for such
+  /// arcs that have infinite upper bound.
+#ifdef DOXYGEN
+  template <typename GR, typename V, typename C, typename TR>
+#else
+  template < typename GR, typename V = int, typename C = V,
+             typename TR = CapacityScalingDefaultTraits<GR, V, C> >
+#endif
+  class CapacityScaling
+  {
+  public:
+
+    /// The type of the digraph
+    typedef typename TR::Digraph Digraph;
+    /// The type of the flow amounts, capacity bounds and supply values
+    typedef typename TR::Value Value;
+    /// The type of the arc costs
+    typedef typename TR::Cost Cost;
+
+    /// The type of the heap used for internal Dijkstra computations
+    typedef typename TR::Heap Heap;
+
+    /// The \ref CapacityScalingDefaultTraits "traits class" of the algorithm
+    typedef TR Traits;
+
+  public:
+
+    /// \brief Problem type constants for the \c run() function.
+    ///
+    /// Enum type containing the problem type constants that can be
+    /// returned by the \ref run() function of the algorithm.
+    enum ProblemType {
+      /// The problem has no feasible solution (flow).
+      INFEASIBLE,
+      /// The problem has optimal solution (i.e. it is feasible and
+      /// bounded), and the algorithm has found optimal flow and node
+      /// potentials (primal and dual solutions).
+      OPTIMAL,
+      /// The digraph contains an arc of negative cost and infinite
+      /// upper bound. It means that the objective function is unbounded
+      /// on that arc, however, note that it could actually be bounded
+      /// over the feasible flows, but this algroithm cannot handle
+      /// these cases.
+      UNBOUNDED
+    };
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
+
+    typedef std::vector<int> IntVector;
+    typedef std::vector<Value> ValueVector;
+    typedef std::vector<Cost> CostVector;
+    typedef std::vector<char> BoolVector;
+    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
+
+  private:
+
+    // Data related to the underlying digraph
+    const GR &_graph;
+    int _node_num;
+    int _arc_num;
+    int _res_arc_num;
+    int _root;
+
+    // Parameters of the problem
+    bool _have_lower;
+    Value _sum_supply;
+
+    // Data structures for storing the digraph
+    IntNodeMap _node_id;
+    IntArcMap _arc_idf;
+    IntArcMap _arc_idb;
+    IntVector _first_out;
+    BoolVector _forward;
+    IntVector _source;
+    IntVector _target;
+    IntVector _reverse;
+
+    // Node and arc data
+    ValueVector _lower;
+    ValueVector _upper;
+    CostVector _cost;
+    ValueVector _supply;
+
+    ValueVector _res_cap;
+    CostVector _pi;
+    ValueVector _excess;
+    IntVector _excess_nodes;
+    IntVector _deficit_nodes;
+
+    Value _delta;
+    int _factor;
+    IntVector _pred;
+
+  public:
+
+    /// \brief Constant for infinite upper bounds (capacities).
+    ///
+    /// Constant for infinite upper bounds (capacities).
+    /// It is \c std::numeric_limits<Value>::infinity() if available,
+    /// \c std::numeric_limits<Value>::max() otherwise.
+    const Value INF;
+
+  private:
+
+    // Special implementation of the Dijkstra algorithm for finding
+    // shortest paths in the residual network of the digraph with
+    // respect to the reduced arc costs and modifying the node
+    // potentials according to the found distance labels.
+    class ResidualDijkstra
+    {
+    private:
+
+      int _node_num;
+      bool _geq;
+      const IntVector &_first_out;
+      const IntVector &_target;
+      const CostVector &_cost;
+      const ValueVector &_res_cap;
+      const ValueVector &_excess;
+      CostVector &_pi;
+      IntVector &_pred;
+
+      IntVector _proc_nodes;
+      CostVector _dist;
+
+    public:
+
+      ResidualDijkstra(CapacityScaling& cs) :
+        _node_num(cs._node_num), _geq(cs._sum_supply < 0),
+        _first_out(cs._first_out), _target(cs._target), _cost(cs._cost),
+        _res_cap(cs._res_cap), _excess(cs._excess), _pi(cs._pi),
+        _pred(cs._pred), _dist(cs._node_num)
+      {}
+
+      int run(int s, Value delta = 1) {
+        RangeMap<int> heap_cross_ref(_node_num, Heap::PRE_HEAP);
+        Heap heap(heap_cross_ref);
+        heap.push(s, 0);
+        _pred[s] = -1;
+        _proc_nodes.clear();
+
+        // Process nodes
+        while (!heap.empty() && _excess[heap.top()] > -delta) {
+          int u = heap.top(), v;
+          Cost d = heap.prio() + _pi[u], dn;
+          _dist[u] = heap.prio();
+          _proc_nodes.push_back(u);
+          heap.pop();
+
+          // Traverse outgoing residual arcs
+          int last_out = _geq ? _first_out[u+1] : _first_out[u+1] - 1;
+          for (int a = _first_out[u]; a != last_out; ++a) {
+            if (_res_cap[a] < delta) continue;
+            v = _target[a];
+            switch (heap.state(v)) {
+              case Heap::PRE_HEAP:
+                heap.push(v, d + _cost[a] - _pi[v]);
+                _pred[v] = a;
+                break;
+              case Heap::IN_HEAP:
+                dn = d + _cost[a] - _pi[v];
+                if (dn < heap[v]) {
+                  heap.decrease(v, dn);
+                  _pred[v] = a;
+                }
+                break;
+              case Heap::POST_HEAP:
+                break;
+            }
+          }
+        }
+        if (heap.empty()) return -1;
+
+        // Update potentials of processed nodes
+        int t = heap.top();
+        Cost dt = heap.prio();
+        for (int i = 0; i < int(_proc_nodes.size()); ++i) {
+          _pi[_proc_nodes[i]] += _dist[_proc_nodes[i]] - dt;
+        }
+
+        return t;
+      }
+
+    }; //class ResidualDijkstra
+
+  public:
+
+    /// \name Named Template Parameters
+    /// @{
+
+    template <typename T>
+    struct SetHeapTraits : public Traits {
+      typedef T Heap;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c Heap type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c Heap
+    /// type, which is used for internal Dijkstra computations.
+    /// It must conform to the \ref lemon::concepts::Heap "Heap" concept,
+    /// its priority type must be \c Cost and its cross reference type
+    /// must be \ref RangeMap "RangeMap<int>".
+    template <typename T>
+    struct SetHeap
+      : public CapacityScaling<GR, V, C, SetHeapTraits<T> > {
+      typedef  CapacityScaling<GR, V, C, SetHeapTraits<T> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    CapacityScaling() {}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// The constructor of the class.
+    ///
+    /// \param graph The digraph the algorithm runs on.
+    CapacityScaling(const GR& graph) :
+      _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph),
+      INF(std::numeric_limits<Value>::has_infinity ?
+          std::numeric_limits<Value>::infinity() :
+          std::numeric_limits<Value>::max())
+    {
+      // Check the number types
+      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
+        "The flow type of CapacityScaling must be signed");
+      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
+        "The cost type of CapacityScaling must be signed");
+
+      // Reset data structures
+      reset();
+    }
+
+    /// \name Parameters
+    /// The parameters of the algorithm can be specified using these
+    /// functions.
+
+    /// @{
+
+    /// \brief Set the lower bounds on the arcs.
+    ///
+    /// This function sets the lower bounds on the arcs.
+    /// If it is not used before calling \ref run(), the lower bounds
+    /// will be set to zero on all arcs.
+    ///
+    /// \param map An arc map storing the lower bounds.
+    /// Its \c Value type must be convertible to the \c Value type
+    /// of the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    template <typename LowerMap>
+    CapacityScaling& lowerMap(const LowerMap& map) {
+      _have_lower = true;
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        _lower[_arc_idf[a]] = map[a];
+        _lower[_arc_idb[a]] = map[a];
+      }
+      return *this;
+    }
+
+    /// \brief Set the upper bounds (capacities) on the arcs.
+    ///
+    /// This function sets the upper bounds (capacities) on the arcs.
+    /// If it is not used before calling \ref run(), the upper bounds
+    /// will be set to \ref INF on all arcs (i.e. the flow value will be
+    /// unbounded from above).
+    ///
+    /// \param map An arc map storing the upper bounds.
+    /// Its \c Value type must be convertible to the \c Value type
+    /// of the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    template<typename UpperMap>
+    CapacityScaling& upperMap(const UpperMap& map) {
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        _upper[_arc_idf[a]] = map[a];
+      }
+      return *this;
+    }
+
+    /// \brief Set the costs of the arcs.
+    ///
+    /// This function sets the costs of the arcs.
+    /// If it is not used before calling \ref run(), the costs
+    /// will be set to \c 1 on all arcs.
+    ///
+    /// \param map An arc map storing the costs.
+    /// Its \c Value type must be convertible to the \c Cost type
+    /// of the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    template<typename CostMap>
+    CapacityScaling& costMap(const CostMap& map) {
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        _cost[_arc_idf[a]] =  map[a];
+        _cost[_arc_idb[a]] = -map[a];
+      }
+      return *this;
+    }
+
+    /// \brief Set the supply values of the nodes.
+    ///
+    /// This function sets the supply values of the nodes.
+    /// If neither this function nor \ref stSupply() is used before
+    /// calling \ref run(), the supply of each node will be set to zero.
+    ///
+    /// \param map A node map storing the supply values.
+    /// Its \c Value type must be convertible to the \c Value type
+    /// of the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    template<typename SupplyMap>
+    CapacityScaling& supplyMap(const SupplyMap& map) {
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _supply[_node_id[n]] = map[n];
+      }
+      return *this;
+    }
+
+    /// \brief Set single source and target nodes and a supply value.
+    ///
+    /// This function sets a single source node and a single target node
+    /// and the required flow value.
+    /// If neither this function nor \ref supplyMap() is used before
+    /// calling \ref run(), the supply of each node will be set to zero.
+    ///
+    /// Using this function has the same effect as using \ref supplyMap()
+    /// with such a map in which \c k is assigned to \c s, \c -k is
+    /// assigned to \c t and all other nodes have zero supply value.
+    ///
+    /// \param s The source node.
+    /// \param t The target node.
+    /// \param k The required amount of flow from node \c s to node \c t
+    /// (i.e. the supply of \c s and the demand of \c t).
+    ///
+    /// \return <tt>(*this)</tt>
+    CapacityScaling& stSupply(const Node& s, const Node& t, Value k) {
+      for (int i = 0; i != _node_num; ++i) {
+        _supply[i] = 0;
+      }
+      _supply[_node_id[s]] =  k;
+      _supply[_node_id[t]] = -k;
+      return *this;
+    }
+
+    /// @}
+
+    /// \name Execution control
+    /// The algorithm can be executed using \ref run().
+
+    /// @{
+
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm.
+    /// The paramters can be specified using functions \ref lowerMap(),
+    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
+    /// For example,
+    /// \code
+    ///   CapacityScaling<ListDigraph> cs(graph);
+    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
+    ///     .supplyMap(sup).run();
+    /// \endcode
+    ///
+    /// This function can be called more than once. All the given parameters
+    /// are kept for the next call, unless \ref resetParams() or \ref reset()
+    /// is used, thus only the modified parameters have to be set again.
+    /// If the underlying digraph was also modified after the construction
+    /// of the class (or the last \ref reset() call), then the \ref reset()
+    /// function must be called.
+    ///
+    /// \param factor The capacity scaling factor. It must be larger than
+    /// one to use scaling. If it is less or equal to one, then scaling
+    /// will be disabled.
+    ///
+    /// \return \c INFEASIBLE if no feasible flow exists,
+    /// \n \c OPTIMAL if the problem has optimal solution
+    /// (i.e. it is feasible and bounded), and the algorithm has found
+    /// optimal flow and node potentials (primal and dual solutions),
+    /// \n \c UNBOUNDED if the digraph contains an arc of negative cost
+    /// and infinite upper bound. It means that the objective function
+    /// is unbounded on that arc, however, note that it could actually be
+    /// bounded over the feasible flows, but this algroithm cannot handle
+    /// these cases.
+    ///
+    /// \see ProblemType
+    /// \see resetParams(), reset()
+    ProblemType run(int factor = 4) {
+      _factor = factor;
+      ProblemType pt = init();
+      if (pt != OPTIMAL) return pt;
+      return start();
+    }
+
+    /// \brief Reset all the parameters that have been given before.
+    ///
+    /// This function resets all the paramaters that have been given
+    /// before using functions \ref lowerMap(), \ref upperMap(),
+    /// \ref costMap(), \ref supplyMap(), \ref stSupply().
+    ///
+    /// It is useful for multiple \ref run() calls. Basically, all the given
+    /// parameters are kept for the next \ref run() call, unless
+    /// \ref resetParams() or \ref reset() is used.
+    /// If the underlying digraph was also modified after the construction
+    /// of the class or the last \ref reset() call, then the \ref reset()
+    /// function must be used, otherwise \ref resetParams() is sufficient.
+    ///
+    /// For example,
+    /// \code
+    ///   CapacityScaling<ListDigraph> cs(graph);
+    ///
+    ///   // First run
+    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
+    ///     .supplyMap(sup).run();
+    ///
+    ///   // Run again with modified cost map (resetParams() is not called,
+    ///   // so only the cost map have to be set again)
+    ///   cost[e] += 100;
+    ///   cs.costMap(cost).run();
+    ///
+    ///   // Run again from scratch using resetParams()
+    ///   // (the lower bounds will be set to zero on all arcs)
+    ///   cs.resetParams();
+    ///   cs.upperMap(capacity).costMap(cost)
+    ///     .supplyMap(sup).run();
+    /// \endcode
+    ///
+    /// \return <tt>(*this)</tt>
+    ///
+    /// \see reset(), run()
+    CapacityScaling& resetParams() {
+      for (int i = 0; i != _node_num; ++i) {
+        _supply[i] = 0;
+      }
+      for (int j = 0; j != _res_arc_num; ++j) {
+        _lower[j] = 0;
+        _upper[j] = INF;
+        _cost[j] = _forward[j] ? 1 : -1;
+      }
+      _have_lower = false;
+      return *this;
+    }
+
+    /// \brief Reset the internal data structures and all the parameters
+    /// that have been given before.
+    ///
+    /// This function resets the internal data structures and all the
+    /// paramaters that have been given before using functions \ref lowerMap(),
+    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
+    ///
+    /// It is useful for multiple \ref run() calls. Basically, all the given
+    /// parameters are kept for the next \ref run() call, unless
+    /// \ref resetParams() or \ref reset() is used.
+    /// If the underlying digraph was also modified after the construction
+    /// of the class or the last \ref reset() call, then the \ref reset()
+    /// function must be used, otherwise \ref resetParams() is sufficient.
+    ///
+    /// See \ref resetParams() for examples.
+    ///
+    /// \return <tt>(*this)</tt>
+    ///
+    /// \see resetParams(), run()
+    CapacityScaling& reset() {
+      // Resize vectors
+      _node_num = countNodes(_graph);
+      _arc_num = countArcs(_graph);
+      _res_arc_num = 2 * (_arc_num + _node_num);
+      _root = _node_num;
+      ++_node_num;
+
+      _first_out.resize(_node_num + 1);
+      _forward.resize(_res_arc_num);
+      _source.resize(_res_arc_num);
+      _target.resize(_res_arc_num);
+      _reverse.resize(_res_arc_num);
+
+      _lower.resize(_res_arc_num);
+      _upper.resize(_res_arc_num);
+      _cost.resize(_res_arc_num);
+      _supply.resize(_node_num);
+
+      _res_cap.resize(_res_arc_num);
+      _pi.resize(_node_num);
+      _excess.resize(_node_num);
+      _pred.resize(_node_num);
+
+      // Copy the graph
+      int i = 0, j = 0, k = 2 * _arc_num + _node_num - 1;
+      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
+        _node_id[n] = i;
+      }
+      i = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
+        _first_out[i] = j;
+        for (OutArcIt a(_graph, n); a != INVALID; ++a, ++j) {
+          _arc_idf[a] = j;
+          _forward[j] = true;
+          _source[j] = i;
+          _target[j] = _node_id[_graph.runningNode(a)];
+        }
+        for (InArcIt a(_graph, n); a != INVALID; ++a, ++j) {
+          _arc_idb[a] = j;
+          _forward[j] = false;
+          _source[j] = i;
+          _target[j] = _node_id[_graph.runningNode(a)];
+        }
+        _forward[j] = false;
+        _source[j] = i;
+        _target[j] = _root;
+        _reverse[j] = k;
+        _forward[k] = true;
+        _source[k] = _root;
+        _target[k] = i;
+        _reverse[k] = j;
+        ++j; ++k;
+      }
+      _first_out[i] = j;
+      _first_out[_node_num] = k;
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        int fi = _arc_idf[a];
+        int bi = _arc_idb[a];
+        _reverse[fi] = bi;
+        _reverse[bi] = fi;
+      }
+
+      // Reset parameters
+      resetParams();
+      return *this;
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The results of the algorithm can be obtained using these
+    /// functions.\n
+    /// The \ref run() function must be called before using them.
+
+    /// @{
+
+    /// \brief Return the total cost of the found flow.
+    ///
+    /// This function returns the total cost of the found flow.
+    /// Its complexity is O(e).
+    ///
+    /// \note The return type of the function can be specified as a
+    /// template parameter. For example,
+    /// \code
+    ///   cs.totalCost<double>();
+    /// \endcode
+    /// It is useful if the total cost cannot be stored in the \c Cost
+    /// type of the algorithm, which is the default return type of the
+    /// function.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    template <typename Number>
+    Number totalCost() const {
+      Number c = 0;
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        int i = _arc_idb[a];
+        c += static_cast<Number>(_res_cap[i]) *
+             (-static_cast<Number>(_cost[i]));
+      }
+      return c;
+    }
+
+#ifndef DOXYGEN
+    Cost totalCost() const {
+      return totalCost<Cost>();
+    }
+#endif
+
+    /// \brief Return the flow on the given arc.
+    ///
+    /// This function returns the flow on the given arc.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Value flow(const Arc& a) const {
+      return _res_cap[_arc_idb[a]];
+    }
+
+    /// \brief Return the flow map (the primal solution).
+    ///
+    /// This function copies the flow value on each arc into the given
+    /// map. The \c Value type of the algorithm must be convertible to
+    /// the \c Value type of the map.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    template <typename FlowMap>
+    void flowMap(FlowMap &map) const {
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        map.set(a, _res_cap[_arc_idb[a]]);
+      }
+    }
+
+    /// \brief Return the potential (dual value) of the given node.
+    ///
+    /// This function returns the potential (dual value) of the
+    /// given node.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Cost potential(const Node& n) const {
+      return _pi[_node_id[n]];
+    }
+
+    /// \brief Return the potential map (the dual solution).
+    ///
+    /// This function copies the potential (dual value) of each node
+    /// into the given map.
+    /// The \c Cost type of the algorithm must be convertible to the
+    /// \c Value type of the map.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    template <typename PotentialMap>
+    void potentialMap(PotentialMap &map) const {
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        map.set(n, _pi[_node_id[n]]);
+      }
+    }
+
+    /// @}
+
+  private:
+
+    // Initialize the algorithm
+    ProblemType init() {
+      if (_node_num <= 1) return INFEASIBLE;
+
+      // Check the sum of supply values
+      _sum_supply = 0;
+      for (int i = 0; i != _root; ++i) {
+        _sum_supply += _supply[i];
+      }
+      if (_sum_supply > 0) return INFEASIBLE;
+
+      // Initialize vectors
+      for (int i = 0; i != _root; ++i) {
+        _pi[i] = 0;
+        _excess[i] = _supply[i];
+      }
+
+      // Remove non-zero lower bounds
+      const Value MAX = std::numeric_limits<Value>::max();
+      int last_out;
+      if (_have_lower) {
+        for (int i = 0; i != _root; ++i) {
+          last_out = _first_out[i+1];
+          for (int j = _first_out[i]; j != last_out; ++j) {
+            if (_forward[j]) {
+              Value c = _lower[j];
+              if (c >= 0) {
+                _res_cap[j] = _upper[j] < MAX ? _upper[j] - c : INF;
+              } else {
+                _res_cap[j] = _upper[j] < MAX + c ? _upper[j] - c : INF;
+              }
+              _excess[i] -= c;
+              _excess[_target[j]] += c;
+            } else {
+              _res_cap[j] = 0;
+            }
+          }
+        }
+      } else {
+        for (int j = 0; j != _res_arc_num; ++j) {
+          _res_cap[j] = _forward[j] ? _upper[j] : 0;
+        }
+      }
+
+      // Handle negative costs
+      for (int i = 0; i != _root; ++i) {
+        last_out = _first_out[i+1] - 1;
+        for (int j = _first_out[i]; j != last_out; ++j) {
+          Value rc = _res_cap[j];
+          if (_cost[j] < 0 && rc > 0) {
+            if (rc >= MAX) return UNBOUNDED;
+            _excess[i] -= rc;
+            _excess[_target[j]] += rc;
+            _res_cap[j] = 0;
+            _res_cap[_reverse[j]] += rc;
+          }
+        }
+      }
+
+      // Handle GEQ supply type
+      if (_sum_supply < 0) {
+        _pi[_root] = 0;
+        _excess[_root] = -_sum_supply;
+        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
+          int ra = _reverse[a];
+          _res_cap[a] = -_sum_supply + 1;
+          _res_cap[ra] = 0;
+          _cost[a] = 0;
+          _cost[ra] = 0;
+        }
+      } else {
+        _pi[_root] = 0;
+        _excess[_root] = 0;
+        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
+          int ra = _reverse[a];
+          _res_cap[a] = 1;
+          _res_cap[ra] = 0;
+          _cost[a] = 0;
+          _cost[ra] = 0;
+        }
+      }
+
+      // Initialize delta value
+      if (_factor > 1) {
+        // With scaling
+        Value max_sup = 0, max_dem = 0, max_cap = 0;
+        for (int i = 0; i != _root; ++i) {
+          Value ex = _excess[i];
+          if ( ex > max_sup) max_sup =  ex;
+          if (-ex > max_dem) max_dem = -ex;
+          int last_out = _first_out[i+1] - 1;
+          for (int j = _first_out[i]; j != last_out; ++j) {
+            if (_res_cap[j] > max_cap) max_cap = _res_cap[j];
+          }
+        }
+        max_sup = std::min(std::min(max_sup, max_dem), max_cap);
+        for (_delta = 1; 2 * _delta <= max_sup; _delta *= 2) ;
+      } else {
+        // Without scaling
+        _delta = 1;
+      }
+
+      return OPTIMAL;
+    }
+
+    ProblemType start() {
+      // Execute the algorithm
+      ProblemType pt;
+      if (_delta > 1)
+        pt = startWithScaling();
+      else
+        pt = startWithoutScaling();
+
+      // Handle non-zero lower bounds
+      if (_have_lower) {
+        int limit = _first_out[_root];
+        for (int j = 0; j != limit; ++j) {
+          if (!_forward[j]) _res_cap[j] += _lower[j];
+        }
+      }
+
+      // Shift potentials if necessary
+      Cost pr = _pi[_root];
+      if (_sum_supply < 0 || pr > 0) {
+        for (int i = 0; i != _node_num; ++i) {
+          _pi[i] -= pr;
+        }
+      }
+
+      return pt;
+    }
+
+    // Execute the capacity scaling algorithm
+    ProblemType startWithScaling() {
+      // Perform capacity scaling phases
+      int s, t;
+      ResidualDijkstra _dijkstra(*this);
+      while (true) {
+        // Saturate all arcs not satisfying the optimality condition
+        int last_out;
+        for (int u = 0; u != _node_num; ++u) {
+          last_out = _sum_supply < 0 ?
+            _first_out[u+1] : _first_out[u+1] - 1;
+          for (int a = _first_out[u]; a != last_out; ++a) {
+            int v = _target[a];
+            Cost c = _cost[a] + _pi[u] - _pi[v];
+            Value rc = _res_cap[a];
+            if (c < 0 && rc >= _delta) {
+              _excess[u] -= rc;
+              _excess[v] += rc;
+              _res_cap[a] = 0;
+              _res_cap[_reverse[a]] += rc;
+            }
+          }
+        }
+
+        // Find excess nodes and deficit nodes
+        _excess_nodes.clear();
+        _deficit_nodes.clear();
+        for (int u = 0; u != _node_num; ++u) {
+          Value ex = _excess[u];
+          if (ex >=  _delta) _excess_nodes.push_back(u);
+          if (ex <= -_delta) _deficit_nodes.push_back(u);
+        }
+        int next_node = 0, next_def_node = 0;
+
+        // Find augmenting shortest paths
+        while (next_node < int(_excess_nodes.size())) {
+          // Check deficit nodes
+          if (_delta > 1) {
+            bool delta_deficit = false;
+            for ( ; next_def_node < int(_deficit_nodes.size());
+                    ++next_def_node ) {
+              if (_excess[_deficit_nodes[next_def_node]] <= -_delta) {
+                delta_deficit = true;
+                break;
+              }
+            }
+            if (!delta_deficit) break;
+          }
+
+          // Run Dijkstra in the residual network
+          s = _excess_nodes[next_node];
+          if ((t = _dijkstra.run(s, _delta)) == -1) {
+            if (_delta > 1) {
+              ++next_node;
+              continue;
+            }
+            return INFEASIBLE;
+          }
+
+          // Augment along a shortest path from s to t
+          Value d = std::min(_excess[s], -_excess[t]);
+          int u = t;
+          int a;
+          if (d > _delta) {
+            while ((a = _pred[u]) != -1) {
+              if (_res_cap[a] < d) d = _res_cap[a];
+              u = _source[a];
+            }
+          }
+          u = t;
+          while ((a = _pred[u]) != -1) {
+            _res_cap[a] -= d;
+            _res_cap[_reverse[a]] += d;
+            u = _source[a];
+          }
+          _excess[s] -= d;
+          _excess[t] += d;
+
+          if (_excess[s] < _delta) ++next_node;
+        }
+
+        if (_delta == 1) break;
+        _delta = _delta <= _factor ? 1 : _delta / _factor;
+      }
+
+      return OPTIMAL;
+    }
+
+    // Execute the successive shortest path algorithm
+    ProblemType startWithoutScaling() {
+      // Find excess nodes
+      _excess_nodes.clear();
+      for (int i = 0; i != _node_num; ++i) {
+        if (_excess[i] > 0) _excess_nodes.push_back(i);
+      }
+      if (_excess_nodes.size() == 0) return OPTIMAL;
+      int next_node = 0;
+
+      // Find shortest paths
+      int s, t;
+      ResidualDijkstra _dijkstra(*this);
+      while ( _excess[_excess_nodes[next_node]] > 0 ||
+              ++next_node < int(_excess_nodes.size()) )
+      {
+        // Run Dijkstra in the residual network
+        s = _excess_nodes[next_node];
+        if ((t = _dijkstra.run(s)) == -1) return INFEASIBLE;
+
+        // Augment along a shortest path from s to t
+        Value d = std::min(_excess[s], -_excess[t]);
+        int u = t;
+        int a;
+        if (d > 1) {
+          while ((a = _pred[u]) != -1) {
+            if (_res_cap[a] < d) d = _res_cap[a];
+            u = _source[a];
+          }
+        }
+        u = t;
+        while ((a = _pred[u]) != -1) {
+          _res_cap[a] -= d;
+          _res_cap[_reverse[a]] += d;
+          u = _source[a];
+        }
+        _excess[s] -= d;
+        _excess[t] += d;
+      }
+
+      return OPTIMAL;
+    }
+
+  }; //class CapacityScaling
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_CAPACITY_SCALING_H
Index: lemon/cbc.cc
===================================================================
--- lemon/cbc.cc	(revision 966)
+++ lemon/cbc.cc	(revision 966)
@@ -0,0 +1,460 @@
+/* -*- 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 Implementation of the CBC MIP solver interface.
+
+#include "cbc.h"
+
+#include <coin/CoinModel.hpp>
+#include <coin/CbcModel.hpp>
+#include <coin/OsiSolverInterface.hpp>
+
+#include "coin/OsiClpSolverInterface.hpp"
+
+#include "coin/CbcCutGenerator.hpp"
+#include "coin/CbcHeuristicLocal.hpp"
+#include "coin/CbcHeuristicGreedy.hpp"
+#include "coin/CbcHeuristicFPump.hpp"
+#include "coin/CbcHeuristicRINS.hpp"
+
+#include "coin/CglGomory.hpp"
+#include "coin/CglProbing.hpp"
+#include "coin/CglKnapsackCover.hpp"
+#include "coin/CglOddHole.hpp"
+#include "coin/CglClique.hpp"
+#include "coin/CglFlowCover.hpp"
+#include "coin/CglMixedIntegerRounding.hpp"
+
+#include "coin/CbcHeuristic.hpp"
+
+namespace lemon {
+
+  CbcMip::CbcMip() {
+    _prob = new CoinModel();
+    _prob->setProblemName("LEMON");
+    _osi_solver = 0;
+    _cbc_model = 0;
+    messageLevel(MESSAGE_NOTHING);
+  }
+
+  CbcMip::CbcMip(const CbcMip& other) {
+    _prob = new CoinModel(*other._prob);
+    _prob->setProblemName("LEMON");
+    _osi_solver = 0;
+    _cbc_model = 0;
+    messageLevel(MESSAGE_NOTHING);
+  }
+
+  CbcMip::~CbcMip() {
+    delete _prob;
+    if (_osi_solver) delete _osi_solver;
+    if (_cbc_model) delete _cbc_model;
+  }
+
+  const char* CbcMip::_solverName() const { return "CbcMip"; }
+
+  int CbcMip::_addCol() {
+    _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0, 0, false);
+    return _prob->numberColumns() - 1;
+  }
+
+  CbcMip* CbcMip::newSolver() const {
+    CbcMip* newlp = new CbcMip;
+    return newlp;
+  }
+
+  CbcMip* CbcMip::cloneSolver() const {
+    CbcMip* copylp = new CbcMip(*this);
+    return copylp;
+  }
+
+  int CbcMip::_addRow() {
+    _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
+    return _prob->numberRows() - 1;
+  }
+
+  int CbcMip::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
+    std::vector<int> indexes;
+    std::vector<Value> values;
+
+    for(ExprIterator it = b; it != e; ++it) {
+      indexes.push_back(it->first);
+      values.push_back(it->second);
+    }
+
+    _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
+    return _prob->numberRows() - 1;
+  }
+
+  void CbcMip::_eraseCol(int i) {
+    _prob->deleteColumn(i);
+  }
+
+  void CbcMip::_eraseRow(int i) {
+    _prob->deleteRow(i);
+  }
+
+  void CbcMip::_eraseColId(int i) {
+    cols.eraseIndex(i);
+  }
+
+  void CbcMip::_eraseRowId(int i) {
+    rows.eraseIndex(i);
+  }
+
+  void CbcMip::_getColName(int c, std::string& name) const {
+    name = _prob->getColumnName(c);
+  }
+
+  void CbcMip::_setColName(int c, const std::string& name) {
+    _prob->setColumnName(c, name.c_str());
+  }
+
+  int CbcMip::_colByName(const std::string& name) const {
+    return _prob->column(name.c_str());
+  }
+
+  void CbcMip::_getRowName(int r, std::string& name) const {
+    name = _prob->getRowName(r);
+  }
+
+  void CbcMip::_setRowName(int r, const std::string& name) {
+    _prob->setRowName(r, name.c_str());
+  }
+
+  int CbcMip::_rowByName(const std::string& name) const {
+    return _prob->row(name.c_str());
+  }
+
+  void CbcMip::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
+    for (ExprIterator it = b; it != e; ++it) {
+      _prob->setElement(i, it->first, it->second);
+    }
+  }
+
+  void CbcMip::_getRowCoeffs(int ix, InsertIterator b) const {
+    int length = _prob->numberRows();
+
+    std::vector<int> indices(length);
+    std::vector<Value> values(length);
+
+    length = _prob->getRow(ix, &indices[0], &values[0]);
+
+    for (int i = 0; i < length; ++i) {
+      *b = std::make_pair(indices[i], values[i]);
+      ++b;
+    }
+  }
+
+  void CbcMip::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) {
+    for (ExprIterator it = b; it != e; ++it) {
+      _prob->setElement(it->first, ix, it->second);
+    }
+  }
+
+  void CbcMip::_getColCoeffs(int ix, InsertIterator b) const {
+    int length = _prob->numberColumns();
+
+    std::vector<int> indices(length);
+    std::vector<Value> values(length);
+
+    length = _prob->getColumn(ix, &indices[0], &values[0]);
+
+    for (int i = 0; i < length; ++i) {
+      *b = std::make_pair(indices[i], values[i]);
+      ++b;
+    }
+  }
+
+  void CbcMip::_setCoeff(int ix, int jx, Value value) {
+    _prob->setElement(ix, jx, value);
+  }
+
+  CbcMip::Value CbcMip::_getCoeff(int ix, int jx) const {
+    return _prob->getElement(ix, jx);
+  }
+
+
+  void CbcMip::_setColLowerBound(int i, Value lo) {
+    LEMON_ASSERT(lo != INF, "Invalid bound");
+    _prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
+  }
+
+  CbcMip::Value CbcMip::_getColLowerBound(int i) const {
+    double val = _prob->getColumnLower(i);
+    return val == - COIN_DBL_MAX ? - INF : val;
+  }
+
+  void CbcMip::_setColUpperBound(int i, Value up) {
+    LEMON_ASSERT(up != -INF, "Invalid bound");
+    _prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up);
+  }
+
+  CbcMip::Value CbcMip::_getColUpperBound(int i) const {
+    double val = _prob->getColumnUpper(i);
+    return val == COIN_DBL_MAX ? INF : val;
+  }
+
+  void CbcMip::_setRowLowerBound(int i, Value lo) {
+    LEMON_ASSERT(lo != INF, "Invalid bound");
+    _prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
+  }
+
+  CbcMip::Value CbcMip::_getRowLowerBound(int i) const {
+    double val = _prob->getRowLower(i);
+    return val == - COIN_DBL_MAX ? - INF : val;
+  }
+
+  void CbcMip::_setRowUpperBound(int i, Value up) {
+    LEMON_ASSERT(up != -INF, "Invalid bound");
+    _prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up);
+  }
+
+  CbcMip::Value CbcMip::_getRowUpperBound(int i) const {
+    double val = _prob->getRowUpper(i);
+    return val == COIN_DBL_MAX ? INF : val;
+  }
+
+  void CbcMip::_setObjCoeffs(ExprIterator b, ExprIterator e) {
+    int num = _prob->numberColumns();
+    for (int i = 0; i < num; ++i) {
+      _prob->setColumnObjective(i, 0.0);
+    }
+    for (ExprIterator it = b; it != e; ++it) {
+      _prob->setColumnObjective(it->first, it->second);
+    }
+  }
+
+  void CbcMip::_getObjCoeffs(InsertIterator b) const {
+    int num = _prob->numberColumns();
+    for (int i = 0; i < num; ++i) {
+      Value coef = _prob->getColumnObjective(i);
+      if (coef != 0.0) {
+        *b = std::make_pair(i, coef);
+        ++b;
+      }
+    }
+  }
+
+  void CbcMip::_setObjCoeff(int i, Value obj_coef) {
+    _prob->setColumnObjective(i, obj_coef);
+  }
+
+  CbcMip::Value CbcMip::_getObjCoeff(int i) const {
+    return _prob->getColumnObjective(i);
+  }
+
+  CbcMip::SolveExitStatus CbcMip::_solve() {
+
+    if (_osi_solver) {
+      delete _osi_solver;
+    }
+    _osi_solver = new OsiClpSolverInterface();
+
+    _osi_solver->loadFromCoinModel(*_prob);
+
+    if (_cbc_model) {
+      delete _cbc_model;
+    }
+    _cbc_model= new CbcModel(*_osi_solver);
+
+    _osi_solver->messageHandler()->setLogLevel(_message_level);
+    _cbc_model->setLogLevel(_message_level);
+
+    _cbc_model->initialSolve();
+    _cbc_model->solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
+
+    if (!_cbc_model->isInitialSolveAbandoned() &&
+        _cbc_model->isInitialSolveProvenOptimal() &&
+        !_cbc_model->isInitialSolveProvenPrimalInfeasible() &&
+        !_cbc_model->isInitialSolveProvenDualInfeasible()) {
+
+      CglProbing generator1;
+      generator1.setUsingObjective(true);
+      generator1.setMaxPass(3);
+      generator1.setMaxProbe(100);
+      generator1.setMaxLook(50);
+      generator1.setRowCuts(3);
+      _cbc_model->addCutGenerator(&generator1, -1, "Probing");
+
+      CglGomory generator2;
+      generator2.setLimit(300);
+      _cbc_model->addCutGenerator(&generator2, -1, "Gomory");
+
+      CglKnapsackCover generator3;
+      _cbc_model->addCutGenerator(&generator3, -1, "Knapsack");
+
+      CglOddHole generator4;
+      generator4.setMinimumViolation(0.005);
+      generator4.setMinimumViolationPer(0.00002);
+      generator4.setMaximumEntries(200);
+      _cbc_model->addCutGenerator(&generator4, -1, "OddHole");
+
+      CglClique generator5;
+      generator5.setStarCliqueReport(false);
+      generator5.setRowCliqueReport(false);
+      _cbc_model->addCutGenerator(&generator5, -1, "Clique");
+
+      CglMixedIntegerRounding mixedGen;
+      _cbc_model->addCutGenerator(&mixedGen, -1, "MixedIntegerRounding");
+
+      CglFlowCover flowGen;
+      _cbc_model->addCutGenerator(&flowGen, -1, "FlowCover");
+
+      OsiClpSolverInterface* osiclp =
+        dynamic_cast<OsiClpSolverInterface*>(_cbc_model->solver());
+      if (osiclp->getNumRows() < 300 && osiclp->getNumCols() < 500) {
+        osiclp->setupForRepeatedUse(2, 0);
+      }
+
+      CbcRounding heuristic1(*_cbc_model);
+      heuristic1.setWhen(3);
+      _cbc_model->addHeuristic(&heuristic1);
+
+      CbcHeuristicLocal heuristic2(*_cbc_model);
+      heuristic2.setWhen(3);
+      _cbc_model->addHeuristic(&heuristic2);
+
+      CbcHeuristicGreedyCover heuristic3(*_cbc_model);
+      heuristic3.setAlgorithm(11);
+      heuristic3.setWhen(3);
+      _cbc_model->addHeuristic(&heuristic3);
+
+      CbcHeuristicFPump heuristic4(*_cbc_model);
+      heuristic4.setWhen(3);
+      _cbc_model->addHeuristic(&heuristic4);
+
+      CbcHeuristicRINS heuristic5(*_cbc_model);
+      heuristic5.setWhen(3);
+      _cbc_model->addHeuristic(&heuristic5);
+
+      if (_cbc_model->getNumCols() < 500) {
+        _cbc_model->setMaximumCutPassesAtRoot(-100);
+      } else if (_cbc_model->getNumCols() < 5000) {
+        _cbc_model->setMaximumCutPassesAtRoot(100);
+      } else {
+        _cbc_model->setMaximumCutPassesAtRoot(20);
+      }
+
+      if (_cbc_model->getNumCols() < 5000) {
+        _cbc_model->setNumberStrong(10);
+      }
+
+      _cbc_model->solver()->setIntParam(OsiMaxNumIterationHotStart, 100);
+      _cbc_model->branchAndBound();
+    }
+
+    if (_cbc_model->isAbandoned()) {
+      return UNSOLVED;
+    } else {
+      return SOLVED;
+    }
+  }
+
+  CbcMip::Value CbcMip::_getSol(int i) const {
+    return _cbc_model->getColSolution()[i];
+  }
+
+  CbcMip::Value CbcMip::_getSolValue() const {
+    return _cbc_model->getObjValue();
+  }
+
+  CbcMip::ProblemType CbcMip::_getType() const {
+    if (_cbc_model->isProvenOptimal()) {
+      return OPTIMAL;
+    } else if (_cbc_model->isContinuousUnbounded()) {
+      return UNBOUNDED;
+    }
+    return FEASIBLE;
+  }
+
+  void CbcMip::_setSense(Sense sense) {
+    switch (sense) {
+    case MIN:
+      _prob->setOptimizationDirection(1.0);
+      break;
+    case MAX:
+      _prob->setOptimizationDirection(- 1.0);
+      break;
+    }
+  }
+
+  CbcMip::Sense CbcMip::_getSense() const {
+    if (_prob->optimizationDirection() > 0.0) {
+      return MIN;
+    } else if (_prob->optimizationDirection() < 0.0) {
+      return MAX;
+    } else {
+      LEMON_ASSERT(false, "Wrong sense");
+      return CbcMip::Sense();
+    }
+  }
+
+  void CbcMip::_setColType(int i, CbcMip::ColTypes col_type) {
+    switch (col_type){
+    case INTEGER:
+      _prob->setInteger(i);
+      break;
+    case REAL:
+      _prob->setContinuous(i);
+      break;
+    default:;
+      LEMON_ASSERT(false, "Wrong sense");
+    }
+  }
+
+  CbcMip::ColTypes CbcMip::_getColType(int i) const {
+    return _prob->getColumnIsInteger(i) ? INTEGER : REAL;
+  }
+
+  void CbcMip::_clear() {
+    delete _prob;
+    if (_osi_solver) {
+      delete _osi_solver;
+      _osi_solver = 0;
+    }
+    if (_cbc_model) {
+      delete _cbc_model;
+      _cbc_model = 0;
+    }
+
+    _prob = new CoinModel();
+  }
+
+  void CbcMip::_messageLevel(MessageLevel level) {
+    switch (level) {
+    case MESSAGE_NOTHING:
+      _message_level = 0;
+      break;
+    case MESSAGE_ERROR:
+      _message_level = 1;
+      break;
+    case MESSAGE_WARNING:
+      _message_level = 1;
+      break;
+    case MESSAGE_NORMAL:
+      _message_level = 2;
+      break;
+    case MESSAGE_VERBOSE:
+      _message_level = 3;
+      break;
+    }
+  }
+
+} //END OF NAMESPACE LEMON
Index: lemon/cbc.h
===================================================================
--- lemon/cbc.h	(revision 877)
+++ lemon/cbc.h	(revision 877)
@@ -0,0 +1,130 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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.
+ *
+ */
+
+// -*- C++ -*-
+#ifndef LEMON_CBC_H
+#define LEMON_CBC_H
+
+///\file
+///\brief Header of the LEMON-CBC mip solver interface.
+///\ingroup lp_group
+
+#include <lemon/lp_base.h>
+
+class CoinModel;
+class OsiSolverInterface;
+class CbcModel;
+
+namespace lemon {
+
+  /// \brief Interface for the CBC MIP solver
+  ///
+  /// This class implements an interface for the CBC MIP solver.
+  ///\ingroup lp_group
+  class CbcMip : public MipSolver {
+  protected:
+
+    CoinModel *_prob;
+    OsiSolverInterface *_osi_solver;
+    CbcModel *_cbc_model;
+
+  public:
+
+    /// \e
+    CbcMip();
+    /// \e
+    CbcMip(const CbcMip&);
+    /// \e
+    ~CbcMip();
+    /// \e
+    virtual CbcMip* newSolver() const;
+    /// \e
+    virtual CbcMip* cloneSolver() const;
+
+  protected:
+
+    virtual const char* _solverName() const;
+
+    virtual int _addCol();
+    virtual int _addRow();
+    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
+
+    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 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;
+
+    virtual void _clear();
+
+    virtual void _messageLevel(MessageLevel level);
+    void _applyMessageLevel();
+
+    int _message_level;
+
+
+
+  };
+
+}
+
+#endif
Index: lemon/circulation.h
===================================================================
--- lemon/circulation.h	(revision 559)
+++ lemon/circulation.h	(revision 964)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -22,4 +22,5 @@
 #include <lemon/tolerance.h>
 #include <lemon/elevator.h>
+#include <limits>
 
 ///\ingroup max_flow
@@ -32,10 +33,11 @@
   ///
   /// Default traits class of Circulation class.
-  /// \tparam GR Digraph type.
-  /// \tparam LM Lower bound capacity map type.
-  /// \tparam UM Upper bound capacity map type.
-  /// \tparam DM Delta map type.
+  ///
+  /// \tparam GR Type of the digraph the algorithm runs on.
+  /// \tparam LM The type of the lower bound map.
+  /// \tparam UM The type of the upper bound (capacity) map.
+  /// \tparam SM The type of the supply map.
   template <typename GR, typename LM,
-            typename UM, typename DM>
+            typename UM, typename SM>
   struct CirculationDefaultTraits {
 
@@ -43,39 +45,42 @@
     typedef GR Digraph;
 
-    /// \brief The type of the map that stores the circulation lower
-    /// bound.
-    ///
-    /// The type of the map that stores the circulation lower bound.
-    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
-    typedef LM LCapMap;
-
-    /// \brief The type of the map that stores the circulation upper
-    /// bound.
-    ///
-    /// The type of the map that stores the circulation upper bound.
-    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
-    typedef UM UCapMap;
-
-    /// \brief The type of the map that stores the lower bound for
-    /// the supply of the nodes.
-    ///
-    /// The type of the map that stores the lower bound for the supply
-    /// of the nodes. It must meet the \ref concepts::ReadMap "ReadMap"
+    /// \brief The type of the lower bound map.
+    ///
+    /// The type of the map that stores the lower bounds on the arcs.
+    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+    typedef LM LowerMap;
+
+    /// \brief The type of the upper bound (capacity) map.
+    ///
+    /// The type of the map that stores the upper bounds (capacities)
+    /// on the arcs.
+    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+    typedef UM UpperMap;
+
+    /// \brief The type of supply map.
+    ///
+    /// The type of the map that stores the signed supply values of the
+    /// nodes.
+    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+    typedef SM SupplyMap;
+
+    /// \brief The type of the flow and supply values.
+    typedef typename SupplyMap::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 conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
     /// concept.
-    typedef DM DeltaMap;
-
-    /// \brief The type of the flow values.
-    typedef typename DeltaMap::Value Value;
-
-    /// \brief The type of the map that stores the flow values.
-    ///
-    /// The type of the map that stores the flow values.
-    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+#ifdef DOXYGEN
+    typedef GR::ArcMap<Value> FlowMap;
+#else
     typedef typename Digraph::template ArcMap<Value> FlowMap;
+#endif
 
     /// \brief Instantiates a FlowMap.
     ///
     /// This function instantiates a \ref FlowMap.
-    /// \param digraph The digraph, to which we would like to define
+    /// \param digraph The digraph for which we would like to define
     /// the flow map.
     static FlowMap* createFlowMap(const Digraph& digraph) {
@@ -87,12 +92,15 @@
     /// The elevator type used by the algorithm.
     ///
-    /// \sa Elevator
-    /// \sa LinkedElevator
+    /// \sa Elevator, LinkedElevator
+#ifdef DOXYGEN
+    typedef lemon::Elevator<GR, GR::Node> Elevator;
+#else
     typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
+#endif
 
     /// \brief Instantiates an Elevator.
     ///
     /// This function instantiates an \ref Elevator.
-    /// \param digraph The digraph, to which we would like to define
+    /// \param digraph The digraph for which we would like to define
     /// the elevator.
     /// \param max_level The maximum level of the elevator.
@@ -112,38 +120,63 @@
 
      \ingroup max_flow
-     This class implements a push-relabel algorithm for the network
-     circulation problem.
+     This class implements a push-relabel algorithm for the \e network
+     \e 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.
+     are given for the flow values on the arcs and lower bounds are
+     given for the difference between the outgoing and incoming flow
+     at 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.
+     Let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$
+     \f$upper: A\rightarrow\mathbf{R}\cup\{\infty\}\f$ denote the lower and
+     upper bounds on the arcs, for which \f$lower(uv) \leq upper(uv)\f$
+     holds for all \f$uv\in A\f$, and \f$sup: V\rightarrow\mathbf{R}\f$
+     denotes the signed supply values of the nodes.
+     If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
+     supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
+     \f$-sup(u)\f$ demand.
+     A feasible circulation is an \f$f: A\rightarrow\mathbf{R}\f$
+     solution of the following problem.
+
+     \f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu)
+     \geq sup(u) \quad \forall u\in V, \f]
+     \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A. \f]
+
+     The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
+     zero or negative in order to have a feasible solution (since the sum
+     of the expressions on the left-hand side of the inequalities is zero).
+     It means that the total demand must be greater or equal to the total
+     supply and all the supplies have to be carried out from the supply nodes,
+     but there could be demands that are not satisfied.
+     If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand
+     constraints have to be satisfied with equality, i.e. all demands
+     have to be satisfied and all supplies have to be used.
+
+     If you need the opposite inequalities in the supply/demand constraints
+     (i.e. the total demand is less than the total supply and all the demands
+     have to be satisfied while there could be supplies that are not used),
+     then you could easily transform the problem to the above form by reversing
+     the direction of the arcs and taking the negative of the supply values
+     (e.g. using \ref ReverseDigraph and \ref NegMap adaptors).
+
+     This algorithm either calculates a feasible circulation, or provides
+     a \ref barrier() "barrier", which prooves that a feasible soultion
+     cannot exist.
+
+     Note that this algorithm also provides a feasible solution for the
+     \ref min_cost_flow "minimum cost flow problem".
 
      \tparam GR The type of the digraph the algorithm runs on.
-     \tparam LM The type of the lower bound capacity map. The default
+     \tparam LM The type of the lower bound map. The default
      map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
-     \tparam UM The type of the upper bound capacity map. The default
-     map type is \c LM.
-     \tparam DM The type of the map that stores the lower bound
-     for the supply of the nodes. The default map type is
+     \tparam UM The type of the upper bound (capacity) map.
+     The default map type is \c LM.
+     \tparam SM The type of the supply map. The default map type is
      \ref concepts::Digraph::NodeMap "GR::NodeMap<UM::Value>".
+     \tparam TR The traits class that defines various types used by the
+     algorithm. By default, it is \ref CirculationDefaultTraits
+     "CirculationDefaultTraits<GR, LM, UM, SM>".
+     In most cases, this parameter should not be set directly,
+     consider to use the named template parameters instead.
   */
 #ifdef DOXYGEN
@@ -151,5 +184,5 @@
           typename LM,
           typename UM,
-          typename DM,
+          typename SM,
           typename TR >
 #else
@@ -157,6 +190,6 @@
           typename LM = typename GR::template ArcMap<int>,
           typename UM = LM,
-          typename DM = typename GR::template NodeMap<typename UM::Value>,
-          typename TR = CirculationDefaultTraits<GR, LM, UM, DM> >
+          typename SM = typename GR::template NodeMap<typename UM::Value>,
+          typename TR = CirculationDefaultTraits<GR, LM, UM, SM> >
 #endif
   class Circulation {
@@ -167,14 +200,13 @@
     ///The type of the digraph the algorithm runs on.
     typedef typename Traits::Digraph Digraph;
-    ///The type of the flow values.
+    ///The type of the flow and supply 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 lower bound map.
+    typedef typename Traits::LowerMap LowerMap;
+    ///The type of the upper bound (capacity) map.
+    typedef typename Traits::UpperMap UpperMap;
+    ///The type of the supply map.
+    typedef typename Traits::SupplyMap SupplyMap;
     ///The type of the flow map.
     typedef typename Traits::FlowMap FlowMap;
@@ -192,7 +224,7 @@
     int _node_num;
 
-    const LCapMap *_lo;
-    const UCapMap *_up;
-    const DeltaMap *_delta;
+    const LowerMap *_lo;
+    const UpperMap *_up;
+    const SupplyMap *_supply;
 
     FlowMap *_flow;
@@ -232,7 +264,7 @@
     template <typename T>
     struct SetFlowMap
-      : public Circulation<Digraph, LCapMap, UCapMap, DeltaMap,
+      : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
                            SetFlowMapTraits<T> > {
-      typedef Circulation<Digraph, LCapMap, UCapMap, DeltaMap,
+      typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
                           SetFlowMapTraits<T> > Create;
     };
@@ -258,7 +290,7 @@
     template <typename T>
     struct SetElevator
-      : public Circulation<Digraph, LCapMap, UCapMap, DeltaMap,
+      : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
                            SetElevatorTraits<T> > {
-      typedef Circulation<Digraph, LCapMap, UCapMap, DeltaMap,
+      typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
                           SetElevatorTraits<T> > Create;
     };
@@ -280,5 +312,5 @@
     /// 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
+    /// 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().
@@ -286,7 +318,7 @@
     template <typename T>
     struct SetStandardElevator
-      : public Circulation<Digraph, LCapMap, UCapMap, DeltaMap,
+      : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
                        SetStandardElevatorTraits<T> > {
-      typedef Circulation<Digraph, LCapMap, UCapMap, DeltaMap,
+      typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
                       SetStandardElevatorTraits<T> > Create;
     };
@@ -300,16 +332,18 @@
   public:
 
+    /// Constructor.
+
     /// 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() {}
+    ///
+    /// \param graph The digraph the algorithm runs on.
+    /// \param lower The lower bounds for the flow values on the arcs.
+    /// \param upper The upper bounds (capacities) for the flow values
+    /// on the arcs.
+    /// \param supply The signed supply values of the nodes.
+    Circulation(const Digraph &graph, const LowerMap &lower,
+                const UpperMap &upper, const SupplyMap &supply)
+      : _g(graph), _lo(&lower), _up(&upper), _supply(&supply),
+        _flow(NULL), _local_flow(false), _level(NULL), _local_level(false),
+        _excess(NULL) {}
 
     /// Destructor.
@@ -321,4 +355,11 @@
   private:
 
+    bool checkBoundMaps() {
+      for (ArcIt e(_g);e!=INVALID;++e) {
+        if (_tol.less((*_up)[e], (*_lo)[e])) return false;
+      }
+      return true;
+    }
+
     void createStructures() {
       _node_num = _el = countNodes(_g);
@@ -351,28 +392,28 @@
   public:
 
-    /// Sets the lower bound capacity map.
-
-    /// Sets the lower bound capacity map.
+    /// Sets the lower bound map.
+
+    /// Sets the lower bound map.
     /// \return <tt>(*this)</tt>
-    Circulation& lowerCapMap(const LCapMap& map) {
+    Circulation& lowerMap(const LowerMap& map) {
       _lo = &map;
       return *this;
     }
 
-    /// Sets the upper bound capacity map.
-
-    /// Sets the upper bound capacity map.
+    /// Sets the upper bound (capacity) map.
+
+    /// Sets the upper bound (capacity) map.
     /// \return <tt>(*this)</tt>
-    Circulation& upperCapMap(const LCapMap& map) {
+    Circulation& upperMap(const UpperMap& 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.
+    /// Sets the supply map.
+
+    /// Sets the supply map.
     /// \return <tt>(*this)</tt>
-    Circulation& deltaMap(const DeltaMap& map) {
-      _delta = &map;
+    Circulation& supplyMap(const SupplyMap& map) {
+      _supply = &map;
       return *this;
     }
@@ -422,8 +463,9 @@
     }
 
-    /// \brief Sets the tolerance used by algorithm.
-    ///
-    /// Sets the tolerance used by algorithm.
-    Circulation& tolerance(const Tolerance& tolerance) const {
+    /// \brief Sets the tolerance used by the algorithm.
+    ///
+    /// Sets the tolerance object used by the algorithm.
+    /// \return <tt>(*this)</tt>
+    Circulation& tolerance(const Tolerance& tolerance) {
       _tol = tolerance;
       return *this;
@@ -432,13 +474,14 @@
     /// \brief Returns a const reference to the tolerance.
     ///
-    /// Returns a const reference to the tolerance.
+    /// Returns a const reference to the tolerance object used by
+    /// the algorithm.
     const Tolerance& tolerance() const {
-      return tolerance;
+      return _tol;
     }
 
     /// \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
+    /// If you need better control on the initial solution or the execution,
+    /// you have to call one of the \ref init() functions first, then
     /// the \ref start() function.
 
@@ -451,14 +494,17 @@
     void init()
     {
+      LEMON_DEBUG(checkBoundMaps(),
+        "Upper bounds must be greater or equal to the lower bounds");
+
       createStructures();
 
       for(NodeIt n(_g);n!=INVALID;++n) {
-        _excess->set(n, (*_delta)[n]);
+        (*_excess)[n] = (*_supply)[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]);
+        (*_excess)[_g.target(e)] += (*_flow)[e];
+        (*_excess)[_g.source(e)] -= (*_flow)[e];
       }
 
@@ -480,24 +526,27 @@
     void greedyInit()
     {
+      LEMON_DEBUG(checkBoundMaps(),
+        "Upper bounds must be greater or equal to the lower bounds");
+
       createStructures();
 
       for(NodeIt n(_g);n!=INVALID;++n) {
-        _excess->set(n, (*_delta)[n]);
+        (*_excess)[n] = (*_supply)[n];
       }
 
       for (ArcIt e(_g);e!=INVALID;++e) {
-        if (!_tol.positive((*_excess)[_g.target(e)] + (*_up)[e])) {
+        if (!_tol.less(-(*_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])) {
+          (*_excess)[_g.target(e)] += (*_up)[e];
+          (*_excess)[_g.source(e)] -= (*_up)[e];
+        } else if (_tol.less(-(*_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]);
+          (*_excess)[_g.target(e)] += (*_lo)[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);
+          (*_excess)[_g.target(e)] = 0;
+          (*_excess)[_g.source(e)] -= fc;
         }
       }
@@ -524,6 +573,4 @@
 
       Node act;
-      Node bact=INVALID;
-      Node last_activated=INVALID;
       while((act=_level->highestActive())!=INVALID) {
         int actlevel=(*_level)[act];
@@ -538,8 +585,8 @@
             if(!_tol.less(fc, exc)) {
               _flow->set(e, (*_flow)[e] + exc);
-              _excess->set(v, (*_excess)[v] + exc);
+              (*_excess)[v] += exc;
               if(!_level->active(v) && _tol.positive((*_excess)[v]))
                 _level->activate(v);
-              _excess->set(act,0);
+              (*_excess)[act] = 0;
               _level->deactivate(act);
               goto next_l;
@@ -547,5 +594,5 @@
             else {
               _flow->set(e, (*_up)[e]);
-              _excess->set(v, (*_excess)[v] + fc);
+              (*_excess)[v] += fc;
               if(!_level->active(v) && _tol.positive((*_excess)[v]))
                 _level->activate(v);
@@ -562,8 +609,8 @@
             if(!_tol.less(fc, exc)) {
               _flow->set(e, (*_flow)[e] - exc);
-              _excess->set(v, (*_excess)[v] + exc);
+              (*_excess)[v] += exc;
               if(!_level->active(v) && _tol.positive((*_excess)[v]))
                 _level->activate(v);
-              _excess->set(act,0);
+              (*_excess)[act] = 0;
               _level->deactivate(act);
               goto next_l;
@@ -571,5 +618,5 @@
             else {
               _flow->set(e, (*_lo)[e]);
-              _excess->set(v, (*_excess)[v] + fc);
+              (*_excess)[v] += fc;
               if(!_level->active(v) && _tol.positive((*_excess)[v]))
                 _level->activate(v);
@@ -580,5 +627,5 @@
         }
 
-        _excess->set(act, exc);
+        (*_excess)[act] = exc;
         if(!_tol.positive(exc)) _level->deactivate(act);
         else if(mlevel==_node_num) {
@@ -627,7 +674,7 @@
     ///@{
 
-    /// \brief Returns the flow on the given arc.
-    ///
-    /// Returns the flow on the given arc.
+    /// \brief Returns the flow value on the given arc.
+    ///
+    /// Returns the flow value on the given arc.
     ///
     /// \pre Either \ref run() or \ref init() must be called before
@@ -652,6 +699,6 @@
        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]
+       \f[ \sum_{uv\in A: u\in B} upper(uv) -
+           \sum_{uv\in A: v\in B} lower(uv) < \sum_{v\in B} sup(v) \f]
 
        holds. The existence of a set with this property prooves that a
@@ -716,5 +763,5 @@
       for(NodeIt n(_g);n!=INVALID;++n)
         {
-          Value dif=-(*_delta)[n];
+          Value dif=-(*_supply)[n];
           for(InArcIt e(_g,n);e!=INVALID;++e) dif-=(*_flow)[e];
           for(OutArcIt e(_g,n);e!=INVALID;++e) dif+=(*_flow)[e];
@@ -732,12 +779,18 @@
     {
       Value delta=0;
+      Value inf_cap = std::numeric_limits<Value>::has_infinity ?
+        std::numeric_limits<Value>::infinity() :
+        std::numeric_limits<Value>::max();
       for(NodeIt n(_g);n!=INVALID;++n)
         if(barrier(n))
-          delta-=(*_delta)[n];
+          delta-=(*_supply)[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];
+          if(barrier(s)&&!barrier(t)) {
+            if (_tol.less(inf_cap - (*_up)[e], delta)) return false;
+            delta+=(*_up)[e];
+          }
           else if(barrier(t)&&!barrier(s)) delta-=(*_lo)[e];
         }
Index: lemon/clp.cc
===================================================================
--- lemon/clp.cc	(revision 540)
+++ lemon/clp.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -25,5 +25,5 @@
     _prob = new ClpSimplex();
     _init_temporals();
-    messageLevel(MESSAGE_NO_OUTPUT);
+    messageLevel(MESSAGE_NOTHING);
   }
 
@@ -33,5 +33,5 @@
     cols = other.cols;
     _init_temporals();
-    messageLevel(MESSAGE_NO_OUTPUT);
+    messageLevel(MESSAGE_NOTHING);
   }
 
@@ -76,4 +76,17 @@
   int ClpLp::_addRow() {
     _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
+    return _prob->numberRows() - 1;
+  }
+
+  int ClpLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
+    std::vector<int> indexes;
+    std::vector<Value> values;
+
+    for(ExprIterator it = b; it != e; ++it) {
+      indexes.push_back(it->first);
+      values.push_back(it->second);
+    }
+
+    _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
     return _prob->numberRows() - 1;
   }
@@ -425,12 +438,26 @@
     delete _prob;
     _prob = new ClpSimplex();
-    rows.clear();
-    cols.clear();
     _col_names_ref.clear();
     _clear_temporals();
   }
 
-  void ClpLp::messageLevel(MessageLevel m) {
-    _prob->setLogLevel(static_cast<int>(m));
+  void ClpLp::_messageLevel(MessageLevel level) {
+    switch (level) {
+    case MESSAGE_NOTHING:
+      _prob->setLogLevel(0);
+      break;
+    case MESSAGE_ERROR:
+      _prob->setLogLevel(1);
+      break;
+    case MESSAGE_WARNING:
+      _prob->setLogLevel(2);
+      break;
+    case MESSAGE_NORMAL:
+      _prob->setLogLevel(3);
+      break;
+    case MESSAGE_VERBOSE:
+      _prob->setLogLevel(4);
+      break;
+    }
   }
 
Index: lemon/clp.h
===================================================================
--- lemon/clp.h	(revision 540)
+++ lemon/clp.h	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -76,4 +76,5 @@
     virtual int _addCol();
     virtual int _addRow();
+    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
 
     virtual void _eraseCol(int i);
@@ -137,4 +138,6 @@
     virtual void _clear();
 
+    virtual void _messageLevel(MessageLevel);
+
   public:
 
@@ -154,24 +157,4 @@
     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);
-
   };
 
Index: lemon/concept_check.h
===================================================================
--- lemon/concept_check.h	(revision 440)
+++ lemon/concept_check.h	(revision 982)
@@ -36,4 +36,20 @@
 
   template <class T> inline void ignore_unused_variable_warning(const T&) { }
+  template <class T1, class T2>
+  inline void ignore_unused_variable_warning(const T1&, const T2&) { }
+  template <class T1, class T2, class T3>
+  inline void ignore_unused_variable_warning(const T1&, const T2&,
+                                             const T3&) { }
+  template <class T1, class T2, class T3, class T4>
+  inline void ignore_unused_variable_warning(const T1&, const T2&,
+                                             const T3&, const T4&) { }
+  template <class T1, class T2, class T3, class T4, class T5>
+  inline void ignore_unused_variable_warning(const T1&, const T2&,
+                                             const T3&, const T4&,
+                                             const T5&) { }
+  template <class T1, class T2, class T3, class T4, class T5, class T6>
+  inline void ignore_unused_variable_warning(const T1&, const T2&,
+                                             const T3&, const T4&,
+                                             const T5&, const T6&) { }
 
   ///\e
@@ -43,5 +59,5 @@
 #if !defined(NDEBUG)
     void (Concept::*x)() = & Concept::constraints;
-    ignore_unused_variable_warning(x);
+    ::lemon::ignore_unused_variable_warning(x);
 #endif
   }
@@ -53,5 +69,5 @@
     typedef typename Concept::template Constraints<Type> ConceptCheck;
     void (ConceptCheck::*x)() = & ConceptCheck::constraints;
-    ignore_unused_variable_warning(x);
+    ::lemon::ignore_unused_variable_warning(x);
 #endif
   }
Index: lemon/concepts/digraph.h
===================================================================
--- lemon/concepts/digraph.h	(revision 529)
+++ lemon/concepts/digraph.h	(revision 983)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -36,44 +36,38 @@
     /// \brief Class describing the concept of directed graphs.
     ///
-    /// This class describes the \ref concept "concept" of the
-    /// immutable directed digraphs.
+    /// This class describes the common interface of all directed
+    /// graphs (digraphs).
     ///
-    /// Note that actual digraph implementation like @ref ListDigraph or
-    /// @ref SmartDigraph may have several additional functionality.
+    /// Like all concept classes, it only provides an interface
+    /// without any sensible implementation. So any general algorithm for
+    /// directed graphs should compile with this class, but it will not
+    /// run properly, of course.
+    /// An actual digraph implementation like \ref ListDigraph or
+    /// \ref SmartDigraph may have additional functionality.
     ///
-    /// \sa concept
+    /// \sa Graph
     class Digraph {
     private:
-      ///Digraphs are \e not copy constructible. Use DigraphCopy() instead.
-
-      ///Digraphs are \e not copy constructible. Use DigraphCopy() instead.
-      ///
-      Digraph(const Digraph &) {};
-      ///\brief Assignment of \ref Digraph "Digraph"s to another ones are
-      ///\e not allowed. Use DigraphCopy() instead.
-
-      ///Assignment of \ref Digraph "Digraph"s to another ones are
-      ///\e not allowed.  Use DigraphCopy() instead.
-
+      /// Diraphs are \e not copy constructible. Use DigraphCopy instead.
+      Digraph(const Digraph &) {}
+      /// \brief Assignment of a digraph to another one is \e not allowed.
+      /// Use DigraphCopy instead.
       void operator=(const Digraph &) {}
+
     public:
-      ///\e
-
-      /// Defalult constructor.
-
-      /// Defalult constructor.
-      ///
+      /// Default constructor.
       Digraph() { }
-      /// Class for identifying a node of the digraph
+
+      /// The node type of the digraph
 
       /// This class identifies a node of the digraph. It also serves
       /// as a base class of the node iterators,
-      /// thus they will convert to this type.
+      /// thus they convert to this type.
       class Node {
       public:
         /// Default constructor
 
-        /// @warning The default constructor sets the iterator
-        /// to an undefined value.
+        /// Default constructor.
+        /// \warning It sets the object to an undefined value.
         Node() { }
         /// Copy constructor.
@@ -83,38 +77,37 @@
         Node(const Node&) { }
 
-        /// Invalid constructor \& conversion.
-
-        /// This constructor initializes the iterator to be invalid.
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the object to be invalid.
         /// \sa Invalid for more details.
         Node(Invalid) { }
         /// Equality operator
 
+        /// Equality operator.
+        ///
         /// Two iterators are equal if and only if they point to the
-        /// same object or both are invalid.
+        /// same object or both are \c INVALID.
         bool operator==(Node) const { return true; }
 
         /// Inequality operator
 
-        /// \sa operator==(Node n)
-        ///
+        /// Inequality operator.
         bool operator!=(Node) const { return true; }
 
         /// Artificial ordering operator.
 
-        /// To allow the use of digraph descriptors as key type 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.
+        /// Artificial ordering operator.
+        ///
+        /// \note This operator only has to define some strict ordering of
+        /// the nodes; this order has nothing to do with the iteration
+        /// ordering of the nodes.
         bool operator<(Node) const { return false; }
-
-      };
-
-      /// This iterator goes through each node.
-
-      /// This iterator goes through each node.
-      /// Its usage is quite simple, for example you can count the number
-      /// of nodes in digraph \c g of type \c Digraph like this:
+      };
+
+      /// Iterator class for the nodes.
+
+      /// This iterator goes through each node of the digraph.
+      /// Its usage is quite simple, for example, you can count the number
+      /// of nodes in a digraph \c g of type \c %Digraph like this:
       ///\code
       /// int count=0;
@@ -125,6 +118,6 @@
         /// Default constructor
 
-        /// @warning The default constructor sets the iterator
-        /// to an undefined value.
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
         NodeIt() { }
         /// Copy constructor.
@@ -133,20 +126,18 @@
         ///
         NodeIt(const NodeIt& n) : Node(n) { }
-        /// Invalid constructor \& conversion.
-
-        /// Initialize the iterator to be invalid.
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
         /// \sa Invalid for more details.
         NodeIt(Invalid) { }
         /// Sets the iterator to the first node.
 
-        /// Sets the iterator to the first node of \c g.
-        ///
-        NodeIt(const Digraph&) { }
-        /// Node -> NodeIt conversion.
-
-        /// Sets the iterator to the node of \c the digraph pointed by
-        /// the trivial iterator.
-        /// This feature necessitates that each time we
-        /// iterate the arc-set, the iteration order is the same.
+        /// Sets the iterator to the first node of the given digraph.
+        ///
+        explicit NodeIt(const Digraph&) { }
+        /// Sets the iterator to the given node.
+
+        /// Sets the iterator to the given node of the given digraph.
+        ///
         NodeIt(const Digraph&, const Node&) { }
         /// Next node.
@@ -158,5 +149,5 @@
 
 
-      /// Class for identifying an arc of the digraph
+      /// The arc type of the digraph
 
       /// This class identifies an arc of the digraph. It also serves
@@ -167,6 +158,6 @@
         /// Default constructor
 
-        /// @warning The default constructor sets the iterator
-        /// to an undefined value.
+        /// Default constructor.
+        /// \warning It sets the object to an undefined value.
         Arc() { }
         /// Copy constructor.
@@ -175,49 +166,48 @@
         ///
         Arc(const Arc&) { }
-        /// Initialize the iterator to be invalid.
-
-        /// Initialize the iterator to be invalid.
-        ///
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the object to be invalid.
+        /// \sa Invalid for more details.
         Arc(Invalid) { }
         /// Equality operator
 
+        /// Equality operator.
+        ///
         /// Two iterators are equal if and only if they point to the
-        /// same object or both are invalid.
+        /// same object or both are \c INVALID.
         bool operator==(Arc) const { return true; }
         /// Inequality operator
 
-        /// \sa operator==(Arc n)
-        ///
+        /// Inequality operator.
         bool operator!=(Arc) const { return true; }
 
         /// Artificial ordering operator.
 
-        /// To allow the use of digraph descriptors as key type 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.
+        /// Artificial ordering operator.
+        ///
+        /// \note This operator only has to define some strict ordering of
+        /// the arcs; this order has nothing to do with the iteration
+        /// ordering of the arcs.
         bool operator<(Arc) const { return false; }
       };
 
-      /// This iterator goes trough the outgoing arcs of a node.
+      /// Iterator class for the outgoing arcs of a node.
 
       /// This iterator goes trough the \e outgoing arcs of a certain node
       /// of a digraph.
-      /// Its usage is quite simple, for example you can count the number
+      /// Its usage is quite simple, for example, you can count the number
       /// of outgoing arcs of a node \c n
-      /// in digraph \c g of type \c Digraph as follows.
+      /// in a digraph \c g of type \c %Digraph as follows.
       ///\code
       /// int count=0;
-      /// for (Digraph::OutArcIt e(g, n); e!=INVALID; ++e) ++count;
+      /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
       ///\endcode
-
       class OutArcIt : public Arc {
       public:
         /// Default constructor
 
-        /// @warning The default constructor sets the iterator
-        /// to an undefined value.
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
         OutArcIt() { }
         /// Copy constructor.
@@ -226,21 +216,20 @@
         ///
         OutArcIt(const OutArcIt& e) : Arc(e) { }
-        /// Initialize the iterator to be invalid.
-
-        /// Initialize the iterator to be invalid.
-        ///
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
         OutArcIt(Invalid) { }
-        /// This constructor sets the iterator to the first outgoing arc.
-
-        /// This constructor sets the iterator to the first outgoing arc of
-        /// the node.
+        /// Sets the iterator to the first outgoing arc.
+
+        /// Sets the iterator to the first outgoing arc of the given node.
+        ///
         OutArcIt(const Digraph&, const Node&) { }
-        /// Arc -> OutArcIt conversion
-
-        /// Sets the iterator to the value of the trivial iterator.
-        /// This feature necessitates that each time we
-        /// iterate the arc-set, the iteration order is the same.
+        /// Sets the iterator to the given arc.
+
+        /// Sets the iterator to the given arc of the given digraph.
+        ///
         OutArcIt(const Digraph&, const Arc&) { }
-        ///Next outgoing arc
+        /// Next outgoing arc
 
         /// Assign the iterator to the next
@@ -249,22 +238,21 @@
       };
 
-      /// This iterator goes trough the incoming arcs of a node.
+      /// Iterator class for the incoming arcs of a node.
 
       /// This iterator goes trough the \e incoming arcs of a certain node
       /// of a digraph.
-      /// Its usage is quite simple, for example you can count the number
-      /// of outgoing arcs of a node \c n
-      /// in digraph \c g of type \c Digraph as follows.
+      /// Its usage is quite simple, for example, you can count the number
+      /// of incoming arcs of a node \c n
+      /// in a digraph \c g of type \c %Digraph as follows.
       ///\code
       /// int count=0;
-      /// for(Digraph::InArcIt e(g, n); e!=INVALID; ++e) ++count;
+      /// for(Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
       ///\endcode
-
       class InArcIt : public Arc {
       public:
         /// Default constructor
 
-        /// @warning The default constructor sets the iterator
-        /// to an undefined value.
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
         InArcIt() { }
         /// Copy constructor.
@@ -273,34 +261,34 @@
         ///
         InArcIt(const InArcIt& e) : Arc(e) { }
-        /// Initialize the iterator to be invalid.
-
-        /// Initialize the iterator to be invalid.
-        ///
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
         InArcIt(Invalid) { }
-        /// This constructor sets the iterator to first incoming arc.
-
-        /// This constructor set the iterator to the first incoming arc of
-        /// the node.
+        /// Sets the iterator to the first incoming arc.
+
+        /// Sets the iterator to the first incoming arc of the given node.
+        ///
         InArcIt(const Digraph&, const Node&) { }
-        /// Arc -> InArcIt conversion
-
-        /// Sets the iterator to the value of the trivial iterator \c e.
-        /// This feature necessitates that each time we
-        /// iterate the arc-set, the iteration order is the same.
+        /// Sets the iterator to the given arc.
+
+        /// Sets the iterator to the given arc of the given digraph.
+        ///
         InArcIt(const Digraph&, const Arc&) { }
         /// Next incoming arc
 
-        /// Assign the iterator to the next inarc of the corresponding node.
-        ///
+        /// Assign the iterator to the next
+        /// incoming arc of the corresponding node.
         InArcIt& operator++() { return *this; }
       };
-      /// This iterator goes through each arc.
-
-      /// This iterator goes through each arc of a digraph.
-      /// Its usage is quite simple, for example you can count the number
-      /// of arcs in a digraph \c g of type \c Digraph as follows:
+
+      /// Iterator class for the arcs.
+
+      /// This iterator goes through each arc of the digraph.
+      /// Its usage is quite simple, for example, you can count the number
+      /// of arcs in a digraph \c g of type \c %Digraph as follows:
       ///\code
       /// int count=0;
-      /// for(Digraph::ArcIt e(g); e!=INVALID; ++e) ++count;
+      /// for(Digraph::ArcIt a(g); a!=INVALID; ++a) ++count;
       ///\endcode
       class ArcIt : public Arc {
@@ -308,6 +296,6 @@
         /// Default constructor
 
-        /// @warning The default constructor sets the iterator
-        /// to an undefined value.
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
         ArcIt() { }
         /// Copy constructor.
@@ -316,56 +304,66 @@
         ///
         ArcIt(const ArcIt& e) : Arc(e) { }
-        /// Initialize the iterator to be invalid.
-
-        /// Initialize the iterator to be invalid.
-        ///
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
         ArcIt(Invalid) { }
-        /// This constructor sets the iterator to the first arc.
-
-        /// This constructor sets the iterator to the first arc of \c g.
-        ///@param g the digraph
-        ArcIt(const Digraph& g) { ignore_unused_variable_warning(g); }
-        /// Arc -> ArcIt conversion
-
-        /// Sets the iterator to the value of the trivial iterator \c e.
-        /// This feature necessitates that each time we
-        /// iterate the arc-set, the iteration order is the same.
+        /// Sets the iterator to the first arc.
+
+        /// Sets the iterator to the first arc of the given digraph.
+        ///
+        explicit ArcIt(const Digraph& g) { ::lemon::ignore_unused_variable_warning(g); }
+        /// Sets the iterator to the given arc.
+
+        /// Sets the iterator to the given arc of the given digraph.
+        ///
         ArcIt(const Digraph&, const Arc&) { }
-        ///Next arc
+        /// Next arc
 
         /// Assign the iterator to the next arc.
+        ///
         ArcIt& operator++() { return *this; }
       };
-      ///Gives back the target node of an arc.
-
-      ///Gives back the target node of an arc.
-      ///
+
+      /// \brief The source node of the arc.
+      ///
+      /// Returns the source node of the given arc.
+      Node source(Arc) const { return INVALID; }
+
+      /// \brief The target node of the arc.
+      ///
+      /// Returns the target node of the given arc.
       Node target(Arc) const { return INVALID; }
-      ///Gives back the source node of an arc.
-
-      ///Gives back the source node of an arc.
-      ///
-      Node source(Arc) const { return INVALID; }
-
-      /// \brief Returns the ID of the node.
+
+      /// \brief The ID of the node.
+      ///
+      /// Returns the ID of the given node.
       int id(Node) const { return -1; }
 
-      /// \brief Returns the ID of the arc.
+      /// \brief The ID of the arc.
+      ///
+      /// Returns the ID of the given arc.
       int id(Arc) const { return -1; }
 
-      /// \brief Returns the node with the given ID.
-      ///
-      /// \pre The argument should be a valid node ID in the graph.
+      /// \brief The node with the given ID.
+      ///
+      /// Returns the node with the given ID.
+      /// \pre The argument should be a valid node ID in the digraph.
       Node nodeFromId(int) const { return INVALID; }
 
-      /// \brief Returns the arc with the given ID.
-      ///
-      /// \pre The argument should be a valid arc ID in the graph.
+      /// \brief The arc with the given ID.
+      ///
+      /// Returns the arc with the given ID.
+      /// \pre The argument should be a valid arc ID in the digraph.
       Arc arcFromId(int) const { return INVALID; }
 
-      /// \brief Returns an upper bound on the node IDs.
+      /// \brief An upper bound on the node IDs.
+      ///
+      /// Returns an upper bound on the node IDs.
       int maxNodeId() const { return -1; }
 
-      /// \brief Returns an upper bound on the arc IDs.
+      /// \brief An upper bound on the arc IDs.
+      ///
+      /// Returns an upper bound on the arc IDs.
       int maxArcId() const { return -1; }
 
@@ -393,49 +391,50 @@
       int maxId(Arc) const { return -1; }
 
+      /// \brief The opposite node on the arc.
+      ///
+      /// Returns the opposite node on the given arc.
+      Node oppositeNode(Node, Arc) const { return INVALID; }
+
       /// \brief The base node of the iterator.
       ///
-      /// Gives back the base node of the iterator.
-      /// It is always the target of the pointed arc.
-      Node baseNode(const InArcIt&) const { return INVALID; }
+      /// Returns the base node of the given outgoing arc iterator
+      /// (i.e. the source node of the corresponding arc).
+      Node baseNode(OutArcIt) const { return INVALID; }
 
       /// \brief The running node of the iterator.
       ///
-      /// Gives back the running node of the iterator.
-      /// It is always the source of the pointed arc.
-      Node runningNode(const InArcIt&) const { return INVALID; }
+      /// Returns the running node of the given outgoing arc iterator
+      /// (i.e. the target node of the corresponding arc).
+      Node runningNode(OutArcIt) const { return INVALID; }
 
       /// \brief The base node of the iterator.
       ///
-      /// Gives back the base node of the iterator.
-      /// It is always the source of the pointed arc.
-      Node baseNode(const OutArcIt&) const { return INVALID; }
+      /// Returns the base node of the given incomming arc iterator
+      /// (i.e. the target node of the corresponding arc).
+      Node baseNode(InArcIt) const { return INVALID; }
 
       /// \brief The running node of the iterator.
       ///
-      /// Gives back the running node of the iterator.
-      /// It is always the target of the pointed arc.
-      Node runningNode(const OutArcIt&) const { return INVALID; }
-
-      /// \brief The opposite node on the given arc.
-      ///
-      /// Gives back the opposite node on the given arc.
-      Node oppositeNode(const Node&, const Arc&) const { return INVALID; }
-
-      /// \brief Read write map of the nodes to type \c T.
-      ///
-      /// ReadWrite map of the nodes to type \c T.
-      /// \sa Reference
+      /// Returns the running node of the given incomming arc iterator
+      /// (i.e. the source node of the corresponding arc).
+      Node runningNode(InArcIt) const { return INVALID; }
+
+      /// \brief Standard graph map type for the nodes.
+      ///
+      /// Standard graph map type for the nodes.
+      /// It conforms to the ReferenceMap concept.
       template<class T>
-      class NodeMap : public ReadWriteMap< Node, T > {
-      public:
-
-        ///\e
-        NodeMap(const Digraph&) { }
-        ///\e
+      class NodeMap : public ReferenceMap<Node, T, T&, const T&> {
+      public:
+
+        /// Constructor
+        explicit NodeMap(const Digraph&) { }
+        /// Constructor with given initial value
         NodeMap(const Digraph&, T) { }
 
       private:
         ///Copy constructor
-        NodeMap(const NodeMap& nm) : ReadWriteMap< Node, T >(nm) { }
+        NodeMap(const NodeMap& nm) :
+          ReferenceMap<Node, T, T&, const T&>(nm) { }
         ///Assignment operator
         template <typename CMap>
@@ -446,19 +445,21 @@
       };
 
-      /// \brief Read write map of the arcs to type \c T.
-      ///
-      /// Reference map of the arcs to type \c T.
-      /// \sa Reference
+      /// \brief Standard graph map type for the arcs.
+      ///
+      /// Standard graph map type for the arcs.
+      /// It conforms to the ReferenceMap concept.
       template<class T>
-      class ArcMap : public ReadWriteMap<Arc,T> {
-      public:
-
-        ///\e
-        ArcMap(const Digraph&) { }
-        ///\e
+      class ArcMap : public ReferenceMap<Arc, T, T&, const T&> {
+      public:
+
+        /// Constructor
+        explicit ArcMap(const Digraph&) { }
+        /// Constructor with given initial value
         ArcMap(const Digraph&, T) { }
+
       private:
         ///Copy constructor
-        ArcMap(const ArcMap& em) : ReadWriteMap<Arc,T>(em) { }
+        ArcMap(const ArcMap& em) :
+          ReferenceMap<Arc, T, T&, const T&>(em) { }
         ///Assignment operator
         template <typename CMap>
@@ -472,4 +473,5 @@
       struct Constraints {
         void constraints() {
+          checkConcept<BaseDigraphComponent, _Digraph>();
           checkConcept<IterableDigraphComponent<>, _Digraph>();
           checkConcept<IDableDigraphComponent<>, _Digraph>();
Index: lemon/concepts/graph.h
===================================================================
--- lemon/concepts/graph.h	(revision 559)
+++ lemon/concepts/graph.h	(revision 983)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -19,5 +19,5 @@
 ///\ingroup graph_concepts
 ///\file
-///\brief The concept of Undirected Graphs.
+///\brief The concept of undirected graphs.
 
 #ifndef LEMON_CONCEPTS_GRAPH_H
@@ -25,4 +25,6 @@
 
 #include <lemon/concepts/graph_components.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/concept_check.h>
 #include <lemon/core.h>
 
@@ -32,61 +34,72 @@
     /// \ingroup graph_concepts
     ///
-    /// \brief Class describing the concept of Undirected Graphs.
+    /// \brief Class describing the concept of undirected graphs.
     ///
-    /// This class describes the common interface of all Undirected
-    /// Graphs.
+    /// This class describes the common interface of all undirected
+    /// graphs.
     ///
-    /// As all concept describing classes it provides only interface
-    /// without any sensible implementation. So any algorithm for
-    /// undirected graph should compile with this class, but it will not
+    /// Like all concept classes, it only provides an interface
+    /// without any sensible implementation. So any general algorithm for
+    /// undirected graphs should compile with this class, but it will not
     /// run properly, of course.
+    /// An actual graph implementation like \ref ListGraph or
+    /// \ref SmartGraph may have additional functionality.
     ///
-    /// The LEMON undirected graphs also fulfill the concept of
-    /// directed graphs (\ref lemon::concepts::Digraph "Digraph
-    /// Concept"). Each edges can be seen as two opposite
-    /// directed arc and consequently the undirected graph can be
-    /// seen as the direceted graph of these directed arcs. The
-    /// Graph has the Edge inner class for the edges and
-    /// the Arc type for the directed arcs. The Arc type is
-    /// convertible to Edge or inherited from it so from a directed
-    /// arc we can get the represented edge.
+    /// The undirected graphs also fulfill the concept of \ref Digraph
+    /// "directed graphs", since each edge can also be regarded as two
+    /// oppositely directed arcs.
+    /// Undirected graphs provide an Edge type for the undirected edges and
+    /// an Arc type for the directed arcs. The Arc type is convertible to
+    /// Edge or inherited from it, i.e. the corresponding edge can be
+    /// obtained from an arc.
+    /// EdgeIt and EdgeMap classes can be used for the edges, while ArcIt
+    /// and ArcMap classes can be used for the arcs (just like in digraphs).
+    /// Both InArcIt and OutArcIt iterates on the same edges but with
+    /// opposite direction. IncEdgeIt also iterates on the same edges
+    /// as OutArcIt and InArcIt, but it is not convertible to Arc,
+    /// only to Edge.
     ///
-    /// In the sense of the LEMON each edge has a default
-    /// direction (it should be in every computer implementation,
-    /// because the order of edge's nodes defines an
-    /// orientation). With the default orientation we can define that
-    /// the directed arc is forward or backward directed. With the \c
-    /// direction() and \c direct() function we can get the direction
-    /// of the directed arc and we can direct an edge.
+    /// In LEMON, each undirected edge has an inherent orientation.
+    /// Thus it can defined if an arc is forward or backward oriented in
+    /// an undirected graph with respect to this default oriantation of
+    /// the represented edge.
+    /// With the direction() and direct() functions the direction
+    /// of an arc can be obtained and set, respectively.
     ///
-    /// The EdgeIt is an iterator for the edges. We can use
-    /// the EdgeMap to map values for the edges. The InArcIt and
-    /// OutArcIt iterates on the same edges but with opposite
-    /// direction. The IncEdgeIt iterates also on the same edges
-    /// as the OutArcIt and InArcIt but it is not convertible to Arc just
-    /// to Edge.
+    /// Only nodes and edges can be added to or removed from an undirected
+    /// graph and the corresponding arcs are added or removed automatically.
+    ///
+    /// \sa Digraph
     class Graph {
+    private:
+      /// Graphs are \e not copy constructible. Use DigraphCopy instead.
+      Graph(const Graph&) {}
+      /// \brief Assignment of a graph to another one is \e not allowed.
+      /// Use DigraphCopy instead.
+      void operator=(const Graph&) {}
+
     public:
-      /// \brief The undirected graph should be tagged by the
-      /// UndirectedTag.
-      ///
-      /// The undirected graph should be tagged by the UndirectedTag. This
-      /// tag helps the enable_if technics to make compile time
+      /// Default constructor.
+      Graph() {}
+
+      /// \brief Undirected graphs should be tagged with \c UndirectedTag.
+      ///
+      /// Undirected graphs should be tagged with \c UndirectedTag.
+      ///
+      /// This tag helps the \c enable_if technics to make compile time
       /// specializations for undirected graphs.
       typedef True UndirectedTag;
 
-      /// \brief The base type of node iterators,
-      /// or in other words, the trivial node iterator.
-      ///
-      /// This is the base type of each node iterator,
-      /// thus each kind of node iterator converts to this.
-      /// More precisely each kind of node iterator should be inherited
-      /// from the trivial node iterator.
+      /// The node type of the graph
+
+      /// This class identifies a node of the graph. It also serves
+      /// as a base class of the node iterators,
+      /// thus they convert to this type.
       class Node {
       public:
         /// Default constructor
 
-        /// @warning The default constructor sets the iterator
-        /// to an undefined value.
+        /// Default constructor.
+        /// \warning It sets the object to an undefined value.
         Node() { }
         /// Copy constructor.
@@ -96,27 +109,27 @@
         Node(const Node&) { }
 
-        /// Invalid constructor \& conversion.
-
-        /// This constructor initializes the iterator to be invalid.
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the object to be invalid.
         /// \sa Invalid for more details.
         Node(Invalid) { }
         /// Equality operator
 
+        /// Equality operator.
+        ///
         /// Two iterators are equal if and only if they point to the
-        /// same object or both are invalid.
+        /// same object or both are \c INVALID.
         bool operator==(Node) const { return true; }
 
         /// Inequality operator
 
-        /// \sa operator==(Node n)
-        ///
+        /// Inequality operator.
         bool operator!=(Node) const { return true; }
 
         /// Artificial ordering operator.
 
-        /// To allow the use of graph descriptors as key type in std::map or
-        /// similar associative container we require this.
-        ///
-        /// \note This operator only have to define some strict ordering of
+        /// Artificial ordering operator.
+        ///
+        /// \note This operator only has to define some strict ordering of
         /// the items; this order has nothing to do with the iteration
         /// ordering of the items.
@@ -125,9 +138,9 @@
       };
 
-      /// This iterator goes through each node.
-
-      /// This iterator goes through each node.
-      /// Its usage is quite simple, for example you can count the number
-      /// of nodes in graph \c g of type \c Graph like this:
+      /// Iterator class for the nodes.
+
+      /// This iterator goes through each node of the graph.
+      /// Its usage is quite simple, for example, you can count the number
+      /// of nodes in a graph \c g of type \c %Graph like this:
       ///\code
       /// int count=0;
@@ -138,6 +151,6 @@
         /// Default constructor
 
-        /// @warning The default constructor sets the iterator
-        /// to an undefined value.
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
         NodeIt() { }
         /// Copy constructor.
@@ -146,20 +159,18 @@
         ///
         NodeIt(const NodeIt& n) : Node(n) { }
-        /// Invalid constructor \& conversion.
-
-        /// Initialize the iterator to be invalid.
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
         /// \sa Invalid for more details.
         NodeIt(Invalid) { }
         /// Sets the iterator to the first node.
 
-        /// Sets the iterator to the first node of \c g.
-        ///
-        NodeIt(const Graph&) { }
-        /// Node -> NodeIt conversion.
-
-        /// Sets the iterator to the node of \c the graph pointed by
-        /// the trivial iterator.
-        /// This feature necessitates that each time we
-        /// iterate the arc-set, the iteration order is the same.
+        /// Sets the iterator to the first node of the given digraph.
+        ///
+        explicit NodeIt(const Graph&) { }
+        /// Sets the iterator to the given node.
+
+        /// Sets the iterator to the given node of the given digraph.
+        ///
         NodeIt(const Graph&, const Node&) { }
         /// Next node.
@@ -171,14 +182,15 @@
 
 
-      /// The base type of the edge iterators.
-
-      /// The base type of the edge iterators.
-      ///
+      /// The edge type of the graph
+
+      /// This class identifies an edge of the graph. It also serves
+      /// as a base class of the edge iterators,
+      /// thus they will convert to this type.
       class Edge {
       public:
         /// Default constructor
 
-        /// @warning The default constructor sets the iterator
-        /// to an undefined value.
+        /// Default constructor.
+        /// \warning It sets the object to an undefined value.
         Edge() { }
         /// Copy constructor.
@@ -187,36 +199,36 @@
         ///
         Edge(const Edge&) { }
-        /// Initialize the iterator to be invalid.
-
-        /// Initialize the iterator to be invalid.
-        ///
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the object to be invalid.
+        /// \sa Invalid for more details.
         Edge(Invalid) { }
         /// Equality operator
 
+        /// Equality operator.
+        ///
         /// Two iterators are equal if and only if they point to the
-        /// same object or both are invalid.
+        /// same object or both are \c INVALID.
         bool operator==(Edge) const { return true; }
         /// Inequality operator
 
-        /// \sa operator==(Edge n)
-        ///
+        /// Inequality operator.
         bool operator!=(Edge) const { return true; }
 
         /// Artificial ordering operator.
 
-        /// To allow the use of graph descriptors as key type 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.
+        /// Artificial ordering operator.
+        ///
+        /// \note This operator only has to define some strict ordering of
+        /// the edges; this order has nothing to do with the iteration
+        /// ordering of the edges.
         bool operator<(Edge) const { return false; }
       };
 
-      /// This iterator goes through each edge.
-
-      /// This iterator goes through each edge of a graph.
-      /// Its usage is quite simple, for example you can count the number
-      /// of edges in a graph \c g of type \c Graph as follows:
+      /// Iterator class for the edges.
+
+      /// This iterator goes through each edge of the graph.
+      /// Its usage is quite simple, for example, you can count the number
+      /// of edges in a graph \c g of type \c %Graph as follows:
       ///\code
       /// int count=0;
@@ -227,6 +239,6 @@
         /// Default constructor
 
-        /// @warning The default constructor sets the iterator
-        /// to an undefined value.
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
         EdgeIt() { }
         /// Copy constructor.
@@ -235,36 +247,33 @@
         ///
         EdgeIt(const EdgeIt& e) : Edge(e) { }
-        /// Initialize the iterator to be invalid.
-
-        /// Initialize the iterator to be invalid.
-        ///
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
         EdgeIt(Invalid) { }
-        /// This constructor sets the iterator to the first edge.
-
-        /// This constructor sets the iterator to the first edge.
-        EdgeIt(const Graph&) { }
-        /// Edge -> EdgeIt conversion
-
-        /// Sets the iterator to the value of the trivial iterator.
-        /// This feature necessitates that each time we
-        /// iterate the edge-set, the iteration order is the
-        /// same.
+        /// Sets the iterator to the first edge.
+
+        /// Sets the iterator to the first edge of the given graph.
+        ///
+        explicit EdgeIt(const Graph&) { }
+        /// Sets the iterator to the given edge.
+
+        /// Sets the iterator to the given edge of the given graph.
+        ///
         EdgeIt(const Graph&, const Edge&) { }
         /// Next edge
 
         /// Assign the iterator to the next edge.
+        ///
         EdgeIt& operator++() { return *this; }
       };
 
-      /// \brief This iterator goes trough the incident undirected
-      /// arcs of a node.
-      ///
-      /// This iterator goes trough the incident edges
-      /// of a certain node of a graph. You should assume that the
-      /// loop arcs will be iterated twice.
-      ///
-      /// Its usage is quite simple, for example you can compute the
-      /// degree (i.e. count the number of incident arcs of a node \c n
-      /// in graph \c g of type \c Graph as follows.
+      /// Iterator class for the incident edges of a node.
+
+      /// This iterator goes trough the incident undirected edges
+      /// of a certain node of a graph.
+      /// Its usage is quite simple, for example, you can compute the
+      /// degree (i.e. the number of incident edges) of a node \c n
+      /// in a graph \c g of type \c %Graph as follows.
       ///
       ///\code
@@ -272,10 +281,12 @@
       /// for(Graph::IncEdgeIt e(g, n); e!=INVALID; ++e) ++count;
       ///\endcode
+      ///
+      /// \warning Loop edges will be iterated twice.
       class IncEdgeIt : public Edge {
       public:
         /// Default constructor
 
-        /// @warning The default constructor sets the iterator
-        /// to an undefined value.
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
         IncEdgeIt() { }
         /// Copy constructor.
@@ -284,38 +295,37 @@
         ///
         IncEdgeIt(const IncEdgeIt& e) : Edge(e) { }
-        /// Initialize the iterator to be invalid.
-
-        /// Initialize the iterator to be invalid.
-        ///
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
         IncEdgeIt(Invalid) { }
-        /// This constructor sets the iterator to first incident arc.
-
-        /// This constructor set the iterator to the first incident arc of
-        /// the node.
+        /// Sets the iterator to the first incident edge.
+
+        /// Sets the iterator to the first incident edge of the given node.
+        ///
         IncEdgeIt(const Graph&, const Node&) { }
-        /// Edge -> IncEdgeIt conversion
-
-        /// Sets the iterator to the value of the trivial iterator \c e.
-        /// This feature necessitates that each time we
-        /// iterate the arc-set, the iteration order is the same.
+        /// Sets the iterator to the given edge.
+
+        /// Sets the iterator to the given edge of the given graph.
+        ///
         IncEdgeIt(const Graph&, const Edge&) { }
-        /// Next incident arc
-
-        /// Assign the iterator to the next incident arc
+        /// Next incident edge
+
+        /// Assign the iterator to the next incident edge
         /// of the corresponding node.
         IncEdgeIt& operator++() { return *this; }
       };
 
-      /// The directed arc type.
-
-      /// The directed arc type. It can be converted to the
-      /// edge or it should be inherited from the undirected
-      /// arc.
-      class Arc : public Edge {
-      public:
-        /// Default constructor
-
-        /// @warning The default constructor sets the iterator
-        /// to an undefined value.
+      /// The arc type of the graph
+
+      /// This class identifies a directed arc of the graph. It also serves
+      /// as a base class of the arc iterators,
+      /// thus they will convert to this type.
+      class Arc {
+      public:
+        /// Default constructor
+
+        /// Default constructor.
+        /// \warning It sets the object to an undefined value.
         Arc() { }
         /// Copy constructor.
@@ -323,40 +333,46 @@
         /// Copy constructor.
         ///
-        Arc(const Arc& e) : Edge(e) { }
-        /// Initialize the iterator to be invalid.
-
-        /// Initialize the iterator to be invalid.
-        ///
+        Arc(const Arc&) { }
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the object to be invalid.
+        /// \sa Invalid for more details.
         Arc(Invalid) { }
         /// Equality operator
 
+        /// Equality operator.
+        ///
         /// Two iterators are equal if and only if they point to the
-        /// same object or both are invalid.
+        /// same object or both are \c INVALID.
         bool operator==(Arc) const { return true; }
         /// Inequality operator
 
-        /// \sa operator==(Arc n)
-        ///
+        /// Inequality operator.
         bool operator!=(Arc) const { return true; }
 
         /// Artificial ordering operator.
 
-        /// To allow the use of graph descriptors as key type 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.
+        /// Artificial ordering operator.
+        ///
+        /// \note This operator only has to define some strict ordering of
+        /// the arcs; this order has nothing to do with the iteration
+        /// ordering of the arcs.
         bool operator<(Arc) const { return false; }
 
-      };
-      /// This iterator goes through each directed arc.
-
-      /// This iterator goes through each arc of a graph.
-      /// Its usage is quite simple, for example you can count the number
-      /// of arcs in a graph \c g of type \c Graph as follows:
+        /// Converison to \c Edge
+
+        /// Converison to \c Edge.
+        ///
+        operator Edge() const { return Edge(); }
+      };
+
+      /// Iterator class for the arcs.
+
+      /// This iterator goes through each directed arc of the graph.
+      /// Its usage is quite simple, for example, you can count the number
+      /// of arcs in a graph \c g of type \c %Graph as follows:
       ///\code
       /// int count=0;
-      /// for(Graph::ArcIt e(g); e!=INVALID; ++e) ++count;
+      /// for(Graph::ArcIt a(g); a!=INVALID; ++a) ++count;
       ///\endcode
       class ArcIt : public Arc {
@@ -364,6 +380,6 @@
         /// Default constructor
 
-        /// @warning The default constructor sets the iterator
-        /// to an undefined value.
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
         ArcIt() { }
         /// Copy constructor.
@@ -372,44 +388,43 @@
         ///
         ArcIt(const ArcIt& e) : Arc(e) { }
-        /// Initialize the iterator to be invalid.
-
-        /// Initialize the iterator to be invalid.
-        ///
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
         ArcIt(Invalid) { }
-        /// This constructor sets the iterator to the first arc.
-
-        /// This constructor sets the iterator to the first arc of \c g.
-        ///@param g the graph
-        ArcIt(const Graph &g) { ignore_unused_variable_warning(g); }
-        /// Arc -> ArcIt conversion
-
-        /// Sets the iterator to the value of the trivial iterator \c e.
-        /// This feature necessitates that each time we
-        /// iterate the arc-set, the iteration order is the same.
+        /// Sets the iterator to the first arc.
+
+        /// Sets the iterator to the first arc of the given graph.
+        ///
+        explicit ArcIt(const Graph &g) { ::lemon::ignore_unused_variable_warning(g); }
+        /// Sets the iterator to the given arc.
+
+        /// Sets the iterator to the given arc of the given graph.
+        ///
         ArcIt(const Graph&, const Arc&) { }
-        ///Next arc
+        /// Next arc
 
         /// Assign the iterator to the next arc.
+        ///
         ArcIt& operator++() { return *this; }
       };
 
-      /// This iterator goes trough the outgoing directed arcs of a node.
-
-      /// This iterator goes trough the \e outgoing arcs of a certain node
-      /// of a graph.
-      /// Its usage is quite simple, for example you can count the number
+      /// Iterator class for the outgoing arcs of a node.
+
+      /// This iterator goes trough the \e outgoing directed arcs of a
+      /// certain node of a graph.
+      /// Its usage is quite simple, for example, you can count the number
       /// of outgoing arcs of a node \c n
-      /// in graph \c g of type \c Graph as follows.
+      /// in a graph \c g of type \c %Graph as follows.
       ///\code
       /// int count=0;
-      /// for (Graph::OutArcIt e(g, n); e!=INVALID; ++e) ++count;
+      /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
       ///\endcode
-
       class OutArcIt : public Arc {
       public:
         /// Default constructor
 
-        /// @warning The default constructor sets the iterator
-        /// to an undefined value.
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
         OutArcIt() { }
         /// Copy constructor.
@@ -418,26 +433,23 @@
         ///
         OutArcIt(const OutArcIt& e) : Arc(e) { }
-        /// Initialize the iterator to be invalid.
-
-        /// Initialize the iterator to be invalid.
-        ///
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
         OutArcIt(Invalid) { }
-        /// This constructor sets the iterator to the first outgoing arc.
-
-        /// This constructor sets the iterator to the first outgoing arc of
-        /// the node.
-        ///@param n the node
-        ///@param g the graph
+        /// Sets the iterator to the first outgoing arc.
+
+        /// Sets the iterator to the first outgoing arc of the given node.
+        ///
         OutArcIt(const Graph& n, const Node& g) {
-          ignore_unused_variable_warning(n);
-          ignore_unused_variable_warning(g);
+          ::lemon::ignore_unused_variable_warning(n);
+          ::lemon::ignore_unused_variable_warning(g);
         }
-        /// Arc -> OutArcIt conversion
-
-        /// Sets the iterator to the value of the trivial iterator.
-        /// This feature necessitates that each time we
-        /// iterate the arc-set, the iteration order is the same.
+        /// Sets the iterator to the given arc.
+
+        /// Sets the iterator to the given arc of the given graph.
+        ///
         OutArcIt(const Graph&, const Arc&) { }
-        ///Next outgoing arc
+        /// Next outgoing arc
 
         /// Assign the iterator to the next
@@ -446,22 +458,21 @@
       };
 
-      /// This iterator goes trough the incoming directed arcs of a node.
-
-      /// This iterator goes trough the \e incoming arcs of a certain node
-      /// of a graph.
-      /// Its usage is quite simple, for example you can count the number
-      /// of outgoing arcs of a node \c n
-      /// in graph \c g of type \c Graph as follows.
+      /// Iterator class for the incoming arcs of a node.
+
+      /// This iterator goes trough the \e incoming directed arcs of a
+      /// certain node of a graph.
+      /// Its usage is quite simple, for example, you can count the number
+      /// of incoming arcs of a node \c n
+      /// in a graph \c g of type \c %Graph as follows.
       ///\code
       /// int count=0;
-      /// for(Graph::InArcIt e(g, n); e!=INVALID; ++e) ++count;
+      /// for (Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
       ///\endcode
-
       class InArcIt : public Arc {
       public:
         /// Default constructor
 
-        /// @warning The default constructor sets the iterator
-        /// to an undefined value.
+        /// Default constructor.
+        /// \warning It sets the iterator to an undefined value.
         InArcIt() { }
         /// Copy constructor.
@@ -470,49 +481,47 @@
         ///
         InArcIt(const InArcIt& e) : Arc(e) { }
-        /// Initialize the iterator to be invalid.
-
-        /// Initialize the iterator to be invalid.
-        ///
+        /// %Invalid constructor \& conversion.
+
+        /// Initializes the iterator to be invalid.
+        /// \sa Invalid for more details.
         InArcIt(Invalid) { }
-        /// This constructor sets the iterator to first incoming arc.
-
-        /// This constructor set the iterator to the first incoming arc of
-        /// the node.
-        ///@param n the node
-        ///@param g the graph
+        /// Sets the iterator to the first incoming arc.
+
+        /// Sets the iterator to the first incoming arc of the given node.
+        ///
         InArcIt(const Graph& g, const Node& n) {
-          ignore_unused_variable_warning(n);
-          ignore_unused_variable_warning(g);
+          ::lemon::ignore_unused_variable_warning(n);
+          ::lemon::ignore_unused_variable_warning(g);
         }
-        /// Arc -> InArcIt conversion
-
-        /// Sets the iterator to the value of the trivial iterator \c e.
-        /// This feature necessitates that each time we
-        /// iterate the arc-set, the iteration order is the same.
+        /// Sets the iterator to the given arc.
+
+        /// Sets the iterator to the given arc of the given graph.
+        ///
         InArcIt(const Graph&, const Arc&) { }
         /// Next incoming arc
 
-        /// Assign the iterator to the next inarc of the corresponding node.
-        ///
+        /// Assign the iterator to the next
+        /// incoming arc of the corresponding node.
         InArcIt& operator++() { return *this; }
       };
 
-      /// \brief Read write map of the nodes to type \c T.
-      ///
-      /// ReadWrite map of the nodes to type \c T.
-      /// \sa Reference
+      /// \brief Standard graph map type for the nodes.
+      ///
+      /// Standard graph map type for the nodes.
+      /// It conforms to the ReferenceMap concept.
       template<class T>
-      class NodeMap : public ReadWriteMap< Node, T >
+      class NodeMap : public ReferenceMap<Node, T, T&, const T&>
       {
       public:
 
-        ///\e
-        NodeMap(const Graph&) { }
-        ///\e
+        /// Constructor
+        explicit NodeMap(const Graph&) { }
+        /// Constructor with given initial value
         NodeMap(const Graph&, T) { }
 
       private:
         ///Copy constructor
-        NodeMap(const NodeMap& nm) : ReadWriteMap< Node, T >(nm) { }
+        NodeMap(const NodeMap& nm) :
+          ReferenceMap<Node, T, T&, const T&>(nm) { }
         ///Assignment operator
         template <typename CMap>
@@ -523,20 +532,22 @@
       };
 
-      /// \brief Read write map of the directed arcs to type \c T.
-      ///
-      /// Reference map of the directed arcs to type \c T.
-      /// \sa Reference
+      /// \brief Standard graph map type for the arcs.
+      ///
+      /// Standard graph map type for the arcs.
+      /// It conforms to the ReferenceMap concept.
       template<class T>
-      class ArcMap : public ReadWriteMap<Arc,T>
+      class ArcMap : public ReferenceMap<Arc, T, T&, const T&>
       {
       public:
 
-        ///\e
-        ArcMap(const Graph&) { }
-        ///\e
+        /// Constructor
+        explicit ArcMap(const Graph&) { }
+        /// Constructor with given initial value
         ArcMap(const Graph&, T) { }
+
       private:
         ///Copy constructor
-        ArcMap(const ArcMap& em) : ReadWriteMap<Arc,T>(em) { }
+        ArcMap(const ArcMap& em) :
+          ReferenceMap<Arc, T, T&, const T&>(em) { }
         ///Assignment operator
         template <typename CMap>
@@ -547,20 +558,22 @@
       };
 
-      /// Read write map of the edges to type \c T.
-
-      /// Reference map of the arcs to type \c T.
-      /// \sa Reference
+      /// \brief Standard graph map type for the edges.
+      ///
+      /// Standard graph map type for the edges.
+      /// It conforms to the ReferenceMap concept.
       template<class T>
-      class EdgeMap : public ReadWriteMap<Edge,T>
+      class EdgeMap : public ReferenceMap<Edge, T, T&, const T&>
       {
       public:
 
-        ///\e
-        EdgeMap(const Graph&) { }
-        ///\e
+        /// Constructor
+        explicit EdgeMap(const Graph&) { }
+        /// Constructor with given initial value
         EdgeMap(const Graph&, T) { }
+
       private:
         ///Copy constructor
-        EdgeMap(const EdgeMap& em) : ReadWriteMap<Edge,T>(em) {}
+        EdgeMap(const EdgeMap& em) :
+          ReferenceMap<Edge, T, T&, const T&>(em) {}
         ///Assignment operator
         template <typename CMap>
@@ -571,104 +584,121 @@
       };
 
-      /// \brief Direct the given edge.
-      ///
-      /// Direct the given edge. The returned arc source
-      /// will be the given node.
-      Arc direct(const Edge&, const Node&) const {
-        return INVALID;
-      }
-
-      /// \brief Direct the given edge.
-      ///
-      /// Direct the given edge. The returned arc
-      /// represents the given edge and the direction comes
-      /// from the bool parameter. The source of the edge and
-      /// the directed arc is the same when the given bool is true.
-      Arc direct(const Edge&, bool) const {
-        return INVALID;
-      }
-
-      /// \brief Returns true if the arc has default orientation.
-      ///
-      /// Returns whether the given directed arc is same orientation as
-      /// the corresponding edge's default orientation.
-      bool direction(Arc) const { return true; }
-
-      /// \brief Returns the opposite directed arc.
-      ///
-      /// Returns the opposite directed arc.
-      Arc oppositeArc(Arc) const { return INVALID; }
-
-      /// \brief Opposite node on an arc
-      ///
-      /// \return The opposite of the given node on the given edge.
-      Node oppositeNode(Node, Edge) const { return INVALID; }
-
-      /// \brief First node of the edge.
-      ///
-      /// \return The first node of the given edge.
-      ///
-      /// Naturally edges don't have direction and thus
-      /// don't have source and target node. However we use \c u() and \c v()
-      /// methods to query the two nodes of the arc. The direction of the
-      /// arc which arises this way is called the inherent direction of the
-      /// edge, and is used to define the "default" direction
-      /// of the directed versions of the arcs.
+      /// \brief The first node of the edge.
+      ///
+      /// Returns the first node of the given edge.
+      ///
+      /// Edges don't have source and target nodes, however, methods
+      /// u() and v() are used to query the two end-nodes of an edge.
+      /// The orientation of an edge that arises this way is called
+      /// the inherent direction, it is used to define the default
+      /// direction for the corresponding arcs.
       /// \sa v()
       /// \sa direction()
       Node u(Edge) const { return INVALID; }
 
-      /// \brief Second node of the edge.
-      ///
-      /// \return The second node of the given edge.
-      ///
-      /// Naturally edges don't have direction and thus
-      /// don't have source and target node. However we use \c u() and \c v()
-      /// methods to query the two nodes of the arc. The direction of the
-      /// arc which arises this way is called the inherent direction of the
-      /// edge, and is used to define the "default" direction
-      /// of the directed versions of the arcs.
+      /// \brief The second node of the edge.
+      ///
+      /// Returns the second node of the given edge.
+      ///
+      /// Edges don't have source and target nodes, however, methods
+      /// u() and v() are used to query the two end-nodes of an edge.
+      /// The orientation of an edge that arises this way is called
+      /// the inherent direction, it is used to define the default
+      /// direction for the corresponding arcs.
       /// \sa u()
       /// \sa direction()
       Node v(Edge) const { return INVALID; }
 
-      /// \brief Source node of the directed arc.
+      /// \brief The source node of the arc.
+      ///
+      /// Returns the source node of the given arc.
       Node source(Arc) const { return INVALID; }
 
-      /// \brief Target node of the directed arc.
+      /// \brief The target node of the arc.
+      ///
+      /// Returns the target node of the given arc.
       Node target(Arc) const { return INVALID; }
 
-      /// \brief Returns the id of the node.
+      /// \brief The ID of the node.
+      ///
+      /// Returns the ID of the given node.
       int id(Node) const { return -1; }
 
-      /// \brief Returns the id of the edge.
+      /// \brief The ID of the edge.
+      ///
+      /// Returns the ID of the given edge.
       int id(Edge) const { return -1; }
 
-      /// \brief Returns the id of the arc.
+      /// \brief The ID of the arc.
+      ///
+      /// Returns the ID of the given arc.
       int id(Arc) const { return -1; }
 
-      /// \brief Returns the node with the given id.
-      ///
-      /// \pre The argument should be a valid node id in the graph.
+      /// \brief The node with the given ID.
+      ///
+      /// Returns the node with the given ID.
+      /// \pre The argument should be a valid node ID in the graph.
       Node nodeFromId(int) const { return INVALID; }
 
-      /// \brief Returns the edge with the given id.
-      ///
-      /// \pre The argument should be a valid edge id in the graph.
+      /// \brief The edge with the given ID.
+      ///
+      /// Returns the edge with the given ID.
+      /// \pre The argument should be a valid edge ID in the graph.
       Edge edgeFromId(int) const { return INVALID; }
 
-      /// \brief Returns the arc with the given id.
-      ///
-      /// \pre The argument should be a valid arc id in the graph.
+      /// \brief The arc with the given ID.
+      ///
+      /// Returns the arc with the given ID.
+      /// \pre The argument should be a valid arc ID in the graph.
       Arc arcFromId(int) const { return INVALID; }
 
-      /// \brief Returns an upper bound on the node IDs.
+      /// \brief An upper bound on the node IDs.
+      ///
+      /// Returns an upper bound on the node IDs.
       int maxNodeId() const { return -1; }
 
-      /// \brief Returns an upper bound on the edge IDs.
+      /// \brief An upper bound on the edge IDs.
+      ///
+      /// Returns an upper bound on the edge IDs.
       int maxEdgeId() const { return -1; }
 
-      /// \brief Returns an upper bound on the arc IDs.
+      /// \brief An upper bound on the arc IDs.
+      ///
+      /// Returns an upper bound on the arc IDs.
       int maxArcId() const { return -1; }
+
+      /// \brief The direction of the arc.
+      ///
+      /// Returns \c true if the direction of the given arc is the same as
+      /// the inherent orientation of the represented edge.
+      bool direction(Arc) const { return true; }
+
+      /// \brief Direct the edge.
+      ///
+      /// Direct the given edge. The returned arc
+      /// represents the given edge and its direction comes
+      /// from the bool parameter. If it is \c true, then the direction
+      /// of the arc is the same as the inherent orientation of the edge.
+      Arc direct(Edge, bool) const {
+        return INVALID;
+      }
+
+      /// \brief Direct the edge.
+      ///
+      /// Direct the given edge. The returned arc represents the given
+      /// edge and its source node is the given node.
+      Arc direct(Edge, Node) const {
+        return INVALID;
+      }
+
+      /// \brief The oppositely directed arc.
+      ///
+      /// Returns the oppositely directed arc representing the same edge.
+      Arc oppositeArc(Arc) const { return INVALID; }
+
+      /// \brief The opposite node on the edge.
+      ///
+      /// Returns the opposite node on the given edge.
+      Node oppositeNode(Node, Edge) const { return INVALID; }
 
       void first(Node&) const {}
@@ -704,49 +734,42 @@
       int maxId(Arc) const { return -1; }
 
-      /// \brief Base node of the iterator
-      ///
-      /// Returns the base node (the source in this case) of the iterator
-      Node baseNode(OutArcIt e) const {
-        return source(e);
-      }
-      /// \brief Running node of the iterator
-      ///
-      /// Returns the running node (the target in this case) of the
-      /// iterator
-      Node runningNode(OutArcIt e) const {
-        return target(e);
-      }
-
-      /// \brief Base node of the iterator
-      ///
-      /// Returns the base node (the target in this case) of the iterator
-      Node baseNode(InArcIt e) const {
-        return target(e);
-      }
-      /// \brief Running node of the iterator
-      ///
-      /// Returns the running node (the source in this case) of the
-      /// iterator
-      Node runningNode(InArcIt e) const {
-        return source(e);
-      }
-
-      /// \brief Base node of the iterator
-      ///
-      /// Returns the base node of the iterator
-      Node baseNode(IncEdgeIt) const {
-        return INVALID;
-      }
-
-      /// \brief Running node of the iterator
-      ///
-      /// Returns the running node of the iterator
-      Node runningNode(IncEdgeIt) const {
-        return INVALID;
-      }
+      /// \brief The base node of the iterator.
+      ///
+      /// Returns the base node of the given incident edge iterator.
+      Node baseNode(IncEdgeIt) const { return INVALID; }
+
+      /// \brief The running node of the iterator.
+      ///
+      /// Returns the running node of the given incident edge iterator.
+      Node runningNode(IncEdgeIt) const { return INVALID; }
+
+      /// \brief The base node of the iterator.
+      ///
+      /// Returns the base node of the given outgoing arc iterator
+      /// (i.e. the source node of the corresponding arc).
+      Node baseNode(OutArcIt) const { return INVALID; }
+
+      /// \brief The running node of the iterator.
+      ///
+      /// Returns the running node of the given outgoing arc iterator
+      /// (i.e. the target node of the corresponding arc).
+      Node runningNode(OutArcIt) const { return INVALID; }
+
+      /// \brief The base node of the iterator.
+      ///
+      /// Returns the base node of the given incomming arc iterator
+      /// (i.e. the target node of the corresponding arc).
+      Node baseNode(InArcIt) const { return INVALID; }
+
+      /// \brief The running node of the iterator.
+      ///
+      /// Returns the running node of the given incomming arc iterator
+      /// (i.e. the source node of the corresponding arc).
+      Node runningNode(InArcIt) const { return INVALID; }
 
       template <typename _Graph>
       struct Constraints {
         void constraints() {
+          checkConcept<BaseGraphComponent, _Graph>();
           checkConcept<IterableGraphComponent<>, _Graph>();
           checkConcept<IDableGraphComponent<>, _Graph>();
Index: lemon/concepts/graph_components.h
===================================================================
--- lemon/concepts/graph_components.h	(revision 559)
+++ lemon/concepts/graph_components.h	(revision 985)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -19,5 +19,5 @@
 ///\ingroup graph_concepts
 ///\file
-///\brief The concept of graph components.
+///\brief The concepts of graph components.
 
 #ifndef LEMON_CONCEPTS_GRAPH_COMPONENTS_H
@@ -32,15 +32,14 @@
   namespace concepts {
 
-    /// \brief Skeleton class for graph Node and Arc types
-    ///
-    /// This class describes the interface of Node and Arc (and Edge
-    /// in undirected graphs) subtypes of graph types.
+    /// \brief Concept class for \c Node, \c Arc and \c Edge types.
+    ///
+    /// This class describes the concept of \c Node, \c Arc and \c Edge
+    /// subtypes of digraph and graph types.
     ///
     /// \note This class is a template class so that we can use it to
-    /// create graph skeleton classes. The reason for this is than Node
-    /// and Arc types should \em not derive from the same base class.
-    /// For Node you should instantiate it with character 'n' and for Arc
-    /// with 'a'.
-
+    /// create graph skeleton classes. The reason for this is that \c Node
+    /// and \c Arc (or \c Edge) types should \e not derive from the same
+    /// base class. For \c Node you should instantiate it with character
+    /// \c 'n', for \c Arc with \c 'a' and for \c Edge with \c 'e'.
 #ifndef DOXYGEN
     template <char sel = '0'>
@@ -50,43 +49,52 @@
       /// \brief Default constructor.
       ///
+      /// Default constructor.
       /// \warning The default constructor is not required to set
       /// the item to some well-defined value. So you should consider it
       /// as uninitialized.
       GraphItem() {}
+
       /// \brief Copy constructor.
       ///
       /// Copy constructor.
-      ///
       GraphItem(const GraphItem &) {}
-      /// \brief Invalid constructor \& conversion.
-      ///
-      /// This constructor initializes the item to be invalid.
+
+      /// \brief Constructor for conversion from \c INVALID.
+      ///
+      /// Constructor for conversion from \c INVALID.
+      /// It initializes the item to be invalid.
       /// \sa Invalid for more details.
       GraphItem(Invalid) {}
-      /// \brief Assign operator for nodes.
-      ///
-      /// The nodes are assignable.
-      ///
-      GraphItem& operator=(GraphItem const&) { return *this; }
+
+      /// \brief Assignment operator.
+      ///
+      /// Assignment operator for the item.
+      GraphItem& operator=(const GraphItem&) { return *this; }
+
+      /// \brief Assignment operator for INVALID.
+      ///
+      /// This operator makes the item invalid.
+      GraphItem& operator=(Invalid) { return *this; }
+
       /// \brief Equality operator.
       ///
-      /// Two iterators are equal if and only if they represents the
-      /// same node in the graph or both are invalid.
-      bool operator==(GraphItem) const { return false; }
+      /// Equality operator.
+      bool operator==(const GraphItem&) const { return false; }
+
       /// \brief Inequality operator.
       ///
-      /// \sa operator==(const Node& n)
-      ///
-      bool operator!=(GraphItem) const { return false; }
-
-      /// \brief Artificial ordering operator.
-      ///
-      /// To allow the use of graph descriptors as key type in std::map or
-      /// similar associative container we require this.
-      ///
-      /// \note This operator only have to define some strict ordering of
+      /// Inequality operator.
+      bool operator!=(const GraphItem&) const { return false; }
+
+      /// \brief Ordering operator.
+      ///
+      /// This operator defines an ordering of the items.
+      /// It makes possible to use graph item types as key types in
+      /// associative containers (e.g. \c std::map).
+      ///
+      /// \note This operator only has to define some strict ordering of
       /// the items; this order has nothing to do with the iteration
       /// ordering of the items.
-      bool operator<(GraphItem) const { return false; }
+      bool operator<(const GraphItem&) const { return false; }
 
       template<typename _GraphItem>
@@ -94,4 +102,5 @@
         void constraints() {
           _GraphItem i1;
+          i1=INVALID;
           _GraphItem i2 = i1;
           _GraphItem i3 = INVALID;
@@ -100,5 +109,6 @@
 
           bool b;
-          //          b = (ia == ib) && (ia != ib) && (ia < ib);
+          ::lemon::ignore_unused_variable_warning(b);
+
           b = (ia == ib) && (ia != ib);
           b = (ia == INVALID) && (ib != INVALID);
@@ -108,14 +118,14 @@
         const _GraphItem &ia;
         const _GraphItem &ib;
-      };
-    };
-
-    /// \brief An empty base directed graph class.
-    ///
-    /// This class provides the minimal set of features needed for a
-    /// directed graph structure. All digraph concepts have to
-    /// conform to this base directed graph. It just provides types
-    /// for nodes and arcs and functions to get the source and the
-    /// target of the arcs.
+        Constraints() {}
+      };
+    };
+
+    /// \brief Base skeleton class for directed graphs.
+    ///
+    /// This class describes the base interface of directed graph types.
+    /// All digraph %concepts have to conform to this class.
+    /// It just provides types for nodes and arcs and functions
+    /// to get the source and the target nodes of arcs.
     class BaseDigraphComponent {
     public:
@@ -125,29 +135,25 @@
       /// \brief Node class of the digraph.
       ///
-      /// This class represents the Nodes of the digraph.
-      ///
+      /// This class represents the nodes of the digraph.
       typedef GraphItem<'n'> Node;
 
       /// \brief Arc class of the digraph.
       ///
-      /// This class represents the Arcs of the digraph.
-      ///
-      typedef GraphItem<'e'> Arc;
-
-      /// \brief Gives back the target node of an arc.
-      ///
-      /// Gives back the target node of an arc.
-      ///
-      Node target(const Arc&) const { return INVALID;}
-
-      /// \brief Gives back the source node of an arc.
-      ///
-      /// Gives back the source node of an arc.
-      ///
-      Node source(const Arc&) const { return INVALID;}
-
-      /// \brief Gives back the opposite node on the given arc.
-      ///
-      /// Gives back the opposite node on the given arc.
+      /// This class represents the arcs of the digraph.
+      typedef GraphItem<'a'> Arc;
+
+      /// \brief Return the source node of an arc.
+      ///
+      /// This function returns the source node of an arc.
+      Node source(const Arc&) const { return INVALID; }
+
+      /// \brief Return the target node of an arc.
+      ///
+      /// This function returns the target node of an arc.
+      Node target(const Arc&) const { return INVALID; }
+
+      /// \brief Return the opposite node on the given arc.
+      ///
+      /// This function returns the opposite node on the given arc.
       Node oppositeNode(const Node&, const Arc&) const {
         return INVALID;
@@ -172,59 +178,83 @@
 
         const _Digraph& digraph;
-      };
-    };
-
-    /// \brief An empty base undirected graph class.
-    ///
-    /// This class provides the minimal set of features needed for an
-    /// undirected graph structure. All undirected graph concepts have
-    /// to conform to this base graph. It just provides types for
-    /// nodes, arcs and edges and functions to get the
-    /// source and the target of the arcs and edges,
-    /// conversion from arcs to edges and function to get
-    /// both direction of the edges.
+        Constraints() {}
+      };
+    };
+
+    /// \brief Base skeleton class for undirected graphs.
+    ///
+    /// This class describes the base interface of undirected graph types.
+    /// All graph %concepts have to conform to this class.
+    /// It extends the interface of \ref BaseDigraphComponent with an
+    /// \c Edge type and functions to get the end nodes of edges,
+    /// to convert from arcs to edges and to get both direction of edges.
     class BaseGraphComponent : public BaseDigraphComponent {
     public:
+
+      typedef BaseGraphComponent Graph;
+
       typedef BaseDigraphComponent::Node Node;
       typedef BaseDigraphComponent::Arc Arc;
-      /// \brief Undirected arc class of the graph.
-      ///
-      /// This class represents the edges of the graph.
-      /// The undirected graphs can be used as a directed graph which
-      /// for each arc contains the opposite arc too so the graph is
-      /// bidirected. The edge represents two opposite
-      /// directed arcs.
-      class Edge : public GraphItem<'u'> {
+
+      /// \brief Undirected edge class of the graph.
+      ///
+      /// This class represents the undirected edges of the graph.
+      /// Undirected graphs can be used as directed graphs, each edge is
+      /// represented by two opposite directed arcs.
+      class Edge : public GraphItem<'e'> {
+        typedef GraphItem<'e'> Parent;
+
       public:
-        typedef GraphItem<'u'> Parent;
         /// \brief Default constructor.
         ///
+        /// Default constructor.
         /// \warning The default constructor is not required to set
         /// the item to some well-defined value. So you should consider it
         /// as uninitialized.
         Edge() {}
+
         /// \brief Copy constructor.
         ///
         /// Copy constructor.
+        Edge(const Edge &) : Parent() {}
+
+        /// \brief Constructor for conversion from \c INVALID.
         ///
-        Edge(const Edge &) : Parent() {}
-        /// \brief Invalid constructor \& conversion.
-        ///
-        /// This constructor initializes the item to be invalid.
+        /// Constructor for conversion from \c INVALID.
+        /// It initializes the item to be invalid.
         /// \sa Invalid for more details.
         Edge(Invalid) {}
-        /// \brief Converter from arc to edge.
+
+        /// \brief Constructor for conversion from an arc.
         ///
+        /// Constructor for conversion from an arc.
         /// Besides the core graph item functionality each arc should
         /// be convertible to the represented edge.
         Edge(const Arc&) {}
-        /// \brief Assign arc to edge.
-        ///
-        /// Besides the core graph item functionality each arc should
-        /// be convertible to the represented edge.
-        Edge& operator=(const Arc&) { return *this; }
-      };
-
-      /// \brief Returns the direction of the arc.
+     };
+
+      /// \brief Return one end node of an edge.
+      ///
+      /// This function returns one end node of an edge.
+      Node u(const Edge&) const { return INVALID; }
+
+      /// \brief Return the other end node of an edge.
+      ///
+      /// This function returns the other end node of an edge.
+      Node v(const Edge&) const { return INVALID; }
+
+      /// \brief Return a directed arc related to an edge.
+      ///
+      /// This function returns a directed arc from its direction and the
+      /// represented edge.
+      Arc direct(const Edge&, bool) const { return INVALID; }
+
+      /// \brief Return a directed arc related to an edge.
+      ///
+      /// This function returns a directed arc from its source node and the
+      /// represented edge.
+      Arc direct(const Edge&, const Node&) const { return INVALID; }
+
+      /// \brief Return the direction of the arc.
       ///
       /// Returns the direction of the arc. Each arc represents an
@@ -233,31 +263,9 @@
       bool direction(const Arc&) const { return true; }
 
-      /// \brief Returns the directed arc.
-      ///
-      /// Returns the directed arc from its direction and the
-      /// represented edge.
-      Arc direct(const Edge&, bool) const { return INVALID;}
-
-      /// \brief Returns the directed arc.
-      ///
-      /// Returns the directed arc from its source and the
-      /// represented edge.
-      Arc direct(const Edge&, const Node&) const { return INVALID;}
-
-      /// \brief Returns the opposite arc.
-      ///
-      /// Returns the opposite arc. It is the arc representing the
-      /// same edge and has opposite direction.
-      Arc oppositeArc(const Arc&) const { return INVALID;}
-
-      /// \brief Gives back one ending of an edge.
-      ///
-      /// Gives back one ending of an edge.
-      Node u(const Edge&) const { return INVALID;}
-
-      /// \brief Gives back the other ending of an edge.
-      ///
-      /// Gives back the other ending of an edge.
-      Node v(const Edge&) const { return INVALID;}
+      /// \brief Return the opposite arc.
+      ///
+      /// This function returns the opposite arc, i.e. the arc representing
+      /// the same edge and has opposite direction.
+      Arc oppositeArc(const Arc&) const { return INVALID; }
 
       template <typename _Graph>
@@ -269,5 +277,5 @@
         void constraints() {
           checkConcept<BaseDigraphComponent, _Graph>();
-          checkConcept<GraphItem<'u'>, Edge>();
+          checkConcept<GraphItem<'e'>, Edge>();
           {
             Node n;
@@ -277,23 +285,25 @@
             n = graph.v(ue);
             e = graph.direct(ue, true);
+            e = graph.direct(ue, false);
             e = graph.direct(ue, n);
             e = graph.oppositeArc(e);
             ue = e;
             bool d = graph.direction(e);
-            ignore_unused_variable_warning(d);
+            ::lemon::ignore_unused_variable_warning(d);
           }
         }
 
         const _Graph& graph;
-      };
-
-    };
-
-    /// \brief An empty idable base digraph class.
-    ///
-    /// This class provides beside the core digraph features
-    /// core id functions for the digraph structure.
-    /// The most of the base digraphs should conform to this concept.
-    /// The id's are unique and immutable.
+      Constraints() {}
+      };
+
+    };
+
+    /// \brief Skeleton class for \e idable directed graphs.
+    ///
+    /// This class describes the interface of \e idable directed graphs.
+    /// It extends \ref BaseDigraphComponent with the core ID functions.
+    /// The ids of the items must be unique and immutable.
+    /// This concept is part of the Digraph concept.
     template <typename BAS = BaseDigraphComponent>
     class IDableDigraphComponent : public BAS {
@@ -304,43 +314,41 @@
       typedef typename Base::Arc Arc;
 
-      /// \brief Gives back an unique integer id for the Node.
-      ///
-      /// Gives back an unique integer id for the Node.
-      ///
-      int id(const Node&) const { return -1;}
-
-      /// \brief Gives back the node by the unique id.
-      ///
-      /// Gives back the node by the unique id.
-      /// If the digraph does not contain node with the given id
-      /// then the result of the function is undetermined.
-      Node nodeFromId(int) const { return INVALID;}
-
-      /// \brief Gives back an unique integer id for the Arc.
-      ///
-      /// Gives back an unique integer id for the Arc.
-      ///
-      int id(const Arc&) const { return -1;}
-
-      /// \brief Gives back the arc by the unique id.
-      ///
-      /// Gives back the arc by the unique id.
-      /// If the digraph does not contain arc with the given id
-      /// then the result of the function is undetermined.
-      Arc arcFromId(int) const { return INVALID;}
-
-      /// \brief Gives back an integer greater or equal to the maximum
-      /// Node id.
-      ///
-      /// Gives back an integer greater or equal to the maximum Node
-      /// id.
-      int maxNodeId() const { return -1;}
-
-      /// \brief Gives back an integer greater or equal to the maximum
-      /// Arc id.
-      ///
-      /// Gives back an integer greater or equal to the maximum Arc
-      /// id.
-      int maxArcId() const { return -1;}
+      /// \brief Return a unique integer id for the given node.
+      ///
+      /// This function returns a unique integer id for the given node.
+      int id(const Node&) const { return -1; }
+
+      /// \brief Return the node by its unique id.
+      ///
+      /// This function returns the node by its unique id.
+      /// If the digraph does not contain a node with the given id,
+      /// then the result of the function is undefined.
+      Node nodeFromId(int) const { return INVALID; }
+
+      /// \brief Return a unique integer id for the given arc.
+      ///
+      /// This function returns a unique integer id for the given arc.
+      int id(const Arc&) const { return -1; }
+
+      /// \brief Return the arc by its unique id.
+      ///
+      /// This function returns the arc by its unique id.
+      /// If the digraph does not contain an arc with the given id,
+      /// then the result of the function is undefined.
+      Arc arcFromId(int) const { return INVALID; }
+
+      /// \brief Return an integer greater or equal to the maximum
+      /// node id.
+      ///
+      /// This function returns an integer greater or equal to the
+      /// maximum node id.
+      int maxNodeId() const { return -1; }
+
+      /// \brief Return an integer greater or equal to the maximum
+      /// arc id.
+      ///
+      /// This function returns an integer greater or equal to the
+      /// maximum arc id.
+      int maxArcId() const { return -1; }
 
       template <typename _Digraph>
@@ -350,8 +358,10 @@
           checkConcept<Base, _Digraph >();
           typename _Digraph::Node node;
+          node=INVALID;
           int nid = digraph.id(node);
           nid = digraph.id(node);
           node = digraph.nodeFromId(nid);
           typename _Digraph::Arc arc;
+          arc=INVALID;
           int eid = digraph.id(arc);
           eid = digraph.id(arc);
@@ -359,19 +369,21 @@
 
           nid = digraph.maxNodeId();
-          ignore_unused_variable_warning(nid);
+          ::lemon::ignore_unused_variable_warning(nid);
           eid = digraph.maxArcId();
-          ignore_unused_variable_warning(eid);
+          ::lemon::ignore_unused_variable_warning(eid);
         }
 
         const _Digraph& digraph;
-      };
-    };
-
-    /// \brief An empty idable base undirected graph class.
-    ///
-    /// This class provides beside the core undirected graph features
-    /// core id functions for the undirected graph structure.  The
-    /// most of the base undirected graphs should conform to this
-    /// concept.  The id's are unique and immutable.
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for \e idable undirected graphs.
+    ///
+    /// This class describes the interface of \e idable undirected
+    /// graphs. It extends \ref IDableDigraphComponent with the core ID
+    /// functions of undirected graphs.
+    /// The ids of the items must be unique and immutable.
+    /// This concept is part of the Graph concept.
     template <typename BAS = BaseGraphComponent>
     class IDableGraphComponent : public IDableDigraphComponent<BAS> {
@@ -383,23 +395,22 @@
       using IDableDigraphComponent<Base>::id;
 
-      /// \brief Gives back an unique integer id for the Edge.
-      ///
-      /// Gives back an unique integer id for the Edge.
-      ///
-      int id(const Edge&) const { return -1;}
-
-      /// \brief Gives back the edge by the unique id.
-      ///
-      /// Gives back the edge by the unique id.  If the
-      /// graph does not contain arc with the given id then the
-      /// result of the function is undetermined.
-      Edge edgeFromId(int) const { return INVALID;}
-
-      /// \brief Gives back an integer greater or equal to the maximum
-      /// Edge id.
-      ///
-      /// Gives back an integer greater or equal to the maximum Edge
-      /// id.
-      int maxEdgeId() const { return -1;}
+      /// \brief Return a unique integer id for the given edge.
+      ///
+      /// This function returns a unique integer id for the given edge.
+      int id(const Edge&) const { return -1; }
+
+      /// \brief Return the edge by its unique id.
+      ///
+      /// This function returns the edge by its unique id.
+      /// If the graph does not contain an edge with the given id,
+      /// then the result of the function is undefined.
+      Edge edgeFromId(int) const { return INVALID; }
+
+      /// \brief Return an integer greater or equal to the maximum
+      /// edge id.
+      ///
+      /// This function returns an integer greater or equal to the
+      /// maximum edge id.
+      int maxEdgeId() const { return -1; }
 
       template <typename _Graph>
@@ -407,5 +418,4 @@
 
         void constraints() {
-          checkConcept<Base, _Graph >();
           checkConcept<IDableDigraphComponent<Base>, _Graph >();
           typename _Graph::Edge edge;
@@ -414,15 +424,16 @@
           edge = graph.edgeFromId(ueid);
           ueid = graph.maxEdgeId();
-          ignore_unused_variable_warning(ueid);
+          ::lemon::ignore_unused_variable_warning(ueid);
         }
 
         const _Graph& graph;
-      };
-    };
-
-    /// \brief Skeleton class for graph NodeIt and ArcIt
-    ///
-    /// Skeleton class for graph NodeIt and ArcIt.
-    ///
+        Constraints() {}
+      };
+    };
+
+    /// \brief Concept class for \c NodeIt, \c ArcIt and \c EdgeIt types.
+    ///
+    /// This class describes the concept of \c NodeIt, \c ArcIt and
+    /// \c EdgeIt subtypes of digraph and graph types.
     template <typename GR, typename Item>
     class GraphItemIt : public Item {
@@ -430,41 +441,50 @@
       /// \brief Default constructor.
       ///
-      /// @warning The default constructor sets the iterator
-      /// to an undefined value.
+      /// Default constructor.
+      /// \warning The default constructor is not required to set
+      /// the iterator to some well-defined value. So you should consider it
+      /// as uninitialized.
       GraphItemIt() {}
+
       /// \brief Copy constructor.
       ///
       /// Copy constructor.
-      ///
-      GraphItemIt(const GraphItemIt& ) {}
-      /// \brief Sets the iterator to the first item.
-      ///
-      /// Sets the iterator to the first item of \c the graph.
-      ///
+      GraphItemIt(const GraphItemIt& it) : Item(it) {}
+
+      /// \brief Constructor that sets the iterator to the first item.
+      ///
+      /// Constructor that sets the iterator to the first item.
       explicit GraphItemIt(const GR&) {}
-      /// \brief Invalid constructor \& conversion.
-      ///
-      /// This constructor initializes the item to be invalid.
+
+      /// \brief Constructor for conversion from \c INVALID.
+      ///
+      /// Constructor for conversion from \c INVALID.
+      /// It initializes the iterator to be invalid.
       /// \sa Invalid for more details.
       GraphItemIt(Invalid) {}
-      /// \brief Assign operator for items.
-      ///
-      /// The items are assignable.
-      ///
+
+      /// \brief Assignment operator.
+      ///
+      /// Assignment operator for the iterator.
       GraphItemIt& operator=(const GraphItemIt&) { return *this; }
-      /// \brief Next item.
-      ///
-      /// Assign the iterator to the next item.
-      ///
+
+      /// \brief Increment the iterator.
+      ///
+      /// This operator increments the iterator, i.e. assigns it to the
+      /// next item.
       GraphItemIt& operator++() { return *this; }
+
       /// \brief Equality operator
       ///
+      /// Equality operator.
       /// Two iterators are equal if and only if they point to the
       /// same object or both are invalid.
       bool operator==(const GraphItemIt&) const { return true;}
+
       /// \brief Inequality operator
       ///
-      /// \sa operator==(Node n)
-      ///
+      /// Inequality operator.
+      /// Two iterators are equal if and only if they point to the
+      /// same object or both are invalid.
       bool operator!=(const GraphItemIt&) const { return true;}
 
@@ -472,6 +492,11 @@
       struct Constraints {
         void constraints() {
+          checkConcept<GraphItem<>, _GraphItemIt>();
           _GraphItemIt it1(g);
           _GraphItemIt it2;
+          _GraphItemIt it3 = it1;
+          _GraphItemIt it4 = INVALID;
+          ::lemon::ignore_unused_variable_warning(it3);
+          ::lemon::ignore_unused_variable_warning(it4);
 
           it2 = ++it1;
@@ -482,14 +507,19 @@
           bi = it2;
         }
-        GR& g;
-      };
-    };
-
-    /// \brief Skeleton class for graph InArcIt and OutArcIt
-    ///
-    /// \note Because InArcIt and OutArcIt may not inherit from the same
-    /// base class, the \c sel is a additional template parameter (selector).
-    /// For InArcIt you should instantiate it with character 'i' and for
-    /// OutArcIt with 'o'.
+        const GR& g;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Concept class for \c InArcIt, \c OutArcIt and
+    /// \c IncEdgeIt types.
+    ///
+    /// This class describes the concept of \c InArcIt, \c OutArcIt
+    /// and \c IncEdgeIt subtypes of digraph and graph types.
+    ///
+    /// \note Since these iterator classes do not inherit from the same
+    /// base class, there is an additional template parameter (selector)
+    /// \c sel. For \c InArcIt you should instantiate it with character
+    /// \c 'i', for \c OutArcIt with \c 'o' and for \c IncEdgeIt with \c 'e'.
     template <typename GR,
               typename Item = typename GR::Arc,
@@ -500,37 +530,43 @@
       /// \brief Default constructor.
       ///
-      /// @warning The default constructor sets the iterator
-      /// to an undefined value.
+      /// Default constructor.
+      /// \warning The default constructor is not required to set
+      /// the iterator to some well-defined value. So you should consider it
+      /// as uninitialized.
       GraphIncIt() {}
+
       /// \brief Copy constructor.
       ///
       /// Copy constructor.
-      ///
-      GraphIncIt(GraphIncIt const& gi) : Item(gi) {}
-      /// \brief Sets the iterator to the first arc incoming into or outgoing
-      /// from the node.
-      ///
-      /// Sets the iterator to the first arc incoming into or outgoing
-      /// from the node.
-      ///
+      GraphIncIt(const GraphIncIt& it) : Item(it) {}
+
+      /// \brief Constructor that sets the iterator to the first
+      /// incoming or outgoing arc.
+      ///
+      /// Constructor that sets the iterator to the first arc
+      /// incoming to or outgoing from the given node.
       explicit GraphIncIt(const GR&, const Base&) {}
-      /// \brief Invalid constructor \& conversion.
-      ///
-      /// This constructor initializes the item to be invalid.
+
+      /// \brief Constructor for conversion from \c INVALID.
+      ///
+      /// Constructor for conversion from \c INVALID.
+      /// It initializes the iterator to be invalid.
       /// \sa Invalid for more details.
       GraphIncIt(Invalid) {}
-      /// \brief Assign operator for iterators.
-      ///
-      /// The iterators are assignable.
-      ///
-      GraphIncIt& operator=(GraphIncIt const&) { return *this; }
-      /// \brief Next item.
-      ///
-      /// Assign the iterator to the next item.
-      ///
+
+      /// \brief Assignment operator.
+      ///
+      /// Assignment operator for the iterator.
+      GraphIncIt& operator=(const GraphIncIt&) { return *this; }
+
+      /// \brief Increment the iterator.
+      ///
+      /// This operator increments the iterator, i.e. assigns it to the
+      /// next arc incoming to or outgoing from the given node.
       GraphIncIt& operator++() { return *this; }
 
       /// \brief Equality operator
       ///
+      /// Equality operator.
       /// Two iterators are equal if and only if they point to the
       /// same object or both are invalid.
@@ -539,6 +575,7 @@
       /// \brief Inequality operator
       ///
-      /// \sa operator==(Node n)
-      ///
+      /// Inequality operator.
+      /// Two iterators are equal if and only if they point to the
+      /// same object or both are invalid.
       bool operator!=(const GraphIncIt&) const { return true;}
 
@@ -549,4 +586,8 @@
           _GraphIncIt it1(graph, node);
           _GraphIncIt it2;
+          _GraphIncIt it3 = it1;
+          _GraphIncIt it4 = INVALID;
+          ::lemon::ignore_unused_variable_warning(it3);
+          ::lemon::ignore_unused_variable_warning(it4);
 
           it2 = ++it1;
@@ -555,19 +596,16 @@
           Item e = it1;
           e = it2;
-
-        }
-
-        Item arc;
-        Base node;
-        GR graph;
-        _GraphIncIt it;
-      };
-    };
-
-
-    /// \brief An empty iterable digraph class.
-    ///
-    /// This class provides beside the core digraph features
-    /// iterator based iterable interface for the digraph structure.
+        }
+        const Base& node;
+        const GR& graph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for iterable directed graphs.
+    ///
+    /// This class describes the interface of iterable directed
+    /// graphs. It extends \ref BaseDigraphComponent with the core
+    /// iterable interface.
     /// This concept is part of the Digraph concept.
     template <typename BAS = BaseDigraphComponent>
@@ -582,68 +620,59 @@
       typedef IterableDigraphComponent Digraph;
 
-      /// \name Base iteration
-      ///
-      /// This interface provides functions for iteration on digraph items
+      /// \name Base Iteration
+      ///
+      /// This interface provides functions for iteration on digraph items.
       ///
       /// @{
 
-      /// \brief Gives back the first node in the iterating order.
-      ///
-      /// Gives back the first node in the iterating order.
-      ///
+      /// \brief Return the first node.
+      ///
+      /// This function gives back the first node in the iteration order.
       void first(Node&) const {}
 
-      /// \brief Gives back the next node in the iterating order.
-      ///
-      /// Gives back the next node in the iterating order.
-      ///
+      /// \brief Return the next node.
+      ///
+      /// This function gives back the next node in the iteration order.
       void next(Node&) const {}
 
-      /// \brief Gives back the first arc in the iterating order.
-      ///
-      /// Gives back the first arc in the iterating order.
-      ///
+      /// \brief Return the first arc.
+      ///
+      /// This function gives back the first arc in the iteration order.
       void first(Arc&) const {}
 
-      /// \brief Gives back the next arc in the iterating order.
-      ///
-      /// Gives back the next arc in the iterating order.
-      ///
+      /// \brief Return the next arc.
+      ///
+      /// This function gives back the next arc in the iteration order.
       void next(Arc&) const {}
 
-
-      /// \brief Gives back the first of the arcs point to the given
-      /// node.
-      ///
-      /// Gives back the first of the arcs point to the given node.
-      ///
+      /// \brief Return the first arc incomming to the given node.
+      ///
+      /// This function gives back the first arc incomming to the
+      /// given node.
       void firstIn(Arc&, const Node&) const {}
 
-      /// \brief Gives back the next of the arcs points to the given
-      /// node.
-      ///
-      /// Gives back the next of the arcs points to the given node.
-      ///
+      /// \brief Return the next arc incomming to the given node.
+      ///
+      /// This function gives back the next arc incomming to the
+      /// given node.
       void nextIn(Arc&) const {}
 
-      /// \brief Gives back the first of the arcs start from the
+      /// \brief Return the first arc outgoing form the given node.
+      ///
+      /// This function gives back the first arc outgoing form the
       /// given node.
-      ///
-      /// Gives back the first of the arcs start from the given node.
-      ///
       void firstOut(Arc&, const Node&) const {}
 
-      /// \brief Gives back the next of the arcs start from the given
-      /// node.
-      ///
-      /// Gives back the next of the arcs start from the given node.
-      ///
+      /// \brief Return the next arc outgoing form the given node.
+      ///
+      /// This function gives back the next arc outgoing form the
+      /// given node.
       void nextOut(Arc&) const {}
 
       /// @}
 
-      /// \name Class based iteration
-      ///
-      /// This interface provides functions for iteration on digraph items
+      /// \name Class Based Iteration
+      ///
+      /// This interface provides iterator classes for digraph items.
       ///
       /// @{
@@ -655,7 +684,7 @@
       typedef GraphItemIt<Digraph, Node> NodeIt;
 
-      /// \brief This iterator goes through each node.
-      ///
-      /// This iterator goes through each node.
+      /// \brief This iterator goes through each arc.
+      ///
+      /// This iterator goes through each arc.
       ///
       typedef GraphItemIt<Digraph, Arc> ArcIt;
@@ -663,5 +692,5 @@
       /// \brief This iterator goes trough the incoming arcs of a node.
       ///
-      /// This iterator goes trough the \e inccoming arcs of a certain node
+      /// This iterator goes trough the \e incoming arcs of a certain node
       /// of a digraph.
       typedef GraphIncIt<Digraph, Arc, Node, 'i'> InArcIt;
@@ -675,24 +704,24 @@
       /// \brief The base node of the iterator.
       ///
-      /// Gives back the base node of the iterator.
-      /// It is always the target of the pointed arc.
+      /// This function gives back the base node of the iterator.
+      /// It is always the target node of the pointed arc.
       Node baseNode(const InArcIt&) const { return INVALID; }
 
       /// \brief The running node of the iterator.
       ///
-      /// Gives back the running node of the iterator.
-      /// It is always the source of the pointed arc.
+      /// This function gives back the running node of the iterator.
+      /// It is always the source node of the pointed arc.
       Node runningNode(const InArcIt&) const { return INVALID; }
 
       /// \brief The base node of the iterator.
       ///
-      /// Gives back the base node of the iterator.
-      /// It is always the source of the pointed arc.
+      /// This function gives back the base node of the iterator.
+      /// It is always the source node of the pointed arc.
       Node baseNode(const OutArcIt&) const { return INVALID; }
 
       /// \brief The running node of the iterator.
       ///
-      /// Gives back the running node of the iterator.
-      /// It is always the target of the pointed arc.
+      /// This function gives back the running node of the iterator.
+      /// It is always the target node of the pointed arc.
       Node runningNode(const OutArcIt&) const { return INVALID; }
 
@@ -736,23 +765,24 @@
 
             typename _Digraph::Node n;
-            typename _Digraph::InArcIt ieit(INVALID);
-            typename _Digraph::OutArcIt oeit(INVALID);
-            n = digraph.baseNode(ieit);
-            n = digraph.runningNode(ieit);
-            n = digraph.baseNode(oeit);
-            n = digraph.runningNode(oeit);
-            ignore_unused_variable_warning(n);
+            const typename _Digraph::InArcIt iait(INVALID);
+            const typename _Digraph::OutArcIt oait(INVALID);
+            n = digraph.baseNode(iait);
+            n = digraph.runningNode(iait);
+            n = digraph.baseNode(oait);
+            n = digraph.runningNode(oait);
+            ::lemon::ignore_unused_variable_warning(n);
           }
         }
 
         const _Digraph& digraph;
-
-      };
-    };
-
-    /// \brief An empty iterable undirected graph class.
-    ///
-    /// This class provides beside the core graph features iterator
-    /// based iterable interface for the undirected graph structure.
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for iterable undirected graphs.
+    ///
+    /// This class describes the interface of iterable undirected
+    /// graphs. It extends \ref IterableDigraphComponent with the core
+    /// iterable interface of undirected graphs.
     /// This concept is part of the Graph concept.
     template <typename BAS = BaseGraphComponent>
@@ -768,7 +798,8 @@
       typedef IterableGraphComponent Graph;
 
-      /// \name Base iteration
-      ///
-      /// This interface provides functions for iteration on graph items
+      /// \name Base Iteration
+      ///
+      /// This interface provides functions for iteration on edges.
+      ///
       /// @{
 
@@ -776,26 +807,20 @@
       using IterableDigraphComponent<Base>::next;
 
-      /// \brief Gives back the first edge in the iterating
-      /// order.
-      ///
-      /// Gives back the first edge in the iterating order.
-      ///
+      /// \brief Return the first edge.
+      ///
+      /// This function gives back the first edge in the iteration order.
       void first(Edge&) const {}
 
-      /// \brief Gives back the next edge in the iterating
-      /// order.
-      ///
-      /// Gives back the next edge in the iterating order.
-      ///
+      /// \brief Return the next edge.
+      ///
+      /// This function gives back the next edge in the iteration order.
       void next(Edge&) const {}
 
-
-      /// \brief Gives back the first of the edges from the
+      /// \brief Return the first edge incident to the given node.
+      ///
+      /// This function gives back the first edge incident to the given
+      /// node. The bool parameter gives back the direction for which the
+      /// source node of the directed arc representing the edge is the
       /// given node.
-      ///
-      /// Gives back the first of the edges from the given
-      /// node. The bool parameter gives back that direction which
-      /// gives a good direction of the edge so the source of the
-      /// directed arc is the given node.
       void firstInc(Edge&, bool&, const Node&) const {}
 
@@ -803,7 +828,6 @@
       /// given node.
       ///
-      /// Gives back the next of the edges from the given
-      /// node. The bool parameter should be used as the \c firstInc()
-      /// use it.
+      /// This function gives back the next edge incident to the given
+      /// node. The bool parameter should be used as \c firstInc() use it.
       void nextInc(Edge&, bool&) const {}
 
@@ -813,28 +837,30 @@
       /// @}
 
-      /// \name Class based iteration
-      ///
-      /// This interface provides functions for iteration on graph items
+      /// \name Class Based Iteration
+      ///
+      /// This interface provides iterator classes for edges.
       ///
       /// @{
 
-      /// \brief This iterator goes through each node.
-      ///
-      /// This iterator goes through each node.
+      /// \brief This iterator goes through each edge.
+      ///
+      /// This iterator goes through each edge.
       typedef GraphItemIt<Graph, Edge> EdgeIt;
-      /// \brief This iterator goes trough the incident arcs of a
+
+      /// \brief This iterator goes trough the incident edges of a
       /// node.
       ///
-      /// This iterator goes trough the incident arcs of a certain
+      /// This iterator goes trough the incident edges of a certain
       /// node of a graph.
-      typedef GraphIncIt<Graph, Edge, Node, 'u'> IncEdgeIt;
+      typedef GraphIncIt<Graph, Edge, Node, 'e'> IncEdgeIt;
+
       /// \brief The base node of the iterator.
       ///
-      /// Gives back the base node of the iterator.
+      /// This function gives back the base node of the iterator.
       Node baseNode(const IncEdgeIt&) const { return INVALID; }
 
       /// \brief The running node of the iterator.
       ///
-      /// Gives back the running node of the iterator.
+      /// This function gives back the running node of the iterator.
       Node runningNode(const IncEdgeIt&) const { return INVALID; }
 
@@ -865,24 +891,26 @@
               typename _Graph::EdgeIt >();
             checkConcept<GraphIncIt<_Graph, typename _Graph::Edge,
-              typename _Graph::Node, 'u'>, typename _Graph::IncEdgeIt>();
+              typename _Graph::Node, 'e'>, typename _Graph::IncEdgeIt>();
 
             typename _Graph::Node n;
-            typename _Graph::IncEdgeIt ueit(INVALID);
-            n = graph.baseNode(ueit);
-            n = graph.runningNode(ueit);
+            const typename _Graph::IncEdgeIt ieit(INVALID);
+            n = graph.baseNode(ieit);
+            n = graph.runningNode(ieit);
           }
         }
 
         const _Graph& graph;
-      };
-    };
-
-    /// \brief An empty alteration notifier digraph class.
-    ///
-    /// This class provides beside the core digraph features alteration
-    /// notifier interface for the digraph structure.  This implements
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for alterable directed graphs.
+    ///
+    /// This class describes the interface of alterable directed
+    /// graphs. It extends \ref BaseDigraphComponent with the alteration
+    /// notifier interface. It implements
     /// an observer-notifier pattern for each digraph item. More
     /// obsevers can be registered into the notifier and whenever an
-    /// alteration occured in the digraph all the observers will
+    /// alteration occured in the digraph all the observers will be
     /// notified about it.
     template <typename BAS = BaseDigraphComponent>
@@ -895,21 +923,21 @@
 
 
-      /// The node observer registry.
+      /// Node alteration notifier class.
       typedef AlterationNotifier<AlterableDigraphComponent, Node>
       NodeNotifier;
-      /// The arc observer registry.
+      /// Arc alteration notifier class.
       typedef AlterationNotifier<AlterableDigraphComponent, Arc>
       ArcNotifier;
 
-      /// \brief Gives back the node alteration notifier.
-      ///
-      /// Gives back the node alteration notifier.
+      /// \brief Return the node alteration notifier.
+      ///
+      /// This function gives back the node alteration notifier.
       NodeNotifier& notifier(Node) const {
-        return NodeNotifier();
+         return NodeNotifier();
       }
 
-      /// \brief Gives back the arc alteration notifier.
-      ///
-      /// Gives back the arc alteration notifier.
+      /// \brief Return the arc alteration notifier.
+      ///
+      /// This function gives back the arc alteration notifier.
       ArcNotifier& notifier(Arc) const {
         return ArcNotifier();
@@ -926,21 +954,21 @@
             = digraph.notifier(typename _Digraph::Arc());
 
-          ignore_unused_variable_warning(nn);
-          ignore_unused_variable_warning(en);
+          ::lemon::ignore_unused_variable_warning(nn);
+          ::lemon::ignore_unused_variable_warning(en);
         }
 
         const _Digraph& digraph;
-
-      };
-
-    };
-
-    /// \brief An empty alteration notifier undirected graph class.
-    ///
-    /// This class provides beside the core graph features alteration
-    /// notifier interface for the graph structure.  This implements
-    /// an observer-notifier pattern for each graph item. More
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for alterable undirected graphs.
+    ///
+    /// This class describes the interface of alterable undirected
+    /// graphs. It extends \ref AlterableDigraphComponent with the alteration
+    /// notifier interface of undirected graphs. It implements
+    /// an observer-notifier pattern for the edges. More
     /// obsevers can be registered into the notifier and whenever an
-    /// alteration occured in the graph all the observers will
+    /// alteration occured in the graph all the observers will be
     /// notified about it.
     template <typename BAS = BaseGraphComponent>
@@ -952,11 +980,11 @@
 
 
-      /// The arc observer registry.
+      /// Edge alteration notifier class.
       typedef AlterationNotifier<AlterableGraphComponent, Edge>
       EdgeNotifier;
 
-      /// \brief Gives back the arc alteration notifier.
-      ///
-      /// Gives back the arc alteration notifier.
+      /// \brief Return the edge alteration notifier.
+      ///
+      /// This function gives back the edge alteration notifier.
       EdgeNotifier& notifier(Edge) const {
         return EdgeNotifier();
@@ -966,40 +994,47 @@
       struct Constraints {
         void constraints() {
-          checkConcept<AlterableGraphComponent<Base>, _Graph>();
+          checkConcept<AlterableDigraphComponent<Base>, _Graph>();
           typename _Graph::EdgeNotifier& uen
             = graph.notifier(typename _Graph::Edge());
-          ignore_unused_variable_warning(uen);
+          ::lemon::ignore_unused_variable_warning(uen);
         }
 
         const _Graph& graph;
-      };
-    };
-
-    /// \brief Class describing the concept of graph maps
-    ///
-    /// This class describes the common interface of the graph maps
-    /// (NodeMap, ArcMap), that is maps that can be used to
-    /// associate data to graph descriptors (nodes or arcs).
+        Constraints() {}
+      };
+    };
+
+    /// \brief Concept class for standard graph maps.
+    ///
+    /// This class describes the concept of standard graph maps, i.e.
+    /// the \c NodeMap, \c ArcMap and \c EdgeMap subtypes of digraph and
+    /// graph types, which can be used for associating data to graph items.
+    /// The standard graph maps must conform to the ReferenceMap concept.
     template <typename GR, typename K, typename V>
-    class GraphMap : public ReadWriteMap<K, V> {
-    public:
-
-      typedef ReadWriteMap<K, V> Parent;
-
-      /// The graph type of the map.
-      typedef GR Graph;
+    class GraphMap : public ReferenceMap<K, V, V&, const V&> {
+      typedef ReferenceMap<K, V, V&, const V&> Parent;
+
+    public:
+
       /// The key type of the map.
       typedef K Key;
       /// The value type of the map.
       typedef V Value;
+      /// The reference type of the map.
+      typedef Value& Reference;
+      /// The const reference type of the map.
+      typedef const Value& ConstReference;
+
+      // The reference map tag.
+      typedef True ReferenceMapTag;
 
       /// \brief Construct a new map.
       ///
       /// Construct a new map for the graph.
-      explicit GraphMap(const Graph&) {}
+      explicit GraphMap(const GR&) {}
       /// \brief Construct a new map with default value.
       ///
-      /// Construct a new map for the graph and initalise the values.
-      GraphMap(const Graph&, const Value&) {}
+      /// Construct a new map for the graph and initalize the values.
+      GraphMap(const GR&, const Value&) {}
 
     private:
@@ -1009,7 +1044,7 @@
       GraphMap(const GraphMap&) : Parent() {}
 
-      /// \brief Assign operator.
-      ///
-      /// Assign operator. It does not mofify the underlying graph,
+      /// \brief Assignment operator.
+      ///
+      /// Assignment operator. It does not mofify the underlying graph,
       /// it just iterates on the current item set and set the  map
       /// with the value returned by the assigned map.
@@ -1024,31 +1059,34 @@
       struct Constraints {
         void constraints() {
-          checkConcept<ReadWriteMap<Key, Value>, _Map >();
-          // Construction with a graph parameter
-          _Map a(g);
-          // Constructor with a graph and a default value parameter
-          _Map a2(g,t);
-          // Copy constructor.
-          // _Map b(c);
-
+          checkConcept
+            <ReferenceMap<Key, Value, Value&, const Value&>, _Map>();
+          _Map m1(g);
+          _Map m2(g,t);
+
+          // Copy constructor
+          // _Map m3(m);
+
+          // Assignment operator
           // ReadMap<Key, Value> cmap;
-          // b = cmap;
-
-          ignore_unused_variable_warning(a);
-          ignore_unused_variable_warning(a2);
-          // ignore_unused_variable_warning(b);
-        }
-
-        const _Map &c;
-        const Graph &g;
+          // m3 = cmap;
+
+          ::lemon::ignore_unused_variable_warning(m1);
+          ::lemon::ignore_unused_variable_warning(m2);
+          // ::lemon::ignore_unused_variable_warning(m3);
+        }
+
+        const _Map &m;
+        const GR &g;
         const typename GraphMap::Value &t;
-      };
-
-    };
-
-    /// \brief An empty mappable digraph class.
-    ///
-    /// This class provides beside the core digraph features
-    /// map interface for the digraph structure.
+        Constraints() {}
+      };
+
+    };
+
+    /// \brief Skeleton class for mappable directed graphs.
+    ///
+    /// This class describes the interface of mappable directed graphs.
+    /// It extends \ref BaseDigraphComponent with the standard digraph
+    /// map classes, namely \c NodeMap and \c ArcMap.
     /// This concept is part of the Digraph concept.
     template <typename BAS = BaseDigraphComponent>
@@ -1062,13 +1100,13 @@
       typedef MappableDigraphComponent Digraph;
 
-      /// \brief ReadWrite map of the nodes.
-      ///
-      /// ReadWrite map of the nodes.
-      ///
+      /// \brief Standard graph map for the nodes.
+      ///
+      /// Standard graph map for the nodes.
+      /// It conforms to the ReferenceMap concept.
       template <typename V>
-      class NodeMap : public GraphMap<Digraph, Node, V> {
+      class NodeMap : public GraphMap<MappableDigraphComponent, Node, V> {
+        typedef GraphMap<MappableDigraphComponent, Node, V> Parent;
+
       public:
-        typedef GraphMap<MappableDigraphComponent, Node, V> Parent;
-
         /// \brief Construct a new map.
         ///
@@ -1079,5 +1117,5 @@
         /// \brief Construct a new map with default value.
         ///
-        /// Construct a new map for the digraph and initalise the values.
+        /// Construct a new map for the digraph and initalize the values.
         NodeMap(const MappableDigraphComponent& digraph, const V& value)
           : Parent(digraph, value) {}
@@ -1089,7 +1127,7 @@
         NodeMap(const NodeMap& nm) : Parent(nm) {}
 
-        /// \brief Assign operator.
+        /// \brief Assignment operator.
         ///
-        /// Assign operator.
+        /// Assignment operator.
         template <typename CMap>
         NodeMap& operator=(const CMap&) {
@@ -1100,13 +1138,13 @@
       };
 
-      /// \brief ReadWrite map of the arcs.
-      ///
-      /// ReadWrite map of the arcs.
-      ///
+      /// \brief Standard graph map for the arcs.
+      ///
+      /// Standard graph map for the arcs.
+      /// It conforms to the ReferenceMap concept.
       template <typename V>
-      class ArcMap : public GraphMap<Digraph, Arc, V> {
+      class ArcMap : public GraphMap<MappableDigraphComponent, Arc, V> {
+        typedef GraphMap<MappableDigraphComponent, Arc, V> Parent;
+
       public:
-        typedef GraphMap<MappableDigraphComponent, Arc, V> Parent;
-
         /// \brief Construct a new map.
         ///
@@ -1117,5 +1155,5 @@
         /// \brief Construct a new map with default value.
         ///
-        /// Construct a new map for the digraph and initalise the values.
+        /// Construct a new map for the digraph and initalize the values.
         ArcMap(const MappableDigraphComponent& digraph, const V& value)
           : Parent(digraph, value) {}
@@ -1127,7 +1165,7 @@
         ArcMap(const ArcMap& nm) : Parent(nm) {}
 
-        /// \brief Assign operator.
+        /// \brief Assignment operator.
         ///
-        /// Assign operator.
+        /// Assignment operator.
         template <typename CMap>
         ArcMap& operator=(const CMap&) {
@@ -1179,12 +1217,14 @@
         }
 
-        _Digraph& digraph;
-      };
-    };
-
-    /// \brief An empty mappable base bipartite graph class.
-    ///
-    /// This class provides beside the core graph features
-    /// map interface for the graph structure.
+        const _Digraph& digraph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for mappable undirected graphs.
+    ///
+    /// This class describes the interface of mappable undirected graphs.
+    /// It extends \ref MappableDigraphComponent with the standard graph
+    /// map class for edges (\c EdgeMap).
     /// This concept is part of the Graph concept.
     template <typename BAS = BaseGraphComponent>
@@ -1197,13 +1237,13 @@
       typedef MappableGraphComponent Graph;
 
-      /// \brief ReadWrite map of the edges.
-      ///
-      /// ReadWrite map of the edges.
-      ///
+      /// \brief Standard graph map for the edges.
+      ///
+      /// Standard graph map for the edges.
+      /// It conforms to the ReferenceMap concept.
       template <typename V>
-      class EdgeMap : public GraphMap<Graph, Edge, V> {
+      class EdgeMap : public GraphMap<MappableGraphComponent, Edge, V> {
+        typedef GraphMap<MappableGraphComponent, Edge, V> Parent;
+
       public:
-        typedef GraphMap<MappableGraphComponent, Edge, V> Parent;
-
         /// \brief Construct a new map.
         ///
@@ -1214,5 +1254,5 @@
         /// \brief Construct a new map with default value.
         ///
-        /// Construct a new map for the graph and initalise the values.
+        /// Construct a new map for the graph and initalize the values.
         EdgeMap(const MappableGraphComponent& graph, const V& value)
           : Parent(graph, value) {}
@@ -1224,7 +1264,7 @@
         EdgeMap(const EdgeMap& nm) : Parent(nm) {}
 
-        /// \brief Assign operator.
+        /// \brief Assignment operator.
         ///
-        /// Assign operator.
+        /// Assignment operator.
         template <typename CMap>
         EdgeMap& operator=(const CMap&) {
@@ -1246,5 +1286,5 @@
 
         void constraints() {
-          checkConcept<MappableGraphComponent<Base>, _Graph>();
+          checkConcept<MappableDigraphComponent<Base>, _Graph>();
 
           { // int map test
@@ -1263,14 +1303,15 @@
         }
 
-        _Graph& graph;
-      };
-    };
-
-    /// \brief An empty extendable digraph class.
-    ///
-    /// This class provides beside the core digraph features digraph
-    /// extendable interface for the digraph structure.  The main
-    /// difference between the base and this interface is that the
-    /// digraph alterations should handled already on this level.
+        const _Graph& graph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for extendable directed graphs.
+    ///
+    /// This class describes the interface of extendable directed graphs.
+    /// It extends \ref BaseDigraphComponent with functions for adding
+    /// nodes and arcs to the digraph.
+    /// This concept requires \ref AlterableDigraphComponent.
     template <typename BAS = BaseDigraphComponent>
     class ExtendableDigraphComponent : public BAS {
@@ -1281,15 +1322,15 @@
       typedef typename Base::Arc Arc;
 
-      /// \brief Adds a new node to the digraph.
-      ///
-      /// Adds a new node to the digraph.
-      ///
+      /// \brief Add a new node to the digraph.
+      ///
+      /// This function adds a new node to the digraph.
       Node addNode() {
         return INVALID;
       }
 
-      /// \brief Adds a new arc connects the given two nodes.
-      ///
-      /// Adds a new arc connects the the given two nodes.
+      /// \brief Add a new arc connecting the given two nodes.
+      ///
+      /// This function adds a new arc connecting the given two nodes
+      /// of the digraph.
       Arc addArc(const Node&, const Node&) {
         return INVALID;
@@ -1308,14 +1349,14 @@
 
         _Digraph& digraph;
-      };
-    };
-
-    /// \brief An empty extendable base undirected graph class.
-    ///
-    /// This class provides beside the core undirected graph features
-    /// core undircted graph extend interface for the graph structure.
-    /// The main difference between the base and this interface is
-    /// that the graph alterations should handled already on this
-    /// level.
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for extendable undirected graphs.
+    ///
+    /// This class describes the interface of extendable undirected graphs.
+    /// It extends \ref BaseGraphComponent with functions for adding
+    /// nodes and edges to the graph.
+    /// This concept requires \ref AlterableGraphComponent.
     template <typename BAS = BaseGraphComponent>
     class ExtendableGraphComponent : public BAS {
@@ -1326,16 +1367,16 @@
       typedef typename Base::Edge Edge;
 
-      /// \brief Adds a new node to the graph.
-      ///
-      /// Adds a new node to the graph.
-      ///
+      /// \brief Add a new node to the digraph.
+      ///
+      /// This function adds a new node to the digraph.
       Node addNode() {
         return INVALID;
       }
 
-      /// \brief Adds a new arc connects the given two nodes.
-      ///
-      /// Adds a new arc connects the the given two nodes.
-      Edge addArc(const Node&, const Node&) {
+      /// \brief Add a new edge connecting the given two nodes.
+      ///
+      /// This function adds a new edge connecting the given two nodes
+      /// of the graph.
+      Edge addEdge(const Node&, const Node&) {
         return INVALID;
       }
@@ -1353,13 +1394,14 @@
 
         _Graph& graph;
-      };
-    };
-
-    /// \brief An empty erasable digraph class.
-    ///
-    /// This class provides beside the core digraph features core erase
-    /// functions for the digraph structure. The main difference between
-    /// the base and this interface is that the digraph alterations
-    /// should handled already on this level.
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for erasable directed graphs.
+    ///
+    /// This class describes the interface of erasable directed graphs.
+    /// It extends \ref BaseDigraphComponent with functions for removing
+    /// nodes and arcs from the digraph.
+    /// This concept requires \ref AlterableDigraphComponent.
     template <typename BAS = BaseDigraphComponent>
     class ErasableDigraphComponent : public BAS {
@@ -1372,12 +1414,11 @@
       /// \brief Erase a node from the digraph.
       ///
-      /// Erase a node from the digraph. This function should
-      /// erase all arcs connecting to the node.
+      /// This function erases the given node from the digraph and all arcs
+      /// connected to the node.
       void erase(const Node&) {}
 
       /// \brief Erase an arc from the digraph.
       ///
-      /// Erase an arc from the digraph.
-      ///
+      /// This function erases the given arc from the digraph.
       void erase(const Arc&) {}
 
@@ -1386,20 +1427,21 @@
         void constraints() {
           checkConcept<Base, _Digraph>();
-          typename _Digraph::Node node;
+          const typename _Digraph::Node node(INVALID);
           digraph.erase(node);
-          typename _Digraph::Arc arc;
+          const typename _Digraph::Arc arc(INVALID);
           digraph.erase(arc);
         }
 
         _Digraph& digraph;
-      };
-    };
-
-    /// \brief An empty erasable base undirected graph class.
-    ///
-    /// This class provides beside the core undirected graph features
-    /// core erase functions for the undirceted graph structure. The
-    /// main difference between the base and this interface is that
-    /// the graph alterations should handled already on this level.
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for erasable undirected graphs.
+    ///
+    /// This class describes the interface of erasable undirected graphs.
+    /// It extends \ref BaseGraphComponent with functions for removing
+    /// nodes and edges from the graph.
+    /// This concept requires \ref AlterableGraphComponent.
     template <typename BAS = BaseGraphComponent>
     class ErasableGraphComponent : public BAS {
@@ -1412,12 +1454,11 @@
       /// \brief Erase a node from the graph.
       ///
-      /// Erase a node from the graph. This function should erase
-      /// arcs connecting to the node.
+      /// This function erases the given node from the graph and all edges
+      /// connected to the node.
       void erase(const Node&) {}
 
-      /// \brief Erase an arc from the graph.
-      ///
-      /// Erase an arc from the graph.
-      ///
+      /// \brief Erase an edge from the digraph.
+      ///
+      /// This function erases the given edge from the digraph.
       void erase(const Edge&) {}
 
@@ -1426,20 +1467,21 @@
         void constraints() {
           checkConcept<Base, _Graph>();
-          typename _Graph::Node node;
+          const typename _Graph::Node node(INVALID);
           graph.erase(node);
-          typename _Graph::Edge edge;
+          const typename _Graph::Edge edge(INVALID);
           graph.erase(edge);
         }
 
         _Graph& graph;
-      };
-    };
-
-    /// \brief An empty clearable base digraph class.
-    ///
-    /// This class provides beside the core digraph features core clear
-    /// functions for the digraph structure. The main difference between
-    /// the base and this interface is that the digraph alterations
-    /// should handled already on this level.
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for clearable directed graphs.
+    ///
+    /// This class describes the interface of clearable directed graphs.
+    /// It extends \ref BaseDigraphComponent with a function for clearing
+    /// the digraph.
+    /// This concept requires \ref AlterableDigraphComponent.
     template <typename BAS = BaseDigraphComponent>
     class ClearableDigraphComponent : public BAS {
@@ -1450,6 +1492,5 @@
       /// \brief Erase all nodes and arcs from the digraph.
       ///
-      /// Erase all nodes and arcs from the digraph.
-      ///
+      /// This function erases all nodes and arcs from the digraph.
       void clear() {}
 
@@ -1461,14 +1502,15 @@
         }
 
-        _Digraph digraph;
-      };
-    };
-
-    /// \brief An empty clearable base undirected graph class.
-    ///
-    /// This class provides beside the core undirected graph features
-    /// core clear functions for the undirected graph structure. The
-    /// main difference between the base and this interface is that
-    /// the graph alterations should handled already on this level.
+        _Digraph& digraph;
+        Constraints() {}
+      };
+    };
+
+    /// \brief Skeleton class for clearable undirected graphs.
+    ///
+    /// This class describes the interface of clearable undirected graphs.
+    /// It extends \ref BaseGraphComponent with a function for clearing
+    /// the graph.
+    /// This concept requires \ref AlterableGraphComponent.
     template <typename BAS = BaseGraphComponent>
     class ClearableGraphComponent : public ClearableDigraphComponent<BAS> {
@@ -1477,11 +1519,18 @@
       typedef BAS Base;
 
+      /// \brief Erase all nodes and edges from the graph.
+      ///
+      /// This function erases all nodes and edges from the graph.
+      void clear() {}
+
       template <typename _Graph>
       struct Constraints {
         void constraints() {
-          checkConcept<ClearableGraphComponent<Base>, _Graph>();
-        }
-
-        _Graph graph;
+          checkConcept<Base, _Graph>();
+          graph.clear();
+        }
+
+        _Graph& graph;
+        Constraints() {}
       };
     };
Index: lemon/concepts/heap.h
===================================================================
--- lemon/concepts/heap.h	(revision 559)
+++ lemon/concepts/heap.h	(revision 983)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -17,11 +17,11 @@
  */
 
+#ifndef LEMON_CONCEPTS_HEAP_H
+#define LEMON_CONCEPTS_HEAP_H
+
 ///\ingroup concept
 ///\file
 ///\brief The concept of heaps.
 
-#ifndef LEMON_CONCEPTS_HEAP_H
-#define LEMON_CONCEPTS_HEAP_H
-
 #include <lemon/core.h>
 #include <lemon/concept_check.h>
@@ -36,19 +36,25 @@
     /// \brief The heap concept.
     ///
-    /// Concept class describing the main interface of heaps. A \e heap
-    /// is a data structure for storing items with specified values called
-    /// \e priorities in such a way that finding the item with minimum
-    /// priority is efficient. In a heap one can change the priority of an
-    /// item, add or erase an item, etc.
+    /// This concept class describes the main interface of heaps.
+    /// The various \ref heaps "heap structures" are efficient
+    /// implementations of the abstract data type \e priority \e queue.
+    /// They store items with specified values called \e priorities
+    /// in such a way that finding and removing the item with minimum
+    /// priority are efficient. The basic operations are adding and
+    /// erasing items, changing the priority of an item, etc.
     ///
-    /// \tparam PR Type of the priority of the items.
-    /// \tparam IM A read and writable item map with int values, used
+    /// Heaps are crucial in several algorithms, such as Dijkstra and Prim.
+    /// Any class that conforms to this concept can be used easily in such
+    /// algorithms.
+    ///
+    /// \tparam PR Type of the priorities of the items.
+    /// \tparam IM A read-writable item map with \c int values, used
     /// internally to handle the cross references.
-    /// \tparam Comp A functor class for the ordering of the priorities.
+    /// \tparam CMP A functor class for comparing the priorities.
     /// The default is \c std::less<PR>.
 #ifdef DOXYGEN
-    template <typename PR, typename IM, typename Comp = std::less<PR> >
-#else
-    template <typename PR, typename IM>
+    template <typename PR, typename IM, typename CMP>
+#else
+    template <typename PR, typename IM, typename CMP = std::less<PR> >
 #endif
     class Heap {
@@ -65,107 +71,155 @@
       ///
       /// Each item has a state associated to it. It can be "in heap",
-      /// "pre heap" or "post heap". The later two are indifferent
-      /// from the point of view of the heap, but may be useful for
-      /// the user.
+      /// "pre-heap" or "post-heap". The latter two are indifferent from the
+      /// heap's point of view, but may be useful to the user.
       ///
       /// The item-int map must be initialized in such way that it assigns
       /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
       enum State {
-        IN_HEAP = 0,    ///< The "in heap" state constant.
-        PRE_HEAP = -1,  ///< The "pre heap" state constant.
-        POST_HEAP = -2  ///< The "post heap" state constant.
+        IN_HEAP = 0,    ///< = 0. The "in heap" state constant.
+        PRE_HEAP = -1,  ///< = -1. The "pre-heap" state constant.
+        POST_HEAP = -2  ///< = -2. The "post-heap" state constant.
       };
 
-      /// \brief The constructor.
-      ///
-      /// The constructor.
+      /// \brief Constructor.
+      ///
+      /// Constructor.
       /// \param map A map that assigns \c int values to keys of type
       /// \c Item. It is used internally by the heap implementations to
       /// handle the cross references. The assigned value must be
-      /// \c PRE_HEAP (<tt>-1</tt>) for every item.
+      /// \c PRE_HEAP (<tt>-1</tt>) for each item.
+#ifdef DOXYGEN
       explicit Heap(ItemIntMap &map) {}
+#else
+      explicit Heap(ItemIntMap&) {}
+#endif
+
+      /// \brief Constructor.
+      ///
+      /// Constructor.
+      /// \param map A map that assigns \c int values to keys of type
+      /// \c Item. It is used internally by the heap implementations to
+      /// handle the cross references. The assigned value must be
+      /// \c PRE_HEAP (<tt>-1</tt>) for each item.
+      /// \param comp The function object used for comparing the priorities.
+#ifdef DOXYGEN
+      explicit Heap(ItemIntMap &map, const CMP &comp) {}
+#else
+      explicit Heap(ItemIntMap&, const CMP&) {}
+#endif
 
       /// \brief The number of items stored in the heap.
       ///
-      /// Returns the number of items stored in the heap.
+      /// This function returns the number of items stored in the heap.
       int size() const { return 0; }
 
-      /// \brief Checks if the heap is empty.
-      ///
-      /// Returns \c true if the heap is empty.
+      /// \brief Check if the heap is empty.
+      ///
+      /// This function returns \c true if the heap is empty.
       bool empty() const { return false; }
 
-      /// \brief Makes the heap empty.
-      ///
-      /// Makes the heap empty.
-      void clear();
-
-      /// \brief Inserts an item into the heap with the given priority.
-      ///
-      /// Inserts the given item into the heap with the given priority.
+      /// \brief Make the heap empty.
+      ///
+      /// This functon makes the heap empty.
+      /// It does not change the cross reference map. If you want to reuse
+      /// a heap that is not surely empty, you should first clear it and
+      /// then you should set the cross reference map to \c PRE_HEAP
+      /// for each item.
+      void clear() {}
+
+      /// \brief Insert an item into the heap with the given priority.
+      ///
+      /// This function inserts the given item into the heap with the
+      /// given priority.
       /// \param i The item to insert.
       /// \param p The priority of the item.
+      /// \pre \e i must not be stored in the heap.
+#ifdef DOXYGEN
       void push(const Item &i, const Prio &p) {}
-
-      /// \brief Returns the item having minimum priority.
-      ///
-      /// Returns the item having minimum priority.
+#else
+      void push(const Item&, const Prio&) {}
+#endif
+
+      /// \brief Return the item having minimum priority.
+      ///
+      /// This function returns the item having minimum priority.
       /// \pre The heap must be non-empty.
-      Item top() const {}
+      Item top() const { return Item(); }
 
       /// \brief The minimum priority.
       ///
-      /// Returns the minimum priority.
+      /// This function returns the minimum priority.
       /// \pre The heap must be non-empty.
-      Prio prio() const {}
-
-      /// \brief Removes the item having minimum priority.
-      ///
-      /// Removes the item having minimum priority.
+      Prio prio() const { return Prio(); }
+
+      /// \brief Remove the item having minimum priority.
+      ///
+      /// This function removes the item having minimum priority.
       /// \pre The heap must be non-empty.
       void pop() {}
 
-      /// \brief Removes an item from the heap.
-      ///
-      /// Removes the given item from the heap if it is already stored.
+      /// \brief Remove the given item from the heap.
+      ///
+      /// This function removes the given item from the heap if it is
+      /// already stored.
       /// \param i The item to delete.
+      /// \pre \e i must be in the heap.
+#ifdef DOXYGEN
       void erase(const Item &i) {}
-
-      /// \brief The priority of an item.
-      ///
-      /// Returns the priority of the given item.
-      /// \param i The item.
-      /// \pre \c i must be in the heap.
+#else
+      void erase(const Item&) {}
+#endif
+
+      /// \brief The priority of the given item.
+      ///
+      /// This function returns the priority of the given item.
+      /// \param i The item.
+      /// \pre \e i must be in the heap.
+#ifdef DOXYGEN
       Prio operator[](const Item &i) const {}
-
-      /// \brief Sets the priority of an item or inserts it, if it is
+#else
+      Prio operator[](const Item&) const { return Prio(); }
+#endif
+
+      /// \brief Set the priority of an item or insert it, if it is
       /// not stored in the heap.
       ///
       /// This method sets the priority of the given item if it is
-      /// already stored in the heap.
-      /// Otherwise it inserts the given item with the given priority.
+      /// already stored in the heap. Otherwise it inserts the given
+      /// item into the heap with the given priority.
       ///
       /// \param i The item.
       /// \param p The priority.
+#ifdef DOXYGEN
       void set(const Item &i, const Prio &p) {}
-
-      /// \brief Decreases the priority of an item to the given value.
-      ///
-      /// Decreases the priority of an item to the given value.
+#else
+      void set(const Item&, const Prio&) {}
+#endif
+
+      /// \brief Decrease the priority of an item to the given value.
+      ///
+      /// This function decreases the priority of an item to the given value.
       /// \param i The item.
       /// \param p The priority.
-      /// \pre \c i must be stored in the heap with priority at least \c p.
+      /// \pre \e i must be stored in the heap with priority at least \e p.
+#ifdef DOXYGEN
       void decrease(const Item &i, const Prio &p) {}
-
-      /// \brief Increases the priority of an item to the given value.
-      ///
-      /// Increases the priority of an item to the given value.
+#else
+      void decrease(const Item&, const Prio&) {}
+#endif
+
+      /// \brief Increase the priority of an item to the given value.
+      ///
+      /// This function increases the priority of an item to the given value.
       /// \param i The item.
       /// \param p The priority.
-      /// \pre \c i must be stored in the heap with priority at most \c p.
+      /// \pre \e i must be stored in the heap with priority at most \e p.
+#ifdef DOXYGEN
       void increase(const Item &i, const Prio &p) {}
-
-      /// \brief Returns if an item is in, has already been in, or has
-      /// never been in the heap.
+#else
+      void increase(const Item&, const Prio&) {}
+#endif
+
+      /// \brief Return the state of an item.
       ///
       /// This method returns \c PRE_HEAP if the given item has never
@@ -175,14 +229,22 @@
       /// to the heap again.
       /// \param i The item.
+#ifdef DOXYGEN
       State state(const Item &i) const {}
-
-      /// \brief Sets the state of an item in the heap.
-      ///
-      /// Sets the state of the given item in the heap. It can be used
-      /// to manually clear the heap when it is important to achive the
-      /// better time complexity.
+#else
+      State state(const Item&) const { return PRE_HEAP; }
+#endif
+
+      /// \brief Set the state of an item in the heap.
+      ///
+      /// This function sets the state of the given item in the heap.
+      /// It can be used to manually clear the heap when it is important
+      /// to achive better time complexity.
       /// \param i The item.
       /// \param st The state. It should not be \c IN_HEAP.
+#ifdef DOXYGEN
       void state(const Item& i, State st) {}
+#else
+      void state(const Item&, State) {}
+#endif
 
 
@@ -199,6 +261,6 @@
           item=Item();
           prio=Prio();
-          ignore_unused_variable_warning(item);
-          ignore_unused_variable_warning(prio);
+          ::lemon::ignore_unused_variable_warning(item);
+          ::lemon::ignore_unused_variable_warning(prio);
 
           OwnItem own_item;
@@ -207,17 +269,17 @@
           own_item=Item();
           own_prio=Prio();
-          ignore_unused_variable_warning(own_item);
-          ignore_unused_variable_warning(own_prio);
-          ignore_unused_variable_warning(own_state);
+          ::lemon::ignore_unused_variable_warning(own_item);
+          ::lemon::ignore_unused_variable_warning(own_prio);
+          ::lemon::ignore_unused_variable_warning(own_state);
 
           _Heap heap1(map);
           _Heap heap2 = heap1;
-          ignore_unused_variable_warning(heap1);
-          ignore_unused_variable_warning(heap2);
+          ::lemon::ignore_unused_variable_warning(heap1);
+          ::lemon::ignore_unused_variable_warning(heap2);
 
           int s = heap.size();
-          ignore_unused_variable_warning(s);
+          ::lemon::ignore_unused_variable_warning(s);
           bool e = heap.empty();
-          ignore_unused_variable_warning(e);
+          ::lemon::ignore_unused_variable_warning(e);
 
           prio = heap.prio();
@@ -253,4 +315,5 @@
         _Heap& heap;
         ItemIntMap& map;
+        Constraints() {}
       };
     };
Index: lemon/concepts/maps.h
===================================================================
--- lemon/concepts/maps.h	(revision 529)
+++ lemon/concepts/maps.h	(revision 982)
@@ -50,5 +50,5 @@
       /// Returns the value associated with the given key.
       Value operator[](const Key &) const {
-        return *static_cast<Value *>(0);
+        return *(static_cast<Value *>(0)+1);
       }
 
@@ -61,12 +61,13 @@
           own_val = m[own_key];
 
-          ignore_unused_variable_warning(key);
-          ignore_unused_variable_warning(val);
-          ignore_unused_variable_warning(own_key);
-          ignore_unused_variable_warning(own_val);
+          ::lemon::ignore_unused_variable_warning(key);
+          ::lemon::ignore_unused_variable_warning(val);
+          ::lemon::ignore_unused_variable_warning(own_key);
+          ::lemon::ignore_unused_variable_warning(own_val);
         }
         const Key& key;
         const typename _ReadMap::Key& own_key;
         const _ReadMap& m;
+        Constraints() {}
       };
 
@@ -100,8 +101,8 @@
           m.set(own_key, own_val);
 
-          ignore_unused_variable_warning(key);
-          ignore_unused_variable_warning(val);
-          ignore_unused_variable_warning(own_key);
-          ignore_unused_variable_warning(own_val);
+          ::lemon::ignore_unused_variable_warning(key);
+          ::lemon::ignore_unused_variable_warning(val);
+          ::lemon::ignore_unused_variable_warning(own_key);
+          ::lemon::ignore_unused_variable_warning(own_val);
         }
         const Key& key;
@@ -110,4 +111,5 @@
         const typename _WriteMap::Value& own_val;
         _WriteMap& m;
+        Constraints() {}
       };
     };
@@ -130,5 +132,6 @@
       /// Returns the value associated with the given key.
       Value operator[](const Key &) const {
-        return *static_cast<Value *>(0);
+        Value *r = 0;
+        return *r;
       }
 
@@ -170,10 +173,12 @@
       /// Returns a reference to the value associated with the given key.
       Reference operator[](const Key &) {
-        return *static_cast<Value *>(0);
+        Value *r = 0;
+        return *r;
       }
 
       /// Returns a const reference to the value associated with the given key.
       ConstReference operator[](const Key &) const {
-        return *static_cast<Value *>(0);
+        Value *r = 0;
+        return *r;
       }
 
@@ -183,5 +188,6 @@
       template<typename _ReferenceMap>
       struct Constraints {
-        void constraints() {
+        typename enable_if<typename _ReferenceMap::ReferenceMapTag, void>::type
+        constraints() {
           checkConcept<ReadWriteMap<K, T>, _ReferenceMap >();
           ref = m[key];
@@ -205,4 +211,5 @@
         typename _ReferenceMap::ConstReference own_cref;
         _ReferenceMap& m;
+        Constraints() {}
       };
     };
Index: lemon/concepts/path.h
===================================================================
--- lemon/concepts/path.h	(revision 559)
+++ lemon/concepts/path.h	(revision 983)
@@ -19,5 +19,5 @@
 ///\ingroup concept
 ///\file
-///\brief Classes for representing paths in digraphs.
+///\brief The concept of paths
 ///
 
@@ -39,11 +39,20 @@
     /// A skeleton structure for representing directed paths in a
     /// digraph.
+    /// In a sense, a path can be treated as a list of arcs.
+    /// LEMON path types just store this list. As a consequence, they cannot
+    /// enumerate the nodes on the path directly and a zero length path
+    /// cannot store its source node.
+    ///
+    /// The arcs of a path should be stored in the order of their directions,
+    /// i.e. the target node of each arc should be the same as the source
+    /// node of the next arc. This consistency could be checked using
+    /// \ref checkPath().
+    /// The source and target nodes of a (consistent) path can be obtained
+    /// using \ref pathSource() and \ref pathTarget().
+    ///
+    /// A path can be constructed from another path of any type using the
+    /// copy constructor or the assignment operator.
+    ///
     /// \tparam GR The digraph type in which the path is.
-    ///
-    /// In a sense, the path can be treated as a list of arcs. The
-    /// lemon path type stores just this list. As a consequence it
-    /// cannot enumerate the nodes in the path and the zero length
-    /// paths cannot store the source.
-    ///
     template <typename GR>
     class Path {
@@ -60,16 +69,16 @@
       Path() {}
 
-      /// \brief Template constructor
+      /// \brief Template copy constructor
       template <typename CPath>
       Path(const CPath& cpath) {}
 
-      /// \brief Template assigment
+      /// \brief Template assigment operator
       template <typename CPath>
       Path& operator=(const CPath& cpath) {
-        ignore_unused_variable_warning(cpath);
+        ::lemon::ignore_unused_variable_warning(cpath);
         return *this;
       }
 
-      /// Length of the path ie. the number of arcs in the path.
+      /// Length of the path, i.e. the number of arcs on the path.
       int length() const { return 0;}
 
@@ -80,7 +89,7 @@
       void clear() {}
 
-      /// \brief LEMON style iterator for path arcs
+      /// \brief LEMON style iterator for enumerating the arcs of a path.
       ///
-      /// This class is used to iterate on the arcs of the paths.
+      /// LEMON style iterator class for enumerating the arcs of a path.
       class ArcIt {
       public:
@@ -89,8 +98,8 @@
         /// Invalid constructor
         ArcIt(Invalid) {}
-        /// Constructor for first arc
+        /// Sets the iterator to the first arc of the given path
         ArcIt(const Path &) {}
 
-        /// Conversion to Arc
+        /// Conversion to \c Arc
         operator Arc() const { return INVALID; }
 
@@ -127,10 +136,10 @@
           e = (i < ii);
 
-          ignore_unused_variable_warning(l);
-          ignore_unused_variable_warning(pp);
-          ignore_unused_variable_warning(e);
-          ignore_unused_variable_warning(id);
-          ignore_unused_variable_warning(ii);
-          ignore_unused_variable_warning(ed);
+          ::lemon::ignore_unused_variable_warning(l);
+          ::lemon::ignore_unused_variable_warning(pp);
+          ::lemon::ignore_unused_variable_warning(e);
+          ::lemon::ignore_unused_variable_warning(id);
+          ::lemon::ignore_unused_variable_warning(ii);
+          ::lemon::ignore_unused_variable_warning(ed);
         }
       };
@@ -154,10 +163,11 @@
           e = (i != INVALID);
 
-          ignore_unused_variable_warning(l);
-          ignore_unused_variable_warning(e);
-          ignore_unused_variable_warning(id);
-          ignore_unused_variable_warning(ed);
+          ::lemon::ignore_unused_variable_warning(l);
+          ::lemon::ignore_unused_variable_warning(e);
+          ::lemon::ignore_unused_variable_warning(id);
+          ::lemon::ignore_unused_variable_warning(ed);
         }
         _Path& p;
+        PathDumperConstraints() {}
       };
 
@@ -179,10 +189,11 @@
           e = (i != INVALID);
 
-          ignore_unused_variable_warning(l);
-          ignore_unused_variable_warning(e);
-          ignore_unused_variable_warning(id);
-          ignore_unused_variable_warning(ed);
+          ::lemon::ignore_unused_variable_warning(l);
+          ::lemon::ignore_unused_variable_warning(e);
+          ::lemon::ignore_unused_variable_warning(id);
+          ::lemon::ignore_unused_variable_warning(ed);
         }
         _Path& p;
+        PathDumperConstraints() {}
       };
 
@@ -193,22 +204,16 @@
     ///
     /// A skeleton structure for path dumpers. The path dumpers are
-    /// the generalization of the paths. The path dumpers can
-    /// enumerate the arcs of the path wheter in forward or in
-    /// backward order.  In most time these classes are not used
-    /// directly rather it used to assign a dumped class to a real
-    /// path type.
+    /// the generalization of the paths, they can enumerate the arcs
+    /// of the path either in forward or in backward order.
+    /// These classes are typically not used directly, they are rather
+    /// used to be assigned to a real path type.
     ///
     /// The main purpose of this concept is that the shortest path
-    /// algorithms can enumerate easily the arcs in reverse order.
-    /// If we would like to give back a real path from these
-    /// algorithms then we should create a temporarly path object. In
-    /// LEMON such algorithms gives back a path dumper what can
-    /// assigned to a real path and the dumpers can be implemented as
+    /// algorithms can enumerate the arcs easily in reverse order.
+    /// In LEMON, such algorithms give back a (reverse) path dumper that
+    /// can be assigned to a real path. The dumpers can be implemented as
     /// an adaptor class to the predecessor map.
     ///
     /// \tparam GR The digraph type in which the path is.
-    ///
-    /// The paths can be constructed from any path type by a
-    /// template constructor or a template assignment operator.
     template <typename GR>
     class PathDumper {
@@ -220,5 +225,5 @@
       typedef typename Digraph::Arc Arc;
 
-      /// Length of the path ie. the number of arcs in the path.
+      /// Length of the path, i.e. the number of arcs on the path.
       int length() const { return 0;}
 
@@ -228,13 +233,12 @@
       /// \brief Forward or reverse dumping
       ///
-      /// If the RevPathTag is defined and true then reverse dumping
-      /// is provided in the path dumper. In this case instead of the
-      /// ArcIt the RevArcIt iterator should be implemented in the
-      /// dumper.
+      /// If this tag is defined to be \c True, then reverse dumping
+      /// is provided in the path dumper. In this case, \c RevArcIt
+      /// iterator should be implemented instead of \c ArcIt iterator.
       typedef False RevPathTag;
 
-      /// \brief LEMON style iterator for path arcs
+      /// \brief LEMON style iterator for enumerating the arcs of a path.
       ///
-      /// This class is used to iterate on the arcs of the paths.
+      /// LEMON style iterator class for enumerating the arcs of a path.
       class ArcIt {
       public:
@@ -243,8 +247,8 @@
         /// Invalid constructor
         ArcIt(Invalid) {}
-        /// Constructor for first arc
+        /// Sets the iterator to the first arc of the given path
         ArcIt(const PathDumper&) {}
 
-        /// Conversion to Arc
+        /// Conversion to \c Arc
         operator Arc() const { return INVALID; }
 
@@ -261,8 +265,9 @@
       };
 
-      /// \brief LEMON style iterator for path arcs
+      /// \brief LEMON style iterator for enumerating the arcs of a path
+      /// in reverse direction.
       ///
-      /// This class is used to iterate on the arcs of the paths in
-      /// reverse direction.
+      /// LEMON style iterator class for enumerating the arcs of a path
+      /// in reverse direction.
       class RevArcIt {
       public:
@@ -271,8 +276,8 @@
         /// Invalid constructor
         RevArcIt(Invalid) {}
-        /// Constructor for first arc
+        /// Sets the iterator to the last arc of the given path
         RevArcIt(const PathDumper &) {}
 
-        /// Conversion to Arc
+        /// Conversion to \c Arc
         operator Arc() const { return INVALID; }
 
Index: lemon/config.h.cmake
===================================================================
--- lemon/config.h.cmake	(revision 517)
+++ lemon/config.h.cmake	(revision 678)
@@ -1,4 +1,8 @@
-#cmakedefine HAVE_LONG_LONG 1
-#cmakedefine HAVE_LP 1
-#cmakedefine HAVE_MIP 1
-#cmakedefine HAVE_GLPK 1
+#define LEMON_VERSION "@PROJECT_VERSION@"
+#cmakedefine LEMON_HAVE_LONG_LONG 1
+#cmakedefine LEMON_HAVE_LP 1
+#cmakedefine LEMON_HAVE_MIP 1
+#cmakedefine LEMON_HAVE_GLPK 1
+#cmakedefine LEMON_HAVE_CPLEX 1
+#cmakedefine LEMON_HAVE_CLP 1
+#cmakedefine LEMON_HAVE_CBC 1
Index: lemon/config.h.in
===================================================================
--- lemon/config.h.in	(revision 517)
+++ lemon/config.h.in	(revision 678)
@@ -1,20 +1,26 @@
+/* The version string */
+#undef LEMON_VERSION
+
 /* Define to 1 if you have long long */
-#undef HAVE_LONG_LONG
+#undef LEMON_HAVE_LONG_LONG
 
 /* Define to 1 if you have any LP solver. */
-#undef HAVE_LP
+#undef LEMON_HAVE_LP
 
 /* Define to 1 if you have any MIP solver. */
-#undef HAVE_MIP
+#undef LEMON_HAVE_MIP
 
 /* Define to 1 if you have CPLEX. */
-#undef HAVE_CPLEX
+#undef LEMON_HAVE_CPLEX
 
 /* Define to 1 if you have GLPK. */
-#undef HAVE_GLPK
+#undef LEMON_HAVE_GLPK
 
 /* Define to 1 if you have SOPLEX */
-#undef HAVE_SOPLEX
+#undef LEMON_HAVE_SOPLEX
 
 /* Define to 1 if you have CLP */
-#undef HAVE_CLP
+#undef LEMON_HAVE_CLP
+
+/* Define to 1 if you have CBC */
+#undef LEMON_HAVE_CBC
Index: lemon/connectivity.h
===================================================================
--- lemon/connectivity.h	(revision 559)
+++ lemon/connectivity.h	(revision 988)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -33,5 +33,5 @@
 #include <functional>
 
-/// \ingroup connectivity
+/// \ingroup graph_properties
 /// \file
 /// \brief Connectivity algorithms
@@ -41,12 +41,16 @@
 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 \c true when there is path between any two nodes in the graph.
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether an undirected graph is connected.
+  ///
+  /// This function checks whether the given undirected graph is connected,
+  /// i.e. there is a path between any two nodes in the graph.
+  ///
+  /// \return \c true if the graph is connected.
   /// \note By definition, the empty graph is connected.
+  ///
+  /// \see countConnectedComponents(), connectedComponents()
+  /// \see stronglyConnected()
   template <typename Graph>
   bool connected(const Graph& graph) {
@@ -64,14 +68,20 @@
   }
 
-  /// \ingroup connectivity
+  /// \ingroup graph_properties
   ///
   /// \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
+  /// This function counts the number of connected components of the given
+  /// undirected graph.
+  ///
+  /// The connected components are the classes of an equivalence relation
+  /// on the nodes of an undirected graph. Two nodes are in the same class
+  /// if they are connected with a path.
+  ///
+  /// \return The number of connected components.
   /// \note By definition, the empty graph consists
   /// of zero connected components.
+  ///
+  /// \see connected(), connectedComponents()
   template <typename Graph>
   int countConnectedComponents(const Graph &graph) {
@@ -106,17 +116,28 @@
   }
 
-  /// \ingroup connectivity
+  /// \ingroup graph_properties
   ///
   /// \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.
+  /// This function finds the connected components of the given undirected
+  /// graph.
+  ///
+  /// The connected components are the classes of an equivalence relation
+  /// on the nodes of an undirected graph. Two nodes are in the same class
+  /// if they are connected with a path.
+  ///
+  /// \image html connected_components.png
+  /// \image latex connected_components.eps "Connected components" width=\textwidth
+  ///
+  /// \param graph The undirected graph.
   /// \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
+  /// the number of the connected components minus one. Each value of the map
+  /// will be set exactly once, and the values of a certain component will be
   /// set continuously.
-  /// \return The number of components
-  ///
+  /// \return The number of connected components.
+  /// \note By definition, the empty graph consists
+  /// of zero connected components.
+  ///
+  /// \see connected(), countConnectedComponents()
   template <class Graph, class NodeMap>
   int connectedComponents(const Graph &graph, NodeMap &compMap) {
@@ -228,15 +249,17 @@
 
 
-  /// \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
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether a directed graph is strongly connected.
+  ///
+  /// This function checks whether the given directed graph is strongly
+  /// connected, i.e. any two nodes of the digraph are
   /// connected with directed paths in both direction.
-  /// \return \c false when the graph is not strongly connected.
-  /// \see connected
-  ///
-  /// \note By definition, the empty graph is strongly connected.
+  ///
+  /// \return \c true if the digraph is strongly connected.
+  /// \note By definition, the empty digraph is strongly connected.
+  ///
+  /// \see countStronglyConnectedComponents(), stronglyConnectedComponents()
+  /// \see connected()
   template <typename Digraph>
   bool stronglyConnected(const Digraph& digraph) {
@@ -269,5 +292,5 @@
     RDigraph rdigraph(digraph);
 
-    typedef DfsVisitor<Digraph> RVisitor;
+    typedef DfsVisitor<RDigraph> RVisitor;
     RVisitor rvisitor;
 
@@ -286,18 +309,22 @@
   }
 
-  /// \ingroup connectivity
-  ///
-  /// \brief Count the strongly connected components of a directed graph
-  ///
-  /// Count the strongly connected components of a directed graph.
+  /// \ingroup graph_properties
+  ///
+  /// \brief Count the number of strongly connected components of a
+  /// directed graph
+  ///
+  /// This function counts the number of strongly connected components of
+  /// the given directed graph.
+  ///
   /// The strongly connected components are the classes of an
-  /// equivalence relation on the nodes of the graph. Two nodes are in
+  /// equivalence relation on the nodes of a digraph. 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
+  /// \return The number of strongly connected components.
+  /// \note By definition, the empty digraph has zero
   /// strongly connected components.
+  ///
+  /// \see stronglyConnected(), stronglyConnectedComponents()
   template <typename Digraph>
   int countStronglyConnectedComponents(const Digraph& digraph) {
@@ -350,23 +377,31 @@
   }
 
-  /// \ingroup connectivity
+  /// \ingroup graph_properties
   ///
   /// \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.
+  /// This function finds the strongly connected components of the given
+  /// directed graph. In addition, the numbering of the components will
+  /// satisfy that there is no arc going from a higher numbered component
+  /// to a lower one (i.e. it provides a topological order of the components).
+  ///
+  /// The strongly connected components are the classes of an
+  /// equivalence relation on the nodes of a digraph. Two nodes are in
+  /// the same class if they are connected with directed paths in both
+  /// direction.
+  ///
+  /// \image html strongly_connected_components.png
+  /// \image latex strongly_connected_components.eps "Strongly connected components" width=\textwidth
   ///
   /// \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
-  ///
+  /// of the map will be set exactly once, and the values of a certain
+  /// component will be set continuously.
+  /// \return The number of strongly connected components.
+  /// \note By definition, the empty digraph has zero
+  /// strongly connected components.
+  ///
+  /// \see stronglyConnected(), countStronglyConnectedComponents()
   template <typename Digraph, typename NodeMap>
   int stronglyConnectedComponents(const Digraph& digraph, NodeMap& compMap) {
@@ -417,21 +452,26 @@
   }
 
-  /// \ingroup connectivity
+  /// \ingroup graph_properties
   ///
   /// \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.
+  /// This function finds the cut arcs of the strongly connected components
+  /// of the given digraph.
+  ///
+  /// The strongly connected components are the classes of an
+  /// equivalence relation on the nodes of a digraph. Two nodes are in
+  /// the same class if they are connected with directed paths 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
+  /// \param digraph The digraph.
+  /// \retval cutMap A writable arc map. The values will be set to \c true
+  /// for the cut arcs (exactly once for each cut arc), and will not be
+  /// changed for other arcs.
+  /// \return The number of cut arcs.
+  ///
+  /// \see stronglyConnected(), stronglyConnectedComponents()
   template <typename Digraph, typename ArcMap>
-  int stronglyConnectedCutArcs(const Digraph& graph, ArcMap& cutMap) {
+  int stronglyConnectedCutArcs(const Digraph& digraph, ArcMap& cutMap) {
     checkConcept<concepts::Digraph, Digraph>();
     typedef typename Digraph::Node Node;
@@ -445,11 +485,11 @@
     typedef typename Container::iterator Iterator;
 
-    Container nodes(countNodes(graph));
+    Container nodes(countNodes(digraph));
     typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
     Visitor visitor(nodes.begin());
 
-    DfsVisit<Digraph, Visitor> dfs(graph, visitor);
+    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
     dfs.init();
-    for (NodeIt it(graph); it != INVALID; ++it) {
+    for (NodeIt it(digraph); it != INVALID; ++it) {
       if (!dfs.reached(it)) {
         dfs.addSource(it);
@@ -461,12 +501,12 @@
     typedef ReverseDigraph<const Digraph> RDigraph;
 
-    RDigraph rgraph(graph);
+    RDigraph rdigraph(digraph);
 
     int cutNum = 0;
 
     typedef StronglyConnectedCutArcsVisitor<RDigraph, ArcMap> RVisitor;
-    RVisitor rvisitor(rgraph, cutMap, cutNum);
-
-    DfsVisit<RDigraph, RVisitor> rdfs(rgraph, rvisitor);
+    RVisitor rvisitor(rdigraph, cutMap, cutNum);
+
+    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
 
     rdfs.init();
@@ -701,30 +741,58 @@
   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 \c true when the graph bi-node-connected.
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether an undirected graph is bi-node-connected.
+  ///
+  /// This function checks whether the given undirected graph is
+  /// bi-node-connected, i.e. a connected graph without articulation
+  /// node.
+  ///
+  /// \return \c true if the graph bi-node-connected.
+  ///
+  /// \note By definition,
+  /// \li a graph consisting of zero or one node is bi-node-connected,
+  /// \li a graph consisting of two isolated nodes
+  /// is \e not bi-node-connected and
+  /// \li a graph consisting of two nodes connected by an edge
+  /// is bi-node-connected.
+  ///
+  /// \see countBiNodeConnectedComponents(), biNodeConnectedComponents()
   template <typename Graph>
   bool biNodeConnected(const Graph& graph) {
+    bool hasNonIsolated = false, hasIsolated = false;
+    for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
+      if (typename Graph::OutArcIt(graph, n) == INVALID) {
+        if (hasIsolated || hasNonIsolated) {
+          return false;
+        } else {
+          hasIsolated = true;
+        }
+      } else {
+        if (hasIsolated) {
+          return false;
+        } else {
+          hasNonIsolated = true;
+        }
+      }
+    }
     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.
+  /// \ingroup graph_properties
+  ///
+  /// \brief Count the number of bi-node-connected components of an
+  /// undirected graph.
+  ///
+  /// This function counts the number of bi-node-connected components of
+  /// the given undirected graph.
+  ///
+  /// The bi-node-connected components are the classes of an equivalence
+  /// relation on the edges of a undirected graph. Two edges are in the
+  /// same class if they are on same circle.
+  ///
+  /// \return The number of bi-node-connected components.
+  ///
+  /// \see biNodeConnected(), biNodeConnectedComponents()
   template <typename Graph>
   int countBiNodeConnectedComponents(const Graph& graph) {
@@ -751,20 +819,26 @@
   }
 
-  /// \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.
-  ///
+  /// \ingroup graph_properties
+  ///
+  /// \brief Find the bi-node-connected components of an undirected graph.
+  ///
+  /// This function finds the bi-node-connected components of the given
+  /// undirected graph.
+  ///
+  /// The bi-node-connected components are the classes of an equivalence
+  /// relation on the edges of a undirected graph. Two edges are in the
+  /// same class if they are on same circle.
+  ///
+  /// \image html node_biconnected_components.png
+  /// \image latex node_biconnected_components.eps "bi-node-connected components" width=\textwidth
+  ///
+  /// \param graph The undirected graph.
+  /// \retval compMap A writable edge map. The values will be set from 0
+  /// to the number of the bi-node-connected components minus one. Each
+  /// value of the map will be set exactly once, and the values of a
+  /// certain component will be set continuously.
+  /// \return The number of bi-node-connected components.
+  ///
+  /// \see biNodeConnected(), countBiNodeConnectedComponents()
   template <typename Graph, typename EdgeMap>
   int biNodeConnectedComponents(const Graph& graph,
@@ -794,18 +868,25 @@
   }
 
-  /// \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.
+  /// \ingroup graph_properties
+  ///
+  /// \brief Find the bi-node-connected cut nodes in an undirected graph.
+  ///
+  /// This function finds the bi-node-connected cut nodes in the given
+  /// undirected graph.
+  ///
+  /// The bi-node-connected components are the classes of an equivalence
+  /// relation on the edges of a undirected graph. Two edges are in the
+  /// same class if they are on same circle.
+  /// The bi-node-connected components are separted by the cut nodes of
+  /// the components.
+  ///
+  /// \param graph The undirected graph.
+  /// \retval cutMap A writable node map. The values will be set to
+  /// \c true for the nodes that separate two or more components
+  /// (exactly once for each cut node), and will not be changed for
+  /// other nodes.
   /// \return The number of the cut nodes.
+  ///
+  /// \see biNodeConnected(), biNodeConnectedComponents()
   template <typename Graph, typename NodeMap>
   int biNodeConnectedCutNodes(const Graph& graph, NodeMap& cutMap) {
@@ -1024,14 +1105,16 @@
   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.
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether an undirected graph is bi-edge-connected.
+  ///
+  /// This function checks whether the given undirected graph is
+  /// bi-edge-connected, i.e. any two nodes are connected with at least
+  /// two edge-disjoint paths.
+  ///
+  /// \return \c true if the graph is bi-edge-connected.
+  /// \note By definition, the empty graph is bi-edge-connected.
+  ///
+  /// \see countBiEdgeConnectedComponents(), biEdgeConnectedComponents()
   template <typename Graph>
   bool biEdgeConnected(const Graph& graph) {
@@ -1039,15 +1122,20 @@
   }
 
-  /// \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.
+  /// \ingroup graph_properties
+  ///
+  /// \brief Count the number of bi-edge-connected components of an
+  /// undirected graph.
+  ///
+  /// This function counts the number of bi-edge-connected components of
+  /// the given undirected graph.
+  ///
+  /// The bi-edge-connected components are the classes of an equivalence
+  /// relation on the nodes of an undirected graph. Two nodes are in the
+  /// same class if they are connected with at least two edge-disjoint
+  /// paths.
+  ///
+  /// \return The number of bi-edge-connected components.
+  ///
+  /// \see biEdgeConnected(), biEdgeConnectedComponents()
   template <typename Graph>
   int countBiEdgeConnectedComponents(const Graph& graph) {
@@ -1074,20 +1162,27 @@
   }
 
-  /// \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.
+  /// \ingroup graph_properties
+  ///
+  /// \brief Find the bi-edge-connected components of an undirected graph.
+  ///
+  /// This function finds the bi-edge-connected components of the given
+  /// undirected graph.
+  ///
+  /// The bi-edge-connected components are the classes of an equivalence
+  /// relation on the nodes of an undirected graph. Two nodes are in the
+  /// same class if they are connected with at least two edge-disjoint
+  /// paths.
+  ///
+  /// \image html edge_biconnected_components.png
+  /// \image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
+  ///
+  /// \param graph The undirected 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.
-  ///
+  /// the number of the bi-edge-connected components minus one. Each value
+  /// of the map will be set exactly once, and the values of a certain
+  /// component will be set continuously.
+  /// \return The number of bi-edge-connected components.
+  ///
+  /// \see biEdgeConnected(), countBiEdgeConnectedComponents()
   template <typename Graph, typename NodeMap>
   int biEdgeConnectedComponents(const Graph& graph, NodeMap& compMap) {
@@ -1116,19 +1211,25 @@
   }
 
-  /// \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.
+  /// \ingroup graph_properties
+  ///
+  /// \brief Find the bi-edge-connected cut edges in an undirected graph.
+  ///
+  /// This function finds the bi-edge-connected cut edges in the given
+  /// undirected graph.
+  ///
+  /// The bi-edge-connected components are the classes of an equivalence
+  /// relation on the nodes of an undirected graph. Two nodes are in the
+  /// same class if they are connected with at least two edge-disjoint
+  /// paths.
+  /// The bi-edge-connected components are separted by the cut edges of
+  /// the components.
+  ///
+  /// \param graph The undirected graph.
+  /// \retval cutMap A writable edge map. The values will be set to \c true
+  /// for the cut edges (exactly once for each cut edge), and will not be
+  /// changed for other edges.
   /// \return The number of cut edges.
+  ///
+  /// \see biEdgeConnected(), biEdgeConnectedComponents()
   template <typename Graph, typename EdgeMap>
   int biEdgeConnectedCutEdges(const Graph& graph, EdgeMap& cutMap) {
@@ -1180,23 +1281,16 @@
   }
 
-  /// \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;
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether a digraph is DAG.
+  ///
+  /// This function checks whether the given digraph is DAG, i.e.
+  /// \e Directed \e Acyclic \e Graph.
+  /// \return \c true if there is no directed cycle in the digraph.
+  /// \see acyclic()
+  template <typename Digraph>
+  bool dag(const Digraph& digraph) {
 
     checkConcept<concepts::Digraph, Digraph>();
-    checkConcept<concepts::WriteMap<typename Digraph::Node, int>, NodeMap>();
 
     typedef typename Digraph::Node Node;
@@ -1204,12 +1298,62 @@
     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 arc = dfs.nextArc();
+          Node target = digraph.target(arc);
+          if (dfs.reached(target) && !processed[target]) {
+            return false;
+          }
+          dfs.processNextArc();
+        }
+      }
+    }
+    return true;
+  }
+
+  /// \ingroup graph_properties
+  ///
+  /// \brief Sort the nodes of a DAG into topolgical order.
+  ///
+  /// This function sorts the nodes of the given acyclic digraph (DAG)
+  /// into topolgical order.
+  ///
+  /// \param digraph The digraph, which must be DAG.
+  /// \retval order A writable node map. The values will be set from 0 to
+  /// the number of the nodes in the digraph minus one. Each value of the
+  /// map will be set exactly once, and the values will be set descending
+  /// order.
+  ///
+  /// \see dag(), checkedTopologicalSort()
+  template <typename Digraph, typename NodeMap>
+  void topologicalSort(const Digraph& digraph, 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));
+      visitor(order, countNodes(digraph));
 
     DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
-      dfs(graph, visitor);
+      dfs(digraph, visitor);
 
     dfs.init();
-    for (NodeIt it(graph); it != INVALID; ++it) {
+    for (NodeIt it(digraph); it != INVALID; ++it) {
       if (!dfs.reached(it)) {
         dfs.addSource(it);
@@ -1219,20 +1363,20 @@
   }
 
-  /// \ingroup connectivity
+  /// \ingroup graph_properties
   ///
   /// \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 \c false when the graph is not DAG.
-  ///
-  /// \see topologicalSort
-  /// \see dag
+  /// This function sorts the nodes of the given acyclic digraph (DAG)
+  /// into topolgical order and also checks whether the given digraph
+  /// is DAG.
+  ///
+  /// \param digraph The digraph.
+  /// \retval order A readable and writable node map. The values will be
+  /// set from 0 to the number of the nodes in the digraph minus one.
+  /// Each value of the map will be set exactly once, and the values will
+  /// be set descending order.
+  /// \return \c false if the digraph is not DAG.
+  ///
+  /// \see dag(), topologicalSort()
   template <typename Digraph, typename NodeMap>
   bool checkedTopologicalSort(const Digraph& digraph, NodeMap& order) {
@@ -1274,54 +1418,11 @@
   }
 
-  /// \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 \c 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 \c true when there is no circle in the graph.
-  /// \see dag
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether an undirected graph is acyclic.
+  ///
+  /// This function checks whether the given undirected graph is acyclic.
+  /// \return \c true if there is no cycle in the graph.
+  /// \see dag()
   template <typename Graph>
   bool acyclic(const Graph& graph) {
@@ -1336,9 +1437,9 @@
         dfs.addSource(it);
         while (!dfs.emptyQueue()) {
-          Arc edge = dfs.nextArc();
-          Node source = graph.source(edge);
-          Node target = graph.target(edge);
+          Arc arc = dfs.nextArc();
+          Node source = graph.source(arc);
+          Node target = graph.target(arc);
           if (dfs.reached(target) &&
-              dfs.predArc(source) != graph.oppositeArc(edge)) {
+              dfs.predArc(source) != graph.oppositeArc(arc)) {
             return false;
           }
@@ -1350,11 +1451,11 @@
   }
 
-  /// \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 \c true when the graph is acyclic and connected.
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether an undirected graph is tree.
+  ///
+  /// This function checks whether the given undirected graph is tree.
+  /// \return \c true if the graph is acyclic and connected.
+  /// \see acyclic(), connected()
   template <typename Graph>
   bool tree(const Graph& graph) {
@@ -1363,13 +1464,14 @@
     typedef typename Graph::NodeIt NodeIt;
     typedef typename Graph::Arc Arc;
+    if (NodeIt(graph) == INVALID) return true;
     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);
+      Arc arc = dfs.nextArc();
+      Node source = graph.source(arc);
+      Node target = graph.target(arc);
       if (dfs.reached(target) &&
-          dfs.predArc(source) != graph.oppositeArc(edge)) {
+          dfs.predArc(source) != graph.oppositeArc(arc)) {
         return false;
       }
@@ -1442,15 +1544,14 @@
   }
 
-  /// \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 \c true if \c graph is bipartite, \c false otherwise.
-  /// \sa bipartitePartitions
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether an undirected graph is bipartite.
+  ///
+  /// The function checks whether the given undirected graph is bipartite.
+  /// \return \c true if the graph is bipartite.
+  ///
+  /// \see bipartitePartitions()
   template<typename Graph>
-  inline bool bipartite(const Graph &graph){
+  bool bipartite(const Graph &graph){
     using namespace _connectivity_bits;
 
@@ -1479,21 +1580,27 @@
   }
 
-  /// \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.
+  /// \ingroup graph_properties
+  ///
+  /// \brief Find the bipartite partitions of an undirected graph.
+  ///
+  /// This function checks whether the given undirected graph is bipartite
+  /// and gives back the bipartite partitions.
+  ///
+  /// \image html bipartite_partitions.png
+  /// \image latex bipartite_partitions.eps "Bipartite partititions" width=\textwidth
+  ///
   /// \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 \c true if \c graph is bipartite, \c false otherwise.
+  /// \retval partMap A writable node map of \c bool (or convertible) value
+  /// type. The values will be set to \c true for one component and
+  /// \c false for the other one.
+  /// \return \c true if the graph is bipartite, \c false otherwise.
+  ///
+  /// \see bipartite()
   template<typename Graph, typename NodeMap>
-  inline bool bipartitePartitions(const Graph &graph, NodeMap &partMap){
+  bool bipartitePartitions(const Graph &graph, NodeMap &partMap){
     using namespace _connectivity_bits;
 
     checkConcept<concepts::Graph, Graph>();
+    checkConcept<concepts::WriteMap<typename Graph::Node, bool>, NodeMap>();
 
     typedef typename Graph::Node Node;
@@ -1520,51 +1627,57 @@
   }
 
-  /// \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;
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether the given graph contains no loop arcs/edges.
+  ///
+  /// This function returns \c true if there are no loop arcs/edges in
+  /// the given graph. It works for both directed and undirected graphs.
+  template <typename Graph>
+  bool loopFree(const Graph& graph) {
+    for (typename Graph::ArcIt it(graph); it != INVALID; ++it) {
+      if (graph.source(it) == graph.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);
-      }
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether the given graph contains no parallel arcs/edges.
+  ///
+  /// This function returns \c true if there are no parallel arcs/edges in
+  /// the given graph. It works for both directed and undirected graphs.
+  template <typename Graph>
+  bool parallelFree(const Graph& graph) {
+    typename Graph::template NodeMap<int> reached(graph, 0);
+    int cnt = 1;
+    for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
+      for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) {
+        if (reached[graph.target(a)] == cnt) return false;
+        reached[graph.target(a)] = cnt;
+      }
+      ++cnt;
     }
     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);
+  /// \ingroup graph_properties
+  ///
+  /// \brief Check whether the given graph is simple.
+  ///
+  /// This function returns \c true if the given graph is simple, i.e.
+  /// it contains no loop arcs/edges and no parallel arcs/edges.
+  /// The function works for both directed and undirected graphs.
+  /// \see loopFree(), parallelFree()
+  template <typename Graph>
+  bool simpleGraph(const Graph& graph) {
+    typename Graph::template NodeMap<int> reached(graph, 0);
+    int cnt = 1;
+    for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
+      reached[n] = cnt;
+      for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) {
+        if (reached[graph.target(a)] == cnt) return false;
+        reached[graph.target(a)] = cnt;
+      }
+      ++cnt;
     }
     return true;
Index: lemon/core.h
===================================================================
--- lemon/core.h	(revision 559)
+++ lemon/core.h	(revision 985)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -23,8 +23,29 @@
 #include <algorithm>
 
-#include <lemon/core.h>
+#include <lemon/config.h>
 #include <lemon/bits/enable_if.h>
 #include <lemon/bits/traits.h>
 #include <lemon/assert.h>
+
+// Disable the following warnings when compiling with MSVC:
+// C4250: 'class1' : inherits 'class2::member' via dominance
+// C4355: 'this' : used in base member initializer list
+// C4503: 'function' : decorated name length exceeded, name was truncated
+// C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning)
+// C4996: 'function': was declared deprecated
+#ifdef _MSC_VER
+#pragma warning( disable : 4250 4355 4503 4800 4996 )
+#endif
+
+#ifdef __GNUC__
+#define GCC_VERSION (__GNUC__ * 10000                   \
+                     + __GNUC_MINOR__ * 100             \
+                     + __GNUC_PATCHLEVEL__)
+#endif
+
+#if GCC_VERSION >= 40800
+// Needed by the [DI]GRAPH_TYPEDEFS marcos for gcc 4.8
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#endif
 
 ///\file
@@ -385,4 +406,5 @@
       static void copy(const From& from, Digraph &to,
                        NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) {
+        to.clear();
         for (typename From::NodeIt it(from); it != INVALID; ++it) {
           nodeRefMap[it] = to.addNode();
@@ -412,4 +434,5 @@
       static void copy(const From& from, Graph &to,
                        NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) {
+        to.clear();
         for (typename From::NodeIt it(from); it != INVALID; ++it) {
           nodeRefMap[it] = to.addNode();
@@ -1037,11 +1060,10 @@
   template <typename GR>
   class ConArcIt : public GR::Arc {
+    typedef typename GR::Arc Parent;
+
   public:
 
-    typedef GR Graph;
-    typedef typename Graph::Arc Parent;
-
-    typedef typename Graph::Arc Arc;
-    typedef typename Graph::Node Node;
+    typedef typename GR::Arc Arc;
+    typedef typename GR::Node Node;
 
     /// \brief Constructor.
@@ -1049,5 +1071,5 @@
     /// Construct a new ConArcIt iterating on the arcs that
     /// connects nodes \c u and \c v.
-    ConArcIt(const Graph& g, Node u, Node v) : _graph(g) {
+    ConArcIt(const GR& g, Node u, Node v) : _graph(g) {
       Parent::operator=(findArc(_graph, u, v));
     }
@@ -1056,5 +1078,5 @@
     ///
     /// Construct a new ConArcIt that continues the iterating from arc \c a.
-    ConArcIt(const Graph& g, Arc a) : Parent(a), _graph(g) {}
+    ConArcIt(const GR& g, Arc a) : Parent(a), _graph(g) {}
 
     /// \brief Increment operator.
@@ -1067,5 +1089,5 @@
     }
   private:
-    const Graph& _graph;
+    const GR& _graph;
   };
 
@@ -1160,11 +1182,10 @@
   template <typename GR>
   class ConEdgeIt : public GR::Edge {
+    typedef typename GR::Edge Parent;
+
   public:
 
-    typedef GR Graph;
-    typedef typename Graph::Edge Parent;
-
-    typedef typename Graph::Edge Edge;
-    typedef typename Graph::Node Node;
+    typedef typename GR::Edge Edge;
+    typedef typename GR::Node Node;
 
     /// \brief Constructor.
@@ -1172,5 +1193,5 @@
     /// Construct a new ConEdgeIt iterating on the edges that
     /// connects nodes \c u and \c v.
-    ConEdgeIt(const Graph& g, Node u, Node v) : _graph(g), _u(u), _v(v) {
+    ConEdgeIt(const GR& g, Node u, Node v) : _graph(g), _u(u), _v(v) {
       Parent::operator=(findEdge(_graph, _u, _v));
     }
@@ -1179,5 +1200,5 @@
     ///
     /// Construct a new ConEdgeIt that continues iterating from edge \c e.
-    ConEdgeIt(const Graph& g, Edge e) : Parent(e), _graph(g) {}
+    ConEdgeIt(const GR& g, Edge e) : Parent(e), _graph(g) {}
 
     /// \brief Increment operator.
@@ -1189,5 +1210,5 @@
     }
   private:
-    const Graph& _graph;
+    const GR& _graph;
     Node _u, _v;
   };
@@ -1220,17 +1241,21 @@
     : protected ItemSetTraits<GR, typename GR::Arc>::ItemNotifier::ObserverBase
   {
-  public:
     typedef typename ItemSetTraits<GR, typename GR::Arc>
     ::ItemNotifier::ObserverBase Parent;
 
     TEMPLATE_DIGRAPH_TYPEDEFS(GR);
+
+  public:
+
+    /// The Digraph type
     typedef GR Digraph;
 
   protected:
 
-    class AutoNodeMap : public ItemSetTraits<GR, Node>::template Map<Arc>::Type {
+    class AutoNodeMap : public ItemSetTraits<GR, Node>::template Map<Arc>::Type
+    {
+      typedef typename ItemSetTraits<GR, Node>::template Map<Arc>::Type Parent;
+
     public:
-
-      typedef typename ItemSetTraits<GR, Node>::template Map<Arc>::Type Parent;
 
       AutoNodeMap(const GR& digraph) : Parent(digraph, INVALID) {}
@@ -1257,10 +1282,4 @@
       }
     };
-
-    const Digraph &_g;
-    AutoNodeMap _head;
-    typename Digraph::template ArcMap<Arc> _parent;
-    typename Digraph::template ArcMap<Arc> _left;
-    typename Digraph::template ArcMap<Arc> _right;
 
     class ArcLess {
@@ -1274,4 +1293,12 @@
     };
 
+  protected:
+
+    const Digraph &_g;
+    AutoNodeMap _head;
+    typename Digraph::template ArcMap<Arc> _parent;
+    typename Digraph::template ArcMap<Arc> _left;
+    typename Digraph::template ArcMap<Arc> _right;
+
   public:
 
@@ -1316,5 +1343,5 @@
     virtual void clear() {
       for(NodeIt n(_g);n!=INVALID;++n) {
-        _head.set(n, INVALID);
+        _head[n] = INVALID;
       }
     }
@@ -1323,11 +1350,11 @@
       Node s = _g.source(arc);
       Node t = _g.target(arc);
-      _left.set(arc, INVALID);
-      _right.set(arc, INVALID);
+      _left[arc] = INVALID;
+      _right[arc] = INVALID;
 
       Arc e = _head[s];
       if (e == INVALID) {
-        _head.set(s, arc);
-        _parent.set(arc, INVALID);
+        _head[s] = arc;
+        _parent[arc] = INVALID;
         return;
       }
@@ -1335,6 +1362,6 @@
         if (t < _g.target(e)) {
           if (_left[e] == INVALID) {
-            _left.set(e, arc);
-            _parent.set(arc, e);
+            _left[e] = arc;
+            _parent[arc] = e;
             splay(arc);
             return;
@@ -1344,6 +1371,6 @@
         } else {
           if (_right[e] == INVALID) {
-            _right.set(e, arc);
-            _parent.set(arc, e);
+            _right[e] = arc;
+            _parent[arc] = e;
             splay(arc);
             return;
@@ -1358,25 +1385,25 @@
       if (_left[arc] == INVALID) {
         if (_right[arc] != INVALID) {
-          _parent.set(_right[arc], _parent[arc]);
+          _parent[_right[arc]] = _parent[arc];
         }
         if (_parent[arc] != INVALID) {
           if (_left[_parent[arc]] == arc) {
-            _left.set(_parent[arc], _right[arc]);
+            _left[_parent[arc]] = _right[arc];
           } else {
-            _right.set(_parent[arc], _right[arc]);
+            _right[_parent[arc]] = _right[arc];
           }
         } else {
-          _head.set(_g.source(arc), _right[arc]);
+          _head[_g.source(arc)] = _right[arc];
         }
       } else if (_right[arc] == INVALID) {
-        _parent.set(_left[arc], _parent[arc]);
+        _parent[_left[arc]] = _parent[arc];
         if (_parent[arc] != INVALID) {
           if (_left[_parent[arc]] == arc) {
-            _left.set(_parent[arc], _left[arc]);
+            _left[_parent[arc]] = _left[arc];
           } else {
-            _right.set(_parent[arc], _left[arc]);
+            _right[_parent[arc]] = _left[arc];
           }
         } else {
-          _head.set(_g.source(arc), _left[arc]);
+          _head[_g.source(arc)] = _left[arc];
         }
       } else {
@@ -1388,36 +1415,36 @@
           }
           Arc s = _parent[e];
-          _right.set(_parent[e], _left[e]);
+          _right[_parent[e]] = _left[e];
           if (_left[e] != INVALID) {
-            _parent.set(_left[e], _parent[e]);
+            _parent[_left[e]] = _parent[e];
           }
 
-          _left.set(e, _left[arc]);
-          _parent.set(_left[arc], e);
-          _right.set(e, _right[arc]);
-          _parent.set(_right[arc], e);
-
-          _parent.set(e, _parent[arc]);
+          _left[e] = _left[arc];
+          _parent[_left[arc]] = e;
+          _right[e] = _right[arc];
+          _parent[_right[arc]] = e;
+
+          _parent[e] = _parent[arc];
           if (_parent[arc] != INVALID) {
             if (_left[_parent[arc]] == arc) {
-              _left.set(_parent[arc], e);
+              _left[_parent[arc]] = e;
             } else {
-              _right.set(_parent[arc], e);
+              _right[_parent[arc]] = e;
             }
           }
           splay(s);
         } else {
-          _right.set(e, _right[arc]);
-          _parent.set(_right[arc], e);
-          _parent.set(e, _parent[arc]);
+          _right[e] = _right[arc];
+          _parent[_right[arc]] = e;
+          _parent[e] = _parent[arc];
 
           if (_parent[arc] != INVALID) {
             if (_left[_parent[arc]] == arc) {
-              _left.set(_parent[arc], e);
+              _left[_parent[arc]] = e;
             } else {
-              _right.set(_parent[arc], e);
+              _right[_parent[arc]] = e;
             }
           } else {
-            _head.set(_g.source(arc), e);
+            _head[_g.source(arc)] = e;
           }
         }
@@ -1431,15 +1458,15 @@
       if (a < m) {
         Arc left = refreshRec(v,a,m-1);
-        _left.set(me, left);
-        _parent.set(left, me);
+        _left[me] = left;
+        _parent[left] = me;
       } else {
-        _left.set(me, INVALID);
+        _left[me] = INVALID;
       }
       if (m < b) {
         Arc right = refreshRec(v,m+1,b);
-        _right.set(me, right);
-        _parent.set(right, me);
+        _right[me] = right;
+        _parent[right] = me;
       } else {
-        _right.set(me, INVALID);
+        _right[me] = INVALID;
       }
       return me;
@@ -1453,8 +1480,8 @@
           std::sort(v.begin(),v.end(),ArcLess(_g));
           Arc head = refreshRec(v,0,v.size()-1);
-          _head.set(n, head);
-          _parent.set(head, INVALID);
-        }
-        else _head.set(n, INVALID);
+          _head[n] = head;
+          _parent[head] = INVALID;
+        }
+        else _head[n] = INVALID;
       }
     }
@@ -1462,17 +1489,17 @@
     void zig(Arc v) {
       Arc w = _parent[v];
-      _parent.set(v, _parent[w]);
-      _parent.set(w, v);
-      _left.set(w, _right[v]);
-      _right.set(v, w);
+      _parent[v] = _parent[w];
+      _parent[w] = v;
+      _left[w] = _right[v];
+      _right[v] = w;
       if (_parent[v] != INVALID) {
         if (_right[_parent[v]] == w) {
-          _right.set(_parent[v], v);
+          _right[_parent[v]] = v;
         } else {
-          _left.set(_parent[v], v);
+          _left[_parent[v]] = v;
         }
       }
       if (_left[w] != INVALID){
-        _parent.set(_left[w], w);
+        _parent[_left[w]] = w;
       }
     }
@@ -1480,17 +1507,17 @@
     void zag(Arc v) {
       Arc w = _parent[v];
-      _parent.set(v, _parent[w]);
-      _parent.set(w, v);
-      _right.set(w, _left[v]);
-      _left.set(v, w);
+      _parent[v] = _parent[w];
+      _parent[w] = v;
+      _right[w] = _left[v];
+      _left[v] = w;
       if (_parent[v] != INVALID){
         if (_left[_parent[v]] == w) {
-          _left.set(_parent[v], v);
+          _left[_parent[v]] = v;
         } else {
-          _right.set(_parent[v], v);
+          _right[_parent[v]] = v;
         }
       }
       if (_right[w] != INVALID){
-        _parent.set(_right[w], w);
+        _parent[_right[w]] = w;
       }
     }
@@ -1631,6 +1658,9 @@
   class ArcLookUp
   {
+    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
+
   public:
-    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
+
+    /// The Digraph type
     typedef GR Digraph;
 
@@ -1747,7 +1777,6 @@
 
     TEMPLATE_DIGRAPH_TYPEDEFS(GR);
-    typedef GR Digraph;
-
-    typename Digraph::template ArcMap<Arc> _next;
+
+    typename GR::template ArcMap<Arc> _next;
 
     Arc refreshNext(Arc head,Arc next=INVALID)
@@ -1768,4 +1797,8 @@
 
   public:
+
+    /// The Digraph type
+    typedef GR Digraph;
+
     ///Constructor
 
@@ -1828,19 +1861,30 @@
     ///a single node \c n, then \ref refresh(Node) "refresh(n)" is enough.
     ///
-#ifdef DOXYGEN
-    Arc operator()(Node s, Node t, Arc prev=INVALID) const {}
-#else
-    using ArcLookUp<GR>::operator() ;
-    Arc operator()(Node s, Node t, Arc prev) const
+    Arc operator()(Node s, Node t, Arc prev=INVALID) const
     {
-      return prev==INVALID?(*this)(s,t):_next[prev];
-    }
+      if(prev==INVALID)
+        {
+          Arc f=INVALID;
+          Arc e;
+          for(e=_head[s];
+              e!=INVALID&&_g.target(e)!=t;
+              e = t < _g.target(e)?_left[e]:_right[e]) ;
+          while(e!=INVALID)
+            if(_g.target(e)==t)
+              {
+                f = e;
+                e = _left[e];
+              }
+            else e = _right[e];
+          return f;
+        }
+      else return _next[prev];
+    }
+
+  };
+
+  /// @}
+
+} //namespace lemon
+
 #endif
-
-  };
-
-  /// @}
-
-} //namespace lemon
-
-#endif
Index: lemon/cost_scaling.h
===================================================================
--- lemon/cost_scaling.h	(revision 927)
+++ lemon/cost_scaling.h	(revision 927)
@@ -0,0 +1,1316 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2011
+ * 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_COST_SCALING_H
+#define LEMON_COST_SCALING_H
+
+/// \ingroup min_cost_flow_algs
+/// \file
+/// \brief Cost scaling algorithm for finding a minimum cost flow.
+
+#include <vector>
+#include <deque>
+#include <limits>
+
+#include <lemon/core.h>
+#include <lemon/maps.h>
+#include <lemon/math.h>
+#include <lemon/static_graph.h>
+#include <lemon/circulation.h>
+#include <lemon/bellman_ford.h>
+
+namespace lemon {
+
+  /// \brief Default traits class of CostScaling algorithm.
+  ///
+  /// Default traits class of CostScaling algorithm.
+  /// \tparam GR Digraph type.
+  /// \tparam V The number type used for flow amounts, capacity bounds
+  /// and supply values. By default it is \c int.
+  /// \tparam C The number type used for costs and potentials.
+  /// By default it is the same as \c V.
+#ifdef DOXYGEN
+  template <typename GR, typename V = int, typename C = V>
+#else
+  template < typename GR, typename V = int, typename C = V,
+             bool integer = std::numeric_limits<C>::is_integer >
+#endif
+  struct CostScalingDefaultTraits
+  {
+    /// The type of the digraph
+    typedef GR Digraph;
+    /// The type of the flow amounts, capacity bounds and supply values
+    typedef V Value;
+    /// The type of the arc costs
+    typedef C Cost;
+
+    /// \brief The large cost type used for internal computations
+    ///
+    /// The large cost type used for internal computations.
+    /// It is \c long \c long if the \c Cost type is integer,
+    /// otherwise it is \c double.
+    /// \c Cost must be convertible to \c LargeCost.
+    typedef double LargeCost;
+  };
+
+  // Default traits class for integer cost types
+  template <typename GR, typename V, typename C>
+  struct CostScalingDefaultTraits<GR, V, C, true>
+  {
+    typedef GR Digraph;
+    typedef V Value;
+    typedef C Cost;
+#ifdef LEMON_HAVE_LONG_LONG
+    typedef long long LargeCost;
+#else
+    typedef long LargeCost;
+#endif
+  };
+
+
+  /// \addtogroup min_cost_flow_algs
+  /// @{
+
+  /// \brief Implementation of the Cost Scaling algorithm for
+  /// finding a \ref min_cost_flow "minimum cost flow".
+  ///
+  /// \ref CostScaling implements a cost scaling algorithm that performs
+  /// push/augment and relabel operations for finding a \ref min_cost_flow
+  /// "minimum cost flow" \ref amo93networkflows, \ref goldberg90approximation,
+  /// \ref goldberg97efficient, \ref bunnagel98efficient.
+  /// It is a highly efficient primal-dual solution method, which
+  /// can be viewed as the generalization of the \ref Preflow
+  /// "preflow push-relabel" algorithm for the maximum flow problem.
+  ///
+  /// Most of the parameters of the problem (except for the digraph)
+  /// can be given using separate functions, and the algorithm can be
+  /// executed using the \ref run() function. If some parameters are not
+  /// specified, then default values will be used.
+  ///
+  /// \tparam GR The digraph type the algorithm runs on.
+  /// \tparam V The number type used for flow amounts, capacity bounds
+  /// and supply values in the algorithm. By default, it is \c int.
+  /// \tparam C The number type used for costs and potentials in the
+  /// algorithm. By default, it is the same as \c V.
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm. By default, it is \ref CostScalingDefaultTraits
+  /// "CostScalingDefaultTraits<GR, V, C>".
+  /// In most cases, this parameter should not be set directly,
+  /// consider to use the named template parameters instead.
+  ///
+  /// \warning Both number types must be signed and all input data must
+  /// be integer.
+  /// \warning This algorithm does not support negative costs for such
+  /// arcs that have infinite upper bound.
+  ///
+  /// \note %CostScaling provides three different internal methods,
+  /// from which the most efficient one is used by default.
+  /// For more information, see \ref Method.
+#ifdef DOXYGEN
+  template <typename GR, typename V, typename C, typename TR>
+#else
+  template < typename GR, typename V = int, typename C = V,
+             typename TR = CostScalingDefaultTraits<GR, V, C> >
+#endif
+  class CostScaling
+  {
+  public:
+
+    /// The type of the digraph
+    typedef typename TR::Digraph Digraph;
+    /// The type of the flow amounts, capacity bounds and supply values
+    typedef typename TR::Value Value;
+    /// The type of the arc costs
+    typedef typename TR::Cost Cost;
+
+    /// \brief The large cost type
+    ///
+    /// The large cost type used for internal computations.
+    /// By default, it is \c long \c long if the \c Cost type is integer,
+    /// otherwise it is \c double.
+    typedef typename TR::LargeCost LargeCost;
+
+    /// The \ref CostScalingDefaultTraits "traits class" of the algorithm
+    typedef TR Traits;
+
+  public:
+
+    /// \brief Problem type constants for the \c run() function.
+    ///
+    /// Enum type containing the problem type constants that can be
+    /// returned by the \ref run() function of the algorithm.
+    enum ProblemType {
+      /// The problem has no feasible solution (flow).
+      INFEASIBLE,
+      /// The problem has optimal solution (i.e. it is feasible and
+      /// bounded), and the algorithm has found optimal flow and node
+      /// potentials (primal and dual solutions).
+      OPTIMAL,
+      /// The digraph contains an arc of negative cost and infinite
+      /// upper bound. It means that the objective function is unbounded
+      /// on that arc, however, note that it could actually be bounded
+      /// over the feasible flows, but this algroithm cannot handle
+      /// these cases.
+      UNBOUNDED
+    };
+
+    /// \brief Constants for selecting the internal method.
+    ///
+    /// Enum type containing constants for selecting the internal method
+    /// for the \ref run() function.
+    ///
+    /// \ref CostScaling provides three internal methods that differ mainly
+    /// in their base operations, which are used in conjunction with the
+    /// relabel operation.
+    /// By default, the so called \ref PARTIAL_AUGMENT
+    /// "Partial Augment-Relabel" method is used, which proved to be
+    /// the most efficient and the most robust on various test inputs.
+    /// However, the other methods can be selected using the \ref run()
+    /// function with the proper parameter.
+    enum Method {
+      /// Local push operations are used, i.e. flow is moved only on one
+      /// admissible arc at once.
+      PUSH,
+      /// Augment operations are used, i.e. flow is moved on admissible
+      /// paths from a node with excess to a node with deficit.
+      AUGMENT,
+      /// Partial augment operations are used, i.e. flow is moved on
+      /// admissible paths started from a node with excess, but the
+      /// lengths of these paths are limited. This method can be viewed
+      /// as a combined version of the previous two operations.
+      PARTIAL_AUGMENT
+    };
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
+
+    typedef std::vector<int> IntVector;
+    typedef std::vector<Value> ValueVector;
+    typedef std::vector<Cost> CostVector;
+    typedef std::vector<LargeCost> LargeCostVector;
+    typedef std::vector<char> BoolVector;
+    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
+
+  private:
+
+    template <typename KT, typename VT>
+    class StaticVectorMap {
+    public:
+      typedef KT Key;
+      typedef VT Value;
+
+      StaticVectorMap(std::vector<Value>& v) : _v(v) {}
+
+      const Value& operator[](const Key& key) const {
+        return _v[StaticDigraph::id(key)];
+      }
+
+      Value& operator[](const Key& key) {
+        return _v[StaticDigraph::id(key)];
+      }
+
+      void set(const Key& key, const Value& val) {
+        _v[StaticDigraph::id(key)] = val;
+      }
+
+    private:
+      std::vector<Value>& _v;
+    };
+
+    typedef StaticVectorMap<StaticDigraph::Node, LargeCost> LargeCostNodeMap;
+    typedef StaticVectorMap<StaticDigraph::Arc, LargeCost> LargeCostArcMap;
+
+  private:
+
+    // Data related to the underlying digraph
+    const GR &_graph;
+    int _node_num;
+    int _arc_num;
+    int _res_node_num;
+    int _res_arc_num;
+    int _root;
+
+    // Parameters of the problem
+    bool _have_lower;
+    Value _sum_supply;
+    int _sup_node_num;
+
+    // Data structures for storing the digraph
+    IntNodeMap _node_id;
+    IntArcMap _arc_idf;
+    IntArcMap _arc_idb;
+    IntVector _first_out;
+    BoolVector _forward;
+    IntVector _source;
+    IntVector _target;
+    IntVector _reverse;
+
+    // Node and arc data
+    ValueVector _lower;
+    ValueVector _upper;
+    CostVector _scost;
+    ValueVector _supply;
+
+    ValueVector _res_cap;
+    LargeCostVector _cost;
+    LargeCostVector _pi;
+    ValueVector _excess;
+    IntVector _next_out;
+    std::deque<int> _active_nodes;
+
+    // Data for scaling
+    LargeCost _epsilon;
+    int _alpha;
+
+    IntVector _buckets;
+    IntVector _bucket_next;
+    IntVector _bucket_prev;
+    IntVector _rank;
+    int _max_rank;
+
+    // Data for a StaticDigraph structure
+    typedef std::pair<int, int> IntPair;
+    StaticDigraph _sgr;
+    std::vector<IntPair> _arc_vec;
+    std::vector<LargeCost> _cost_vec;
+    LargeCostArcMap _cost_map;
+    LargeCostNodeMap _pi_map;
+
+  public:
+
+    /// \brief Constant for infinite upper bounds (capacities).
+    ///
+    /// Constant for infinite upper bounds (capacities).
+    /// It is \c std::numeric_limits<Value>::infinity() if available,
+    /// \c std::numeric_limits<Value>::max() otherwise.
+    const Value INF;
+
+  public:
+
+    /// \name Named Template Parameters
+    /// @{
+
+    template <typename T>
+    struct SetLargeCostTraits : public Traits {
+      typedef T LargeCost;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c LargeCost type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
+    /// type, which is used for internal computations in the algorithm.
+    /// \c Cost must be convertible to \c LargeCost.
+    template <typename T>
+    struct SetLargeCost
+      : public CostScaling<GR, V, C, SetLargeCostTraits<T> > {
+      typedef  CostScaling<GR, V, C, SetLargeCostTraits<T> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    CostScaling() {}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// The constructor of the class.
+    ///
+    /// \param graph The digraph the algorithm runs on.
+    CostScaling(const GR& graph) :
+      _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph),
+      _cost_map(_cost_vec), _pi_map(_pi),
+      INF(std::numeric_limits<Value>::has_infinity ?
+          std::numeric_limits<Value>::infinity() :
+          std::numeric_limits<Value>::max())
+    {
+      // Check the number types
+      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
+        "The flow type of CostScaling must be signed");
+      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
+        "The cost type of CostScaling must be signed");
+
+      // Reset data structures
+      reset();
+    }
+
+    /// \name Parameters
+    /// The parameters of the algorithm can be specified using these
+    /// functions.
+
+    /// @{
+
+    /// \brief Set the lower bounds on the arcs.
+    ///
+    /// This function sets the lower bounds on the arcs.
+    /// If it is not used before calling \ref run(), the lower bounds
+    /// will be set to zero on all arcs.
+    ///
+    /// \param map An arc map storing the lower bounds.
+    /// Its \c Value type must be convertible to the \c Value type
+    /// of the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    template <typename LowerMap>
+    CostScaling& lowerMap(const LowerMap& map) {
+      _have_lower = true;
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        _lower[_arc_idf[a]] = map[a];
+        _lower[_arc_idb[a]] = map[a];
+      }
+      return *this;
+    }
+
+    /// \brief Set the upper bounds (capacities) on the arcs.
+    ///
+    /// This function sets the upper bounds (capacities) on the arcs.
+    /// If it is not used before calling \ref run(), the upper bounds
+    /// will be set to \ref INF on all arcs (i.e. the flow value will be
+    /// unbounded from above).
+    ///
+    /// \param map An arc map storing the upper bounds.
+    /// Its \c Value type must be convertible to the \c Value type
+    /// of the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    template<typename UpperMap>
+    CostScaling& upperMap(const UpperMap& map) {
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        _upper[_arc_idf[a]] = map[a];
+      }
+      return *this;
+    }
+
+    /// \brief Set the costs of the arcs.
+    ///
+    /// This function sets the costs of the arcs.
+    /// If it is not used before calling \ref run(), the costs
+    /// will be set to \c 1 on all arcs.
+    ///
+    /// \param map An arc map storing the costs.
+    /// Its \c Value type must be convertible to the \c Cost type
+    /// of the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    template<typename CostMap>
+    CostScaling& costMap(const CostMap& map) {
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        _scost[_arc_idf[a]] =  map[a];
+        _scost[_arc_idb[a]] = -map[a];
+      }
+      return *this;
+    }
+
+    /// \brief Set the supply values of the nodes.
+    ///
+    /// This function sets the supply values of the nodes.
+    /// If neither this function nor \ref stSupply() is used before
+    /// calling \ref run(), the supply of each node will be set to zero.
+    ///
+    /// \param map A node map storing the supply values.
+    /// Its \c Value type must be convertible to the \c Value type
+    /// of the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    template<typename SupplyMap>
+    CostScaling& supplyMap(const SupplyMap& map) {
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _supply[_node_id[n]] = map[n];
+      }
+      return *this;
+    }
+
+    /// \brief Set single source and target nodes and a supply value.
+    ///
+    /// This function sets a single source node and a single target node
+    /// and the required flow value.
+    /// If neither this function nor \ref supplyMap() is used before
+    /// calling \ref run(), the supply of each node will be set to zero.
+    ///
+    /// Using this function has the same effect as using \ref supplyMap()
+    /// with such a map in which \c k is assigned to \c s, \c -k is
+    /// assigned to \c t and all other nodes have zero supply value.
+    ///
+    /// \param s The source node.
+    /// \param t The target node.
+    /// \param k The required amount of flow from node \c s to node \c t
+    /// (i.e. the supply of \c s and the demand of \c t).
+    ///
+    /// \return <tt>(*this)</tt>
+    CostScaling& stSupply(const Node& s, const Node& t, Value k) {
+      for (int i = 0; i != _res_node_num; ++i) {
+        _supply[i] = 0;
+      }
+      _supply[_node_id[s]] =  k;
+      _supply[_node_id[t]] = -k;
+      return *this;
+    }
+
+    /// @}
+
+    /// \name Execution control
+    /// The algorithm can be executed using \ref run().
+
+    /// @{
+
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm.
+    /// The paramters can be specified using functions \ref lowerMap(),
+    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
+    /// For example,
+    /// \code
+    ///   CostScaling<ListDigraph> cs(graph);
+    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
+    ///     .supplyMap(sup).run();
+    /// \endcode
+    ///
+    /// This function can be called more than once. All the given parameters
+    /// are kept for the next call, unless \ref resetParams() or \ref reset()
+    /// is used, thus only the modified parameters have to be set again.
+    /// If the underlying digraph was also modified after the construction
+    /// of the class (or the last \ref reset() call), then the \ref reset()
+    /// function must be called.
+    ///
+    /// \param method The internal method that will be used in the
+    /// algorithm. For more information, see \ref Method.
+    /// \param factor The cost scaling factor. It must be larger than one.
+    ///
+    /// \return \c INFEASIBLE if no feasible flow exists,
+    /// \n \c OPTIMAL if the problem has optimal solution
+    /// (i.e. it is feasible and bounded), and the algorithm has found
+    /// optimal flow and node potentials (primal and dual solutions),
+    /// \n \c UNBOUNDED if the digraph contains an arc of negative cost
+    /// and infinite upper bound. It means that the objective function
+    /// is unbounded on that arc, however, note that it could actually be
+    /// bounded over the feasible flows, but this algroithm cannot handle
+    /// these cases.
+    ///
+    /// \see ProblemType, Method
+    /// \see resetParams(), reset()
+    ProblemType run(Method method = PARTIAL_AUGMENT, int factor = 8) {
+      _alpha = factor;
+      ProblemType pt = init();
+      if (pt != OPTIMAL) return pt;
+      start(method);
+      return OPTIMAL;
+    }
+
+    /// \brief Reset all the parameters that have been given before.
+    ///
+    /// This function resets all the paramaters that have been given
+    /// before using functions \ref lowerMap(), \ref upperMap(),
+    /// \ref costMap(), \ref supplyMap(), \ref stSupply().
+    ///
+    /// It is useful for multiple \ref run() calls. Basically, all the given
+    /// parameters are kept for the next \ref run() call, unless
+    /// \ref resetParams() or \ref reset() is used.
+    /// If the underlying digraph was also modified after the construction
+    /// of the class or the last \ref reset() call, then the \ref reset()
+    /// function must be used, otherwise \ref resetParams() is sufficient.
+    ///
+    /// For example,
+    /// \code
+    ///   CostScaling<ListDigraph> cs(graph);
+    ///
+    ///   // First run
+    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
+    ///     .supplyMap(sup).run();
+    ///
+    ///   // Run again with modified cost map (resetParams() is not called,
+    ///   // so only the cost map have to be set again)
+    ///   cost[e] += 100;
+    ///   cs.costMap(cost).run();
+    ///
+    ///   // Run again from scratch using resetParams()
+    ///   // (the lower bounds will be set to zero on all arcs)
+    ///   cs.resetParams();
+    ///   cs.upperMap(capacity).costMap(cost)
+    ///     .supplyMap(sup).run();
+    /// \endcode
+    ///
+    /// \return <tt>(*this)</tt>
+    ///
+    /// \see reset(), run()
+    CostScaling& resetParams() {
+      for (int i = 0; i != _res_node_num; ++i) {
+        _supply[i] = 0;
+      }
+      int limit = _first_out[_root];
+      for (int j = 0; j != limit; ++j) {
+        _lower[j] = 0;
+        _upper[j] = INF;
+        _scost[j] = _forward[j] ? 1 : -1;
+      }
+      for (int j = limit; j != _res_arc_num; ++j) {
+        _lower[j] = 0;
+        _upper[j] = INF;
+        _scost[j] = 0;
+        _scost[_reverse[j]] = 0;
+      }
+      _have_lower = false;
+      return *this;
+    }
+
+    /// \brief Reset all the parameters that have been given before.
+    ///
+    /// This function resets all the paramaters that have been given
+    /// before using functions \ref lowerMap(), \ref upperMap(),
+    /// \ref costMap(), \ref supplyMap(), \ref stSupply().
+    ///
+    /// It is useful for multiple run() calls. If this function is not
+    /// used, all the parameters given before are kept for the next
+    /// \ref run() call.
+    /// However, the underlying digraph must not be modified after this
+    /// class have been constructed, since it copies and extends the graph.
+    /// \return <tt>(*this)</tt>
+    CostScaling& reset() {
+      // Resize vectors
+      _node_num = countNodes(_graph);
+      _arc_num = countArcs(_graph);
+      _res_node_num = _node_num + 1;
+      _res_arc_num = 2 * (_arc_num + _node_num);
+      _root = _node_num;
+
+      _first_out.resize(_res_node_num + 1);
+      _forward.resize(_res_arc_num);
+      _source.resize(_res_arc_num);
+      _target.resize(_res_arc_num);
+      _reverse.resize(_res_arc_num);
+
+      _lower.resize(_res_arc_num);
+      _upper.resize(_res_arc_num);
+      _scost.resize(_res_arc_num);
+      _supply.resize(_res_node_num);
+
+      _res_cap.resize(_res_arc_num);
+      _cost.resize(_res_arc_num);
+      _pi.resize(_res_node_num);
+      _excess.resize(_res_node_num);
+      _next_out.resize(_res_node_num);
+
+      _arc_vec.reserve(_res_arc_num);
+      _cost_vec.reserve(_res_arc_num);
+
+      // Copy the graph
+      int i = 0, j = 0, k = 2 * _arc_num + _node_num;
+      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
+        _node_id[n] = i;
+      }
+      i = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
+        _first_out[i] = j;
+        for (OutArcIt a(_graph, n); a != INVALID; ++a, ++j) {
+          _arc_idf[a] = j;
+          _forward[j] = true;
+          _source[j] = i;
+          _target[j] = _node_id[_graph.runningNode(a)];
+        }
+        for (InArcIt a(_graph, n); a != INVALID; ++a, ++j) {
+          _arc_idb[a] = j;
+          _forward[j] = false;
+          _source[j] = i;
+          _target[j] = _node_id[_graph.runningNode(a)];
+        }
+        _forward[j] = false;
+        _source[j] = i;
+        _target[j] = _root;
+        _reverse[j] = k;
+        _forward[k] = true;
+        _source[k] = _root;
+        _target[k] = i;
+        _reverse[k] = j;
+        ++j; ++k;
+      }
+      _first_out[i] = j;
+      _first_out[_res_node_num] = k;
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        int fi = _arc_idf[a];
+        int bi = _arc_idb[a];
+        _reverse[fi] = bi;
+        _reverse[bi] = fi;
+      }
+
+      // Reset parameters
+      resetParams();
+      return *this;
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The results of the algorithm can be obtained using these
+    /// functions.\n
+    /// The \ref run() function must be called before using them.
+
+    /// @{
+
+    /// \brief Return the total cost of the found flow.
+    ///
+    /// This function returns the total cost of the found flow.
+    /// Its complexity is O(e).
+    ///
+    /// \note The return type of the function can be specified as a
+    /// template parameter. For example,
+    /// \code
+    ///   cs.totalCost<double>();
+    /// \endcode
+    /// It is useful if the total cost cannot be stored in the \c Cost
+    /// type of the algorithm, which is the default return type of the
+    /// function.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    template <typename Number>
+    Number totalCost() const {
+      Number c = 0;
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        int i = _arc_idb[a];
+        c += static_cast<Number>(_res_cap[i]) *
+             (-static_cast<Number>(_scost[i]));
+      }
+      return c;
+    }
+
+#ifndef DOXYGEN
+    Cost totalCost() const {
+      return totalCost<Cost>();
+    }
+#endif
+
+    /// \brief Return the flow on the given arc.
+    ///
+    /// This function returns the flow on the given arc.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Value flow(const Arc& a) const {
+      return _res_cap[_arc_idb[a]];
+    }
+
+    /// \brief Return the flow map (the primal solution).
+    ///
+    /// This function copies the flow value on each arc into the given
+    /// map. The \c Value type of the algorithm must be convertible to
+    /// the \c Value type of the map.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    template <typename FlowMap>
+    void flowMap(FlowMap &map) const {
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        map.set(a, _res_cap[_arc_idb[a]]);
+      }
+    }
+
+    /// \brief Return the potential (dual value) of the given node.
+    ///
+    /// This function returns the potential (dual value) of the
+    /// given node.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Cost potential(const Node& n) const {
+      return static_cast<Cost>(_pi[_node_id[n]]);
+    }
+
+    /// \brief Return the potential map (the dual solution).
+    ///
+    /// This function copies the potential (dual value) of each node
+    /// into the given map.
+    /// The \c Cost type of the algorithm must be convertible to the
+    /// \c Value type of the map.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    template <typename PotentialMap>
+    void potentialMap(PotentialMap &map) const {
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        map.set(n, static_cast<Cost>(_pi[_node_id[n]]));
+      }
+    }
+
+    /// @}
+
+  private:
+
+    // Initialize the algorithm
+    ProblemType init() {
+      if (_res_node_num <= 1) return INFEASIBLE;
+
+      // Check the sum of supply values
+      _sum_supply = 0;
+      for (int i = 0; i != _root; ++i) {
+        _sum_supply += _supply[i];
+      }
+      if (_sum_supply > 0) return INFEASIBLE;
+
+
+      // Initialize vectors
+      for (int i = 0; i != _res_node_num; ++i) {
+        _pi[i] = 0;
+        _excess[i] = _supply[i];
+      }
+
+      // Remove infinite upper bounds and check negative arcs
+      const Value MAX = std::numeric_limits<Value>::max();
+      int last_out;
+      if (_have_lower) {
+        for (int i = 0; i != _root; ++i) {
+          last_out = _first_out[i+1];
+          for (int j = _first_out[i]; j != last_out; ++j) {
+            if (_forward[j]) {
+              Value c = _scost[j] < 0 ? _upper[j] : _lower[j];
+              if (c >= MAX) return UNBOUNDED;
+              _excess[i] -= c;
+              _excess[_target[j]] += c;
+            }
+          }
+        }
+      } else {
+        for (int i = 0; i != _root; ++i) {
+          last_out = _first_out[i+1];
+          for (int j = _first_out[i]; j != last_out; ++j) {
+            if (_forward[j] && _scost[j] < 0) {
+              Value c = _upper[j];
+              if (c >= MAX) return UNBOUNDED;
+              _excess[i] -= c;
+              _excess[_target[j]] += c;
+            }
+          }
+        }
+      }
+      Value ex, max_cap = 0;
+      for (int i = 0; i != _res_node_num; ++i) {
+        ex = _excess[i];
+        _excess[i] = 0;
+        if (ex < 0) max_cap -= ex;
+      }
+      for (int j = 0; j != _res_arc_num; ++j) {
+        if (_upper[j] >= MAX) _upper[j] = max_cap;
+      }
+
+      // Initialize the large cost vector and the epsilon parameter
+      _epsilon = 0;
+      LargeCost lc;
+      for (int i = 0; i != _root; ++i) {
+        last_out = _first_out[i+1];
+        for (int j = _first_out[i]; j != last_out; ++j) {
+          lc = static_cast<LargeCost>(_scost[j]) * _res_node_num * _alpha;
+          _cost[j] = lc;
+          if (lc > _epsilon) _epsilon = lc;
+        }
+      }
+      _epsilon /= _alpha;
+
+      // Initialize maps for Circulation and remove non-zero lower bounds
+      ConstMap<Arc, Value> low(0);
+      typedef typename Digraph::template ArcMap<Value> ValueArcMap;
+      typedef typename Digraph::template NodeMap<Value> ValueNodeMap;
+      ValueArcMap cap(_graph), flow(_graph);
+      ValueNodeMap sup(_graph);
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        sup[n] = _supply[_node_id[n]];
+      }
+      if (_have_lower) {
+        for (ArcIt a(_graph); a != INVALID; ++a) {
+          int j = _arc_idf[a];
+          Value c = _lower[j];
+          cap[a] = _upper[j] - c;
+          sup[_graph.source(a)] -= c;
+          sup[_graph.target(a)] += c;
+        }
+      } else {
+        for (ArcIt a(_graph); a != INVALID; ++a) {
+          cap[a] = _upper[_arc_idf[a]];
+        }
+      }
+
+      _sup_node_num = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if (sup[n] > 0) ++_sup_node_num;
+      }
+
+      // Find a feasible flow using Circulation
+      Circulation<Digraph, ConstMap<Arc, Value>, ValueArcMap, ValueNodeMap>
+        circ(_graph, low, cap, sup);
+      if (!circ.flowMap(flow).run()) return INFEASIBLE;
+
+      // Set residual capacities and handle GEQ supply type
+      if (_sum_supply < 0) {
+        for (ArcIt a(_graph); a != INVALID; ++a) {
+          Value fa = flow[a];
+          _res_cap[_arc_idf[a]] = cap[a] - fa;
+          _res_cap[_arc_idb[a]] = fa;
+          sup[_graph.source(a)] -= fa;
+          sup[_graph.target(a)] += fa;
+        }
+        for (NodeIt n(_graph); n != INVALID; ++n) {
+          _excess[_node_id[n]] = sup[n];
+        }
+        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
+          int u = _target[a];
+          int ra = _reverse[a];
+          _res_cap[a] = -_sum_supply + 1;
+          _res_cap[ra] = -_excess[u];
+          _cost[a] = 0;
+          _cost[ra] = 0;
+          _excess[u] = 0;
+        }
+      } else {
+        for (ArcIt a(_graph); a != INVALID; ++a) {
+          Value fa = flow[a];
+          _res_cap[_arc_idf[a]] = cap[a] - fa;
+          _res_cap[_arc_idb[a]] = fa;
+        }
+        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
+          int ra = _reverse[a];
+          _res_cap[a] = 0;
+          _res_cap[ra] = 0;
+          _cost[a] = 0;
+          _cost[ra] = 0;
+        }
+      }
+
+      return OPTIMAL;
+    }
+
+    // Execute the algorithm and transform the results
+    void start(Method method) {
+      // Maximum path length for partial augment
+      const int MAX_PATH_LENGTH = 4;
+
+      // Initialize data structures for buckets
+      _max_rank = _alpha * _res_node_num;
+      _buckets.resize(_max_rank);
+      _bucket_next.resize(_res_node_num + 1);
+      _bucket_prev.resize(_res_node_num + 1);
+      _rank.resize(_res_node_num + 1);
+
+      // Execute the algorithm
+      switch (method) {
+        case PUSH:
+          startPush();
+          break;
+        case AUGMENT:
+          startAugment(_res_node_num - 1);
+          break;
+        case PARTIAL_AUGMENT:
+          startAugment(MAX_PATH_LENGTH);
+          break;
+      }
+
+      // Compute node potentials for the original costs
+      _arc_vec.clear();
+      _cost_vec.clear();
+      for (int j = 0; j != _res_arc_num; ++j) {
+        if (_res_cap[j] > 0) {
+          _arc_vec.push_back(IntPair(_source[j], _target[j]));
+          _cost_vec.push_back(_scost[j]);
+        }
+      }
+      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
+
+      typename BellmanFord<StaticDigraph, LargeCostArcMap>
+        ::template SetDistMap<LargeCostNodeMap>::Create bf(_sgr, _cost_map);
+      bf.distMap(_pi_map);
+      bf.init(0);
+      bf.start();
+
+      // Handle non-zero lower bounds
+      if (_have_lower) {
+        int limit = _first_out[_root];
+        for (int j = 0; j != limit; ++j) {
+          if (!_forward[j]) _res_cap[j] += _lower[j];
+        }
+      }
+    }
+
+    // Initialize a cost scaling phase
+    void initPhase() {
+      // Saturate arcs not satisfying the optimality condition
+      for (int u = 0; u != _res_node_num; ++u) {
+        int last_out = _first_out[u+1];
+        LargeCost pi_u = _pi[u];
+        for (int a = _first_out[u]; a != last_out; ++a) {
+          int v = _target[a];
+          if (_res_cap[a] > 0 && _cost[a] + pi_u - _pi[v] < 0) {
+            Value delta = _res_cap[a];
+            _excess[u] -= delta;
+            _excess[v] += delta;
+            _res_cap[a] = 0;
+            _res_cap[_reverse[a]] += delta;
+          }
+        }
+      }
+
+      // Find active nodes (i.e. nodes with positive excess)
+      for (int u = 0; u != _res_node_num; ++u) {
+        if (_excess[u] > 0) _active_nodes.push_back(u);
+      }
+
+      // Initialize the next arcs
+      for (int u = 0; u != _res_node_num; ++u) {
+        _next_out[u] = _first_out[u];
+      }
+    }
+
+    // Early termination heuristic
+    bool earlyTermination() {
+      const double EARLY_TERM_FACTOR = 3.0;
+
+      // Build a static residual graph
+      _arc_vec.clear();
+      _cost_vec.clear();
+      for (int j = 0; j != _res_arc_num; ++j) {
+        if (_res_cap[j] > 0) {
+          _arc_vec.push_back(IntPair(_source[j], _target[j]));
+          _cost_vec.push_back(_cost[j] + 1);
+        }
+      }
+      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
+
+      // Run Bellman-Ford algorithm to check if the current flow is optimal
+      BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map);
+      bf.init(0);
+      bool done = false;
+      int K = int(EARLY_TERM_FACTOR * std::sqrt(double(_res_node_num)));
+      for (int i = 0; i < K && !done; ++i) {
+        done = bf.processNextWeakRound();
+      }
+      return done;
+    }
+
+    // Global potential update heuristic
+    void globalUpdate() {
+      int bucket_end = _root + 1;
+
+      // Initialize buckets
+      for (int r = 0; r != _max_rank; ++r) {
+        _buckets[r] = bucket_end;
+      }
+      Value total_excess = 0;
+      for (int i = 0; i != _res_node_num; ++i) {
+        if (_excess[i] < 0) {
+          _rank[i] = 0;
+          _bucket_next[i] = _buckets[0];
+          _bucket_prev[_buckets[0]] = i;
+          _buckets[0] = i;
+        } else {
+          total_excess += _excess[i];
+          _rank[i] = _max_rank;
+        }
+      }
+      if (total_excess == 0) return;
+
+      // Search the buckets
+      int r = 0;
+      for ( ; r != _max_rank; ++r) {
+        while (_buckets[r] != bucket_end) {
+          // Remove the first node from the current bucket
+          int u = _buckets[r];
+          _buckets[r] = _bucket_next[u];
+
+          // Search the incomming arcs of u
+          LargeCost pi_u = _pi[u];
+          int last_out = _first_out[u+1];
+          for (int a = _first_out[u]; a != last_out; ++a) {
+            int ra = _reverse[a];
+            if (_res_cap[ra] > 0) {
+              int v = _source[ra];
+              int old_rank_v = _rank[v];
+              if (r < old_rank_v) {
+                // Compute the new rank of v
+                LargeCost nrc = (_cost[ra] + _pi[v] - pi_u) / _epsilon;
+                int new_rank_v = old_rank_v;
+                if (nrc < LargeCost(_max_rank))
+                  new_rank_v = r + 1 + int(nrc);
+
+                // Change the rank of v
+                if (new_rank_v < old_rank_v) {
+                  _rank[v] = new_rank_v;
+                  _next_out[v] = _first_out[v];
+
+                  // Remove v from its old bucket
+                  if (old_rank_v < _max_rank) {
+                    if (_buckets[old_rank_v] == v) {
+                      _buckets[old_rank_v] = _bucket_next[v];
+                    } else {
+                      _bucket_next[_bucket_prev[v]] = _bucket_next[v];
+                      _bucket_prev[_bucket_next[v]] = _bucket_prev[v];
+                    }
+                  }
+
+                  // Insert v to its new bucket
+                  _bucket_next[v] = _buckets[new_rank_v];
+                  _bucket_prev[_buckets[new_rank_v]] = v;
+                  _buckets[new_rank_v] = v;
+                }
+              }
+            }
+          }
+
+          // Finish search if there are no more active nodes
+          if (_excess[u] > 0) {
+            total_excess -= _excess[u];
+            if (total_excess <= 0) break;
+          }
+        }
+        if (total_excess <= 0) break;
+      }
+
+      // Relabel nodes
+      for (int u = 0; u != _res_node_num; ++u) {
+        int k = std::min(_rank[u], r);
+        if (k > 0) {
+          _pi[u] -= _epsilon * k;
+          _next_out[u] = _first_out[u];
+        }
+      }
+    }
+
+    /// Execute the algorithm performing augment and relabel operations
+    void startAugment(int max_length) {
+      // Paramters for heuristics
+      const int EARLY_TERM_EPSILON_LIMIT = 1000;
+      const double GLOBAL_UPDATE_FACTOR = 3.0;
+
+      const int global_update_freq = int(GLOBAL_UPDATE_FACTOR *
+        (_res_node_num + _sup_node_num * _sup_node_num));
+      int next_update_limit = global_update_freq;
+
+      int relabel_cnt = 0;
+
+      // Perform cost scaling phases
+      std::vector<int> path;
+      for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
+                                        1 : _epsilon / _alpha )
+      {
+        // Early termination heuristic
+        if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) {
+          if (earlyTermination()) break;
+        }
+
+        // Initialize current phase
+        initPhase();
+
+        // Perform partial augment and relabel operations
+        while (true) {
+          // Select an active node (FIFO selection)
+          while (_active_nodes.size() > 0 &&
+                 _excess[_active_nodes.front()] <= 0) {
+            _active_nodes.pop_front();
+          }
+          if (_active_nodes.size() == 0) break;
+          int start = _active_nodes.front();
+
+          // Find an augmenting path from the start node
+          path.clear();
+          int tip = start;
+          while (_excess[tip] >= 0 && int(path.size()) < max_length) {
+            int u;
+            LargeCost min_red_cost, rc, pi_tip = _pi[tip];
+            int last_out = _first_out[tip+1];
+            for (int a = _next_out[tip]; a != last_out; ++a) {
+              u = _target[a];
+              if (_res_cap[a] > 0 && _cost[a] + pi_tip - _pi[u] < 0) {
+                path.push_back(a);
+                _next_out[tip] = a;
+                tip = u;
+                goto next_step;
+              }
+            }
+
+            // Relabel tip node
+            min_red_cost = std::numeric_limits<LargeCost>::max();
+            if (tip != start) {
+              int ra = _reverse[path.back()];
+              min_red_cost = _cost[ra] + pi_tip - _pi[_target[ra]];
+            }
+            for (int a = _first_out[tip]; a != last_out; ++a) {
+              rc = _cost[a] + pi_tip - _pi[_target[a]];
+              if (_res_cap[a] > 0 && rc < min_red_cost) {
+                min_red_cost = rc;
+              }
+            }
+            _pi[tip] -= min_red_cost + _epsilon;
+            _next_out[tip] = _first_out[tip];
+            ++relabel_cnt;
+
+            // Step back
+            if (tip != start) {
+              tip = _source[path.back()];
+              path.pop_back();
+            }
+
+          next_step: ;
+          }
+
+          // Augment along the found path (as much flow as possible)
+          Value delta;
+          int pa, u, v = start;
+          for (int i = 0; i != int(path.size()); ++i) {
+            pa = path[i];
+            u = v;
+            v = _target[pa];
+            delta = std::min(_res_cap[pa], _excess[u]);
+            _res_cap[pa] -= delta;
+            _res_cap[_reverse[pa]] += delta;
+            _excess[u] -= delta;
+            _excess[v] += delta;
+            if (_excess[v] > 0 && _excess[v] <= delta)
+              _active_nodes.push_back(v);
+          }
+
+          // Global update heuristic
+          if (relabel_cnt >= next_update_limit) {
+            globalUpdate();
+            next_update_limit += global_update_freq;
+          }
+        }
+      }
+    }
+
+    /// Execute the algorithm performing push and relabel operations
+    void startPush() {
+      // Paramters for heuristics
+      const int EARLY_TERM_EPSILON_LIMIT = 1000;
+      const double GLOBAL_UPDATE_FACTOR = 2.0;
+
+      const int global_update_freq = int(GLOBAL_UPDATE_FACTOR *
+        (_res_node_num + _sup_node_num * _sup_node_num));
+      int next_update_limit = global_update_freq;
+
+      int relabel_cnt = 0;
+
+      // Perform cost scaling phases
+      BoolVector hyper(_res_node_num, false);
+      LargeCostVector hyper_cost(_res_node_num);
+      for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
+                                        1 : _epsilon / _alpha )
+      {
+        // Early termination heuristic
+        if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) {
+          if (earlyTermination()) break;
+        }
+
+        // Initialize current phase
+        initPhase();
+
+        // Perform push and relabel operations
+        while (_active_nodes.size() > 0) {
+          LargeCost min_red_cost, rc, pi_n;
+          Value delta;
+          int n, t, a, last_out = _res_arc_num;
+
+        next_node:
+          // Select an active node (FIFO selection)
+          n = _active_nodes.front();
+          last_out = _first_out[n+1];
+          pi_n = _pi[n];
+
+          // Perform push operations if there are admissible arcs
+          if (_excess[n] > 0) {
+            for (a = _next_out[n]; a != last_out; ++a) {
+              if (_res_cap[a] > 0 &&
+                  _cost[a] + pi_n - _pi[_target[a]] < 0) {
+                delta = std::min(_res_cap[a], _excess[n]);
+                t = _target[a];
+
+                // Push-look-ahead heuristic
+                Value ahead = -_excess[t];
+                int last_out_t = _first_out[t+1];
+                LargeCost pi_t = _pi[t];
+                for (int ta = _next_out[t]; ta != last_out_t; ++ta) {
+                  if (_res_cap[ta] > 0 &&
+                      _cost[ta] + pi_t - _pi[_target[ta]] < 0)
+                    ahead += _res_cap[ta];
+                  if (ahead >= delta) break;
+                }
+                if (ahead < 0) ahead = 0;
+
+                // Push flow along the arc
+                if (ahead < delta && !hyper[t]) {
+                  _res_cap[a] -= ahead;
+                  _res_cap[_reverse[a]] += ahead;
+                  _excess[n] -= ahead;
+                  _excess[t] += ahead;
+                  _active_nodes.push_front(t);
+                  hyper[t] = true;
+                  hyper_cost[t] = _cost[a] + pi_n - pi_t;
+                  _next_out[n] = a;
+                  goto next_node;
+                } else {
+                  _res_cap[a] -= delta;
+                  _res_cap[_reverse[a]] += delta;
+                  _excess[n] -= delta;
+                  _excess[t] += delta;
+                  if (_excess[t] > 0 && _excess[t] <= delta)
+                    _active_nodes.push_back(t);
+                }
+
+                if (_excess[n] == 0) {
+                  _next_out[n] = a;
+                  goto remove_nodes;
+                }
+              }
+            }
+            _next_out[n] = a;
+          }
+
+          // Relabel the node if it is still active (or hyper)
+          if (_excess[n] > 0 || hyper[n]) {
+             min_red_cost = hyper[n] ? -hyper_cost[n] :
+               std::numeric_limits<LargeCost>::max();
+            for (int a = _first_out[n]; a != last_out; ++a) {
+              rc = _cost[a] + pi_n - _pi[_target[a]];
+              if (_res_cap[a] > 0 && rc < min_red_cost) {
+                min_red_cost = rc;
+              }
+            }
+            _pi[n] -= min_red_cost + _epsilon;
+            _next_out[n] = _first_out[n];
+            hyper[n] = false;
+            ++relabel_cnt;
+          }
+
+          // Remove nodes that are not active nor hyper
+        remove_nodes:
+          while ( _active_nodes.size() > 0 &&
+                  _excess[_active_nodes.front()] <= 0 &&
+                  !hyper[_active_nodes.front()] ) {
+            _active_nodes.pop_front();
+          }
+
+          // Global update heuristic
+          if (relabel_cnt >= next_update_limit) {
+            globalUpdate();
+            for (int u = 0; u != _res_node_num; ++u)
+              hyper[u] = false;
+            next_update_limit += global_update_freq;
+          }
+        }
+      }
+    }
+
+  }; //class CostScaling
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_COST_SCALING_H
Index: lemon/counter.h
===================================================================
--- lemon/counter.h	(revision 440)
+++ lemon/counter.h	(revision 786)
@@ -213,5 +213,5 @@
   /// 'Do nothing' version of Counter.
 
-  /// This class can be used in the same way as \ref Counter however it
+  /// This class can be used in the same way as \ref Counter, but it
   /// does not count at all and does not print report on destruction.
   ///
Index: lemon/cplex.cc
===================================================================
--- lemon/cplex.cc	(revision 551)
+++ lemon/cplex.cc	(revision 974)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -41,4 +41,5 @@
     int status;
     _cnt = new int;
+    (*_cnt) = 1;
     _env = CPXopenCPLEX(&status);
     if (_env == 0) {
@@ -73,4 +74,5 @@
     int status;
     _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
+    messageLevel(MESSAGE_NOTHING);
   }
 
@@ -79,4 +81,5 @@
     int status;
     _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
+    messageLevel(MESSAGE_NOTHING);
   }
 
@@ -87,4 +90,5 @@
     rows = cplex.rows;
     cols = cplex.cols;
+    messageLevel(MESSAGE_NOTHING);
   }
 
@@ -109,4 +113,37 @@
   }
 
+  int CplexBase::_addRow(Value lb, ExprIterator b,
+                         ExprIterator e, Value ub) {
+    int i = CPXgetnumrows(cplexEnv(), _prob);
+    if (lb == -INF) {
+      const char s = 'L';
+      CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
+    } else if (ub == INF) {
+      const char s = 'G';
+      CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
+    } else if (lb == ub){
+      const char s = 'E';
+      CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
+    } else {
+      const char s = 'R';
+      double len = ub - lb;
+      CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, &len, 0);
+    }
+
+    std::vector<int> indices;
+    std::vector<int> rowlist;
+    std::vector<Value> values;
+
+    for(ExprIterator it=b; it!=e; ++it) {
+      indices.push_back(it->first);
+      values.push_back(it->second);
+      rowlist.push_back(i);
+    }
+
+    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
+                   &rowlist.front(), &indices.front(), &values.front());
+
+    return i;
+  }
 
   void CplexBase::_eraseCol(int i) {
@@ -435,6 +472,23 @@
     int status;
     _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
-    rows.clear();
-    cols.clear();
+  }
+
+  void CplexBase::_messageLevel(MessageLevel level) {
+    switch (level) {
+    case MESSAGE_NOTHING:
+      _message_enabled = false;
+      break;
+    case MESSAGE_ERROR:
+    case MESSAGE_WARNING:
+    case MESSAGE_NORMAL:
+    case MESSAGE_VERBOSE:
+      _message_enabled = true;
+      break;
+    }
+  }
+
+  void CplexBase::_applyMessageLevel() {
+    CPXsetintparam(cplexEnv(), CPX_PARAM_SCRIND,
+                   _message_enabled ? CPX_ON : CPX_OFF);
   }
 
@@ -508,4 +562,5 @@
   CplexLp::SolveExitStatus CplexLp::_solve() {
     _clear_temporals();
+    _applyMessageLevel();
     return convertStatus(CPXlpopt(cplexEnv(), _prob));
   }
@@ -513,4 +568,5 @@
   CplexLp::SolveExitStatus CplexLp::solvePrimal() {
     _clear_temporals();
+    _applyMessageLevel();
     return convertStatus(CPXprimopt(cplexEnv(), _prob));
   }
@@ -518,4 +574,5 @@
   CplexLp::SolveExitStatus CplexLp::solveDual() {
     _clear_temporals();
+    _applyMessageLevel();
     return convertStatus(CPXdualopt(cplexEnv(), _prob));
   }
@@ -523,4 +580,5 @@
   CplexLp::SolveExitStatus CplexLp::solveBarrier() {
     _clear_temporals();
+    _applyMessageLevel();
     return convertStatus(CPXbaropt(cplexEnv(), _prob));
   }
@@ -601,5 +659,5 @@
   }
 
-  //7.5-os cplex statusai (Vigyazat: a 9.0-asei masok!)
+  // Cplex 7.0 status values
   // This table lists the statuses, returned by the CPXgetstat()
   // routine, for solutions to LP problems or mixed integer problems. If
@@ -648,5 +706,5 @@
   //       User pivot used
   //
-  //     Ezeket hova tegyem:
+  // Pending return values
   // ??case CPX_ABORT_DUAL_INFEAS
   // ??case CPX_ABORT_CROSSOVER
@@ -719,5 +777,4 @@
     statusSwitch(cplexEnv(),stat);
     //CPXgetstat(cplexEnv(), _prob);
-    //printf("A primal status: %d, CPX_OPTIMAL=%d \n",stat,CPX_OPTIMAL);
     switch (stat) {
     case 0:
@@ -752,5 +809,5 @@
   }
 
-  //9.0-as cplex verzio statusai
+  // Cplex 9.0 status values
   // CPX_STAT_ABORT_DUAL_OBJ_LIM
   // CPX_STAT_ABORT_IT_LIM
@@ -865,4 +922,5 @@
   CplexMip::SolveExitStatus CplexMip::_solve() {
     int status;
+    _applyMessageLevel();
     status = CPXmipopt (cplexEnv(), _prob);
     if (status==0)
Index: lemon/cplex.h
===================================================================
--- lemon/cplex.h	(revision 551)
+++ lemon/cplex.h	(revision 746)
@@ -94,4 +94,5 @@
     virtual int _addCol();
     virtual int _addRow();
+    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
 
     virtual void _eraseCol(int i);
@@ -145,12 +146,27 @@
     virtual void _clear();
 
+    virtual void _messageLevel(MessageLevel level);
+    void _applyMessageLevel();
+
+    bool _message_enabled;
+
   public:
 
     /// Returns the used \c CplexEnv instance
     const CplexEnv& env() const { return _env; }
+
+    /// \brief Returns the const cpxenv pointer
     ///
+    /// \note The cpxenv might be destructed with the solver.
     const cpxenv* cplexEnv() const { return _env.cplexEnv(); }
 
+    /// \brief Returns the const cpxenv pointer
+    ///
+    /// \note The cpxenv might be destructed with the solver.
+    cpxenv* cplexEnv() { return _env.cplexEnv(); }
+
+    /// Returns the cplex problem object
     cpxlp* cplexLp() { return _prob; }
+    /// Returns the cplex problem object
     const cpxlp* cplexLp() const { return _prob; }
 
Index: lemon/cycle_canceling.h
===================================================================
--- lemon/cycle_canceling.h	(revision 877)
+++ lemon/cycle_canceling.h	(revision 877)
@@ -0,0 +1,1170 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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_CYCLE_CANCELING_H
+#define LEMON_CYCLE_CANCELING_H
+
+/// \ingroup min_cost_flow_algs
+/// \file
+/// \brief Cycle-canceling algorithms for finding a minimum cost flow.
+
+#include <vector>
+#include <limits>
+
+#include <lemon/core.h>
+#include <lemon/maps.h>
+#include <lemon/path.h>
+#include <lemon/math.h>
+#include <lemon/static_graph.h>
+#include <lemon/adaptors.h>
+#include <lemon/circulation.h>
+#include <lemon/bellman_ford.h>
+#include <lemon/howard_mmc.h>
+
+namespace lemon {
+
+  /// \addtogroup min_cost_flow_algs
+  /// @{
+
+  /// \brief Implementation of cycle-canceling algorithms for
+  /// finding a \ref min_cost_flow "minimum cost flow".
+  ///
+  /// \ref CycleCanceling implements three different cycle-canceling
+  /// algorithms for finding a \ref min_cost_flow "minimum cost flow"
+  /// \ref amo93networkflows, \ref klein67primal,
+  /// \ref goldberg89cyclecanceling.
+  /// The most efficent one (both theoretically and practically)
+  /// is the \ref CANCEL_AND_TIGHTEN "Cancel and Tighten" algorithm,
+  /// thus it is the default method.
+  /// It is strongly polynomial, but in practice, it is typically much
+  /// slower than the scaling algorithms and NetworkSimplex.
+  ///
+  /// Most of the parameters of the problem (except for the digraph)
+  /// can be given using separate functions, and the algorithm can be
+  /// executed using the \ref run() function. If some parameters are not
+  /// specified, then default values will be used.
+  ///
+  /// \tparam GR The digraph type the algorithm runs on.
+  /// \tparam V The number type used for flow amounts, capacity bounds
+  /// and supply values in the algorithm. By default, it is \c int.
+  /// \tparam C The number type used for costs and potentials in the
+  /// algorithm. By default, it is the same as \c V.
+  ///
+  /// \warning Both number types must be signed and all input data must
+  /// be integer.
+  /// \warning This algorithm does not support negative costs for such
+  /// arcs that have infinite upper bound.
+  ///
+  /// \note For more information about the three available methods,
+  /// see \ref Method.
+#ifdef DOXYGEN
+  template <typename GR, typename V, typename C>
+#else
+  template <typename GR, typename V = int, typename C = V>
+#endif
+  class CycleCanceling
+  {
+  public:
+
+    /// The type of the digraph
+    typedef GR Digraph;
+    /// The type of the flow amounts, capacity bounds and supply values
+    typedef V Value;
+    /// The type of the arc costs
+    typedef C Cost;
+
+  public:
+
+    /// \brief Problem type constants for the \c run() function.
+    ///
+    /// Enum type containing the problem type constants that can be
+    /// returned by the \ref run() function of the algorithm.
+    enum ProblemType {
+      /// The problem has no feasible solution (flow).
+      INFEASIBLE,
+      /// The problem has optimal solution (i.e. it is feasible and
+      /// bounded), and the algorithm has found optimal flow and node
+      /// potentials (primal and dual solutions).
+      OPTIMAL,
+      /// The digraph contains an arc of negative cost and infinite
+      /// upper bound. It means that the objective function is unbounded
+      /// on that arc, however, note that it could actually be bounded
+      /// over the feasible flows, but this algroithm cannot handle
+      /// these cases.
+      UNBOUNDED
+    };
+
+    /// \brief Constants for selecting the used method.
+    ///
+    /// Enum type containing constants for selecting the used method
+    /// for the \ref run() function.
+    ///
+    /// \ref CycleCanceling provides three different cycle-canceling
+    /// methods. By default, \ref CANCEL_AND_TIGHTEN "Cancel and Tighten"
+    /// is used, which proved to be the most efficient and the most robust
+    /// on various test inputs.
+    /// However, the other methods can be selected using the \ref run()
+    /// function with the proper parameter.
+    enum Method {
+      /// A simple cycle-canceling method, which uses the
+      /// \ref BellmanFord "Bellman-Ford" algorithm with limited iteration
+      /// number for detecting negative cycles in the residual network.
+      SIMPLE_CYCLE_CANCELING,
+      /// The "Minimum Mean Cycle-Canceling" algorithm, which is a
+      /// well-known strongly polynomial method
+      /// \ref goldberg89cyclecanceling. It improves along a
+      /// \ref min_mean_cycle "minimum mean cycle" in each iteration.
+      /// Its running time complexity is O(n<sup>2</sup>m<sup>3</sup>log(n)).
+      MINIMUM_MEAN_CYCLE_CANCELING,
+      /// The "Cancel And Tighten" algorithm, which can be viewed as an
+      /// improved version of the previous method
+      /// \ref goldberg89cyclecanceling.
+      /// It is faster both in theory and in practice, its running time
+      /// complexity is O(n<sup>2</sup>m<sup>2</sup>log(n)).
+      CANCEL_AND_TIGHTEN
+    };
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
+
+    typedef std::vector<int> IntVector;
+    typedef std::vector<double> DoubleVector;
+    typedef std::vector<Value> ValueVector;
+    typedef std::vector<Cost> CostVector;
+    typedef std::vector<char> BoolVector;
+    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
+
+  private:
+
+    template <typename KT, typename VT>
+    class StaticVectorMap {
+    public:
+      typedef KT Key;
+      typedef VT Value;
+
+      StaticVectorMap(std::vector<Value>& v) : _v(v) {}
+
+      const Value& operator[](const Key& key) const {
+        return _v[StaticDigraph::id(key)];
+      }
+
+      Value& operator[](const Key& key) {
+        return _v[StaticDigraph::id(key)];
+      }
+
+      void set(const Key& key, const Value& val) {
+        _v[StaticDigraph::id(key)] = val;
+      }
+
+    private:
+      std::vector<Value>& _v;
+    };
+
+    typedef StaticVectorMap<StaticDigraph::Node, Cost> CostNodeMap;
+    typedef StaticVectorMap<StaticDigraph::Arc, Cost> CostArcMap;
+
+  private:
+
+
+    // Data related to the underlying digraph
+    const GR &_graph;
+    int _node_num;
+    int _arc_num;
+    int _res_node_num;
+    int _res_arc_num;
+    int _root;
+
+    // Parameters of the problem
+    bool _have_lower;
+    Value _sum_supply;
+
+    // Data structures for storing the digraph
+    IntNodeMap _node_id;
+    IntArcMap _arc_idf;
+    IntArcMap _arc_idb;
+    IntVector _first_out;
+    BoolVector _forward;
+    IntVector _source;
+    IntVector _target;
+    IntVector _reverse;
+
+    // Node and arc data
+    ValueVector _lower;
+    ValueVector _upper;
+    CostVector _cost;
+    ValueVector _supply;
+
+    ValueVector _res_cap;
+    CostVector _pi;
+
+    // Data for a StaticDigraph structure
+    typedef std::pair<int, int> IntPair;
+    StaticDigraph _sgr;
+    std::vector<IntPair> _arc_vec;
+    std::vector<Cost> _cost_vec;
+    IntVector _id_vec;
+    CostArcMap _cost_map;
+    CostNodeMap _pi_map;
+
+  public:
+
+    /// \brief Constant for infinite upper bounds (capacities).
+    ///
+    /// Constant for infinite upper bounds (capacities).
+    /// It is \c std::numeric_limits<Value>::infinity() if available,
+    /// \c std::numeric_limits<Value>::max() otherwise.
+    const Value INF;
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// The constructor of the class.
+    ///
+    /// \param graph The digraph the algorithm runs on.
+    CycleCanceling(const GR& graph) :
+      _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph),
+      _cost_map(_cost_vec), _pi_map(_pi),
+      INF(std::numeric_limits<Value>::has_infinity ?
+          std::numeric_limits<Value>::infinity() :
+          std::numeric_limits<Value>::max())
+    {
+      // Check the number types
+      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
+        "The flow type of CycleCanceling must be signed");
+      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
+        "The cost type of CycleCanceling must be signed");
+
+      // Reset data structures
+      reset();
+    }
+
+    /// \name Parameters
+    /// The parameters of the algorithm can be specified using these
+    /// functions.
+
+    /// @{
+
+    /// \brief Set the lower bounds on the arcs.
+    ///
+    /// This function sets the lower bounds on the arcs.
+    /// If it is not used before calling \ref run(), the lower bounds
+    /// will be set to zero on all arcs.
+    ///
+    /// \param map An arc map storing the lower bounds.
+    /// Its \c Value type must be convertible to the \c Value type
+    /// of the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    template <typename LowerMap>
+    CycleCanceling& lowerMap(const LowerMap& map) {
+      _have_lower = true;
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        _lower[_arc_idf[a]] = map[a];
+        _lower[_arc_idb[a]] = map[a];
+      }
+      return *this;
+    }
+
+    /// \brief Set the upper bounds (capacities) on the arcs.
+    ///
+    /// This function sets the upper bounds (capacities) on the arcs.
+    /// If it is not used before calling \ref run(), the upper bounds
+    /// will be set to \ref INF on all arcs (i.e. the flow value will be
+    /// unbounded from above).
+    ///
+    /// \param map An arc map storing the upper bounds.
+    /// Its \c Value type must be convertible to the \c Value type
+    /// of the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    template<typename UpperMap>
+    CycleCanceling& upperMap(const UpperMap& map) {
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        _upper[_arc_idf[a]] = map[a];
+      }
+      return *this;
+    }
+
+    /// \brief Set the costs of the arcs.
+    ///
+    /// This function sets the costs of the arcs.
+    /// If it is not used before calling \ref run(), the costs
+    /// will be set to \c 1 on all arcs.
+    ///
+    /// \param map An arc map storing the costs.
+    /// Its \c Value type must be convertible to the \c Cost type
+    /// of the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    template<typename CostMap>
+    CycleCanceling& costMap(const CostMap& map) {
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        _cost[_arc_idf[a]] =  map[a];
+        _cost[_arc_idb[a]] = -map[a];
+      }
+      return *this;
+    }
+
+    /// \brief Set the supply values of the nodes.
+    ///
+    /// This function sets the supply values of the nodes.
+    /// If neither this function nor \ref stSupply() is used before
+    /// calling \ref run(), the supply of each node will be set to zero.
+    ///
+    /// \param map A node map storing the supply values.
+    /// Its \c Value type must be convertible to the \c Value type
+    /// of the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    template<typename SupplyMap>
+    CycleCanceling& supplyMap(const SupplyMap& map) {
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _supply[_node_id[n]] = map[n];
+      }
+      return *this;
+    }
+
+    /// \brief Set single source and target nodes and a supply value.
+    ///
+    /// This function sets a single source node and a single target node
+    /// and the required flow value.
+    /// If neither this function nor \ref supplyMap() is used before
+    /// calling \ref run(), the supply of each node will be set to zero.
+    ///
+    /// Using this function has the same effect as using \ref supplyMap()
+    /// with such a map in which \c k is assigned to \c s, \c -k is
+    /// assigned to \c t and all other nodes have zero supply value.
+    ///
+    /// \param s The source node.
+    /// \param t The target node.
+    /// \param k The required amount of flow from node \c s to node \c t
+    /// (i.e. the supply of \c s and the demand of \c t).
+    ///
+    /// \return <tt>(*this)</tt>
+    CycleCanceling& stSupply(const Node& s, const Node& t, Value k) {
+      for (int i = 0; i != _res_node_num; ++i) {
+        _supply[i] = 0;
+      }
+      _supply[_node_id[s]] =  k;
+      _supply[_node_id[t]] = -k;
+      return *this;
+    }
+
+    /// @}
+
+    /// \name Execution control
+    /// The algorithm can be executed using \ref run().
+
+    /// @{
+
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm.
+    /// The paramters can be specified using functions \ref lowerMap(),
+    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
+    /// For example,
+    /// \code
+    ///   CycleCanceling<ListDigraph> cc(graph);
+    ///   cc.lowerMap(lower).upperMap(upper).costMap(cost)
+    ///     .supplyMap(sup).run();
+    /// \endcode
+    ///
+    /// This function can be called more than once. All the given parameters
+    /// are kept for the next call, unless \ref resetParams() or \ref reset()
+    /// is used, thus only the modified parameters have to be set again.
+    /// If the underlying digraph was also modified after the construction
+    /// of the class (or the last \ref reset() call), then the \ref reset()
+    /// function must be called.
+    ///
+    /// \param method The cycle-canceling method that will be used.
+    /// For more information, see \ref Method.
+    ///
+    /// \return \c INFEASIBLE if no feasible flow exists,
+    /// \n \c OPTIMAL if the problem has optimal solution
+    /// (i.e. it is feasible and bounded), and the algorithm has found
+    /// optimal flow and node potentials (primal and dual solutions),
+    /// \n \c UNBOUNDED if the digraph contains an arc of negative cost
+    /// and infinite upper bound. It means that the objective function
+    /// is unbounded on that arc, however, note that it could actually be
+    /// bounded over the feasible flows, but this algroithm cannot handle
+    /// these cases.
+    ///
+    /// \see ProblemType, Method
+    /// \see resetParams(), reset()
+    ProblemType run(Method method = CANCEL_AND_TIGHTEN) {
+      ProblemType pt = init();
+      if (pt != OPTIMAL) return pt;
+      start(method);
+      return OPTIMAL;
+    }
+
+    /// \brief Reset all the parameters that have been given before.
+    ///
+    /// This function resets all the paramaters that have been given
+    /// before using functions \ref lowerMap(), \ref upperMap(),
+    /// \ref costMap(), \ref supplyMap(), \ref stSupply().
+    ///
+    /// It is useful for multiple \ref run() calls. Basically, all the given
+    /// parameters are kept for the next \ref run() call, unless
+    /// \ref resetParams() or \ref reset() is used.
+    /// If the underlying digraph was also modified after the construction
+    /// of the class or the last \ref reset() call, then the \ref reset()
+    /// function must be used, otherwise \ref resetParams() is sufficient.
+    ///
+    /// For example,
+    /// \code
+    ///   CycleCanceling<ListDigraph> cs(graph);
+    ///
+    ///   // First run
+    ///   cc.lowerMap(lower).upperMap(upper).costMap(cost)
+    ///     .supplyMap(sup).run();
+    ///
+    ///   // Run again with modified cost map (resetParams() is not called,
+    ///   // so only the cost map have to be set again)
+    ///   cost[e] += 100;
+    ///   cc.costMap(cost).run();
+    ///
+    ///   // Run again from scratch using resetParams()
+    ///   // (the lower bounds will be set to zero on all arcs)
+    ///   cc.resetParams();
+    ///   cc.upperMap(capacity).costMap(cost)
+    ///     .supplyMap(sup).run();
+    /// \endcode
+    ///
+    /// \return <tt>(*this)</tt>
+    ///
+    /// \see reset(), run()
+    CycleCanceling& resetParams() {
+      for (int i = 0; i != _res_node_num; ++i) {
+        _supply[i] = 0;
+      }
+      int limit = _first_out[_root];
+      for (int j = 0; j != limit; ++j) {
+        _lower[j] = 0;
+        _upper[j] = INF;
+        _cost[j] = _forward[j] ? 1 : -1;
+      }
+      for (int j = limit; j != _res_arc_num; ++j) {
+        _lower[j] = 0;
+        _upper[j] = INF;
+        _cost[j] = 0;
+        _cost[_reverse[j]] = 0;
+      }
+      _have_lower = false;
+      return *this;
+    }
+
+    /// \brief Reset the internal data structures and all the parameters
+    /// that have been given before.
+    ///
+    /// This function resets the internal data structures and all the
+    /// paramaters that have been given before using functions \ref lowerMap(),
+    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
+    ///
+    /// It is useful for multiple \ref run() calls. Basically, all the given
+    /// parameters are kept for the next \ref run() call, unless
+    /// \ref resetParams() or \ref reset() is used.
+    /// If the underlying digraph was also modified after the construction
+    /// of the class or the last \ref reset() call, then the \ref reset()
+    /// function must be used, otherwise \ref resetParams() is sufficient.
+    ///
+    /// See \ref resetParams() for examples.
+    ///
+    /// \return <tt>(*this)</tt>
+    ///
+    /// \see resetParams(), run()
+    CycleCanceling& reset() {
+      // Resize vectors
+      _node_num = countNodes(_graph);
+      _arc_num = countArcs(_graph);
+      _res_node_num = _node_num + 1;
+      _res_arc_num = 2 * (_arc_num + _node_num);
+      _root = _node_num;
+
+      _first_out.resize(_res_node_num + 1);
+      _forward.resize(_res_arc_num);
+      _source.resize(_res_arc_num);
+      _target.resize(_res_arc_num);
+      _reverse.resize(_res_arc_num);
+
+      _lower.resize(_res_arc_num);
+      _upper.resize(_res_arc_num);
+      _cost.resize(_res_arc_num);
+      _supply.resize(_res_node_num);
+
+      _res_cap.resize(_res_arc_num);
+      _pi.resize(_res_node_num);
+
+      _arc_vec.reserve(_res_arc_num);
+      _cost_vec.reserve(_res_arc_num);
+      _id_vec.reserve(_res_arc_num);
+
+      // Copy the graph
+      int i = 0, j = 0, k = 2 * _arc_num + _node_num;
+      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
+        _node_id[n] = i;
+      }
+      i = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
+        _first_out[i] = j;
+        for (OutArcIt a(_graph, n); a != INVALID; ++a, ++j) {
+          _arc_idf[a] = j;
+          _forward[j] = true;
+          _source[j] = i;
+          _target[j] = _node_id[_graph.runningNode(a)];
+        }
+        for (InArcIt a(_graph, n); a != INVALID; ++a, ++j) {
+          _arc_idb[a] = j;
+          _forward[j] = false;
+          _source[j] = i;
+          _target[j] = _node_id[_graph.runningNode(a)];
+        }
+        _forward[j] = false;
+        _source[j] = i;
+        _target[j] = _root;
+        _reverse[j] = k;
+        _forward[k] = true;
+        _source[k] = _root;
+        _target[k] = i;
+        _reverse[k] = j;
+        ++j; ++k;
+      }
+      _first_out[i] = j;
+      _first_out[_res_node_num] = k;
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        int fi = _arc_idf[a];
+        int bi = _arc_idb[a];
+        _reverse[fi] = bi;
+        _reverse[bi] = fi;
+      }
+
+      // Reset parameters
+      resetParams();
+      return *this;
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The results of the algorithm can be obtained using these
+    /// functions.\n
+    /// The \ref run() function must be called before using them.
+
+    /// @{
+
+    /// \brief Return the total cost of the found flow.
+    ///
+    /// This function returns the total cost of the found flow.
+    /// Its complexity is O(e).
+    ///
+    /// \note The return type of the function can be specified as a
+    /// template parameter. For example,
+    /// \code
+    ///   cc.totalCost<double>();
+    /// \endcode
+    /// It is useful if the total cost cannot be stored in the \c Cost
+    /// type of the algorithm, which is the default return type of the
+    /// function.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    template <typename Number>
+    Number totalCost() const {
+      Number c = 0;
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        int i = _arc_idb[a];
+        c += static_cast<Number>(_res_cap[i]) *
+             (-static_cast<Number>(_cost[i]));
+      }
+      return c;
+    }
+
+#ifndef DOXYGEN
+    Cost totalCost() const {
+      return totalCost<Cost>();
+    }
+#endif
+
+    /// \brief Return the flow on the given arc.
+    ///
+    /// This function returns the flow on the given arc.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Value flow(const Arc& a) const {
+      return _res_cap[_arc_idb[a]];
+    }
+
+    /// \brief Return the flow map (the primal solution).
+    ///
+    /// This function copies the flow value on each arc into the given
+    /// map. The \c Value type of the algorithm must be convertible to
+    /// the \c Value type of the map.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    template <typename FlowMap>
+    void flowMap(FlowMap &map) const {
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        map.set(a, _res_cap[_arc_idb[a]]);
+      }
+    }
+
+    /// \brief Return the potential (dual value) of the given node.
+    ///
+    /// This function returns the potential (dual value) of the
+    /// given node.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Cost potential(const Node& n) const {
+      return static_cast<Cost>(_pi[_node_id[n]]);
+    }
+
+    /// \brief Return the potential map (the dual solution).
+    ///
+    /// This function copies the potential (dual value) of each node
+    /// into the given map.
+    /// The \c Cost type of the algorithm must be convertible to the
+    /// \c Value type of the map.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    template <typename PotentialMap>
+    void potentialMap(PotentialMap &map) const {
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        map.set(n, static_cast<Cost>(_pi[_node_id[n]]));
+      }
+    }
+
+    /// @}
+
+  private:
+
+    // Initialize the algorithm
+    ProblemType init() {
+      if (_res_node_num <= 1) return INFEASIBLE;
+
+      // Check the sum of supply values
+      _sum_supply = 0;
+      for (int i = 0; i != _root; ++i) {
+        _sum_supply += _supply[i];
+      }
+      if (_sum_supply > 0) return INFEASIBLE;
+
+
+      // Initialize vectors
+      for (int i = 0; i != _res_node_num; ++i) {
+        _pi[i] = 0;
+      }
+      ValueVector excess(_supply);
+
+      // Remove infinite upper bounds and check negative arcs
+      const Value MAX = std::numeric_limits<Value>::max();
+      int last_out;
+      if (_have_lower) {
+        for (int i = 0; i != _root; ++i) {
+          last_out = _first_out[i+1];
+          for (int j = _first_out[i]; j != last_out; ++j) {
+            if (_forward[j]) {
+              Value c = _cost[j] < 0 ? _upper[j] : _lower[j];
+              if (c >= MAX) return UNBOUNDED;
+              excess[i] -= c;
+              excess[_target[j]] += c;
+            }
+          }
+        }
+      } else {
+        for (int i = 0; i != _root; ++i) {
+          last_out = _first_out[i+1];
+          for (int j = _first_out[i]; j != last_out; ++j) {
+            if (_forward[j] && _cost[j] < 0) {
+              Value c = _upper[j];
+              if (c >= MAX) return UNBOUNDED;
+              excess[i] -= c;
+              excess[_target[j]] += c;
+            }
+          }
+        }
+      }
+      Value ex, max_cap = 0;
+      for (int i = 0; i != _res_node_num; ++i) {
+        ex = excess[i];
+        if (ex < 0) max_cap -= ex;
+      }
+      for (int j = 0; j != _res_arc_num; ++j) {
+        if (_upper[j] >= MAX) _upper[j] = max_cap;
+      }
+
+      // Initialize maps for Circulation and remove non-zero lower bounds
+      ConstMap<Arc, Value> low(0);
+      typedef typename Digraph::template ArcMap<Value> ValueArcMap;
+      typedef typename Digraph::template NodeMap<Value> ValueNodeMap;
+      ValueArcMap cap(_graph), flow(_graph);
+      ValueNodeMap sup(_graph);
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        sup[n] = _supply[_node_id[n]];
+      }
+      if (_have_lower) {
+        for (ArcIt a(_graph); a != INVALID; ++a) {
+          int j = _arc_idf[a];
+          Value c = _lower[j];
+          cap[a] = _upper[j] - c;
+          sup[_graph.source(a)] -= c;
+          sup[_graph.target(a)] += c;
+        }
+      } else {
+        for (ArcIt a(_graph); a != INVALID; ++a) {
+          cap[a] = _upper[_arc_idf[a]];
+        }
+      }
+
+      // Find a feasible flow using Circulation
+      Circulation<Digraph, ConstMap<Arc, Value>, ValueArcMap, ValueNodeMap>
+        circ(_graph, low, cap, sup);
+      if (!circ.flowMap(flow).run()) return INFEASIBLE;
+
+      // Set residual capacities and handle GEQ supply type
+      if (_sum_supply < 0) {
+        for (ArcIt a(_graph); a != INVALID; ++a) {
+          Value fa = flow[a];
+          _res_cap[_arc_idf[a]] = cap[a] - fa;
+          _res_cap[_arc_idb[a]] = fa;
+          sup[_graph.source(a)] -= fa;
+          sup[_graph.target(a)] += fa;
+        }
+        for (NodeIt n(_graph); n != INVALID; ++n) {
+          excess[_node_id[n]] = sup[n];
+        }
+        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
+          int u = _target[a];
+          int ra = _reverse[a];
+          _res_cap[a] = -_sum_supply + 1;
+          _res_cap[ra] = -excess[u];
+          _cost[a] = 0;
+          _cost[ra] = 0;
+        }
+      } else {
+        for (ArcIt a(_graph); a != INVALID; ++a) {
+          Value fa = flow[a];
+          _res_cap[_arc_idf[a]] = cap[a] - fa;
+          _res_cap[_arc_idb[a]] = fa;
+        }
+        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
+          int ra = _reverse[a];
+          _res_cap[a] = 1;
+          _res_cap[ra] = 0;
+          _cost[a] = 0;
+          _cost[ra] = 0;
+        }
+      }
+
+      return OPTIMAL;
+    }
+
+    // Build a StaticDigraph structure containing the current
+    // residual network
+    void buildResidualNetwork() {
+      _arc_vec.clear();
+      _cost_vec.clear();
+      _id_vec.clear();
+      for (int j = 0; j != _res_arc_num; ++j) {
+        if (_res_cap[j] > 0) {
+          _arc_vec.push_back(IntPair(_source[j], _target[j]));
+          _cost_vec.push_back(_cost[j]);
+          _id_vec.push_back(j);
+        }
+      }
+      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
+    }
+
+    // Execute the algorithm and transform the results
+    void start(Method method) {
+      // Execute the algorithm
+      switch (method) {
+        case SIMPLE_CYCLE_CANCELING:
+          startSimpleCycleCanceling();
+          break;
+        case MINIMUM_MEAN_CYCLE_CANCELING:
+          startMinMeanCycleCanceling();
+          break;
+        case CANCEL_AND_TIGHTEN:
+          startCancelAndTighten();
+          break;
+      }
+
+      // Compute node potentials
+      if (method != SIMPLE_CYCLE_CANCELING) {
+        buildResidualNetwork();
+        typename BellmanFord<StaticDigraph, CostArcMap>
+          ::template SetDistMap<CostNodeMap>::Create bf(_sgr, _cost_map);
+        bf.distMap(_pi_map);
+        bf.init(0);
+        bf.start();
+      }
+
+      // Handle non-zero lower bounds
+      if (_have_lower) {
+        int limit = _first_out[_root];
+        for (int j = 0; j != limit; ++j) {
+          if (!_forward[j]) _res_cap[j] += _lower[j];
+        }
+      }
+    }
+
+    // Execute the "Simple Cycle Canceling" method
+    void startSimpleCycleCanceling() {
+      // Constants for computing the iteration limits
+      const int BF_FIRST_LIMIT  = 2;
+      const double BF_LIMIT_FACTOR = 1.5;
+
+      typedef StaticVectorMap<StaticDigraph::Arc, Value> FilterMap;
+      typedef FilterArcs<StaticDigraph, FilterMap> ResDigraph;
+      typedef StaticVectorMap<StaticDigraph::Node, StaticDigraph::Arc> PredMap;
+      typedef typename BellmanFord<ResDigraph, CostArcMap>
+        ::template SetDistMap<CostNodeMap>
+        ::template SetPredMap<PredMap>::Create BF;
+
+      // Build the residual network
+      _arc_vec.clear();
+      _cost_vec.clear();
+      for (int j = 0; j != _res_arc_num; ++j) {
+        _arc_vec.push_back(IntPair(_source[j], _target[j]));
+        _cost_vec.push_back(_cost[j]);
+      }
+      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
+
+      FilterMap filter_map(_res_cap);
+      ResDigraph rgr(_sgr, filter_map);
+      std::vector<int> cycle;
+      std::vector<StaticDigraph::Arc> pred(_res_arc_num);
+      PredMap pred_map(pred);
+      BF bf(rgr, _cost_map);
+      bf.distMap(_pi_map).predMap(pred_map);
+
+      int length_bound = BF_FIRST_LIMIT;
+      bool optimal = false;
+      while (!optimal) {
+        bf.init(0);
+        int iter_num = 0;
+        bool cycle_found = false;
+        while (!cycle_found) {
+          // Perform some iterations of the Bellman-Ford algorithm
+          int curr_iter_num = iter_num + length_bound <= _node_num ?
+            length_bound : _node_num - iter_num;
+          iter_num += curr_iter_num;
+          int real_iter_num = curr_iter_num;
+          for (int i = 0; i < curr_iter_num; ++i) {
+            if (bf.processNextWeakRound()) {
+              real_iter_num = i;
+              break;
+            }
+          }
+          if (real_iter_num < curr_iter_num) {
+            // Optimal flow is found
+            optimal = true;
+            break;
+          } else {
+            // Search for node disjoint negative cycles
+            std::vector<int> state(_res_node_num, 0);
+            int id = 0;
+            for (int u = 0; u != _res_node_num; ++u) {
+              if (state[u] != 0) continue;
+              ++id;
+              int v = u;
+              for (; v != -1 && state[v] == 0; v = pred[v] == INVALID ?
+                   -1 : rgr.id(rgr.source(pred[v]))) {
+                state[v] = id;
+              }
+              if (v != -1 && state[v] == id) {
+                // A negative cycle is found
+                cycle_found = true;
+                cycle.clear();
+                StaticDigraph::Arc a = pred[v];
+                Value d, delta = _res_cap[rgr.id(a)];
+                cycle.push_back(rgr.id(a));
+                while (rgr.id(rgr.source(a)) != v) {
+                  a = pred_map[rgr.source(a)];
+                  d = _res_cap[rgr.id(a)];
+                  if (d < delta) delta = d;
+                  cycle.push_back(rgr.id(a));
+                }
+
+                // Augment along the cycle
+                for (int i = 0; i < int(cycle.size()); ++i) {
+                  int j = cycle[i];
+                  _res_cap[j] -= delta;
+                  _res_cap[_reverse[j]] += delta;
+                }
+              }
+            }
+          }
+
+          // Increase iteration limit if no cycle is found
+          if (!cycle_found) {
+            length_bound = static_cast<int>(length_bound * BF_LIMIT_FACTOR);
+          }
+        }
+      }
+    }
+
+    // Execute the "Minimum Mean Cycle Canceling" method
+    void startMinMeanCycleCanceling() {
+      typedef SimplePath<StaticDigraph> SPath;
+      typedef typename SPath::ArcIt SPathArcIt;
+      typedef typename HowardMmc<StaticDigraph, CostArcMap>
+        ::template SetPath<SPath>::Create MMC;
+
+      SPath cycle;
+      MMC mmc(_sgr, _cost_map);
+      mmc.cycle(cycle);
+      buildResidualNetwork();
+      while (mmc.findCycleMean() && mmc.cycleCost() < 0) {
+        // Find the cycle
+        mmc.findCycle();
+
+        // Compute delta value
+        Value delta = INF;
+        for (SPathArcIt a(cycle); a != INVALID; ++a) {
+          Value d = _res_cap[_id_vec[_sgr.id(a)]];
+          if (d < delta) delta = d;
+        }
+
+        // Augment along the cycle
+        for (SPathArcIt a(cycle); a != INVALID; ++a) {
+          int j = _id_vec[_sgr.id(a)];
+          _res_cap[j] -= delta;
+          _res_cap[_reverse[j]] += delta;
+        }
+
+        // Rebuild the residual network
+        buildResidualNetwork();
+      }
+    }
+
+    // Execute the "Cancel And Tighten" method
+    void startCancelAndTighten() {
+      // Constants for the min mean cycle computations
+      const double LIMIT_FACTOR = 1.0;
+      const int MIN_LIMIT = 5;
+
+      // Contruct auxiliary data vectors
+      DoubleVector pi(_res_node_num, 0.0);
+      IntVector level(_res_node_num);
+      BoolVector reached(_res_node_num);
+      BoolVector processed(_res_node_num);
+      IntVector pred_node(_res_node_num);
+      IntVector pred_arc(_res_node_num);
+      std::vector<int> stack(_res_node_num);
+      std::vector<int> proc_vector(_res_node_num);
+
+      // Initialize epsilon
+      double epsilon = 0;
+      for (int a = 0; a != _res_arc_num; ++a) {
+        if (_res_cap[a] > 0 && -_cost[a] > epsilon)
+          epsilon = -_cost[a];
+      }
+
+      // Start phases
+      Tolerance<double> tol;
+      tol.epsilon(1e-6);
+      int limit = int(LIMIT_FACTOR * std::sqrt(double(_res_node_num)));
+      if (limit < MIN_LIMIT) limit = MIN_LIMIT;
+      int iter = limit;
+      while (epsilon * _res_node_num >= 1) {
+        // Find and cancel cycles in the admissible network using DFS
+        for (int u = 0; u != _res_node_num; ++u) {
+          reached[u] = false;
+          processed[u] = false;
+        }
+        int stack_head = -1;
+        int proc_head = -1;
+        for (int start = 0; start != _res_node_num; ++start) {
+          if (reached[start]) continue;
+
+          // New start node
+          reached[start] = true;
+          pred_arc[start] = -1;
+          pred_node[start] = -1;
+
+          // Find the first admissible outgoing arc
+          double p = pi[start];
+          int a = _first_out[start];
+          int last_out = _first_out[start+1];
+          for (; a != last_out && (_res_cap[a] == 0 ||
+               !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ;
+          if (a == last_out) {
+            processed[start] = true;
+            proc_vector[++proc_head] = start;
+            continue;
+          }
+          stack[++stack_head] = a;
+
+          while (stack_head >= 0) {
+            int sa = stack[stack_head];
+            int u = _source[sa];
+            int v = _target[sa];
+
+            if (!reached[v]) {
+              // A new node is reached
+              reached[v] = true;
+              pred_node[v] = u;
+              pred_arc[v] = sa;
+              p = pi[v];
+              a = _first_out[v];
+              last_out = _first_out[v+1];
+              for (; a != last_out && (_res_cap[a] == 0 ||
+                   !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ;
+              stack[++stack_head] = a == last_out ? -1 : a;
+            } else {
+              if (!processed[v]) {
+                // A cycle is found
+                int n, w = u;
+                Value d, delta = _res_cap[sa];
+                for (n = u; n != v; n = pred_node[n]) {
+                  d = _res_cap[pred_arc[n]];
+                  if (d <= delta) {
+                    delta = d;
+                    w = pred_node[n];
+                  }
+                }
+
+                // Augment along the cycle
+                _res_cap[sa] -= delta;
+                _res_cap[_reverse[sa]] += delta;
+                for (n = u; n != v; n = pred_node[n]) {
+                  int pa = pred_arc[n];
+                  _res_cap[pa] -= delta;
+                  _res_cap[_reverse[pa]] += delta;
+                }
+                for (n = u; stack_head > 0 && n != w; n = pred_node[n]) {
+                  --stack_head;
+                  reached[n] = false;
+                }
+                u = w;
+              }
+              v = u;
+
+              // Find the next admissible outgoing arc
+              p = pi[v];
+              a = stack[stack_head] + 1;
+              last_out = _first_out[v+1];
+              for (; a != last_out && (_res_cap[a] == 0 ||
+                   !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ;
+              stack[stack_head] = a == last_out ? -1 : a;
+            }
+
+            while (stack_head >= 0 && stack[stack_head] == -1) {
+              processed[v] = true;
+              proc_vector[++proc_head] = v;
+              if (--stack_head >= 0) {
+                // Find the next admissible outgoing arc
+                v = _source[stack[stack_head]];
+                p = pi[v];
+                a = stack[stack_head] + 1;
+                last_out = _first_out[v+1];
+                for (; a != last_out && (_res_cap[a] == 0 ||
+                     !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ;
+                stack[stack_head] = a == last_out ? -1 : a;
+              }
+            }
+          }
+        }
+
+        // Tighten potentials and epsilon
+        if (--iter > 0) {
+          for (int u = 0; u != _res_node_num; ++u) {
+            level[u] = 0;
+          }
+          for (int i = proc_head; i > 0; --i) {
+            int u = proc_vector[i];
+            double p = pi[u];
+            int l = level[u] + 1;
+            int last_out = _first_out[u+1];
+            for (int a = _first_out[u]; a != last_out; ++a) {
+              int v = _target[a];
+              if (_res_cap[a] > 0 && tol.negative(_cost[a] + p - pi[v]) &&
+                  l > level[v]) level[v] = l;
+            }
+          }
+
+          // Modify potentials
+          double q = std::numeric_limits<double>::max();
+          for (int u = 0; u != _res_node_num; ++u) {
+            int lu = level[u];
+            double p, pu = pi[u];
+            int last_out = _first_out[u+1];
+            for (int a = _first_out[u]; a != last_out; ++a) {
+              if (_res_cap[a] == 0) continue;
+              int v = _target[a];
+              int ld = lu - level[v];
+              if (ld > 0) {
+                p = (_cost[a] + pu - pi[v] + epsilon) / (ld + 1);
+                if (p < q) q = p;
+              }
+            }
+          }
+          for (int u = 0; u != _res_node_num; ++u) {
+            pi[u] -= q * level[u];
+          }
+
+          // Modify epsilon
+          epsilon = 0;
+          for (int u = 0; u != _res_node_num; ++u) {
+            double curr, pu = pi[u];
+            int last_out = _first_out[u+1];
+            for (int a = _first_out[u]; a != last_out; ++a) {
+              if (_res_cap[a] == 0) continue;
+              curr = _cost[a] + pu - pi[_target[a]];
+              if (-curr > epsilon) epsilon = -curr;
+            }
+          }
+        } else {
+          typedef HowardMmc<StaticDigraph, CostArcMap> MMC;
+          typedef typename BellmanFord<StaticDigraph, CostArcMap>
+            ::template SetDistMap<CostNodeMap>::Create BF;
+
+          // Set epsilon to the minimum cycle mean
+          buildResidualNetwork();
+          MMC mmc(_sgr, _cost_map);
+          mmc.findCycleMean();
+          epsilon = -mmc.cycleMean();
+          Cost cycle_cost = mmc.cycleCost();
+          int cycle_size = mmc.cycleSize();
+
+          // Compute feasible potentials for the current epsilon
+          for (int i = 0; i != int(_cost_vec.size()); ++i) {
+            _cost_vec[i] = cycle_size * _cost_vec[i] - cycle_cost;
+          }
+          BF bf(_sgr, _cost_map);
+          bf.distMap(_pi_map);
+          bf.init(0);
+          bf.start();
+          for (int u = 0; u != _res_node_num; ++u) {
+            pi[u] = static_cast<double>(_pi[u]) / cycle_size;
+          }
+
+          iter = limit;
+        }
+      }
+    }
+
+  }; //class CycleCanceling
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_CYCLE_CANCELING_H
Index: lemon/dfs.h
===================================================================
--- lemon/dfs.h	(revision 492)
+++ lemon/dfs.h	(revision 966)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -48,5 +48,5 @@
     ///The type of the map that stores the predecessor
     ///arcs of the %DFS paths.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
     ///Instantiates a \c PredMap.
@@ -63,5 +63,6 @@
 
     ///The type of the map that indicates which nodes are processed.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    ///By default, it is a NullMap.
     typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
     ///Instantiates a \c ProcessedMap.
@@ -82,5 +83,6 @@
 
     ///The type of the map that indicates which nodes are reached.
-    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    ///It must conform to
+    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     typedef typename Digraph::template NodeMap<bool> ReachedMap;
     ///Instantiates a \c ReachedMap.
@@ -97,5 +99,5 @@
 
     ///The type of the map that stores the distances of the nodes.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     typedef typename Digraph::template NodeMap<int> DistMap;
     ///Instantiates a \c DistMap.
@@ -121,4 +123,9 @@
   ///\tparam GR The type of the digraph the algorithm runs on.
   ///The default type is \ref ListDigraph.
+  ///\tparam TR The traits class that defines various types used by the
+  ///algorithm. By default, it is \ref DfsDefaultTraits
+  ///"DfsDefaultTraits<GR>".
+  ///In most cases, this parameter should not be set directly,
+  ///consider to use the named template parameters instead.
 #ifdef DOXYGEN
   template <typename GR,
@@ -207,5 +214,5 @@
     typedef Dfs Create;
 
-    ///\name Named template parameters
+    ///\name Named Template Parameters
 
     ///@{
@@ -225,5 +232,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///\c PredMap type.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetPredMap : public Dfs<Digraph, SetPredMapTraits<T> > {
@@ -245,5 +252,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///\c DistMap type.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetDistMap : public Dfs< Digraph, SetDistMapTraits<T> > {
@@ -265,5 +272,6 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///\c ReachedMap type.
-    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    ///It must conform to
+    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     template <class T>
     struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits<T> > {
@@ -285,5 +293,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///\c ProcessedMap type.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetProcessedMap : public Dfs< Digraph, SetProcessedMapTraits<T> > {
@@ -412,6 +420,6 @@
     ///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()
+    ///If you need better control on the execution, you have to call
+    ///\ref init() first, 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
@@ -558,5 +566,5 @@
     void start(Node t)
     {
-      while ( !emptyQueue() && G->target(_stack[_stack_head])!=t )
+      while ( !emptyQueue() && !(*_reached)[t] )
         processNextArc();
     }
@@ -633,10 +641,6 @@
     ///Runs the algorithm to visit all nodes in the digraph.
 
-    ///This method runs the %DFS algorithm in order to compute the
-    ///%DFS path to each node.
-    ///
-    ///The algorithm computes
-    ///- the %DFS tree (forest),
-    ///- the distance of each node from the root(s) in the %DFS tree.
+    ///This method runs the %DFS algorithm in order to visit all nodes
+    ///in the digraph.
     ///
     ///\note <tt>d.run()</tt> is just a shortcut of the following code.
@@ -670,7 +674,7 @@
     ///@{
 
-    ///The DFS path to a node.
-
-    ///Returns the DFS path to a node.
+    ///The DFS path to the given node.
+
+    ///Returns the DFS path to the given node from the root(s).
     ///
     ///\warning \c t should be reached from the root(s).
@@ -680,7 +684,7 @@
     Path path(Node t) const { return Path(*G, *_pred, t); }
 
-    ///The distance of a node from the root(s).
-
-    ///Returns the distance of a node from the root(s).
+    ///The distance of the given node from the root(s).
+
+    ///Returns the distance of the given node from the root(s).
     ///
     ///\warning If node \c v is not reached from the root(s), then
@@ -691,5 +695,5 @@
     int dist(Node v) const { return (*_dist)[v]; }
 
-    ///Returns the 'previous arc' of the %DFS tree for a node.
+    ///Returns the 'previous arc' of the %DFS tree for the given node.
 
     ///This function returns the 'previous arc' of the %DFS tree for the
@@ -699,5 +703,5 @@
     ///
     ///The %DFS tree used here is equal to the %DFS tree used in
-    ///\ref predNode().
+    ///\ref predNode() and \ref predMap().
     ///
     ///\pre Either \ref run(Node) "run()" or \ref init()
@@ -705,13 +709,13 @@
     Arc predArc(Node v) const { return (*_pred)[v];}
 
-    ///Returns the 'previous node' of the %DFS tree.
+    ///Returns the 'previous node' of the %DFS tree for the given node.
 
     ///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 a root to \c v. It is \c INVALID
+    ///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 predArc().
+    ///\ref predArc() and \ref predMap().
     ///
     ///\pre Either \ref run(Node) "run()" or \ref init()
@@ -734,5 +738,5 @@
     ///
     ///Returns a const reference to the node map that stores the predecessor
-    ///arcs, which form the DFS tree.
+    ///arcs, which form the DFS tree (forest).
     ///
     ///\pre Either \ref run(Node) "run()" or \ref init()
@@ -740,5 +744,5 @@
     const PredMap &predMap() const { return *_pred;}
 
-    ///Checks if a node is reached from the root(s).
+    ///Checks if the given node. node is reached from the root(s).
 
     ///Returns \c true if \c v is reached from the root(s).
@@ -766,5 +770,5 @@
     ///The type of the map that stores the predecessor
     ///arcs of the %DFS paths.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
     ///Instantiates a PredMap.
@@ -781,6 +785,6 @@
 
     ///The type of the map that indicates which nodes are processed.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
-    ///By default it is a NullMap.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    ///By default, it is a NullMap.
     typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
     ///Instantiates a ProcessedMap.
@@ -801,5 +805,6 @@
 
     ///The type of the map that indicates which nodes are reached.
-    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    ///It must conform to
+    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     typedef typename Digraph::template NodeMap<bool> ReachedMap;
     ///Instantiates a ReachedMap.
@@ -816,5 +821,5 @@
 
     ///The type of the map that stores the distances of the nodes.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     typedef typename Digraph::template NodeMap<int> DistMap;
     ///Instantiates a DistMap.
@@ -831,5 +836,5 @@
 
     ///The type of the DFS paths.
-    ///It must meet the \ref concepts::Path "Path" concept.
+    ///It must conform to the \ref concepts::Path "Path" concept.
     typedef lemon::Path<Digraph> Path;
   };
@@ -837,10 +842,6 @@
   /// Default traits class used by DfsWizard
 
-  /// To make it easier to use Dfs algorithm
-  /// we have created a wizard class.
-  /// This \ref DfsWizard class needs default traits,
-  /// as well as the \ref Dfs class.
-  /// The \ref DfsWizardBase is a class to be the default traits of the
-  /// \ref DfsWizard class.
+  /// Default traits class used by DfsWizard.
+  /// \tparam GR The type of the digraph.
   template<class GR>
   class DfsWizardBase : public DfsWizardDefaultTraits<GR>
@@ -870,5 +871,5 @@
     /// Constructor.
 
-    /// This constructor does not require parameters, therefore it initiates
+    /// This constructor does not require parameters, it initiates
     /// all of the attributes to \c 0.
     DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
@@ -895,4 +896,7 @@
   /// This class should only be used through the \ref dfs() function,
   /// which makes it easier to use the algorithm.
+  ///
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm.
   template<class TR>
   class DfsWizard : public TR
@@ -900,5 +904,4 @@
     typedef TR Base;
 
-    ///The type of the digraph the algorithm runs on.
     typedef typename TR::Digraph Digraph;
 
@@ -908,14 +911,8 @@
     typedef typename Digraph::OutArcIt OutArcIt;
 
-    ///\brief The type of the map that stores the predecessor
-    ///arcs of the DFS paths.
     typedef typename TR::PredMap PredMap;
-    ///\brief The type of the map that stores the distances of the nodes.
     typedef typename TR::DistMap DistMap;
-    ///\brief The type of the map that indicates which nodes are reached.
     typedef typename TR::ReachedMap ReachedMap;
-    ///\brief The type of the map that indicates which nodes are processed.
     typedef typename TR::ProcessedMap ProcessedMap;
-    ///The type of the DFS paths
     typedef typename TR::Path Path;
 
@@ -987,6 +984,6 @@
     ///Runs DFS algorithm to visit all nodes in the digraph.
 
-    ///This method runs DFS algorithm in order to compute
-    ///the DFS path to each node.
+    ///This method runs DFS algorithm in order to visit all nodes
+    ///in the digraph.
     void run()
     {
@@ -1000,9 +997,10 @@
       SetPredMapBase(const TR &b) : TR(b) {}
     };
-    ///\brief \ref named-func-param "Named parameter"
-    ///for setting PredMap object.
-    ///
-    ///\ref named-func-param "Named parameter"
-    ///for setting PredMap object.
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the predecessor map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that stores the predecessor arcs of the nodes.
     template<class T>
     DfsWizard<SetPredMapBase<T> > predMap(const T &t)
@@ -1018,9 +1016,10 @@
       SetReachedMapBase(const TR &b) : TR(b) {}
     };
-    ///\brief \ref named-func-param "Named parameter"
-    ///for setting ReachedMap object.
-    ///
-    /// \ref named-func-param "Named parameter"
-    ///for setting ReachedMap object.
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the reached map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that indicates which nodes are reached.
     template<class T>
     DfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
@@ -1036,9 +1035,11 @@
       SetDistMapBase(const TR &b) : TR(b) {}
     };
-    ///\brief \ref named-func-param "Named parameter"
-    ///for setting DistMap object.
-    ///
-    /// \ref named-func-param "Named parameter"
-    ///for setting DistMap object.
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the distance map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that stores the distances of the nodes calculated
+    ///by the algorithm.
     template<class T>
     DfsWizard<SetDistMapBase<T> > distMap(const T &t)
@@ -1054,9 +1055,10 @@
       SetProcessedMapBase(const TR &b) : TR(b) {}
     };
-    ///\brief \ref named-func-param "Named parameter"
-    ///for setting ProcessedMap object.
-    ///
-    /// \ref named-func-param "Named parameter"
-    ///for setting ProcessedMap object.
+
+    ///\brief \ref named-func-param "Named parameter" for setting
+    ///the processed map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that indicates which nodes are processed.
     template<class T>
     DfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
@@ -1192,4 +1194,5 @@
       }
       _Visitor& visitor;
+      Constraints() {}
     };
   };
@@ -1209,5 +1212,6 @@
     ///
     /// The type of the map that indicates which nodes are reached.
-    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    /// It must conform to the
+    /// \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     typedef typename Digraph::template NodeMap<bool> ReachedMap;
 
@@ -1247,9 +1251,9 @@
   /// does not observe the DFS events. If you want to observe the DFS
   /// events, you should implement your own visitor class.
-  /// \tparam TR Traits class to set various data types used by the
-  /// algorithm. The default traits class is
-  /// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<GR>".
-  /// See \ref DfsVisitDefaultTraits for the documentation of
-  /// a DFS visit traits class.
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm. By default, it is \ref DfsVisitDefaultTraits
+  /// "DfsVisitDefaultTraits<GR>".
+  /// In most cases, this parameter should not be set directly,
+  /// consider to use the named template parameters instead.
 #ifdef DOXYGEN
   template <typename GR, typename VS, typename TR>
@@ -1370,6 +1374,6 @@
     /// 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()
+    /// If you need better control on the execution, you have to call
+    /// \ref init() first, 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
@@ -1510,5 +1514,5 @@
     /// with addSource() before using this function.
     void start(Node t) {
-      while ( !emptyQueue() && _digraph->target(_stack[_stack_head]) != t )
+      while ( !emptyQueue() && !(*_reached)[t] )
         processNextArc();
     }
@@ -1584,10 +1588,6 @@
     /// \brief Runs the algorithm to visit all nodes in the digraph.
 
-    /// This method runs the %DFS algorithm in order to
-    /// compute the %DFS path to each node.
-    ///
-    /// The algorithm computes
-    /// - the %DFS tree (forest),
-    /// - the distance of each node from the root(s) in the %DFS tree.
+    /// This method runs the %DFS algorithm in order to visit all nodes
+    /// in the digraph.
     ///
     /// \note <tt>d.run()</tt> is just a shortcut of the following code.
@@ -1621,5 +1621,5 @@
     ///@{
 
-    /// \brief Checks if a node is reached from the root(s).
+    /// \brief Checks if the given node is reached from the root(s).
     ///
     /// Returns \c true if \c v is reached from the root(s).
Index: lemon/dheap.h
===================================================================
--- lemon/dheap.h	(revision 855)
+++ lemon/dheap.h	(revision 855)
@@ -0,0 +1,352 @@
+/* -*- 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_DHEAP_H
+#define LEMON_DHEAP_H
+
+///\ingroup heaps
+///\file
+///\brief D-ary heap implementation.
+
+#include <vector>
+#include <utility>
+#include <functional>
+
+namespace lemon {
+
+  /// \ingroup heaps
+  ///
+  ///\brief D-ary heap data structure.
+  ///
+  /// This class implements the \e D-ary \e heap data structure.
+  /// It fully conforms to the \ref concepts::Heap "heap concept".
+  ///
+  /// The \ref DHeap "D-ary heap" is a generalization of the
+  /// \ref BinHeap "binary heap" structure, its nodes have at most
+  /// \c D children, instead of two.
+  /// \ref BinHeap and \ref QuadHeap are specialized implementations
+  /// of this structure for <tt>D=2</tt> and <tt>D=4</tt>, respectively.
+  ///
+  /// \tparam PR Type of the priorities of the items.
+  /// \tparam IM A read-writable item map with \c int values, used
+  /// internally to handle the cross references.
+  /// \tparam D The degree of the heap, each node have at most \e D
+  /// children. The default is 16. Powers of two are suggested to use
+  /// so that the multiplications and divisions needed to traverse the
+  /// nodes of the heap could be performed faster.
+  /// \tparam CMP A functor class for comparing the priorities.
+  /// The default is \c std::less<PR>.
+  ///
+  ///\sa BinHeap
+  ///\sa FouraryHeap
+#ifdef DOXYGEN
+  template <typename PR, typename IM, int D, typename CMP>
+#else
+  template <typename PR, typename IM, int D = 16,
+            typename CMP = std::less<PR> >
+#endif
+  class DHeap {
+  public:
+    /// Type of the item-int map.
+    typedef IM ItemIntMap;
+    /// Type of the priorities.
+    typedef PR Prio;
+    /// Type of the items stored in the heap.
+    typedef typename ItemIntMap::Key Item;
+    /// Type of the item-priority pairs.
+    typedef std::pair<Item,Prio> Pair;
+    /// Functor type for comparing the priorities.
+    typedef CMP Compare;
+
+    /// \brief Type to represent the states of the items.
+    ///
+    /// Each item has a state associated to it. It can be "in heap",
+    /// "pre-heap" or "post-heap". The latter two are indifferent from the
+    /// heap's point of view, but may be useful to the user.
+    ///
+    /// The item-int map must be initialized in such way that it assigns
+    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
+    enum State {
+      IN_HEAP = 0,    ///< = 0.
+      PRE_HEAP = -1,  ///< = -1.
+      POST_HEAP = -2  ///< = -2.
+    };
+
+  private:
+    std::vector<Pair> _data;
+    Compare _comp;
+    ItemIntMap &_iim;
+
+  public:
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    explicit DHeap(ItemIntMap &map) : _iim(map) {}
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    /// \param comp The function object used for comparing the priorities.
+    DHeap(ItemIntMap &map, const Compare &comp)
+      : _iim(map), _comp(comp) {}
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// This function returns the number of items stored in the heap.
+    int size() const { return _data.size(); }
+
+    /// \brief Check if the heap is empty.
+    ///
+    /// This function returns \c true if the heap is empty.
+    bool empty() const { return _data.empty(); }
+
+    /// \brief Make the heap empty.
+    ///
+    /// This functon makes the heap empty.
+    /// It does not change the cross reference map. If you want to reuse
+    /// a heap that is not surely empty, you should first clear it and
+    /// then you should set the cross reference map to \c PRE_HEAP
+    /// for each item.
+    void clear() { _data.clear(); }
+
+  private:
+    int parent(int i) { return (i-1)/D; }
+    int firstChild(int i) { return D*i+1; }
+
+    bool less(const Pair &p1, const Pair &p2) const {
+      return _comp(p1.second, p2.second);
+    }
+
+    void bubbleUp(int hole, Pair p) {
+      int par = parent(hole);
+      while( hole>0 && less(p,_data[par]) ) {
+        move(_data[par],hole);
+        hole = par;
+        par = parent(hole);
+      }
+      move(p, hole);
+    }
+
+    void bubbleDown(int hole, Pair p, int length) {
+      if( length>1 ) {
+        int child = firstChild(hole);
+        while( child+D<=length ) {
+          int min=child;
+          for (int i=1; i<D; ++i) {
+            if( less(_data[child+i], _data[min]) )
+              min=child+i;
+          }
+          if( !less(_data[min], p) )
+            goto ok;
+          move(_data[min], hole);
+          hole = min;
+          child = firstChild(hole);
+        }
+        if ( child<length ) {
+          int min = child;
+          while (++child < length) {
+            if( less(_data[child], _data[min]) )
+              min=child;
+          }
+          if( less(_data[min], p) ) {
+            move(_data[min], hole);
+            hole = min;
+          }
+        }
+      }
+    ok:
+      move(p, hole);
+    }
+
+    void move(const Pair &p, int i) {
+      _data[i] = p;
+      _iim.set(p.first, i);
+    }
+
+  public:
+    /// \brief Insert a pair of item and priority into the heap.
+    ///
+    /// This function inserts \c p.first to the heap with priority
+    /// \c p.second.
+    /// \param p The pair to insert.
+    /// \pre \c p.first must not be stored in the heap.
+    void push(const Pair &p) {
+      int n = _data.size();
+      _data.resize(n+1);
+      bubbleUp(n, p);
+    }
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// This function inserts the given item into the heap with the
+    /// given priority.
+    /// \param i The item to insert.
+    /// \param p The priority of the item.
+    /// \pre \e i must not be stored in the heap.
+    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
+
+    /// \brief Return the item having minimum priority.
+    ///
+    /// This function returns the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    Item top() const { return _data[0].first; }
+
+    /// \brief The minimum priority.
+    ///
+    /// This function returns the minimum priority.
+    /// \pre The heap must be non-empty.
+    Prio prio() const { return _data[0].second; }
+
+    /// \brief Remove the item having minimum priority.
+    ///
+    /// This function removes the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      int n = _data.size()-1;
+      _iim.set(_data[0].first, POST_HEAP);
+      if (n>0) bubbleDown(0, _data[n], n);
+      _data.pop_back();
+    }
+
+    /// \brief Remove the given item from the heap.
+    ///
+    /// This function removes the given item from the heap if it is
+    /// already stored.
+    /// \param i The item to delete.
+    /// \pre \e i must be in the heap.
+    void erase(const Item &i) {
+      int h = _iim[i];
+      int n = _data.size()-1;
+      _iim.set(_data[h].first, POST_HEAP);
+      if( h<n ) {
+        if( less(_data[parent(h)], _data[n]) )
+          bubbleDown(h, _data[n], n);
+        else
+          bubbleUp(h, _data[n]);
+      }
+      _data.pop_back();
+    }
+
+    /// \brief The priority of the given item.
+    ///
+    /// This function returns the priority of the given item.
+    /// \param i The item.
+    /// \pre \e i must be in the heap.
+    Prio operator[](const Item &i) const {
+      int idx = _iim[i];
+      return _data[idx].second;
+    }
+
+    /// \brief Set the priority of an item or insert it, if it is
+    /// not stored in the heap.
+    ///
+    /// This method sets the priority of the given item if it is
+    /// already stored in the heap. Otherwise it inserts the given
+    /// item into the heap with the given priority.
+    /// \param i The item.
+    /// \param p The priority.
+    void set(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      if( idx<0 )
+        push(i,p);
+      else if( _comp(p, _data[idx].second) )
+        bubbleUp(idx, Pair(i,p));
+      else
+        bubbleDown(idx, Pair(i,p), _data.size());
+    }
+
+    /// \brief Decrease the priority of an item to the given value.
+    ///
+    /// This function decreases the priority of an item to the given value.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be stored in the heap with priority at least \e p.
+    void decrease(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      bubbleUp(idx, Pair(i,p));
+    }
+
+    /// \brief Increase the priority of an item to the given value.
+    ///
+    /// This function increases the priority of an item to the given value.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be stored in the heap with priority at most \e p.
+    void increase(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      bubbleDown(idx, Pair(i,p), _data.size());
+    }
+
+    /// \brief Return the state of an item.
+    ///
+    /// This method returns \c PRE_HEAP if the given item has never
+    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
+    /// and \c POST_HEAP otherwise.
+    /// In the latter case it is possible that the item will get back
+    /// to the heap again.
+    /// \param i The item.
+    State state(const Item &i) const {
+      int s = _iim[i];
+      if (s>=0) s=0;
+      return State(s);
+    }
+
+    /// \brief Set the state of an item in the heap.
+    ///
+    /// This function sets the state of the given item in the heap.
+    /// It can be used to manually clear the heap when it is important
+    /// to achive better time complexity.
+    /// \param i The item.
+    /// \param st The state. It should not be \c IN_HEAP.
+    void state(const Item& i, State st) {
+      switch (st) {
+        case POST_HEAP:
+        case PRE_HEAP:
+          if (state(i) == IN_HEAP) erase(i);
+          _iim[i] = st;
+          break;
+        case IN_HEAP:
+          break;
+      }
+    }
+
+    /// \brief Replace an item in the heap.
+    ///
+    /// This function replaces item \c i with item \c j.
+    /// Item \c i must be in the heap, while \c j must be out of the heap.
+    /// After calling this method, item \c i will be out of the
+    /// heap and \c j will be in the heap with the same prioriority
+    /// as item \c i had before.
+    void replace(const Item& i, const Item& j) {
+      int idx=_iim[i];
+      _iim.set(i, _iim[j]);
+      _iim.set(j, idx);
+      _data[idx].first=j;
+    }
+
+  }; // class DHeap
+
+} // namespace lemon
+
+#endif // LEMON_DHEAP_H
Index: lemon/dijkstra.h
===================================================================
--- lemon/dijkstra.h	(revision 559)
+++ lemon/dijkstra.h	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -71,7 +71,7 @@
 
     ///The type of the map that stores the arc lengths.
-    ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
+    ///It must conform to the \ref concepts::ReadMap "ReadMap" concept.
     typedef LEN LengthMap;
-    ///The type of the length of the arcs.
+    ///The type of the arc lengths.
     typedef typename LEN::Value Value;
 
@@ -117,5 +117,5 @@
     ///The type of the map that stores the predecessor
     ///arcs of the shortest paths.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
     ///Instantiates a \c PredMap.
@@ -132,6 +132,6 @@
 
     ///The type of the map that indicates which nodes are processed.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
-    ///By default it is a NullMap.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    ///By default, it is a NullMap.
     typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
     ///Instantiates a \c ProcessedMap.
@@ -152,5 +152,5 @@
 
     ///The type of the map that stores the distances of the nodes.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
     ///Instantiates a \c DistMap.
@@ -169,4 +169,8 @@
   /// \ingroup shortest_path
   ///This class provides an efficient implementation of the %Dijkstra algorithm.
+  ///
+  ///The %Dijkstra algorithm solves the single-source shortest path problem
+  ///when all arc lengths are non-negative. If there are negative lengths,
+  ///the BellmanFord algorithm should be used instead.
   ///
   ///The arc lengths are passed to the algorithm using a
@@ -189,4 +193,9 @@
   ///it is necessary. The default map type is \ref
   ///concepts::Digraph::ArcMap "GR::ArcMap<int>".
+  ///\tparam TR The traits class that defines various types used by the
+  ///algorithm. By default, it is \ref DijkstraDefaultTraits
+  ///"DijkstraDefaultTraits<GR, LEN>".
+  ///In most cases, this parameter should not be set directly,
+  ///consider to use the named template parameters instead.
 #ifdef DOXYGEN
   template <typename GR, typename LEN, typename TR>
@@ -202,6 +211,6 @@
     typedef typename TR::Digraph Digraph;
 
-    ///The type of the length of the arcs.
-    typedef typename TR::LengthMap::Value Value;
+    ///The type of the arc lengths.
+    typedef typename TR::Value Value;
     ///The type of the map that stores the arc lengths.
     typedef typename TR::LengthMap LengthMap;
@@ -287,5 +296,5 @@
     typedef Dijkstra Create;
 
-    ///\name Named template parameters
+    ///\name Named Template Parameters
 
     ///@{
@@ -305,5 +314,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///\c PredMap type.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetPredMap
@@ -326,5 +335,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///\c DistMap type.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetDistMap
@@ -347,5 +356,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///\c ProcessedMap type.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     template <class T>
     struct SetProcessedMap
@@ -423,5 +432,5 @@
     ///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
+    ///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().
@@ -444,4 +453,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///\c OperationTraits type.
+    /// For more information, see \ref DijkstraDefaultOperationTraits.
     template <class T>
     struct SetOperationTraits
@@ -585,6 +595,6 @@
     ///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
+    ///If you need better control on the execution, you have to call
+    ///\ref init() first, 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.
@@ -802,12 +812,12 @@
     ///The results of the %Dijkstra algorithm can be obtained using these
     ///functions.\n
-    ///Either \ref run(Node) "run()" or \ref start() should be called
+    ///Either \ref run(Node) "run()" or \ref init() should be called
     ///before using them.
 
     ///@{
 
-    ///The shortest path to a node.
-
-    ///Returns the shortest path to a node.
+    ///The shortest path to the given node.
+
+    ///Returns the shortest path to the given node from the root(s).
     ///
     ///\warning \c t should be reached from the root(s).
@@ -817,7 +827,7 @@
     Path path(Node t) const { return Path(*G, *_pred, t); }
 
-    ///The distance of a node from the root(s).
-
-    ///Returns the distance of a node from the root(s).
+    ///The distance of the given node from the root(s).
+
+    ///Returns the distance of the given node from the root(s).
     ///
     ///\warning If node \c v is not reached from the root(s), then
@@ -828,6 +838,7 @@
     Value dist(Node v) const { return (*_dist)[v]; }
 
-    ///Returns the 'previous arc' of the shortest path tree for a node.
-
+    ///\brief Returns the 'previous arc' of the shortest path tree for
+    ///the given node.
+    ///
     ///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
@@ -836,5 +847,5 @@
     ///
     ///The shortest path tree used here is equal to the shortest path
-    ///tree used in \ref predNode().
+    ///tree used in \ref predNode() and \ref predMap().
     ///
     ///\pre Either \ref run(Node) "run()" or \ref init()
@@ -842,13 +853,14 @@
     Arc predArc(Node v) const { return (*_pred)[v]; }
 
-    ///Returns the 'previous node' of the shortest path tree for a node.
-
+    ///\brief Returns the 'previous node' of the shortest path tree for
+    ///the given node.
+    ///
     ///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 a root to \c v. It is \c INVALID
+    ///of 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().
+    ///tree used in \ref predArc() and \ref predMap().
     ///
     ///\pre Either \ref run(Node) "run()" or \ref init()
@@ -871,5 +883,5 @@
     ///
     ///Returns a const reference to the node map that stores the predecessor
-    ///arcs, which form the shortest path tree.
+    ///arcs, which form the shortest path tree (forest).
     ///
     ///\pre Either \ref run(Node) "run()" or \ref init()
@@ -877,5 +889,5 @@
     const PredMap &predMap() const { return *_pred;}
 
-    ///Checks if a node is reached from the root(s).
+    ///Checks if the given node is reached from the root(s).
 
     ///Returns \c true if \c v is reached from the root(s).
@@ -896,7 +908,7 @@
                                           Heap::POST_HEAP; }
 
-    ///The current distance of a node from the root(s).
-
-    ///Returns the current distance of a node from the root(s).
+    ///The current distance of the given node from the root(s).
+
+    ///Returns the current distance of the given node from the root(s).
     ///It may be decreased in the following processes.
     ///
@@ -925,7 +937,7 @@
 
     ///The type of the map that stores the arc lengths.
-    ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
+    ///It must conform to the \ref concepts::ReadMap "ReadMap" concept.
     typedef LEN LengthMap;
-    ///The type of the length of the arcs.
+    ///The type of the arc lengths.
     typedef typename LEN::Value Value;
 
@@ -974,5 +986,5 @@
     ///The type of the map that stores the predecessor
     ///arcs of the shortest paths.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
     ///Instantiates a PredMap.
@@ -989,6 +1001,6 @@
 
     ///The type of the map that indicates which nodes are processed.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
-    ///By default it is a NullMap.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    ///By default, it is a NullMap.
     typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
     ///Instantiates a ProcessedMap.
@@ -1009,5 +1021,5 @@
 
     ///The type of the map that stores the distances of the nodes.
-    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
+    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
     typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
     ///Instantiates a DistMap.
@@ -1024,5 +1036,5 @@
 
     ///The type of the shortest paths.
-    ///It must meet the \ref concepts::Path "Path" concept.
+    ///It must conform to the \ref concepts::Path "Path" concept.
     typedef lemon::Path<Digraph> Path;
   };
@@ -1030,10 +1042,7 @@
   /// Default traits class used by DijkstraWizard
 
-  /// To make it easier to use Dijkstra algorithm
-  /// we have created a wizard class.
-  /// This \ref DijkstraWizard class needs default traits,
-  /// as well as the \ref Dijkstra class.
-  /// The \ref DijkstraWizardBase is a class to be the default traits of the
-  /// \ref DijkstraWizard class.
+  /// Default traits class used by DijkstraWizard.
+  /// \tparam GR The type of the digraph.
+  /// \tparam LEN The type of the length map.
   template<typename GR, typename LEN>
   class DijkstraWizardBase : public DijkstraWizardDefaultTraits<GR,LEN>
@@ -1089,4 +1098,7 @@
   /// This class should only be used through the \ref dijkstra() function,
   /// which makes it easier to use the algorithm.
+  ///
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm.
   template<class TR>
   class DijkstraWizard : public TR
@@ -1094,5 +1106,4 @@
     typedef TR Base;
 
-    ///The type of the digraph the algorithm runs on.
     typedef typename TR::Digraph Digraph;
 
@@ -1102,18 +1113,10 @@
     typedef typename Digraph::OutArcIt OutArcIt;
 
-    ///The type of the map that stores the arc lengths.
     typedef typename TR::LengthMap LengthMap;
-    ///The type of the length of the arcs.
     typedef typename LengthMap::Value Value;
-    ///\brief The type of the map that stores the predecessor
-    ///arcs of the shortest paths.
     typedef typename TR::PredMap PredMap;
-    ///The type of the map that stores the distances of the nodes.
     typedef typename TR::DistMap DistMap;
-    ///The type of the map that indicates which nodes are processed.
     typedef typename TR::ProcessedMap ProcessedMap;
-    ///The type of the shortest paths
     typedef typename TR::Path Path;
-    ///The heap type used by the dijkstra algorithm.
     typedef typename TR::Heap Heap;
 
@@ -1187,9 +1190,10 @@
       SetPredMapBase(const TR &b) : TR(b) {}
     };
-    ///\brief \ref named-func-param "Named parameter"
-    ///for setting PredMap object.
-    ///
-    ///\ref named-func-param "Named parameter"
-    ///for setting PredMap object.
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the predecessor map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that stores the predecessor arcs of the nodes.
     template<class T>
     DijkstraWizard<SetPredMapBase<T> > predMap(const T &t)
@@ -1205,9 +1209,11 @@
       SetDistMapBase(const TR &b) : TR(b) {}
     };
-    ///\brief \ref named-func-param "Named parameter"
-    ///for setting DistMap object.
-    ///
-    ///\ref named-func-param "Named parameter"
-    ///for setting DistMap object.
+
+    ///\brief \ref named-templ-param "Named parameter" for setting
+    ///the distance map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that stores the distances of the nodes calculated
+    ///by the algorithm.
     template<class T>
     DijkstraWizard<SetDistMapBase<T> > distMap(const T &t)
@@ -1223,9 +1229,10 @@
       SetProcessedMapBase(const TR &b) : TR(b) {}
     };
-    ///\brief \ref named-func-param "Named parameter"
-    ///for setting ProcessedMap object.
-    ///
-    /// \ref named-func-param "Named parameter"
-    ///for setting ProcessedMap object.
+
+    ///\brief \ref named-func-param "Named parameter" for setting
+    ///the processed map.
+    ///
+    ///\ref named-templ-param "Named parameter" function for setting
+    ///the map that indicates which nodes are processed.
     template<class T>
     DijkstraWizard<SetProcessedMapBase<T> > processedMap(const T &t)
@@ -1240,4 +1247,5 @@
       SetPathBase(const TR &b) : TR(b) {}
     };
+
     ///\brief \ref named-func-param "Named parameter"
     ///for getting the shortest path to the target node.
Index: lemon/dim2.h
===================================================================
--- lemon/dim2.h	(revision 440)
+++ lemon/dim2.h	(revision 714)
@@ -22,14 +22,7 @@
 #include <iostream>
 
-///\ingroup misc
+///\ingroup geomdat
 ///\file
 ///\brief A simple two dimensional vector and a bounding box implementation
-///
-/// The class \ref lemon::dim2::Point "dim2::Point" implements
-/// a two dimensional vector with the usual operations.
-///
-/// The class \ref lemon::dim2::Box "dim2::Box" can be used to determine
-/// the rectangular bounding box of a set of
-/// \ref lemon::dim2::Point "dim2::Point"'s.
 
 namespace lemon {
@@ -41,5 +34,5 @@
   namespace dim2 {
 
-  /// \addtogroup misc
+  /// \addtogroup geomdat
   /// @{
 
Index: lemon/dimacs.h
===================================================================
--- lemon/dimacs.h	(revision 1006)
+++ lemon/dimacs.h	(revision 1007)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -39,9 +39,14 @@
   struct DimacsDescriptor
   {
-    ///File type enum
-    enum Type
-      {
-        NONE, MIN, MAX, SP, MAT
-      };
+    ///\brief DIMACS file type enum
+    ///
+    ///DIMACS file type enum.
+    enum Type {
+      NONE,  ///< Undefined type.
+      MIN,   ///< DIMACS file type for minimum cost flow problems.
+      MAX,   ///< DIMACS file type for maximum flow problems.
+      SP,    ///< DIMACS file type for shostest path problems.
+      MAT    ///< DIMACS file type for plain graphs and matching problems.
+    };
     ///The file type
     Type type;
@@ -51,5 +56,5 @@
     int edgeNum;
     int lineShift;
-    /// Constructor. Sets the type to NONE.
+    ///Constructor. It sets the type to \c NONE.
     DimacsDescriptor() : type(NONE) {}
   };
@@ -57,8 +62,8 @@
   ///Discover the type of a DIMACS file
 
-  ///It starts seeking the beginning 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.
+  ///This function starts seeking the beginning of the given 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)
   {
@@ -98,6 +103,5 @@
 
 
-
-  /// DIMACS minimum cost flow reader function.
+  /// \brief DIMACS minimum cost flow reader function.
   ///
   /// This function reads a minimum cost flow instance from DIMACS format,
@@ -210,5 +214,5 @@
         std::numeric_limits<Capacity>::infinity() :
         std::numeric_limits<Capacity>::max();
- 
+
     while (is >> c) {
       switch (c) {
@@ -235,5 +239,5 @@
           e = g.addArc(nodes[i], nodes[j]);
           capacity.set(e, _cap);
-        } 
+        }
         else if (desc.type==DimacsDescriptor::MAX) {
           is >> i >> j >> _cap;
@@ -255,5 +259,5 @@
   }
 
-  /// DIMACS maximum flow reader function.
+  /// \brief DIMACS maximum flow reader function.
   ///
   /// This function reads a maximum flow instance from DIMACS format,
@@ -289,5 +293,5 @@
   }
 
-  /// DIMACS shortest path reader function.
+  /// \brief DIMACS shortest path reader function.
   ///
   /// This function reads a shortest path instance from DIMACS format,
@@ -315,5 +319,5 @@
   }
 
-  /// DIMACS capacitated digraph reader function.
+  /// \brief DIMACS capacitated digraph reader function.
   ///
   /// This function reads an arc capacitated digraph instance from
@@ -360,10 +364,10 @@
     g.addArc(s,t);
   }
-  
-  /// DIMACS plain (di)graph reader function.
-  ///
-  /// This function reads a (di)graph without any designated nodes and
-  /// maps from DIMACS format, i.e. from DIMACS files having a line
-  /// starting with
+
+  /// \brief DIMACS plain (di)graph reader function.
+  ///
+  /// This function reads a plain (di)graph without any designated nodes
+  /// and maps (e.g. a matching instance) from DIMACS format, i.e. from
+  /// DIMACS files having a line starting with
   /// \code
   ///   p mat
@@ -390,5 +394,5 @@
       nodes[k] = g.addNode();
     }
-    
+
     while (is >> c) {
       switch (c) {
Index: lemon/edge_set.h
===================================================================
--- lemon/edge_set.h	(revision 559)
+++ lemon/edge_set.h	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -23,5 +23,5 @@
 #include <lemon/bits/edge_set_extender.h>
 
-/// \ingroup semi_adaptors
+/// \ingroup graphs
 /// \file
 /// \brief ArcSet and EdgeSet classes.
@@ -34,5 +34,4 @@
   public:
 
-    typedef GR Graph;
     typedef typename GR::Node Node;
     typedef typename GR::NodeIt NodeIt;
@@ -86,4 +85,10 @@
     ListArcSetBase() : first_arc(-1), first_free_arc(-1) {}
 
+    Node addNode() {
+      LEMON_ASSERT(false,
+        "This graph structure does not support node insertion");
+      return INVALID; // avoid warning
+    }
+
     Arc addArc(const Node& u, const Node& v) {
       int n;
@@ -209,7 +214,7 @@
     template <typename V>
     class NodeMap : public GR::template NodeMap<V> {
+      typedef typename GR::template NodeMap<V> Parent;
+
     public:
-
-      typedef typename GR::template NodeMap<V> Parent;
 
       explicit NodeMap(const ListArcSetBase<GR>& arcset)
@@ -232,5 +237,5 @@
   };
 
-  /// \ingroup semi_adaptors
+  /// \ingroup graphs
   ///
   /// \brief Digraph using a node set of another digraph or graph and
@@ -251,23 +256,20 @@
   /// all arcs incident to the given node is erased from the arc set.
   ///
+  /// This class fully conforms to the \ref concepts::Digraph
+  /// "Digraph" concept.
+  /// It provides only linear time counting for nodes and arcs.
+  ///
   /// \param GR The type of the graph which shares its node set with
   /// this class. Its interface must conform to the
   /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
   /// concept.
-  ///
-  /// This class fully conforms to the \ref concepts::Digraph
-  /// "Digraph" concept.
   template <typename GR>
   class ListArcSet : public ArcSetExtender<ListArcSetBase<GR> > {
-
-  public:
-
     typedef ArcSetExtender<ListArcSetBase<GR> > Parent;
+
+  public:
 
     typedef typename Parent::Node Node;
     typedef typename Parent::Arc Arc;
-
-    typedef GR Graph;
-
 
     typedef typename Parent::NodesImplBase NodesImplBase;
@@ -293,7 +295,7 @@
 
     class NodesImpl : public NodesImplBase {
+      typedef NodesImplBase Parent;
+
     public:
-      typedef NodesImplBase Parent;
-
       NodesImpl(const GR& graph, ListArcSet& arcset)
         : Parent(graph), _arcset(arcset) {}
@@ -355,5 +357,4 @@
   public:
 
-    typedef GR Graph;
     typedef typename GR::Node Node;
     typedef typename GR::NodeIt NodeIt;
@@ -422,4 +423,10 @@
 
     ListEdgeSetBase() : first_arc(-1), first_free_arc(-1) {}
+
+    Node addNode() {
+      LEMON_ASSERT(false,
+        "This graph structure does not support node insertion");
+      return INVALID; // avoid warning
+    }
 
     Edge addEdge(const Node& u, const Node& v) {
@@ -638,7 +645,7 @@
     template <typename V>
     class NodeMap : public GR::template NodeMap<V> {
+      typedef typename GR::template NodeMap<V> Parent;
+
     public:
-
-      typedef typename GR::template NodeMap<V> Parent;
 
       explicit NodeMap(const ListEdgeSetBase<GR>& arcset)
@@ -661,5 +668,5 @@
   };
 
-  /// \ingroup semi_adaptors
+  /// \ingroup graphs
   ///
   /// \brief Graph using a node set of another digraph or graph and an
@@ -680,24 +687,21 @@
   /// incident to the given node is erased from the arc set.
   ///
+  /// This class fully conforms to the \ref concepts::Graph "Graph"
+  /// concept.
+  /// It provides only linear time counting for nodes, edges and arcs.
+  ///
   /// \param GR The type of the graph which shares its node set
   /// with this class. Its interface must conform to the
   /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
   /// concept.
-  ///
-  /// This class fully conforms to the \ref concepts::Graph "Graph"
-  /// concept.
   template <typename GR>
   class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<GR> > {
-
-  public:
-
     typedef EdgeSetExtender<ListEdgeSetBase<GR> > Parent;
+
+  public:
 
     typedef typename Parent::Node Node;
     typedef typename Parent::Arc Arc;
     typedef typename Parent::Edge Edge;
-
-    typedef GR Graph;
-
 
     typedef typename Parent::NodesImplBase NodesImplBase;
@@ -718,7 +722,7 @@
 
     class NodesImpl : public NodesImplBase {
+      typedef NodesImplBase Parent;
+
     public:
-      typedef NodesImplBase Parent;
-
       NodesImpl(const GR& graph, ListEdgeSet& arcset)
         : Parent(graph), _arcset(arcset) {}
@@ -780,7 +784,6 @@
   public:
 
-    typedef GR Graph;
-    typedef typename Graph::Node Node;
-    typedef typename Graph::NodeIt NodeIt;
+    typedef typename GR::Node Node;
+    typedef typename GR::NodeIt NodeIt;
 
   protected:
@@ -828,4 +831,10 @@
     SmartArcSetBase() {}
 
+    Node addNode() {
+      LEMON_ASSERT(false,
+        "This graph structure does not support node insertion");
+      return INVALID; // avoid warning
+    }
+
     Arc addArc(const Node& u, const Node& v) {
       int n = arcs.size();
@@ -861,5 +870,5 @@
     }
 
-    void next(Arc& arc) const {
+    static void next(Arc& arc) {
       --arc.id;
     }
@@ -901,7 +910,7 @@
     template <typename V>
     class NodeMap : public GR::template NodeMap<V> {
+      typedef typename GR::template NodeMap<V> Parent;
+
     public:
-
-      typedef typename GR::template NodeMap<V> Parent;
 
       explicit NodeMap(const SmartArcSetBase<GR>& arcset)
@@ -925,5 +934,5 @@
 
 
-  /// \ingroup semi_adaptors
+  /// \ingroup graphs
   ///
   /// \brief Digraph using a node set of another digraph or graph and
@@ -948,22 +957,20 @@
   /// arcs. Therefore the arcs cannot be erased from the arc sets.
   ///
+  /// This class fully conforms to the \ref concepts::Digraph "Digraph"
+  /// concept.
+  /// It provides only linear time counting for nodes and arcs.
+  ///
   /// \warning If a node is erased from the underlying graph and this
   /// node is the source or target of one arc in the arc set, then
   /// the arc set is invalidated, and it cannot be used anymore. The
   /// validity can be checked with the \c valid() member function.
-  ///
-  /// This class fully conforms to the \ref concepts::Digraph
-  /// "Digraph" concept.
   template <typename GR>
   class SmartArcSet : public ArcSetExtender<SmartArcSetBase<GR> > {
-
-  public:
-
     typedef ArcSetExtender<SmartArcSetBase<GR> > Parent;
+
+  public:
 
     typedef typename Parent::Node Node;
     typedef typename Parent::Arc Arc;
-
-    typedef GR Graph;
 
   protected:
@@ -984,7 +991,7 @@
 
     class NodesImpl : public NodesImplBase {
+      typedef NodesImplBase Parent;
+
     public:
-      typedef NodesImplBase Parent;
-
       NodesImpl(const GR& graph, SmartArcSet& arcset)
         : Parent(graph), _arcset(arcset) {}
@@ -1063,5 +1070,4 @@
   public:
 
-    typedef GR Graph;
     typedef typename GR::Node Node;
     typedef typename GR::NodeIt NodeIt;
@@ -1128,4 +1134,10 @@
     SmartEdgeSetBase() {}
 
+    Node addNode() {
+      LEMON_ASSERT(false,
+        "This graph structure does not support node insertion");
+      return INVALID; // avoid warning
+    }
+
     Edge addEdge(const Node& u, const Node& v) {
       int n = arcs.size();
@@ -1165,5 +1177,5 @@
     }
 
-    void next(Arc& arc) const {
+    static void next(Arc& arc) {
       --arc.id;
     }
@@ -1173,5 +1185,5 @@
     }
 
-    void next(Edge& arc) const {
+    static void next(Edge& arc) {
       --arc.id;
     }
@@ -1250,7 +1262,7 @@
     template <typename V>
     class NodeMap : public GR::template NodeMap<V> {
+      typedef typename GR::template NodeMap<V> Parent;
+
     public:
-
-      typedef typename GR::template NodeMap<V> Parent;
 
       explicit NodeMap(const SmartEdgeSetBase<GR>& arcset)
@@ -1273,5 +1285,5 @@
   };
 
-  /// \ingroup semi_adaptors
+  /// \ingroup graphs
   ///
   /// \brief Graph using a node set of another digraph or graph and an
@@ -1296,17 +1308,17 @@
   /// edges cannot be erased from the edge sets.
   ///
+  /// This class fully conforms to the \ref concepts::Graph "Graph"
+  /// concept.
+  /// It provides only linear time counting for nodes, edges and arcs.
+  ///
   /// \warning If a node is erased from the underlying graph and this
   /// node is incident to one edge in the edge set, then the edge set
   /// is invalidated, and it cannot be used anymore. The validity can
   /// be checked with the \c valid() member function.
-  ///
-  /// This class fully conforms to the \ref concepts::Graph
-  /// "Graph" concept.
   template <typename GR>
   class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<GR> > {
-
-  public:
-
     typedef EdgeSetExtender<SmartEdgeSetBase<GR> > Parent;
+
+  public:
 
     typedef typename Parent::Node Node;
@@ -1314,6 +1326,4 @@
     typedef typename Parent::Edge Edge;
 
-    typedef GR Graph;
-
   protected:
 
@@ -1332,7 +1342,7 @@
 
     class NodesImpl : public NodesImplBase {
+      typedef NodesImplBase Parent;
+
     public:
-      typedef NodesImplBase Parent;
-
       NodesImpl(const GR& graph, SmartEdgeSet& arcset)
         : Parent(graph), _arcset(arcset) {}
Index: lemon/elevator.h
===================================================================
--- lemon/elevator.h	(revision 559)
+++ lemon/elevator.h	(revision 581)
@@ -77,5 +77,5 @@
     void copy(Item i, Vit p)
     {
-      _where.set(*p=i,p);
+      _where[*p=i] = p;
     }
     void copy(Vit s, Vit p)
@@ -85,5 +85,5 @@
           Item i=*s;
           *p=i;
-          _where.set(i,p);
+          _where[i] = p;
         }
     }
@@ -92,6 +92,6 @@
       Item ti=*i;
       Vit ct = _where[ti];
-      _where.set(ti,_where[*i=*j]);
-      _where.set(*j,ct);
+      _where[ti] = _where[*i=*j];
+      _where[*j] = ct;
       *j=ti;
     }
@@ -227,5 +227,5 @@
     {
       Item it = *_last_active[_highest_active];
-      _level.set(it,_level[it]+1);
+      ++_level[it];
       swap(_last_active[_highest_active]--,_last_active[_highest_active+1]);
       --_first[++_highest_active];
@@ -250,5 +250,5 @@
         }
       copy(li,_first[new_level]);
-      _level.set(li,new_level);
+      _level[li] = new_level;
       _highest_active=new_level;
     }
@@ -270,5 +270,5 @@
       copy(li,_first[_max_level]);
       --_last_active[_max_level];
-      _level.set(li,_max_level);
+      _level[li] = _max_level;
 
       while(_highest_active>=0 &&
@@ -300,5 +300,5 @@
     {
       Item it =*_last_active[level];
-      _level.set(it,_level[it]+1);
+      ++_level[it];
       swap(_last_active[level]--, --_first[level+1]);
       if (level+1>_highest_active) ++_highest_active;
@@ -320,5 +320,5 @@
         }
       copy(ai,_first[new_level]);
-      _level.set(ai,new_level);
+      _level[ai] = new_level;
       if (new_level>_highest_active) _highest_active=new_level;
     }
@@ -340,5 +340,5 @@
       copy(ai,_first[_max_level]);
       --_last_active[_max_level];
-      _level.set(ai,_max_level);
+      _level[ai] = _max_level;
 
       if (_highest_active==level) {
@@ -371,5 +371,5 @@
         }
       copy(i,_first[new_level]);
-      _level.set(i,new_level);
+      _level[i] = new_level;
       if(new_level>_highest_active) _highest_active=new_level;
     }
@@ -383,5 +383,5 @@
     ///\pre The item is on the top level.
     void dirtyTopButOne(Item i) {
-      _level.set(i,_max_level - 1);
+      _level[i] = _max_level - 1;
     }
 
@@ -395,5 +395,5 @@
       const Vit tl=_first[_max_level];
       for(Vit i=f;i!=tl;++i)
-        _level.set(*i,_max_level);
+        _level[*i] = _max_level;
       for(int i=l;i<=_max_level;i++)
         {
@@ -434,6 +434,6 @@
         {
           *n=i;
-          _where.set(i,n);
-          _level.set(i,_max_level);
+          _where[i] = n;
+          _level[i] = _max_level;
           ++n;
         }
@@ -444,5 +444,5 @@
     {
       swap(_where[i],_init_num);
-      _level.set(i,_init_lev);
+      _level[i] = _init_lev;
       ++_init_num;
     }
@@ -552,5 +552,5 @@
     ///\pre Item \c i shouldn't be active before.
     void activate(Item i) {
-      _active.set(i, true);
+      _active[i] = true;
 
       int level = _level[i];
@@ -561,14 +561,14 @@
       if (_prev[i] == INVALID || _active[_prev[i]]) return;
       //unlace
-      _next.set(_prev[i], _next[i]);
+      _next[_prev[i]] = _next[i];
       if (_next[i] != INVALID) {
-        _prev.set(_next[i], _prev[i]);
+        _prev[_next[i]] = _prev[i];
       } else {
         _last[level] = _prev[i];
       }
       //lace
-      _next.set(i, _first[level]);
-      _prev.set(_first[level], i);
-      _prev.set(i, INVALID);
+      _next[i] = _first[level];
+      _prev[_first[level]] = i;
+      _prev[i] = INVALID;
       _first[level] = i;
 
@@ -580,5 +580,5 @@
     ///\pre Item \c i must be active before.
     void deactivate(Item i) {
-      _active.set(i, false);
+      _active[i] = false;
       int level = _level[i];
 
@@ -587,14 +587,14 @@
 
       //unlace
-      _prev.set(_next[i], _prev[i]);
+      _prev[_next[i]] = _prev[i];
       if (_prev[i] != INVALID) {
-        _next.set(_prev[i], _next[i]);
+        _next[_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);
+      _prev[i] = _last[level];
+      _next[_last[level]] = i;
+      _next[i] = INVALID;
       _last[level] = i;
 
@@ -686,5 +686,5 @@
       Item i = _first[_highest_active];
       if (_next[i] != INVALID) {
-        _prev.set(_next[i], INVALID);
+        _prev[_next[i]] = INVALID;
         _first[_highest_active] = _next[i];
       } else {
@@ -692,13 +692,13 @@
         _last[_highest_active] = INVALID;
       }
-      _level.set(i, ++_highest_active);
+      _level[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]);
+        _prev[i] = INVALID;
+        _next[i] = INVALID;
+      } else {
+        _prev[_first[_highest_active]] = i;
+        _next[i] = _first[_highest_active];
         _first[_highest_active] = i;
       }
@@ -715,5 +715,5 @@
       Item i = _first[_highest_active];
       if (_next[i] != INVALID) {
-        _prev.set(_next[i], INVALID);
+        _prev[_next[i]] = INVALID;
         _first[_highest_active] = _next[i];
       } else {
@@ -721,12 +721,12 @@
         _last[_highest_active] = INVALID;
       }
-      _level.set(i, _highest_active = new_level);
+      _level[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]);
+        _prev[i] = INVALID;
+        _next[i] = INVALID;
+      } else {
+        _prev[_first[_highest_active]] = i;
+        _next[i] = _first[_highest_active];
         _first[_highest_active] = i;
       }
@@ -739,7 +739,7 @@
     void liftHighestActiveToTop() {
       Item i = _first[_highest_active];
-      _level.set(i, _max_level);
+      _level[i] = _max_level;
       if (_next[i] != INVALID) {
-        _prev.set(_next[i], INVALID);
+        _prev[_next[i]] = INVALID;
         _first[_highest_active] = _next[i];
       } else {
@@ -775,5 +775,5 @@
       Item i = _first[l];
       if (_next[i] != INVALID) {
-        _prev.set(_next[i], INVALID);
+        _prev[_next[i]] = INVALID;
         _first[l] = _next[i];
       } else {
@@ -781,12 +781,12 @@
         _last[l] = INVALID;
       }
-      _level.set(i, ++l);
+      _level[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]);
+        _prev[i] = INVALID;
+        _next[i] = INVALID;
+      } else {
+        _prev[_first[l]] = i;
+        _next[i] = _first[l];
         _first[l] = i;
       }
@@ -804,5 +804,5 @@
       Item i = _first[l];
       if (_next[i] != INVALID) {
-        _prev.set(_next[i], INVALID);
+        _prev[_next[i]] = INVALID;
         _first[l] = _next[i];
       } else {
@@ -810,12 +810,12 @@
         _last[l] = INVALID;
       }
-      _level.set(i, l = new_level);
+      _level[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]);
+        _prev[i] = INVALID;
+        _next[i] = INVALID;
+      } else {
+        _prev[_first[l]] = i;
+        _next[i] = _first[l];
         _first[l] = i;
       }
@@ -833,5 +833,5 @@
       Item i = _first[l];
       if (_next[i] != INVALID) {
-        _prev.set(_next[i], INVALID);
+        _prev[_next[i]] = INVALID;
         _first[l] = _next[i];
       } else {
@@ -839,5 +839,5 @@
         _last[l] = INVALID;
       }
-      _level.set(i, _max_level);
+      _level[i] = _max_level;
       if (l == _highest_active) {
         while (_highest_active >= 0 && activeFree(_highest_active))
@@ -857,21 +857,21 @@
     void lift(Item i, int new_level) {
       if (_next[i] != INVALID) {
-        _prev.set(_next[i], _prev[i]);
+        _prev[_next[i]] = _prev[i];
       } else {
         _last[new_level] = _prev[i];
       }
       if (_prev[i] != INVALID) {
-        _next.set(_prev[i], _next[i]);
+        _next[_prev[i]] = _next[i];
       } else {
         _first[new_level] = _next[i];
       }
-      _level.set(i, new_level);
+      _level[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]);
+        _prev[i] = INVALID;
+        _next[i] = INVALID;
+      } else {
+        _prev[_first[new_level]] = i;
+        _next[i] = _first[new_level];
         _first[new_level] = i;
       }
@@ -889,5 +889,5 @@
     ///\pre The item is on the top level.
     void dirtyTopButOne(Item i) {
-      _level.set(i, _max_level - 1);
+      _level[i] = _max_level - 1;
     }
 
@@ -900,5 +900,5 @@
         Item n = _first[i];
         while (n != INVALID) {
-          _level.set(n, _max_level);
+          _level[n] = _max_level;
           n = _next[n];
         }
@@ -938,6 +938,6 @@
       for(typename ItemSetTraits<GR,Item>::ItemIt i(_graph);
           i != INVALID; ++i) {
-        _level.set(i, _max_level);
-        _active.set(i, false);
+        _level[i] = _max_level;
+        _active[i] = false;
       }
     }
@@ -945,14 +945,14 @@
     ///Add an item to the current level.
     void initAddItem(Item i) {
-      _level.set(i, _init_level);
+      _level[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);
+        _prev[i] = INVALID;
+        _next[i] = INVALID;
+      } else {
+        _prev[i] = _last[_init_level];
+        _next[i] = INVALID;
+        _next[_last[_init_level]] = i;
         _last[_init_level] = i;
       }
Index: lemon/euler.h
===================================================================
--- lemon/euler.h	(revision 559)
+++ lemon/euler.h	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -25,33 +25,31 @@
 #include <list>
 
-/// \ingroup graph_prop
+/// \ingroup graph_properties
 /// \file
-/// \brief Euler tour
+/// \brief Euler tour iterators and a function for checking the \e Eulerian
+/// property.
 ///
-///This file provides an Euler tour iterator and ways to check
-///if a digraph is euler.
-
+///This file provides Euler tour iterators and a function to check
+///if a (di)graph is \e Eulerian.
 
 namespace lemon {
 
-  ///Euler iterator for digraphs.
+  ///Euler tour iterator for digraphs.
 
   /// \ingroup graph_prop
-  ///This iterator converts to the \c Arc type of the digraph and using
-  ///operator ++, it provides an Euler tour of a \e directed
-  ///graph (if there exists).
-  ///
-  ///For example
-  ///if the given digraph is Euler (i.e it has only one nontrivial component
-  ///and the in-degree is equal to the out-degree for all nodes),
-  ///the following code will put the arcs of \c g
-  ///to the vector \c et according to an
-  ///Euler tour of \c g.
+  ///This iterator provides an Euler tour (Eulerian circuit) of a \e directed
+  ///graph (if there exists) and it converts to the \c Arc type of the digraph.
+  ///
+  ///For example, if the given digraph has an Euler tour (i.e it has only one
+  ///non-trivial component and the in-degree is equal to the out-degree
+  ///for all nodes), then the following code will put the arcs of \c g
+  ///to the vector \c et according to an Euler tour of \c g.
   ///\code
   ///  std::vector<ListDigraph::Arc> et;
-  ///  for(DiEulerIt<ListDigraph> e(g),e!=INVALID;++e)
+  ///  for(DiEulerIt<ListDigraph> e(g); e!=INVALID; ++e)
   ///    et.push_back(e);
   ///\endcode
-  ///If \c g is not Euler then the resulted tour will not be full or closed.
+  ///If \c g has no Euler tour, then the resulted walk will not be closed
+  ///or not contain all arcs.
   ///\sa EulerIt
   template<typename GR>
@@ -66,5 +64,5 @@
 
     const GR &g;
-    typename GR::template NodeMap<OutArcIt> nedge;
+    typename GR::template NodeMap<OutArcIt> narc;
     std::list<Arc> euler;
 
@@ -73,36 +71,46 @@
     ///Constructor
 
+    ///Constructor.
     ///\param gr A digraph.
-    ///\param start The starting point of the tour. If it is not given
-    ///       the tour will start from the first node.
+    ///\param start The starting point of the tour. If it is not given,
+    ///the tour will start from the first node that has an outgoing arc.
     DiEulerIt(const GR &gr, typename GR::Node start = INVALID)
-      : g(gr), nedge(g)
-    {
-      if(start==INVALID) start=NodeIt(g);
-      for(NodeIt n(g);n!=INVALID;++n) nedge[n]=OutArcIt(g,n);
-      while(nedge[start]!=INVALID) {
-        euler.push_back(nedge[start]);
-        Node next=g.target(nedge[start]);
-        ++nedge[start];
-        start=next;
-      }
-    }
-
-    ///Arc Conversion
+      : g(gr), narc(g)
+    {
+      if (start==INVALID) {
+        NodeIt n(g);
+        while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n;
+        start=n;
+      }
+      if (start!=INVALID) {
+        for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n);
+        while (narc[start]!=INVALID) {
+          euler.push_back(narc[start]);
+          Node next=g.target(narc[start]);
+          ++narc[start];
+          start=next;
+        }
+      }
+    }
+
+    ///Arc conversion
     operator Arc() { return euler.empty()?INVALID:euler.front(); }
+    ///Compare with \c INVALID
     bool operator==(Invalid) { return euler.empty(); }
+    ///Compare with \c INVALID
     bool operator!=(Invalid) { return !euler.empty(); }
 
     ///Next arc of the tour
+
+    ///Next arc of the tour
+    ///
     DiEulerIt &operator++() {
       Node s=g.target(euler.front());
       euler.pop_front();
-      //This produces a warning.Strange.
-      //std::list<Arc>::iterator next=euler.begin();
       typename std::list<Arc>::iterator next=euler.begin();
-      while(nedge[s]!=INVALID) {
-        euler.insert(next,nedge[s]);
-        Node n=g.target(nedge[s]);
-        ++nedge[s];
+      while(narc[s]!=INVALID) {
+        euler.insert(next,narc[s]);
+        Node n=g.target(narc[s]);
+        ++narc[s];
         s=n;
       }
@@ -111,6 +119,8 @@
     ///Postfix incrementation
 
+    /// Postfix incrementation.
+    ///
     ///\warning This incrementation
-    ///returns an \c Arc, not an \ref DiEulerIt, as one may
+    ///returns an \c Arc, not a \ref DiEulerIt, as one may
     ///expect.
     Arc operator++(int)
@@ -122,28 +132,26 @@
   };
 
-  ///Euler iterator for graphs.
-
-  /// \ingroup graph_prop
-  ///This iterator converts to the \c Arc (or \c Edge)
-  ///type of the digraph and using
-  ///operator ++, it provides an Euler tour of an undirected
-  ///digraph (if there exists).
-  ///
-  ///For example
-  ///if the given digraph if Euler (i.e it has only one nontrivial component
-  ///and the degree of each node is even),
+  ///Euler tour iterator for graphs.
+
+  /// \ingroup graph_properties
+  ///This iterator provides an Euler tour (Eulerian circuit) of an
+  ///\e undirected graph (if there exists) and it converts to the \c Arc
+  ///and \c Edge types of the graph.
+  ///
+  ///For example, if the given graph has an Euler tour (i.e it has only one
+  ///non-trivial component and the degree of each node is even),
   ///the following code will print the arc IDs according to an
   ///Euler tour of \c g.
   ///\code
-  ///  for(EulerIt<ListGraph> e(g),e!=INVALID;++e) {
+  ///  for(EulerIt<ListGraph> e(g); e!=INVALID; ++e) {
   ///    std::cout << g.id(Edge(e)) << std::eol;
   ///  }
   ///\endcode
-  ///Although the iterator provides an Euler tour of an graph,
-  ///it still returns Arcs in order to indicate the direction of the tour.
-  ///(But Arc will convert to Edges, of course).
-  ///
-  ///If \c g is not Euler then the resulted tour will not be full or closed.
-  ///\sa EulerIt
+  ///Although this iterator is for undirected graphs, it still returns
+  ///arcs in order to indicate the direction of the tour.
+  ///(But arcs convert to edges, of course.)
+  ///
+  ///If \c g has no Euler tour, then the resulted walk will not be closed
+  ///or not contain all edges.
   template<typename GR>
   class EulerIt
@@ -158,5 +166,5 @@
 
     const GR &g;
-    typename GR::template NodeMap<OutArcIt> nedge;
+    typename GR::template NodeMap<OutArcIt> narc;
     typename GR::template EdgeMap<bool> visited;
     std::list<Arc> euler;
@@ -166,45 +174,54 @@
     ///Constructor
 
-    ///\param gr An graph.
-    ///\param start The starting point of the tour. If it is not given
-    ///       the tour will start from the first node.
+    ///Constructor.
+    ///\param gr A graph.
+    ///\param start The starting point of the tour. If it is not given,
+    ///the tour will start from the first node that has an incident edge.
     EulerIt(const GR &gr, typename GR::Node start = INVALID)
-      : g(gr), nedge(g), visited(g, false)
-    {
-      if(start==INVALID) start=NodeIt(g);
-      for(NodeIt n(g);n!=INVALID;++n) nedge[n]=OutArcIt(g,n);
-      while(nedge[start]!=INVALID) {
-        euler.push_back(nedge[start]);
-        visited[nedge[start]]=true;
-        Node next=g.target(nedge[start]);
-        ++nedge[start];
-        start=next;
-        while(nedge[start]!=INVALID && visited[nedge[start]]) ++nedge[start];
-      }
-    }
-
-    ///Arc Conversion
+      : g(gr), narc(g), visited(g, false)
+    {
+      if (start==INVALID) {
+        NodeIt n(g);
+        while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n;
+        start=n;
+      }
+      if (start!=INVALID) {
+        for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n);
+        while(narc[start]!=INVALID) {
+          euler.push_back(narc[start]);
+          visited[narc[start]]=true;
+          Node next=g.target(narc[start]);
+          ++narc[start];
+          start=next;
+          while(narc[start]!=INVALID && visited[narc[start]]) ++narc[start];
+        }
+      }
+    }
+
+    ///Arc conversion
     operator Arc() const { return euler.empty()?INVALID:euler.front(); }
-    ///Arc Conversion
+    ///Edge conversion
     operator Edge() const { return euler.empty()?INVALID:euler.front(); }
-    ///\e
+    ///Compare with \c INVALID
     bool operator==(Invalid) const { return euler.empty(); }
-    ///\e
+    ///Compare with \c INVALID
     bool operator!=(Invalid) const { return !euler.empty(); }
 
     ///Next arc of the tour
+
+    ///Next arc of the tour
+    ///
     EulerIt &operator++() {
       Node s=g.target(euler.front());
       euler.pop_front();
       typename std::list<Arc>::iterator next=euler.begin();
-
-      while(nedge[s]!=INVALID) {
-        while(nedge[s]!=INVALID && visited[nedge[s]]) ++nedge[s];
-        if(nedge[s]==INVALID) break;
+      while(narc[s]!=INVALID) {
+        while(narc[s]!=INVALID && visited[narc[s]]) ++narc[s];
+        if(narc[s]==INVALID) break;
         else {
-          euler.insert(next,nedge[s]);
-          visited[nedge[s]]=true;
-          Node n=g.target(nedge[s]);
-          ++nedge[s];
+          euler.insert(next,narc[s]);
+          visited[narc[s]]=true;
+          Node n=g.target(narc[s]);
+          ++narc[s];
           s=n;
         }
@@ -215,7 +232,8 @@
     ///Postfix incrementation
 
-    ///\warning This incrementation
-    ///returns an \c Arc, not an \ref EulerIt, as one may
-    ///expect.
+    /// Postfix incrementation.
+    ///
+    ///\warning This incrementation returns an \c Arc (which converts to
+    ///an \c Edge), not an \ref EulerIt, as one may expect.
     Arc operator++(int)
     {
@@ -227,16 +245,21 @@
 
 
-  ///Checks if the graph is Eulerian
-
-  /// \ingroup graph_prop
-  ///Checks if the graph is Eulerian. It works for both directed and undirected
-  ///graphs.
-  ///\note By definition, a digraph is called \e Eulerian if
-  ///and only if it is connected and the number of its incoming and outgoing
+  ///Check if the given graph is Eulerian
+
+  /// \ingroup graph_properties
+  ///This function checks if the given graph is Eulerian.
+  ///It works for both directed and undirected graphs.
+  ///
+  ///By definition, a digraph is called \e Eulerian if
+  ///and only if it is connected and the number of incoming and outgoing
   ///arcs are the same for each node.
   ///Similarly, an undirected graph is called \e Eulerian if
-  ///and only if it is connected and the number of incident arcs is even
-  ///for each node. <em>Therefore, there are digraphs which are not Eulerian,
-  ///but still have an Euler tour</em>.
+  ///and only if it is connected and the number of incident edges is even
+  ///for each node.
+  ///
+  ///\note There are (di)graphs that are not Eulerian, but still have an
+  /// Euler tour, since they may contain isolated nodes.
+  ///
+  ///\sa DiEulerIt, EulerIt
   template<typename GR>
 #ifdef DOXYGEN
@@ -257,5 +280,5 @@
     for(typename GR::NodeIt n(g);n!=INVALID;++n)
       if(countInArcs(g,n)!=countOutArcs(g,n)) return false;
-    return connected(Undirector<const GR>(g));
+    return connected(undirector(g));
   }
 
Index: lemon/fib_heap.h
===================================================================
--- lemon/fib_heap.h	(revision 711)
+++ lemon/fib_heap.h	(revision 711)
@@ -0,0 +1,475 @@
+/* -*- 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_FIB_HEAP_H
+#define LEMON_FIB_HEAP_H
+
+///\file
+///\ingroup heaps
+///\brief Fibonacci heap implementation.
+
+#include <vector>
+#include <utility>
+#include <functional>
+#include <lemon/math.h>
+
+namespace lemon {
+
+  /// \ingroup heaps
+  ///
+  /// \brief Fibonacci heap data structure.
+  ///
+  /// This class implements the \e Fibonacci \e heap data structure.
+  /// It fully conforms to the \ref concepts::Heap "heap concept".
+  ///
+  /// The methods \ref increase() and \ref erase() are not efficient in a
+  /// Fibonacci heap. In case of many calls of these operations, it is
+  /// better to use other heap structure, e.g. \ref BinHeap "binary heap".
+  ///
+  /// \tparam PR Type of the priorities of the items.
+  /// \tparam IM A read-writable item map with \c int values, used
+  /// internally to handle the cross references.
+  /// \tparam CMP A functor class for comparing the priorities.
+  /// The default is \c std::less<PR>.
+#ifdef DOXYGEN
+  template <typename PR, typename IM, typename CMP>
+#else
+  template <typename PR, typename IM, typename CMP = std::less<PR> >
+#endif
+  class FibHeap {
+  public:
+
+    /// Type of the item-int map.
+    typedef IM ItemIntMap;
+    /// Type of the priorities.
+    typedef PR Prio;
+    /// Type of the items stored in the heap.
+    typedef typename ItemIntMap::Key Item;
+    /// Type of the item-priority pairs.
+    typedef std::pair<Item,Prio> Pair;
+    /// Functor type for comparing the priorities.
+    typedef CMP Compare;
+
+  private:
+    class Store;
+
+    std::vector<Store> _data;
+    int _minimum;
+    ItemIntMap &_iim;
+    Compare _comp;
+    int _num;
+
+  public:
+
+    /// \brief Type to represent the states of the items.
+    ///
+    /// Each item has a state associated to it. It can be "in heap",
+    /// "pre-heap" or "post-heap". The latter two are indifferent from the
+    /// heap's point of view, but may be useful to the user.
+    ///
+    /// The item-int map must be initialized in such way that it assigns
+    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
+    enum State {
+      IN_HEAP = 0,    ///< = 0.
+      PRE_HEAP = -1,  ///< = -1.
+      POST_HEAP = -2  ///< = -2.
+    };
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    explicit FibHeap(ItemIntMap &map)
+      : _minimum(0), _iim(map), _num() {}
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    /// \param comp The function object used for comparing the priorities.
+    FibHeap(ItemIntMap &map, const Compare &comp)
+      : _minimum(0), _iim(map), _comp(comp), _num() {}
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// This function returns the number of items stored in the heap.
+    int size() const { return _num; }
+
+    /// \brief Check if the heap is empty.
+    ///
+    /// This function returns \c true if the heap is empty.
+    bool empty() const { return _num==0; }
+
+    /// \brief Make the heap empty.
+    ///
+    /// This functon makes the heap empty.
+    /// It does not change the cross reference map. If you want to reuse
+    /// a heap that is not surely empty, you should first clear it and
+    /// then you should set the cross reference map to \c PRE_HEAP
+    /// for each item.
+    void clear() {
+      _data.clear(); _minimum = 0; _num = 0;
+    }
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// This function inserts the given item into the heap with the
+    /// given priority.
+    /// \param item The item to insert.
+    /// \param prio The priority of the item.
+    /// \pre \e item must not be stored in the heap.
+    void push (const Item& item, const Prio& prio) {
+      int i=_iim[item];
+      if ( i < 0 ) {
+        int s=_data.size();
+        _iim.set( item, s );
+        Store st;
+        st.name=item;
+        _data.push_back(st);
+        i=s;
+      } else {
+        _data[i].parent=_data[i].child=-1;
+        _data[i].degree=0;
+        _data[i].in=true;
+        _data[i].marked=false;
+      }
+
+      if ( _num ) {
+        _data[_data[_minimum].right_neighbor].left_neighbor=i;
+        _data[i].right_neighbor=_data[_minimum].right_neighbor;
+        _data[_minimum].right_neighbor=i;
+        _data[i].left_neighbor=_minimum;
+        if ( _comp( prio, _data[_minimum].prio) ) _minimum=i;
+      } else {
+        _data[i].right_neighbor=_data[i].left_neighbor=i;
+        _minimum=i;
+      }
+      _data[i].prio=prio;
+      ++_num;
+    }
+
+    /// \brief Return the item having minimum priority.
+    ///
+    /// This function returns the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    Item top() const { return _data[_minimum].name; }
+
+    /// \brief The minimum priority.
+    ///
+    /// This function returns the minimum priority.
+    /// \pre The heap must be non-empty.
+    Prio prio() const { return _data[_minimum].prio; }
+
+    /// \brief Remove the item having minimum priority.
+    ///
+    /// This function removes the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      /*The first case is that there are only one root.*/
+      if ( _data[_minimum].left_neighbor==_minimum ) {
+        _data[_minimum].in=false;
+        if ( _data[_minimum].degree!=0 ) {
+          makeRoot(_data[_minimum].child);
+          _minimum=_data[_minimum].child;
+          balance();
+        }
+      } else {
+        int right=_data[_minimum].right_neighbor;
+        unlace(_minimum);
+        _data[_minimum].in=false;
+        if ( _data[_minimum].degree > 0 ) {
+          int left=_data[_minimum].left_neighbor;
+          int child=_data[_minimum].child;
+          int last_child=_data[child].left_neighbor;
+
+          makeRoot(child);
+
+          _data[left].right_neighbor=child;
+          _data[child].left_neighbor=left;
+          _data[right].left_neighbor=last_child;
+          _data[last_child].right_neighbor=right;
+        }
+        _minimum=right;
+        balance();
+      } // the case where there are more roots
+      --_num;
+    }
+
+    /// \brief Remove the given item from the heap.
+    ///
+    /// This function removes the given item from the heap if it is
+    /// already stored.
+    /// \param item The item to delete.
+    /// \pre \e item must be in the heap.
+    void erase (const Item& item) {
+      int i=_iim[item];
+
+      if ( i >= 0 && _data[i].in ) {
+        if ( _data[i].parent!=-1 ) {
+          int p=_data[i].parent;
+          cut(i,p);
+          cascade(p);
+        }
+        _minimum=i;     //As if its prio would be -infinity
+        pop();
+      }
+    }
+
+    /// \brief The priority of the given item.
+    ///
+    /// This function returns the priority of the given item.
+    /// \param item The item.
+    /// \pre \e item must be in the heap.
+    Prio operator[](const Item& item) const {
+      return _data[_iim[item]].prio;
+    }
+
+    /// \brief Set the priority of an item or insert it, if it is
+    /// not stored in the heap.
+    ///
+    /// This method sets the priority of the given item if it is
+    /// already stored in the heap. Otherwise it inserts the given
+    /// item into the heap with the given priority.
+    /// \param item The item.
+    /// \param prio The priority.
+    void set (const Item& item, const Prio& prio) {
+      int i=_iim[item];
+      if ( i >= 0 && _data[i].in ) {
+        if ( _comp(prio, _data[i].prio) ) decrease(item, prio);
+        if ( _comp(_data[i].prio, prio) ) increase(item, prio);
+      } else push(item, prio);
+    }
+
+    /// \brief Decrease the priority of an item to the given value.
+    ///
+    /// This function decreases the priority of an item to the given value.
+    /// \param item The item.
+    /// \param prio The priority.
+    /// \pre \e item must be stored in the heap with priority at least \e prio.
+    void decrease (const Item& item, const Prio& prio) {
+      int i=_iim[item];
+      _data[i].prio=prio;
+      int p=_data[i].parent;
+
+      if ( p!=-1 && _comp(prio, _data[p].prio) ) {
+        cut(i,p);
+        cascade(p);
+      }
+      if ( _comp(prio, _data[_minimum].prio) ) _minimum=i;
+    }
+
+    /// \brief Increase the priority of an item to the given value.
+    ///
+    /// This function increases the priority of an item to the given value.
+    /// \param item The item.
+    /// \param prio The priority.
+    /// \pre \e item must be stored in the heap with priority at most \e prio.
+    void increase (const Item& item, const Prio& prio) {
+      erase(item);
+      push(item, prio);
+    }
+
+    /// \brief Return the state of an item.
+    ///
+    /// This method returns \c PRE_HEAP if the given item has never
+    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
+    /// and \c POST_HEAP otherwise.
+    /// In the latter case it is possible that the item will get back
+    /// to the heap again.
+    /// \param item The item.
+    State state(const Item &item) const {
+      int i=_iim[item];
+      if( i>=0 ) {
+        if ( _data[i].in ) i=0;
+        else i=-2;
+      }
+      return State(i);
+    }
+
+    /// \brief Set the state of an item in the heap.
+    ///
+    /// This function sets the state of the given item in the heap.
+    /// It can be used to manually clear the heap when it is important
+    /// to achive better time complexity.
+    /// \param i The item.
+    /// \param st The state. It should not be \c IN_HEAP.
+    void state(const Item& i, State st) {
+      switch (st) {
+      case POST_HEAP:
+      case PRE_HEAP:
+        if (state(i) == IN_HEAP) {
+          erase(i);
+        }
+        _iim[i] = st;
+        break;
+      case IN_HEAP:
+        break;
+      }
+    }
+
+  private:
+
+    void balance() {
+
+      int maxdeg=int( std::floor( 2.08*log(double(_data.size()))))+1;
+
+      std::vector<int> A(maxdeg,-1);
+
+      /*
+       *Recall that now minimum does not point to the minimum prio element.
+       *We set minimum to this during balance().
+       */
+      int anchor=_data[_minimum].left_neighbor;
+      int next=_minimum;
+      bool end=false;
+
+      do {
+        int active=next;
+        if ( anchor==active ) end=true;
+        int d=_data[active].degree;
+        next=_data[active].right_neighbor;
+
+        while (A[d]!=-1) {
+          if( _comp(_data[active].prio, _data[A[d]].prio) ) {
+            fuse(active,A[d]);
+          } else {
+            fuse(A[d],active);
+            active=A[d];
+          }
+          A[d]=-1;
+          ++d;
+        }
+        A[d]=active;
+      } while ( !end );
+
+
+      while ( _data[_minimum].parent >=0 )
+        _minimum=_data[_minimum].parent;
+      int s=_minimum;
+      int m=_minimum;
+      do {
+        if ( _comp(_data[s].prio, _data[_minimum].prio) ) _minimum=s;
+        s=_data[s].right_neighbor;
+      } while ( s != m );
+    }
+
+    void makeRoot(int c) {
+      int s=c;
+      do {
+        _data[s].parent=-1;
+        s=_data[s].right_neighbor;
+      } while ( s != c );
+    }
+
+    void cut(int a, int b) {
+      /*
+       *Replacing a from the children of b.
+       */
+      --_data[b].degree;
+
+      if ( _data[b].degree !=0 ) {
+        int child=_data[b].child;
+        if ( child==a )
+          _data[b].child=_data[child].right_neighbor;
+        unlace(a);
+      }
+
+
+      /*Lacing a to the roots.*/
+      int right=_data[_minimum].right_neighbor;
+      _data[_minimum].right_neighbor=a;
+      _data[a].left_neighbor=_minimum;
+      _data[a].right_neighbor=right;
+      _data[right].left_neighbor=a;
+
+      _data[a].parent=-1;
+      _data[a].marked=false;
+    }
+
+    void cascade(int a) {
+      if ( _data[a].parent!=-1 ) {
+        int p=_data[a].parent;
+
+        if ( _data[a].marked==false ) _data[a].marked=true;
+        else {
+          cut(a,p);
+          cascade(p);
+        }
+      }
+    }
+
+    void fuse(int a, int b) {
+      unlace(b);
+
+      /*Lacing b under a.*/
+      _data[b].parent=a;
+
+      if (_data[a].degree==0) {
+        _data[b].left_neighbor=b;
+        _data[b].right_neighbor=b;
+        _data[a].child=b;
+      } else {
+        int child=_data[a].child;
+        int last_child=_data[child].left_neighbor;
+        _data[child].left_neighbor=b;
+        _data[b].right_neighbor=child;
+        _data[last_child].right_neighbor=b;
+        _data[b].left_neighbor=last_child;
+      }
+
+      ++_data[a].degree;
+
+      _data[b].marked=false;
+    }
+
+    /*
+     *It is invoked only if a has siblings.
+     */
+    void unlace(int a) {
+      int leftn=_data[a].left_neighbor;
+      int rightn=_data[a].right_neighbor;
+      _data[leftn].right_neighbor=rightn;
+      _data[rightn].left_neighbor=leftn;
+    }
+
+
+    class Store {
+      friend class FibHeap;
+
+      Item name;
+      int parent;
+      int left_neighbor;
+      int right_neighbor;
+      int child;
+      int degree;
+      bool marked;
+      bool in;
+      Prio prio;
+
+      Store() : parent(-1), child(-1), degree(), marked(false), in(true) {}
+    };
+  };
+
+} //namespace lemon
+
+#endif //LEMON_FIB_HEAP_H
+
Index: lemon/fractional_matching.h
===================================================================
--- lemon/fractional_matching.h	(revision 877)
+++ lemon/fractional_matching.h	(revision 877)
@@ -0,0 +1,2139 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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_FRACTIONAL_MATCHING_H
+#define LEMON_FRACTIONAL_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>
+#include <lemon/assert.h>
+#include <lemon/elevator.h>
+
+///\ingroup matching
+///\file
+///\brief Fractional matching algorithms in general graphs.
+
+namespace lemon {
+
+  /// \brief Default traits class of MaxFractionalMatching class.
+  ///
+  /// Default traits class of MaxFractionalMatching class.
+  /// \tparam GR Graph type.
+  template <typename GR>
+  struct MaxFractionalMatchingDefaultTraits {
+
+    /// \brief The type of the graph the algorithm runs on.
+    typedef GR Graph;
+
+    /// \brief The type of the map that stores the matching.
+    ///
+    /// The type of the map that stores the matching arcs.
+    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+    typedef typename Graph::template NodeMap<typename GR::Arc> MatchingMap;
+
+    /// \brief Instantiates a MatchingMap.
+    ///
+    /// This function instantiates a \ref MatchingMap.
+    /// \param graph The graph for which we would like to define
+    /// the matching map.
+    static MatchingMap* createMatchingMap(const Graph& graph) {
+      return new MatchingMap(graph);
+    }
+
+    /// \brief The elevator type used by MaxFractionalMatching algorithm.
+    ///
+    /// The elevator type used by MaxFractionalMatching algorithm.
+    ///
+    /// \sa Elevator
+    /// \sa LinkedElevator
+    typedef LinkedElevator<Graph, typename Graph::Node> Elevator;
+
+    /// \brief Instantiates an Elevator.
+    ///
+    /// This function instantiates an \ref Elevator.
+    /// \param graph The graph for which we would like to define
+    /// the elevator.
+    /// \param max_level The maximum level of the elevator.
+    static Elevator* createElevator(const Graph& graph, int max_level) {
+      return new Elevator(graph, max_level);
+    }
+  };
+
+  /// \ingroup matching
+  ///
+  /// \brief Max cardinality fractional matching
+  ///
+  /// This class provides an implementation of fractional matching
+  /// algorithm based on push-relabel principle.
+  ///
+  /// The maximum cardinality fractional matching is a relaxation of the
+  /// maximum cardinality matching problem where the odd set constraints
+  /// are omitted.
+  /// It 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[x_e \ge 0\quad \forall e\in E\f]
+  /// \f[\max \sum_{e\in E}x_e\f]
+  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
+  /// \f$X\f$. The result can be represented as the union of a
+  /// matching with one value edges and a set of odd length cycles
+  /// with half value edges.
+  ///
+  /// The algorithm calculates an optimal fractional matching and a
+  /// barrier. The number of adjacents of any node set minus the size
+  /// of node set is a lower bound on the uncovered nodes in the
+  /// graph. For maximum matching a barrier is computed which
+  /// maximizes this difference.
+  ///
+  /// The algorithm can be executed with the run() function.  After it
+  /// the matching (the primal solution) and the barrier (the dual
+  /// solution) can be obtained using the query functions.
+  ///
+  /// The primal solution is multiplied by
+  /// \ref MaxFractionalMatching::primalScale "2".
+  ///
+  /// \tparam GR The undirected graph type the algorithm runs on.
+#ifdef DOXYGEN
+  template <typename GR, typename TR>
+#else
+  template <typename GR,
+            typename TR = MaxFractionalMatchingDefaultTraits<GR> >
+#endif
+  class MaxFractionalMatching {
+  public:
+
+    /// \brief The \ref MaxFractionalMatchingDefaultTraits "traits
+    /// class" of the algorithm.
+    typedef TR Traits;
+    /// The type of the graph the algorithm runs on.
+    typedef typename TR::Graph Graph;
+    /// The type of the matching map.
+    typedef typename TR::MatchingMap MatchingMap;
+    /// The type of the elevator.
+    typedef typename TR::Elevator Elevator;
+
+    /// \brief Scaling factor for primal solution
+    ///
+    /// Scaling factor for primal solution.
+    static const int primalScale = 2;
+
+  private:
+
+    const Graph &_graph;
+    int _node_num;
+    bool _allow_loops;
+    int _empty_level;
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    bool _local_matching;
+    MatchingMap *_matching;
+
+    bool _local_level;
+    Elevator *_level;
+
+    typedef typename Graph::template NodeMap<int> InDegMap;
+    InDegMap *_indeg;
+
+    void createStructures() {
+      _node_num = countNodes(_graph);
+
+      if (!_matching) {
+        _local_matching = true;
+        _matching = Traits::createMatchingMap(_graph);
+      }
+      if (!_level) {
+        _local_level = true;
+        _level = Traits::createElevator(_graph, _node_num);
+      }
+      if (!_indeg) {
+        _indeg = new InDegMap(_graph);
+      }
+    }
+
+    void destroyStructures() {
+      if (_local_matching) {
+        delete _matching;
+      }
+      if (_local_level) {
+        delete _level;
+      }
+      if (_indeg) {
+        delete _indeg;
+      }
+    }
+
+    void postprocessing() {
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_indeg)[n] != 0) continue;
+        _indeg->set(n, -1);
+        Node u = n;
+        while ((*_matching)[u] != INVALID) {
+          Node v = _graph.target((*_matching)[u]);
+          _indeg->set(v, -1);
+          Arc a = _graph.oppositeArc((*_matching)[u]);
+          u = _graph.target((*_matching)[v]);
+          _indeg->set(u, -1);
+          _matching->set(v, a);
+        }
+      }
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_indeg)[n] != 1) continue;
+        _indeg->set(n, -1);
+
+        int num = 1;
+        Node u = _graph.target((*_matching)[n]);
+        while (u != n) {
+          _indeg->set(u, -1);
+          u = _graph.target((*_matching)[u]);
+          ++num;
+        }
+        if (num % 2 == 0 && num > 2) {
+          Arc prev = _graph.oppositeArc((*_matching)[n]);
+          Node v = _graph.target((*_matching)[n]);
+          u = _graph.target((*_matching)[v]);
+          _matching->set(v, prev);
+          while (u != n) {
+            prev = _graph.oppositeArc((*_matching)[u]);
+            v = _graph.target((*_matching)[u]);
+            u = _graph.target((*_matching)[v]);
+            _matching->set(v, prev);
+          }
+        }
+      }
+    }
+
+  public:
+
+    typedef MaxFractionalMatching Create;
+
+    ///\name Named Template Parameters
+
+    ///@{
+
+    template <typename T>
+    struct SetMatchingMapTraits : public Traits {
+      typedef T MatchingMap;
+      static MatchingMap *createMatchingMap(const Graph&) {
+        LEMON_ASSERT(false, "MatchingMap is not initialized");
+        return 0; // ignore warnings
+      }
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// MatchingMap type
+    ///
+    /// \ref named-templ-param "Named parameter" for setting MatchingMap
+    /// type.
+    template <typename T>
+    struct SetMatchingMap
+      : public MaxFractionalMatching<Graph, SetMatchingMapTraits<T> > {
+      typedef MaxFractionalMatching<Graph, SetMatchingMapTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetElevatorTraits : public Traits {
+      typedef T Elevator;
+      static Elevator *createElevator(const Graph&, 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 T>
+    struct SetElevator
+      : public MaxFractionalMatching<Graph, SetElevatorTraits<T> > {
+      typedef MaxFractionalMatching<Graph, SetElevatorTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetStandardElevatorTraits : public Traits {
+      typedef T Elevator;
+      static Elevator *createElevator(const Graph& graph, int max_level) {
+        return new Elevator(graph, 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
+    /// graph 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 T>
+    struct SetStandardElevator
+      : public MaxFractionalMatching<Graph, SetStandardElevatorTraits<T> > {
+      typedef MaxFractionalMatching<Graph,
+                                    SetStandardElevatorTraits<T> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    MaxFractionalMatching() {}
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    ///
+    MaxFractionalMatching(const Graph &graph, bool allow_loops = true)
+      : _graph(graph), _allow_loops(allow_loops),
+        _local_matching(false), _matching(0),
+        _local_level(false), _level(0),  _indeg(0)
+    {}
+
+    ~MaxFractionalMatching() {
+      destroyStructures();
+    }
+
+    /// \brief Sets the matching map.
+    ///
+    /// Sets the matching 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>
+    MaxFractionalMatching& matchingMap(MatchingMap& map) {
+      if (_local_matching) {
+        delete _matching;
+        _local_matching = false;
+      }
+      _matching = &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>
+    MaxFractionalMatching& 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;
+    }
+
+    /// \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() and then one variant of the start()
+    /// member.
+
+    /// @{
+
+    /// \brief Initializes the internal data structures.
+    ///
+    /// Initializes the internal data structures and sets the initial
+    /// matching.
+    void init() {
+      createStructures();
+
+      _level->initStart();
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _indeg->set(n, 0);
+        _matching->set(n, INVALID);
+        _level->initAddItem(n);
+      }
+      _level->initFinish();
+
+      _empty_level = _node_num;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        for (OutArcIt a(_graph, n); a != INVALID; ++a) {
+          if (_graph.target(a) == n && !_allow_loops) continue;
+          _matching->set(n, a);
+          Node v = _graph.target((*_matching)[n]);
+          _indeg->set(v, (*_indeg)[v] + 1);
+          break;
+        }
+      }
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_indeg)[n] == 0) {
+          _level->activate(n);
+        }
+      }
+    }
+
+    /// \brief Starts the algorithm and computes a fractional matching
+    ///
+    /// The algorithm computes a maximum fractional matching.
+    ///
+    /// \param postprocess The algorithm computes first a matching
+    /// which is a union of a matching with one value edges, cycles
+    /// with half value edges and even length paths with half value
+    /// edges. If the parameter is true, then after the push-relabel
+    /// algorithm it postprocesses the matching to contain only
+    /// matching edges and half value odd cycles.
+    void start(bool postprocess = true) {
+      Node n;
+      while ((n = _level->highestActive()) != INVALID) {
+        int level = _level->highestActiveLevel();
+        int new_level = _level->maxLevel();
+        for (InArcIt a(_graph, n); a != INVALID; ++a) {
+          Node u = _graph.source(a);
+          if (n == u && !_allow_loops) continue;
+          Node v = _graph.target((*_matching)[u]);
+          if ((*_level)[v] < level) {
+            _indeg->set(v, (*_indeg)[v] - 1);
+            if ((*_indeg)[v] == 0) {
+              _level->activate(v);
+            }
+            _matching->set(u, a);
+            _indeg->set(n, (*_indeg)[n] + 1);
+            _level->deactivate(n);
+            goto no_more_push;
+          } else if (new_level > (*_level)[v]) {
+            new_level = (*_level)[v];
+          }
+        }
+
+        if (new_level + 1 < _level->maxLevel()) {
+          _level->liftHighestActive(new_level + 1);
+        } else {
+          _level->liftHighestActiveToTop();
+        }
+        if (_level->emptyLevel(level)) {
+          _level->liftToTop(level);
+        }
+      no_more_push:
+        ;
+      }
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] == INVALID) continue;
+        Node u = _graph.target((*_matching)[n]);
+        if ((*_indeg)[u] > 1) {
+          _indeg->set(u, (*_indeg)[u] - 1);
+          _matching->set(n, INVALID);
+        }
+      }
+      if (postprocess) {
+        postprocessing();
+      }
+    }
+
+    /// \brief Starts the algorithm and computes a perfect fractional
+    /// matching
+    ///
+    /// The algorithm computes a perfect fractional matching. If it
+    /// does not exists, then the algorithm returns false and the
+    /// matching is undefined and the barrier.
+    ///
+    /// \param postprocess The algorithm computes first a matching
+    /// which is a union of a matching with one value edges, cycles
+    /// with half value edges and even length paths with half value
+    /// edges. If the parameter is true, then after the push-relabel
+    /// algorithm it postprocesses the matching to contain only
+    /// matching edges and half value odd cycles.
+    bool startPerfect(bool postprocess = true) {
+      Node n;
+      while ((n = _level->highestActive()) != INVALID) {
+        int level = _level->highestActiveLevel();
+        int new_level = _level->maxLevel();
+        for (InArcIt a(_graph, n); a != INVALID; ++a) {
+          Node u = _graph.source(a);
+          if (n == u && !_allow_loops) continue;
+          Node v = _graph.target((*_matching)[u]);
+          if ((*_level)[v] < level) {
+            _indeg->set(v, (*_indeg)[v] - 1);
+            if ((*_indeg)[v] == 0) {
+              _level->activate(v);
+            }
+            _matching->set(u, a);
+            _indeg->set(n, (*_indeg)[n] + 1);
+            _level->deactivate(n);
+            goto no_more_push;
+          } else if (new_level > (*_level)[v]) {
+            new_level = (*_level)[v];
+          }
+        }
+
+        if (new_level + 1 < _level->maxLevel()) {
+          _level->liftHighestActive(new_level + 1);
+        } else {
+          _level->liftHighestActiveToTop();
+          _empty_level = _level->maxLevel() - 1;
+          return false;
+        }
+        if (_level->emptyLevel(level)) {
+          _level->liftToTop(level);
+          _empty_level = level;
+          return false;
+        }
+      no_more_push:
+        ;
+      }
+      if (postprocess) {
+        postprocessing();
+      }
+      return true;
+    }
+
+    /// \brief Runs the algorithm
+    ///
+    /// Just a shortcut for the next code:
+    ///\code
+    /// init();
+    /// start();
+    ///\endcode
+    void run(bool postprocess = true) {
+      init();
+      start(postprocess);
+    }
+
+    /// \brief Runs the algorithm to find a perfect fractional matching
+    ///
+    /// Just a shortcut for the next code:
+    ///\code
+    /// init();
+    /// startPerfect();
+    ///\endcode
+    bool runPerfect(bool postprocess = true) {
+      init();
+      return startPerfect(postprocess);
+    }
+
+    ///@}
+
+    /// \name Query Functions
+    /// The result of the %Matching algorithm can be obtained using these
+    /// functions.\n
+    /// Before the use of these functions,
+    /// either run() or start() must be called.
+    ///@{
+
+
+    /// \brief Return the number of covered nodes in the matching.
+    ///
+    /// This function returns the number of covered nodes in the matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    int matchingSize() const {
+      int num = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          ++num;
+        }
+      }
+      return num;
+    }
+
+    /// \brief Returns a const reference to the matching map.
+    ///
+    /// Returns a const reference to the node map storing the found
+    /// fractional matching. This method can be called after
+    /// running the algorithm.
+    ///
+    /// \pre Either \ref run() or \ref init() must be called before
+    /// using this function.
+    const MatchingMap& matchingMap() const {
+      return *_matching;
+    }
+
+    /// \brief Return \c true if the given edge is in the matching.
+    ///
+    /// This function returns \c true if the given edge is in the
+    /// found matching. The result is scaled by \ref primalScale
+    /// "primal scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    int matching(const Edge& edge) const {
+      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0) +
+        (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
+    }
+
+    /// \brief Return the fractional matching arc (or edge) incident
+    /// to the given node.
+    ///
+    /// This function returns one of the fractional matching arc (or
+    /// edge) incident to the given node in the found matching or \c
+    /// INVALID if the node is not covered by the matching or if the
+    /// node is on an odd length cycle then it is the successor edge
+    /// on the cycle.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Arc matching(const Node& node) const {
+      return (*_matching)[node];
+    }
+
+    /// \brief Returns true if the node is in the barrier
+    ///
+    /// The barrier is a subset of the nodes. If the nodes in the
+    /// barrier have less adjacent nodes than the size of the barrier,
+    /// then at least as much nodes cannot be covered as the
+    /// difference of the two subsets.
+    bool barrier(const Node& node) const {
+      return (*_level)[node] >= _empty_level;
+    }
+
+    /// @}
+
+  };
+
+  /// \ingroup matching
+  ///
+  /// \brief Weighted fractional matching in general graphs
+  ///
+  /// This class provides an efficient implementation of fractional
+  /// matching algorithm. The implementation uses priority queues and
+  /// provides \f$O(nm\log n)\f$ time complexity.
+  ///
+  /// The maximum weighted fractional matching is a relaxation of the
+  /// maximum weighted matching problem where the odd set constraints
+  /// are omitted.
+  /// It 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[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$. The result must be the union of a matching with one
+  /// value edges and a set of odd length cycles with half value edges.
+  ///
+  /// The algorithm calculates an optimal fractional 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 following.
+  /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f]
+  /// \f[y_u \ge 0 \quad \forall u \in V\f]
+  /// \f[\min \sum_{u \in V}y_u \f]
+  ///
+  /// The algorithm can be executed with the run() function.
+  /// After it the matching (the primal solution) and the dual solution
+  /// can be obtained using the query functions.
+  ///
+  /// The primal solution is multiplied by
+  /// \ref MaxWeightedFractionalMatching::primalScale "2".
+  /// If the value type is integer, then the dual
+  /// solution is scaled by
+  /// \ref MaxWeightedFractionalMatching::dualScale "4".
+  ///
+  /// \tparam GR The undirected graph type the algorithm runs on.
+  /// \tparam WM The type edge weight map. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
+#ifdef DOXYGEN
+  template <typename GR, typename WM>
+#else
+  template <typename GR,
+            typename WM = typename GR::template EdgeMap<int> >
+#endif
+  class MaxWeightedFractionalMatching {
+  public:
+
+    /// The graph type of the algorithm
+    typedef GR Graph;
+    /// The type of the edge weight map
+    typedef WM WeightMap;
+    /// The value type of the edge weights
+    typedef typename WeightMap::Value Value;
+
+    /// The type of the matching map
+    typedef typename Graph::template NodeMap<typename Graph::Arc>
+    MatchingMap;
+
+    /// \brief Scaling factor for primal solution
+    ///
+    /// Scaling factor for primal solution.
+    static const int primalScale = 2;
+
+    /// \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;
+
+  private:
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    typedef typename Graph::template NodeMap<Value> NodePotential;
+
+    const Graph& _graph;
+    const WeightMap& _weight;
+
+    MatchingMap* _matching;
+    NodePotential* _node_potential;
+
+    int _node_num;
+    bool _allow_loops;
+
+    enum Status {
+      EVEN = -1, MATCHED = 0, ODD = 1
+    };
+
+    typedef typename Graph::template NodeMap<Status> StatusMap;
+    StatusMap* _status;
+
+    typedef typename Graph::template NodeMap<Arc> PredMap;
+    PredMap* _pred;
+
+    typedef ExtendFindEnum<IntNodeMap> TreeSet;
+
+    IntNodeMap *_tree_set_index;
+    TreeSet *_tree_set;
+
+    IntNodeMap *_delta1_index;
+    BinHeap<Value, IntNodeMap> *_delta1;
+
+    IntNodeMap *_delta2_index;
+    BinHeap<Value, IntNodeMap> *_delta2;
+
+    IntEdgeMap *_delta3_index;
+    BinHeap<Value, IntEdgeMap> *_delta3;
+
+    Value _delta_sum;
+
+    void createStructures() {
+      _node_num = countNodes(_graph);
+
+      if (!_matching) {
+        _matching = new MatchingMap(_graph);
+      }
+      if (!_node_potential) {
+        _node_potential = new NodePotential(_graph);
+      }
+      if (!_status) {
+        _status = new StatusMap(_graph);
+      }
+      if (!_pred) {
+        _pred = new PredMap(_graph);
+      }
+      if (!_tree_set) {
+        _tree_set_index = new IntNodeMap(_graph);
+        _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 IntNodeMap(_graph);
+        _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
+      }
+      if (!_delta3) {
+        _delta3_index = new IntEdgeMap(_graph);
+        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
+      }
+    }
+
+    void destroyStructures() {
+      if (_matching) {
+        delete _matching;
+      }
+      if (_node_potential) {
+        delete _node_potential;
+      }
+      if (_status) {
+        delete _status;
+      }
+      if (_pred) {
+        delete _pred;
+      }
+      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;
+      }
+    }
+
+    void matchedToEven(Node node, int tree) {
+      _tree_set->insert(node, tree);
+      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
+      _delta1->push(node, (*_node_potential)[node]);
+
+      if (_delta2->state(node) == _delta2->IN_HEAP) {
+        _delta2->erase(node);
+      }
+
+      for (InArcIt a(_graph, node); a != INVALID; ++a) {
+        Node v = _graph.source(a);
+        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
+          dualScale * _weight[a];
+        if (node == v) {
+          if (_allow_loops && _graph.direction(a)) {
+            _delta3->push(a, rw / 2);
+          }
+        } else if ((*_status)[v] == EVEN) {
+          _delta3->push(a, rw / 2);
+        } else if ((*_status)[v] == MATCHED) {
+          if (_delta2->state(v) != _delta2->IN_HEAP) {
+            _pred->set(v, a);
+            _delta2->push(v, rw);
+          } else if ((*_delta2)[v] > rw) {
+            _pred->set(v, a);
+            _delta2->decrease(v, rw);
+          }
+        }
+      }
+    }
+
+    void matchedToOdd(Node node, int tree) {
+      _tree_set->insert(node, tree);
+      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
+
+      if (_delta2->state(node) == _delta2->IN_HEAP) {
+        _delta2->erase(node);
+      }
+    }
+
+    void evenToMatched(Node node, int tree) {
+      _delta1->erase(node);
+      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
+      Arc min = INVALID;
+      Value minrw = std::numeric_limits<Value>::max();
+      for (InArcIt a(_graph, node); a != INVALID; ++a) {
+        Node v = _graph.source(a);
+        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
+          dualScale * _weight[a];
+
+        if (node == v) {
+          if (_allow_loops && _graph.direction(a)) {
+            _delta3->erase(a);
+          }
+        } else if ((*_status)[v] == EVEN) {
+          _delta3->erase(a);
+          if (minrw > rw) {
+            min = _graph.oppositeArc(a);
+            minrw = rw;
+          }
+        } else if ((*_status)[v]  == MATCHED) {
+          if ((*_pred)[v] == a) {
+            Arc mina = INVALID;
+            Value minrwa = std::numeric_limits<Value>::max();
+            for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
+              Node va = _graph.target(aa);
+              if ((*_status)[va] != EVEN ||
+                  _tree_set->find(va) == tree) continue;
+              Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
+                dualScale * _weight[aa];
+              if (minrwa > rwa) {
+                minrwa = rwa;
+                mina = aa;
+              }
+            }
+            if (mina != INVALID) {
+              _pred->set(v, mina);
+              _delta2->increase(v, minrwa);
+            } else {
+              _pred->set(v, INVALID);
+              _delta2->erase(v);
+            }
+          }
+        }
+      }
+      if (min != INVALID) {
+        _pred->set(node, min);
+        _delta2->push(node, minrw);
+      } else {
+        _pred->set(node, INVALID);
+      }
+    }
+
+    void oddToMatched(Node node) {
+      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
+      Arc min = INVALID;
+      Value minrw = std::numeric_limits<Value>::max();
+      for (InArcIt a(_graph, node); a != INVALID; ++a) {
+        Node v = _graph.source(a);
+        if ((*_status)[v] != EVEN) continue;
+        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
+          dualScale * _weight[a];
+
+        if (minrw > rw) {
+          min = _graph.oppositeArc(a);
+          minrw = rw;
+        }
+      }
+      if (min != INVALID) {
+        _pred->set(node, min);
+        _delta2->push(node, minrw);
+      } else {
+        _pred->set(node, INVALID);
+      }
+    }
+
+    void alternatePath(Node even, int tree) {
+      Node odd;
+
+      _status->set(even, MATCHED);
+      evenToMatched(even, tree);
+
+      Arc prev = (*_matching)[even];
+      while (prev != INVALID) {
+        odd = _graph.target(prev);
+        even = _graph.target((*_pred)[odd]);
+        _matching->set(odd, (*_pred)[odd]);
+        _status->set(odd, MATCHED);
+        oddToMatched(odd);
+
+        prev = (*_matching)[even];
+        _status->set(even, MATCHED);
+        _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
+        evenToMatched(even, tree);
+      }
+    }
+
+    void destroyTree(int tree) {
+      for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) {
+        if ((*_status)[n] == EVEN) {
+          _status->set(n, MATCHED);
+          evenToMatched(n, tree);
+        } else if ((*_status)[n] == ODD) {
+          _status->set(n, MATCHED);
+          oddToMatched(n);
+        }
+      }
+      _tree_set->eraseClass(tree);
+    }
+
+
+    void unmatchNode(const Node& node) {
+      int tree = _tree_set->find(node);
+
+      alternatePath(node, tree);
+      destroyTree(tree);
+
+      _matching->set(node, INVALID);
+    }
+
+
+    void augmentOnEdge(const Edge& edge) {
+      Node left = _graph.u(edge);
+      int left_tree = _tree_set->find(left);
+
+      alternatePath(left, left_tree);
+      destroyTree(left_tree);
+      _matching->set(left, _graph.direct(edge, true));
+
+      Node right = _graph.v(edge);
+      int right_tree = _tree_set->find(right);
+
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+      _matching->set(right, _graph.direct(edge, false));
+    }
+
+    void augmentOnArc(const Arc& arc) {
+      Node left = _graph.source(arc);
+      _status->set(left, MATCHED);
+      _matching->set(left, arc);
+      _pred->set(left, arc);
+
+      Node right = _graph.target(arc);
+      int right_tree = _tree_set->find(right);
+
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+      _matching->set(right, _graph.oppositeArc(arc));
+    }
+
+    void extendOnArc(const Arc& arc) {
+      Node base = _graph.target(arc);
+      int tree = _tree_set->find(base);
+
+      Node odd = _graph.source(arc);
+      _tree_set->insert(odd, tree);
+      _status->set(odd, ODD);
+      matchedToOdd(odd, tree);
+      _pred->set(odd, arc);
+
+      Node even = _graph.target((*_matching)[odd]);
+      _tree_set->insert(even, tree);
+      _status->set(even, EVEN);
+      matchedToEven(even, tree);
+    }
+
+    void cycleOnEdge(const Edge& edge, int tree) {
+      Node nca = INVALID;
+      std::vector<Node> left_path, right_path;
+
+      {
+        std::set<Node> left_set, right_set;
+        Node left = _graph.u(edge);
+        left_path.push_back(left);
+        left_set.insert(left);
+
+        Node right = _graph.v(edge);
+        right_path.push_back(right);
+        right_set.insert(right);
+
+        while (true) {
+
+          if (left_set.find(right) != left_set.end()) {
+            nca = right;
+            break;
+          }
+
+          if ((*_matching)[left] == INVALID) break;
+
+          left = _graph.target((*_matching)[left]);
+          left_path.push_back(left);
+          left = _graph.target((*_pred)[left]);
+          left_path.push_back(left);
+
+          left_set.insert(left);
+
+          if (right_set.find(left) != right_set.end()) {
+            nca = left;
+            break;
+          }
+
+          if ((*_matching)[right] == INVALID) break;
+
+          right = _graph.target((*_matching)[right]);
+          right_path.push_back(right);
+          right = _graph.target((*_pred)[right]);
+          right_path.push_back(right);
+
+          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]);
+              right_path.push_back(nca);
+              nca = _graph.target((*_pred)[nca]);
+              right_path.push_back(nca);
+            }
+          } else {
+            nca = left;
+            while (right_set.find(nca) == right_set.end()) {
+              nca = _graph.target((*_matching)[nca]);
+              left_path.push_back(nca);
+              nca = _graph.target((*_pred)[nca]);
+              left_path.push_back(nca);
+            }
+          }
+        }
+      }
+
+      alternatePath(nca, tree);
+      Arc prev;
+
+      prev = _graph.direct(edge, true);
+      for (int i = 0; left_path[i] != nca; i += 2) {
+        _matching->set(left_path[i], prev);
+        _status->set(left_path[i], MATCHED);
+        evenToMatched(left_path[i], tree);
+
+        prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
+        _status->set(left_path[i + 1], MATCHED);
+        oddToMatched(left_path[i + 1]);
+      }
+      _matching->set(nca, prev);
+
+      for (int i = 0; right_path[i] != nca; i += 2) {
+        _status->set(right_path[i], MATCHED);
+        evenToMatched(right_path[i], tree);
+
+        _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
+        _status->set(right_path[i + 1], MATCHED);
+        oddToMatched(right_path[i + 1]);
+      }
+
+      destroyTree(tree);
+    }
+
+    void extractCycle(const Arc &arc) {
+      Node left = _graph.source(arc);
+      Node odd = _graph.target((*_matching)[left]);
+      Arc prev;
+      while (odd != left) {
+        Node even = _graph.target((*_matching)[odd]);
+        prev = (*_matching)[odd];
+        odd = _graph.target((*_matching)[even]);
+        _matching->set(even, _graph.oppositeArc(prev));
+      }
+      _matching->set(left, arc);
+
+      Node right = _graph.target(arc);
+      int right_tree = _tree_set->find(right);
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+      _matching->set(right, _graph.oppositeArc(arc));
+    }
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    MaxWeightedFractionalMatching(const Graph& graph, const WeightMap& weight,
+                                  bool allow_loops = true)
+      : _graph(graph), _weight(weight), _matching(0),
+      _node_potential(0), _node_num(0), _allow_loops(allow_loops),
+      _status(0),  _pred(0),
+      _tree_set_index(0), _tree_set(0),
+
+      _delta1_index(0), _delta1(0),
+      _delta2_index(0), _delta2(0),
+      _delta3_index(0), _delta3(0),
+
+      _delta_sum() {}
+
+    ~MaxWeightedFractionalMatching() {
+      destroyStructures();
+    }
+
+    /// \name Execution Control
+    /// The simplest way to execute the algorithm is to use the
+    /// \ref run() member function.
+
+    ///@{
+
+    /// \brief Initialize the algorithm
+    ///
+    /// This function initializes the algorithm.
+    void init() {
+      createStructures();
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        (*_delta1_index)[n] = _delta1->PRE_HEAP;
+        (*_delta2_index)[n] = _delta2->PRE_HEAP;
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        (*_delta3_index)[e] = _delta3->PRE_HEAP;
+      }
+
+      _delta1->clear();
+      _delta2->clear();
+      _delta3->clear();
+      _tree_set->clear();
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        Value max = 0;
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          if (_graph.target(e) == n && !_allow_loops) continue;
+          if ((dualScale * _weight[e]) / 2 > max) {
+            max = (dualScale * _weight[e]) / 2;
+          }
+        }
+        _node_potential->set(n, max);
+        _delta1->push(n, max);
+
+        _tree_set->insert(n);
+
+        _matching->set(n, INVALID);
+        _status->set(n, EVEN);
+      }
+
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        Node left = _graph.u(e);
+        Node right = _graph.v(e);
+        if (left == right && !_allow_loops) continue;
+        _delta3->push(e, ((*_node_potential)[left] +
+                          (*_node_potential)[right] -
+                          dualScale * _weight[e]) / 2);
+      }
+    }
+
+    /// \brief Start the algorithm
+    ///
+    /// This function starts the algorithm.
+    ///
+    /// \pre \ref init() must be called before using this function.
+    void start() {
+      enum OpType {
+        D1, D2, D3
+      };
+
+      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();
+
+        _delta_sum = d3; OpType ot = D3;
+        if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
+        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
+
+        switch (ot) {
+        case D1:
+          {
+            Node n = _delta1->top();
+            unmatchNode(n);
+            --unmatched;
+          }
+          break;
+        case D2:
+          {
+            Node n = _delta2->top();
+            Arc a = (*_pred)[n];
+            if ((*_matching)[n] == INVALID) {
+              augmentOnArc(a);
+              --unmatched;
+            } else {
+              Node v = _graph.target((*_matching)[n]);
+              if ((*_matching)[n] !=
+                  _graph.oppositeArc((*_matching)[v])) {
+                extractCycle(a);
+                --unmatched;
+              } else {
+                extendOnArc(a);
+              }
+            }
+          } break;
+        case D3:
+          {
+            Edge e = _delta3->top();
+
+            Node left = _graph.u(e);
+            Node right = _graph.v(e);
+
+            int left_tree = _tree_set->find(left);
+            int right_tree = _tree_set->find(right);
+
+            if (left_tree == right_tree) {
+              cycleOnEdge(e, left_tree);
+              --unmatched;
+            } else {
+              augmentOnEdge(e);
+              unmatched -= 2;
+            }
+          } break;
+        }
+      }
+    }
+
+    /// \brief Run the algorithm.
+    ///
+    /// This method runs the \c %MaxWeightedFractionalMatching algorithm.
+    ///
+    /// \note mwfm.run() is just a shortcut of the following code.
+    /// \code
+    ///   mwfm.init();
+    ///   mwfm.start();
+    /// \endcode
+    void run() {
+      init();
+      start();
+    }
+
+    /// @}
+
+    /// \name Primal Solution
+    /// Functions to get the primal solution, i.e. the maximum weighted
+    /// matching.\n
+    /// Either \ref run() or \ref start() function should be called before
+    /// using them.
+
+    /// @{
+
+    /// \brief Return the weight of the matching.
+    ///
+    /// This function returns the weight of the found matching. This
+    /// value is scaled by \ref primalScale "primal scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value matchingWeight() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          sum += _weight[(*_matching)[n]];
+        }
+      }
+      return sum * primalScale / 2;
+    }
+
+    /// \brief Return the number of covered nodes in the matching.
+    ///
+    /// This function returns the number of covered nodes in the matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    int matchingSize() const {
+      int num = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          ++num;
+        }
+      }
+      return num;
+    }
+
+    /// \brief Return \c true if the given edge is in the matching.
+    ///
+    /// This function returns \c true if the given edge is in the
+    /// found matching. The result is scaled by \ref primalScale
+    /// "primal scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    int matching(const Edge& edge) const {
+      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
+        + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
+    }
+
+    /// \brief Return the fractional matching arc (or edge) incident
+    /// to the given node.
+    ///
+    /// This function returns one of the fractional matching arc (or
+    /// edge) incident to the given node in the found matching or \c
+    /// INVALID if the node is not covered by the matching or if the
+    /// node is on an odd length cycle then it is the successor edge
+    /// on the cycle.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Arc matching(const Node& node) const {
+      return (*_matching)[node];
+    }
+
+    /// \brief Return a const reference to the matching map.
+    ///
+    /// This function returns a const reference to a node map that stores
+    /// the matching arc (or edge) incident to each node.
+    const MatchingMap& matchingMap() const {
+      return *_matching;
+    }
+
+    /// @}
+
+    /// \name Dual Solution
+    /// Functions to get the dual solution.\n
+    /// Either \ref run() or \ref start() function should be called before
+    /// using them.
+
+    /// @{
+
+    /// \brief Return the value of the dual solution.
+    ///
+    /// This function returns the value of the dual solution.
+    /// It should be equal to the primal value scaled by \ref dualScale
+    /// "dual scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value dualValue() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        sum += nodeValue(n);
+      }
+      return sum;
+    }
+
+    /// \brief Return the dual value (potential) of the given node.
+    ///
+    /// This function returns the dual value (potential) of the given node.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value nodeValue(const Node& n) const {
+      return (*_node_potential)[n];
+    }
+
+    /// @}
+
+  };
+
+  /// \ingroup matching
+  ///
+  /// \brief Weighted fractional perfect matching in general graphs
+  ///
+  /// This class provides an efficient implementation of fractional
+  /// matching algorithm. The implementation uses priority queues and
+  /// provides \f$O(nm\log n)\f$ time complexity.
+  ///
+  /// The maximum weighted fractional perfect matching is a relaxation
+  /// of the maximum weighted perfect matching problem where the odd
+  /// set constraints are omitted.
+  /// It can be formulated with the following linear program.
+  /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\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$. The result must be the union of a matching with one
+  /// value edges and a set of odd length cycles with half value edges.
+  ///
+  /// The algorithm calculates an optimal fractional 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 following.
+  /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f]
+  /// \f[\min \sum_{u \in V}y_u \f]
+  ///
+  /// The algorithm can be executed with the run() function.
+  /// After it the matching (the primal solution) and the dual solution
+  /// can be obtained using the query functions.
+  ///
+  /// The primal solution is multiplied by
+  /// \ref MaxWeightedPerfectFractionalMatching::primalScale "2".
+  /// If the value type is integer, then the dual
+  /// solution is scaled by
+  /// \ref MaxWeightedPerfectFractionalMatching::dualScale "4".
+  ///
+  /// \tparam GR The undirected graph type the algorithm runs on.
+  /// \tparam WM The type edge weight map. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
+#ifdef DOXYGEN
+  template <typename GR, typename WM>
+#else
+  template <typename GR,
+            typename WM = typename GR::template EdgeMap<int> >
+#endif
+  class MaxWeightedPerfectFractionalMatching {
+  public:
+
+    /// The graph type of the algorithm
+    typedef GR Graph;
+    /// The type of the edge weight map
+    typedef WM WeightMap;
+    /// The value type of the edge weights
+    typedef typename WeightMap::Value Value;
+
+    /// The type of the matching map
+    typedef typename Graph::template NodeMap<typename Graph::Arc>
+    MatchingMap;
+
+    /// \brief Scaling factor for primal solution
+    ///
+    /// Scaling factor for primal solution.
+    static const int primalScale = 2;
+
+    /// \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;
+
+  private:
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    typedef typename Graph::template NodeMap<Value> NodePotential;
+
+    const Graph& _graph;
+    const WeightMap& _weight;
+
+    MatchingMap* _matching;
+    NodePotential* _node_potential;
+
+    int _node_num;
+    bool _allow_loops;
+
+    enum Status {
+      EVEN = -1, MATCHED = 0, ODD = 1
+    };
+
+    typedef typename Graph::template NodeMap<Status> StatusMap;
+    StatusMap* _status;
+
+    typedef typename Graph::template NodeMap<Arc> PredMap;
+    PredMap* _pred;
+
+    typedef ExtendFindEnum<IntNodeMap> TreeSet;
+
+    IntNodeMap *_tree_set_index;
+    TreeSet *_tree_set;
+
+    IntNodeMap *_delta2_index;
+    BinHeap<Value, IntNodeMap> *_delta2;
+
+    IntEdgeMap *_delta3_index;
+    BinHeap<Value, IntEdgeMap> *_delta3;
+
+    Value _delta_sum;
+
+    void createStructures() {
+      _node_num = countNodes(_graph);
+
+      if (!_matching) {
+        _matching = new MatchingMap(_graph);
+      }
+      if (!_node_potential) {
+        _node_potential = new NodePotential(_graph);
+      }
+      if (!_status) {
+        _status = new StatusMap(_graph);
+      }
+      if (!_pred) {
+        _pred = new PredMap(_graph);
+      }
+      if (!_tree_set) {
+        _tree_set_index = new IntNodeMap(_graph);
+        _tree_set = new TreeSet(*_tree_set_index);
+      }
+      if (!_delta2) {
+        _delta2_index = new IntNodeMap(_graph);
+        _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
+      }
+      if (!_delta3) {
+        _delta3_index = new IntEdgeMap(_graph);
+        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
+      }
+    }
+
+    void destroyStructures() {
+      if (_matching) {
+        delete _matching;
+      }
+      if (_node_potential) {
+        delete _node_potential;
+      }
+      if (_status) {
+        delete _status;
+      }
+      if (_pred) {
+        delete _pred;
+      }
+      if (_tree_set) {
+        delete _tree_set_index;
+        delete _tree_set;
+      }
+      if (_delta2) {
+        delete _delta2_index;
+        delete _delta2;
+      }
+      if (_delta3) {
+        delete _delta3_index;
+        delete _delta3;
+      }
+    }
+
+    void matchedToEven(Node node, int tree) {
+      _tree_set->insert(node, tree);
+      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
+
+      if (_delta2->state(node) == _delta2->IN_HEAP) {
+        _delta2->erase(node);
+      }
+
+      for (InArcIt a(_graph, node); a != INVALID; ++a) {
+        Node v = _graph.source(a);
+        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
+          dualScale * _weight[a];
+        if (node == v) {
+          if (_allow_loops && _graph.direction(a)) {
+            _delta3->push(a, rw / 2);
+          }
+        } else if ((*_status)[v] == EVEN) {
+          _delta3->push(a, rw / 2);
+        } else if ((*_status)[v] == MATCHED) {
+          if (_delta2->state(v) != _delta2->IN_HEAP) {
+            _pred->set(v, a);
+            _delta2->push(v, rw);
+          } else if ((*_delta2)[v] > rw) {
+            _pred->set(v, a);
+            _delta2->decrease(v, rw);
+          }
+        }
+      }
+    }
+
+    void matchedToOdd(Node node, int tree) {
+      _tree_set->insert(node, tree);
+      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
+
+      if (_delta2->state(node) == _delta2->IN_HEAP) {
+        _delta2->erase(node);
+      }
+    }
+
+    void evenToMatched(Node node, int tree) {
+      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
+      Arc min = INVALID;
+      Value minrw = std::numeric_limits<Value>::max();
+      for (InArcIt a(_graph, node); a != INVALID; ++a) {
+        Node v = _graph.source(a);
+        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
+          dualScale * _weight[a];
+
+        if (node == v) {
+          if (_allow_loops && _graph.direction(a)) {
+            _delta3->erase(a);
+          }
+        } else if ((*_status)[v] == EVEN) {
+          _delta3->erase(a);
+          if (minrw > rw) {
+            min = _graph.oppositeArc(a);
+            minrw = rw;
+          }
+        } else if ((*_status)[v]  == MATCHED) {
+          if ((*_pred)[v] == a) {
+            Arc mina = INVALID;
+            Value minrwa = std::numeric_limits<Value>::max();
+            for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
+              Node va = _graph.target(aa);
+              if ((*_status)[va] != EVEN ||
+                  _tree_set->find(va) == tree) continue;
+              Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
+                dualScale * _weight[aa];
+              if (minrwa > rwa) {
+                minrwa = rwa;
+                mina = aa;
+              }
+            }
+            if (mina != INVALID) {
+              _pred->set(v, mina);
+              _delta2->increase(v, minrwa);
+            } else {
+              _pred->set(v, INVALID);
+              _delta2->erase(v);
+            }
+          }
+        }
+      }
+      if (min != INVALID) {
+        _pred->set(node, min);
+        _delta2->push(node, minrw);
+      } else {
+        _pred->set(node, INVALID);
+      }
+    }
+
+    void oddToMatched(Node node) {
+      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
+      Arc min = INVALID;
+      Value minrw = std::numeric_limits<Value>::max();
+      for (InArcIt a(_graph, node); a != INVALID; ++a) {
+        Node v = _graph.source(a);
+        if ((*_status)[v] != EVEN) continue;
+        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
+          dualScale * _weight[a];
+
+        if (minrw > rw) {
+          min = _graph.oppositeArc(a);
+          minrw = rw;
+        }
+      }
+      if (min != INVALID) {
+        _pred->set(node, min);
+        _delta2->push(node, minrw);
+      } else {
+        _pred->set(node, INVALID);
+      }
+    }
+
+    void alternatePath(Node even, int tree) {
+      Node odd;
+
+      _status->set(even, MATCHED);
+      evenToMatched(even, tree);
+
+      Arc prev = (*_matching)[even];
+      while (prev != INVALID) {
+        odd = _graph.target(prev);
+        even = _graph.target((*_pred)[odd]);
+        _matching->set(odd, (*_pred)[odd]);
+        _status->set(odd, MATCHED);
+        oddToMatched(odd);
+
+        prev = (*_matching)[even];
+        _status->set(even, MATCHED);
+        _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
+        evenToMatched(even, tree);
+      }
+    }
+
+    void destroyTree(int tree) {
+      for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) {
+        if ((*_status)[n] == EVEN) {
+          _status->set(n, MATCHED);
+          evenToMatched(n, tree);
+        } else if ((*_status)[n] == ODD) {
+          _status->set(n, MATCHED);
+          oddToMatched(n);
+        }
+      }
+      _tree_set->eraseClass(tree);
+    }
+
+    void augmentOnEdge(const Edge& edge) {
+      Node left = _graph.u(edge);
+      int left_tree = _tree_set->find(left);
+
+      alternatePath(left, left_tree);
+      destroyTree(left_tree);
+      _matching->set(left, _graph.direct(edge, true));
+
+      Node right = _graph.v(edge);
+      int right_tree = _tree_set->find(right);
+
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+      _matching->set(right, _graph.direct(edge, false));
+    }
+
+    void augmentOnArc(const Arc& arc) {
+      Node left = _graph.source(arc);
+      _status->set(left, MATCHED);
+      _matching->set(left, arc);
+      _pred->set(left, arc);
+
+      Node right = _graph.target(arc);
+      int right_tree = _tree_set->find(right);
+
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+      _matching->set(right, _graph.oppositeArc(arc));
+    }
+
+    void extendOnArc(const Arc& arc) {
+      Node base = _graph.target(arc);
+      int tree = _tree_set->find(base);
+
+      Node odd = _graph.source(arc);
+      _tree_set->insert(odd, tree);
+      _status->set(odd, ODD);
+      matchedToOdd(odd, tree);
+      _pred->set(odd, arc);
+
+      Node even = _graph.target((*_matching)[odd]);
+      _tree_set->insert(even, tree);
+      _status->set(even, EVEN);
+      matchedToEven(even, tree);
+    }
+
+    void cycleOnEdge(const Edge& edge, int tree) {
+      Node nca = INVALID;
+      std::vector<Node> left_path, right_path;
+
+      {
+        std::set<Node> left_set, right_set;
+        Node left = _graph.u(edge);
+        left_path.push_back(left);
+        left_set.insert(left);
+
+        Node right = _graph.v(edge);
+        right_path.push_back(right);
+        right_set.insert(right);
+
+        while (true) {
+
+          if (left_set.find(right) != left_set.end()) {
+            nca = right;
+            break;
+          }
+
+          if ((*_matching)[left] == INVALID) break;
+
+          left = _graph.target((*_matching)[left]);
+          left_path.push_back(left);
+          left = _graph.target((*_pred)[left]);
+          left_path.push_back(left);
+
+          left_set.insert(left);
+
+          if (right_set.find(left) != right_set.end()) {
+            nca = left;
+            break;
+          }
+
+          if ((*_matching)[right] == INVALID) break;
+
+          right = _graph.target((*_matching)[right]);
+          right_path.push_back(right);
+          right = _graph.target((*_pred)[right]);
+          right_path.push_back(right);
+
+          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]);
+              right_path.push_back(nca);
+              nca = _graph.target((*_pred)[nca]);
+              right_path.push_back(nca);
+            }
+          } else {
+            nca = left;
+            while (right_set.find(nca) == right_set.end()) {
+              nca = _graph.target((*_matching)[nca]);
+              left_path.push_back(nca);
+              nca = _graph.target((*_pred)[nca]);
+              left_path.push_back(nca);
+            }
+          }
+        }
+      }
+
+      alternatePath(nca, tree);
+      Arc prev;
+
+      prev = _graph.direct(edge, true);
+      for (int i = 0; left_path[i] != nca; i += 2) {
+        _matching->set(left_path[i], prev);
+        _status->set(left_path[i], MATCHED);
+        evenToMatched(left_path[i], tree);
+
+        prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
+        _status->set(left_path[i + 1], MATCHED);
+        oddToMatched(left_path[i + 1]);
+      }
+      _matching->set(nca, prev);
+
+      for (int i = 0; right_path[i] != nca; i += 2) {
+        _status->set(right_path[i], MATCHED);
+        evenToMatched(right_path[i], tree);
+
+        _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
+        _status->set(right_path[i + 1], MATCHED);
+        oddToMatched(right_path[i + 1]);
+      }
+
+      destroyTree(tree);
+    }
+
+    void extractCycle(const Arc &arc) {
+      Node left = _graph.source(arc);
+      Node odd = _graph.target((*_matching)[left]);
+      Arc prev;
+      while (odd != left) {
+        Node even = _graph.target((*_matching)[odd]);
+        prev = (*_matching)[odd];
+        odd = _graph.target((*_matching)[even]);
+        _matching->set(even, _graph.oppositeArc(prev));
+      }
+      _matching->set(left, arc);
+
+      Node right = _graph.target(arc);
+      int right_tree = _tree_set->find(right);
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+      _matching->set(right, _graph.oppositeArc(arc));
+    }
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    MaxWeightedPerfectFractionalMatching(const Graph& graph,
+                                         const WeightMap& weight,
+                                         bool allow_loops = true)
+      : _graph(graph), _weight(weight), _matching(0),
+      _node_potential(0), _node_num(0), _allow_loops(allow_loops),
+      _status(0),  _pred(0),
+      _tree_set_index(0), _tree_set(0),
+
+      _delta2_index(0), _delta2(0),
+      _delta3_index(0), _delta3(0),
+
+      _delta_sum() {}
+
+    ~MaxWeightedPerfectFractionalMatching() {
+      destroyStructures();
+    }
+
+    /// \name Execution Control
+    /// The simplest way to execute the algorithm is to use the
+    /// \ref run() member function.
+
+    ///@{
+
+    /// \brief Initialize the algorithm
+    ///
+    /// This function initializes the algorithm.
+    void init() {
+      createStructures();
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        (*_delta2_index)[n] = _delta2->PRE_HEAP;
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        (*_delta3_index)[e] = _delta3->PRE_HEAP;
+      }
+
+      _delta2->clear();
+      _delta3->clear();
+      _tree_set->clear();
+
+      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 && !_allow_loops) continue;
+          if ((dualScale * _weight[e]) / 2 > max) {
+            max = (dualScale * _weight[e]) / 2;
+          }
+        }
+        _node_potential->set(n, max);
+
+        _tree_set->insert(n);
+
+        _matching->set(n, INVALID);
+        _status->set(n, EVEN);
+      }
+
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        Node left = _graph.u(e);
+        Node right = _graph.v(e);
+        if (left == right && !_allow_loops) continue;
+        _delta3->push(e, ((*_node_potential)[left] +
+                          (*_node_potential)[right] -
+                          dualScale * _weight[e]) / 2);
+      }
+    }
+
+    /// \brief Start the algorithm
+    ///
+    /// This function starts the algorithm.
+    ///
+    /// \pre \ref init() must be called before using this function.
+    bool start() {
+      enum OpType {
+        D2, D3
+      };
+
+      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();
+
+        _delta_sum = d3; OpType ot = D3;
+        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
+
+        if (_delta_sum == std::numeric_limits<Value>::max()) {
+          return false;
+        }
+
+        switch (ot) {
+        case D2:
+          {
+            Node n = _delta2->top();
+            Arc a = (*_pred)[n];
+            if ((*_matching)[n] == INVALID) {
+              augmentOnArc(a);
+              --unmatched;
+            } else {
+              Node v = _graph.target((*_matching)[n]);
+              if ((*_matching)[n] !=
+                  _graph.oppositeArc((*_matching)[v])) {
+                extractCycle(a);
+                --unmatched;
+              } else {
+                extendOnArc(a);
+              }
+            }
+          } break;
+        case D3:
+          {
+            Edge e = _delta3->top();
+
+            Node left = _graph.u(e);
+            Node right = _graph.v(e);
+
+            int left_tree = _tree_set->find(left);
+            int right_tree = _tree_set->find(right);
+
+            if (left_tree == right_tree) {
+              cycleOnEdge(e, left_tree);
+              --unmatched;
+            } else {
+              augmentOnEdge(e);
+              unmatched -= 2;
+            }
+          } break;
+        }
+      }
+      return true;
+    }
+
+    /// \brief Run the algorithm.
+    ///
+    /// This method runs the \c %MaxWeightedPerfectFractionalMatching
+    /// algorithm.
+    ///
+    /// \note mwfm.run() is just a shortcut of the following code.
+    /// \code
+    ///   mwpfm.init();
+    ///   mwpfm.start();
+    /// \endcode
+    bool run() {
+      init();
+      return start();
+    }
+
+    /// @}
+
+    /// \name Primal Solution
+    /// Functions to get the primal solution, i.e. the maximum weighted
+    /// matching.\n
+    /// Either \ref run() or \ref start() function should be called before
+    /// using them.
+
+    /// @{
+
+    /// \brief Return the weight of the matching.
+    ///
+    /// This function returns the weight of the found matching. This
+    /// value is scaled by \ref primalScale "primal scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value matchingWeight() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          sum += _weight[(*_matching)[n]];
+        }
+      }
+      return sum * primalScale / 2;
+    }
+
+    /// \brief Return the number of covered nodes in the matching.
+    ///
+    /// This function returns the number of covered nodes in the matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    int matchingSize() const {
+      int num = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          ++num;
+        }
+      }
+      return num;
+    }
+
+    /// \brief Return \c true if the given edge is in the matching.
+    ///
+    /// This function returns \c true if the given edge is in the
+    /// found matching. The result is scaled by \ref primalScale
+    /// "primal scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    int matching(const Edge& edge) const {
+      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
+        + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
+    }
+
+    /// \brief Return the fractional matching arc (or edge) incident
+    /// to the given node.
+    ///
+    /// This function returns one of the fractional matching arc (or
+    /// edge) incident to the given node in the found matching or \c
+    /// INVALID if the node is not covered by the matching or if the
+    /// node is on an odd length cycle then it is the successor edge
+    /// on the cycle.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Arc matching(const Node& node) const {
+      return (*_matching)[node];
+    }
+
+    /// \brief Return a const reference to the matching map.
+    ///
+    /// This function returns a const reference to a node map that stores
+    /// the matching arc (or edge) incident to each node.
+    const MatchingMap& matchingMap() const {
+      return *_matching;
+    }
+
+    /// @}
+
+    /// \name Dual Solution
+    /// Functions to get the dual solution.\n
+    /// Either \ref run() or \ref start() function should be called before
+    /// using them.
+
+    /// @{
+
+    /// \brief Return the value of the dual solution.
+    ///
+    /// This function returns the value of the dual solution.
+    /// It should be equal to the primal value scaled by \ref dualScale
+    /// "dual scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value dualValue() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        sum += nodeValue(n);
+      }
+      return sum;
+    }
+
+    /// \brief Return the dual value (potential) of the given node.
+    ///
+    /// This function returns the dual value (potential) of the given node.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value nodeValue(const Node& n) const {
+      return (*_node_potential)[n];
+    }
+
+    /// @}
+
+  };
+
+} //END OF NAMESPACE LEMON
+
+#endif //LEMON_FRACTIONAL_MATCHING_H
Index: lemon/full_graph.h
===================================================================
--- lemon/full_graph.h	(revision 440)
+++ lemon/full_graph.h	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -25,5 +25,5 @@
 ///\ingroup graphs
 ///\file
-///\brief FullGraph and FullDigraph classes.
+///\brief FullDigraph and FullGraph classes.
 
 namespace lemon {
@@ -32,5 +32,5 @@
   public:
 
-    typedef FullDigraphBase Graph;
+    typedef FullDigraphBase Digraph;
 
     class Node;
@@ -52,5 +52,5 @@
 
     Node operator()(int ix) const { return Node(ix); }
-    int index(const Node& node) const { return node._id; }
+    static int index(const Node& node) { return node._id; }
 
     Arc arc(const Node& s, const Node& t) const {
@@ -149,31 +149,36 @@
   /// \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,
+  /// \brief A directed full graph class.
+  ///
+  /// FullDigraph is a simple and fast implmenetation of directed full
+  /// (complete) graphs. It contains an arc from each node to each node
+  /// (including a loop for each node), therefore the number of arcs
+  /// is the square of the number of nodes.
+  /// This class is completely static and it needs constant memory space.
+  /// Thus you can neither add nor delete nodes or arcs, however
+  /// the structure can be resized using resize().
+  ///
+  /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
+  /// Most of its member functions and nested classes are documented
+  /// only in the concept class.
+  ///
+  /// This class provides constant time counting for nodes and arcs.
+  ///
+  /// \note FullDigraph and 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.
+  /// to the \ref concepts::Digraph "Digraph" concept, FullGraph
+  /// conforms to the \ref concepts::Graph "Graph" concept,
+  /// moreover FullGraph does not contain a loop for each
+  /// node as this class does.
   ///
   /// \sa FullGraph
   class FullDigraph : public ExtendedFullDigraphBase {
+    typedef ExtendedFullDigraphBase Parent;
+
   public:
 
-    typedef ExtendedFullDigraphBase Parent;
-
-    /// \brief Constructor
+    /// \brief Default constructor.
+    ///
+    /// Default constructor. The number of nodes and arcs will be zero.
     FullDigraph() { construct(0); }
 
@@ -186,6 +191,6 @@
     /// \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
+    /// This function resizes the digraph. It fully destroys and
+    /// rebuilds the structure, therefore the maps of the digraph will be
     /// reallocated automatically and the previous values will be lost.
     void resize(int n) {
@@ -199,7 +204,8 @@
     /// \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>.
+    /// Returns the node with the given index. Since this structure is
+    /// completely static, the nodes can be indexed with integers from
+    /// the range <tt>[0..nodeNum()-1]</tt>.
+    /// The index of a node is the same as its ID.
     /// \sa index()
     Node operator()(int ix) const { return Parent::operator()(ix); }
@@ -207,14 +213,15 @@
     /// \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); }
+    /// Returns the index of the given node. Since this structure is
+    /// completely static, the nodes can be indexed with integers from
+    /// the range <tt>[0..nodeNum()-1]</tt>.
+    /// The index of a node is the same as its ID.
+    /// \sa operator()()
+    static int index(const Node& node) { 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 {
+    Arc arc(Node u, Node v) const {
       return Parent::arc(u, v);
     }
@@ -228,6 +235,4 @@
 
   class FullGraphBase {
-    int _node_num;
-    int _edge_num;
   public:
 
@@ -239,4 +244,7 @@
 
   protected:
+
+    int _node_num;
+    int _edge_num;
 
     FullGraphBase() {}
@@ -284,5 +292,5 @@
 
     Node operator()(int ix) const { return Node(ix); }
-    int index(const Node& node) const { return node._id; }
+    static int index(const Node& node) { return node._id; }
 
     Edge edge(const Node& u, const Node& v) const {
@@ -521,29 +529,33 @@
   /// \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
+  /// FullGraph is a simple and fast implmenetation of undirected full
+  /// (complete) graphs. It contains an edge between every distinct pair
+  /// of nodes, therefore the number of edges is <tt>n(n-1)/2</tt>.
+  /// This class is completely static and it needs constant memory space.
+  /// Thus you can neither add nor delete nodes or edges, however
+  /// the structure can be resized using resize().
+  ///
+  /// This type fully conforms to the \ref concepts::Graph "Graph concept".
+  /// Most of its member functions and nested classes are documented
+  /// only in the concept class.
+  ///
+  /// This class provides constant time counting for nodes, edges and arcs.
+  ///
+  /// \note FullDigraph and FullGraph classes are very similar,
+  /// but there are two differences. While FullDigraph
   /// 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.
+  /// moreover this class does not contain a loop for each
+  /// node as FullDigraph does.
   ///
   /// \sa FullDigraph
   class FullGraph : public ExtendedFullGraphBase {
+    typedef ExtendedFullGraphBase Parent;
+
   public:
 
-    typedef ExtendedFullGraphBase Parent;
-
-    /// \brief Constructor
+    /// \brief Default constructor.
+    ///
+    /// Default constructor. The number of nodes and edges will be zero.
     FullGraph() { construct(0); }
 
@@ -556,6 +568,6 @@
     /// \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
+    /// This function resizes the graph. It fully destroys and
+    /// rebuilds the structure, therefore the maps of the graph will be
     /// reallocated automatically and the previous values will be lost.
     void resize(int n) {
@@ -571,7 +583,8 @@
     /// \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>.
+    /// Returns the node with the given index. Since this structure is
+    /// completely static, the nodes can be indexed with integers from
+    /// the range <tt>[0..nodeNum()-1]</tt>.
+    /// The index of a node is the same as its ID.
     /// \sa index()
     Node operator()(int ix) const { return Parent::operator()(ix); }
@@ -579,21 +592,22 @@
     /// \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); }
+    /// Returns the index of the given node. Since this structure is
+    /// completely static, the nodes can be indexed with integers from
+    /// the range <tt>[0..nodeNum()-1]</tt>.
+    /// The index of a node is the same as its ID.
+    /// \sa operator()()
+    static int index(const Node& node) { 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 {
+    Arc arc(Node s, 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 {
+    /// \brief Returns the edge connecting the given nodes.
+    ///
+    /// Returns the edge connecting the given nodes.
+    Edge edge(Node u, Node v) const {
       return Parent::edge(u, v);
     }
Index: lemon/glpk.cc
===================================================================
--- lemon/glpk.cc	(revision 551)
+++ lemon/glpk.cc	(revision 956)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -32,4 +32,5 @@
     lp = glp_create_prob();
     glp_create_index(lp);
+    messageLevel(MESSAGE_NOTHING);
   }
 
@@ -40,4 +41,5 @@
     rows = other.rows;
     cols = other.cols;
+    messageLevel(MESSAGE_NOTHING);
   }
 
@@ -55,4 +57,40 @@
     int i = glp_add_rows(lp, 1);
     glp_set_row_bnds(lp, i, GLP_FR, 0.0, 0.0);
+    return i;
+  }
+
+  int GlpkBase::_addRow(Value lo, ExprIterator b,
+                        ExprIterator e, Value up) {
+    int i = glp_add_rows(lp, 1);
+
+    if (lo == -INF) {
+      if (up == INF) {
+        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
+      } else {
+        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
+      }
+    } else {
+      if (up == INF) {
+        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
+      } else if (lo != up) {
+        glp_set_row_bnds(lp, i, GLP_DB, lo, up);
+      } else {
+        glp_set_row_bnds(lp, i, GLP_FX, lo, up);
+      }
+    }
+
+    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());
     return i;
   }
@@ -519,6 +557,4 @@
   void GlpkBase::_clear() {
     glp_erase_prob(lp);
-    rows.clear();
-    cols.clear();
   }
 
@@ -527,4 +563,24 @@
   }
 
+  void GlpkBase::_messageLevel(MessageLevel level) {
+    switch (level) {
+    case MESSAGE_NOTHING:
+      _message_level = GLP_MSG_OFF;
+      break;
+    case MESSAGE_ERROR:
+      _message_level = GLP_MSG_ERR;
+      break;
+    case MESSAGE_WARNING:
+      _message_level = GLP_MSG_ERR;
+      break;
+    case MESSAGE_NORMAL:
+      _message_level = GLP_MSG_ON;
+      break;
+    case MESSAGE_VERBOSE:
+      _message_level = GLP_MSG_ALL;
+      break;
+    }
+  }
+
   GlpkBase::FreeEnvHelper GlpkBase::freeEnvHelper;
 
@@ -533,10 +589,10 @@
   GlpkLp::GlpkLp()
     : LpBase(), LpSolver(), GlpkBase() {
-    messageLevel(MESSAGE_NO_OUTPUT);
+    presolver(false);
   }
 
   GlpkLp::GlpkLp(const GlpkLp& other)
     : LpBase(other), LpSolver(other), GlpkBase(other) {
-    messageLevel(MESSAGE_NO_OUTPUT);
+    presolver(false);
   }
 
@@ -561,20 +617,24 @@
     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;
+    smcp.msg_lev = _message_level;
+    smcp.presolve = _presolve;
+
+    // If the basis is not valid we get an error return value.
+    // In this case we can try to create a new basis.
+    switch (glp_simplex(lp, &smcp)) {
+    case 0:
+      break;
+    case GLP_EBADB:
+    case GLP_ESING:
+    case GLP_ECOND:
+      glp_term_out(false);
+      glp_adv_basis(lp, 0);
+      glp_term_out(true);
+      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
+      break;
+    default:
+      return UNSOLVED;
+    }
+
     return SOLVED;
   }
@@ -586,21 +646,24 @@
     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.msg_lev = _message_level;
     smcp.meth = GLP_DUAL;
-
-    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
+    smcp.presolve = _presolve;
+
+    // If the basis is not valid we get an error return value.
+    // In this case we can try to create a new basis.
+    switch (glp_simplex(lp, &smcp)) {
+    case 0:
+      break;
+    case GLP_EBADB:
+    case GLP_ESING:
+    case GLP_ECOND:
+      glp_term_out(false);
+      glp_adv_basis(lp, 0);
+      glp_term_out(true);
+      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
+      break;
+    default:
+      return UNSOLVED;
+    }
     return SOLVED;
   }
@@ -820,10 +883,6 @@
   }
 
-  void GlpkLp::presolver(bool b) {
-    lpx_set_int_parm(lp, LPX_K_PRESOL, b ? 1 : 0);
-  }
-
-  void GlpkLp::messageLevel(MessageLevel m) {
-    _message_level = m;
+  void GlpkLp::presolver(bool presolve) {
+    _presolve = presolve;
   }
 
@@ -832,10 +891,8 @@
   GlpkMip::GlpkMip()
     : LpBase(), MipSolver(), GlpkBase() {
-    messageLevel(MESSAGE_NO_OUTPUT);
   }
 
   GlpkMip::GlpkMip(const GlpkMip& other)
     : LpBase(), MipSolver(), GlpkBase(other) {
-    messageLevel(MESSAGE_NO_OUTPUT);
   }
 
@@ -866,21 +923,24 @@
     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.msg_lev = _message_level;
     smcp.meth = GLP_DUAL;
 
-    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
+    // If the basis is not valid we get an error return value.
+    // In this case we can try to create a new basis.
+    switch (glp_simplex(lp, &smcp)) {
+    case 0:
+      break;
+    case GLP_EBADB:
+    case GLP_ESING:
+    case GLP_ECOND:
+      glp_term_out(false);
+      glp_adv_basis(lp, 0);
+      glp_term_out(true);
+      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
+      break;
+    default:
+      return UNSOLVED;
+    }
+
     if (glp_get_status(lp) != GLP_OPT) return SOLVED;
 
@@ -888,18 +948,5 @@
     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;
-    }
+    iocp.msg_lev = _message_level;
 
     if (glp_intopt(lp, &iocp) != 0) return UNSOLVED;
@@ -952,7 +999,3 @@
   const char* GlpkMip::_solverName() const { return "GlpkMip"; }
 
-  void GlpkMip::messageLevel(MessageLevel m) {
-    _message_level = m;
-  }
-
 } //END OF NAMESPACE LEMON
Index: lemon/glpk.h
===================================================================
--- lemon/glpk.h	(revision 542)
+++ lemon/glpk.h	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -26,13 +26,26 @@
 #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 {
 
+  namespace _solver_bits {
+    class VoidPtr {
+    private:
+      void *_ptr;
+    public:
+      VoidPtr() : _ptr(0) {}
+
+      template <typename T>
+      VoidPtr(T* ptr) : _ptr(reinterpret_cast<void*>(ptr)) {}
+
+      template <typename T>
+      VoidPtr& operator=(T* ptr) {
+        _ptr = reinterpret_cast<void*>(ptr);
+        return *this;
+      }
+
+      template <typename T>
+      operator T*() const { return reinterpret_cast<T*>(_ptr); }
+    };
+  }
 
   /// \brief Base interface for the GLPK LP and MIP solver
@@ -43,6 +56,5 @@
   protected:
 
-    typedef glp_prob LPX;
-    glp_prob* lp;
+    _solver_bits::VoidPtr lp;
 
     GlpkBase();
@@ -54,4 +66,5 @@
     virtual int _addCol();
     virtual int _addRow();
+    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
 
     virtual void _eraseCol(int i);
@@ -100,4 +113,6 @@
 
     virtual void _clear();
+
+    virtual void _messageLevel(MessageLevel level);
 
   private:
@@ -110,13 +125,17 @@
       }
     };
-    
+
     static FreeEnvHelper freeEnvHelper;
-    
+
+  protected:
+
+    int _message_level;
+
   public:
 
     ///Pointer to the underlying GLPK data structure.
-    LPX *lpx() {return lp;}
+    _solver_bits::VoidPtr lpx() {return lp;}
     ///Const pointer to the underlying GLPK data structure.
-    const LPX *lpx() const {return lp;}
+    _solver_bits::VoidPtr lpx() const {return lp;}
 
     ///Returns the constraint identifier understood by GLPK.
@@ -179,4 +198,10 @@
     SolveExitStatus solveDual();
 
+  private:
+
+    bool _presolve;
+
+  public:
+
     ///Turns on or off the presolver
 
@@ -184,30 +209,6 @@
     ///
     ///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);
+    void presolver(bool presolve);
+
   };
 
@@ -239,28 +240,4 @@
     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);
   };
 
Index: lemon/gomory_hu.h
===================================================================
--- lemon/gomory_hu.h	(revision 546)
+++ lemon/gomory_hu.h	(revision 877)
@@ -1,7 +1,7 @@
-/* -*- C++ -*-
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
  *
- * This file is a part of LEMON, a generic C++ optimization library
+ * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -28,5 +28,5 @@
 
 /// \ingroup min_cut
-/// \file 
+/// \file
 /// \brief Gomory-Hu cut tree in graphs.
 
@@ -39,19 +39,17 @@
   /// The Gomory-Hu tree is a tree on the node set of a given graph, but it
   /// may contain edges which are not in the original graph. It has the
-  /// property that the minimum capacity edge of the path between two nodes 
+  /// property that the minimum capacity edge of the path between two nodes
   /// in this tree has the same weight as the minimum cut in the graph
   /// between these nodes. Moreover the components obtained by removing
   /// this edge from the tree determine the corresponding minimum cut.
-  ///
   /// Therefore once this tree is computed, the minimum cut between any pair
   /// of nodes can easily be obtained.
-  /// 
+  ///
   /// The algorithm calculates \e n-1 distinct minimum cuts (currently with
-  /// the \ref Preflow algorithm), therefore the algorithm has
-  /// \f$(O(n^3\sqrt{e})\f$ overall time complexity. It calculates a
-  /// rooted Gomory-Hu tree, its structure and the weights can be obtained
-  /// by \c predNode(), \c predValue() and \c rootDist().
-  /// 
-  /// The members \c minCutMap() and \c minCutValue() calculate
+  /// the \ref Preflow algorithm), thus it has \f$O(n^3\sqrt{e})\f$ overall
+  /// time complexity. It calculates a rooted Gomory-Hu tree.
+  /// The structure of the tree and the edge weights can be
+  /// obtained using \c predNode(), \c predValue() and \c rootDist().
+  /// The functions \c minCutMap() and \c minCutValue() calculate
   /// the minimum cut and the minimum cut value between any two nodes
   /// in the graph. You can also list (iterate on) the nodes and the
@@ -59,23 +57,23 @@
   ///
   /// \tparam GR The type of the undirected graph the algorithm runs on.
-  /// \tparam CAP The type of the edge map describing the edge capacities.
-  /// It is \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>" by default.
+  /// \tparam CAP The type of the edge map containing the capacities.
+  /// The default map type is \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
 #ifdef DOXYGEN
   template <typename GR,
-	    typename CAP>
+            typename CAP>
 #else
   template <typename GR,
-	    typename CAP = typename GR::template EdgeMap<int> >
+            typename CAP = typename GR::template EdgeMap<int> >
 #endif
   class GomoryHu {
   public:
 
-    /// The graph type
+    /// The graph type of the algorithm
     typedef GR Graph;
-    /// The type of the edge capacity map
+    /// The capacity map type of the algorithm
     typedef CAP Capacity;
     /// The value type of capacities
     typedef typename Capacity::Value Value;
-    
+
   private:
 
@@ -92,11 +90,11 @@
     void createStructures() {
       if (!_pred) {
-	_pred = new typename Graph::template NodeMap<Node>(_graph);
+        _pred = new typename Graph::template NodeMap<Node>(_graph);
       }
       if (!_weight) {
-	_weight = new typename Graph::template NodeMap<Value>(_graph);
+        _weight = new typename Graph::template NodeMap<Value>(_graph);
       }
       if (!_order) {
-	_order = new typename Graph::template NodeMap<int>(_graph);
+        _order = new typename Graph::template NodeMap<int>(_graph);
       }
     }
@@ -104,24 +102,24 @@
     void destroyStructures() {
       if (_pred) {
-	delete _pred;
+        delete _pred;
       }
       if (_weight) {
-	delete _weight;
+        delete _weight;
       }
       if (_order) {
-	delete _order;
-      }
-    }
-  
+        delete _order;
+      }
+    }
+
   public:
 
     /// \brief Constructor
     ///
-    /// Constructor
+    /// Constructor.
     /// \param graph The undirected graph the algorithm runs on.
     /// \param capacity The edge capacity map.
-    GomoryHu(const Graph& graph, const Capacity& capacity) 
+    GomoryHu(const Graph& graph, const Capacity& capacity)
       : _graph(graph), _capacity(capacity),
-	_pred(0), _weight(0), _order(0) 
+        _pred(0), _weight(0), _order(0)
     {
       checkConcept<concepts::ReadMap<Edge, Value>, Capacity>();
@@ -131,5 +129,5 @@
     /// \brief Destructor
     ///
-    /// Destructor
+    /// Destructor.
     ~GomoryHu() {
       destroyStructures();
@@ -137,5 +135,5 @@
 
   private:
-  
+
     // Initialize the internal data structures
     void init() {
@@ -144,9 +142,9 @@
       _root = NodeIt(_graph);
       for (NodeIt n(_graph); n != INVALID; ++n) {
-	_pred->set(n, _root);
-	_order->set(n, -1);
-      }
-      _pred->set(_root, INVALID);
-      _weight->set(_root, std::numeric_limits<Value>::max()); 
+        (*_pred)[n] = _root;
+        (*_order)[n] = -1;
+      }
+      (*_pred)[_root] = INVALID;
+      (*_weight)[_root] = std::numeric_limits<Value>::max();
     }
 
@@ -157,41 +155,41 @@
 
       for (NodeIt n(_graph); n != INVALID; ++n) {
-	if (n == _root) continue;
-
-	Node pn = (*_pred)[n];
-	fa.source(n);
-	fa.target(pn);
-
-	fa.runMinCut();
-
-	_weight->set(n, fa.flowValue());
-
-	for (NodeIt nn(_graph); nn != INVALID; ++nn) {
-	  if (nn != n && fa.minCut(nn) && (*_pred)[nn] == pn) {
-	    _pred->set(nn, n);
-	  }
-	}
-	if ((*_pred)[pn] != INVALID && fa.minCut((*_pred)[pn])) {
-	  _pred->set(n, (*_pred)[pn]);
-	  _pred->set(pn, n);
-	  _weight->set(n, (*_weight)[pn]);
-	  _weight->set(pn, fa.flowValue());	
-	}
-      }
-
-      _order->set(_root, 0);
+        if (n == _root) continue;
+
+        Node pn = (*_pred)[n];
+        fa.source(n);
+        fa.target(pn);
+
+        fa.runMinCut();
+
+        (*_weight)[n] = fa.flowValue();
+
+        for (NodeIt nn(_graph); nn != INVALID; ++nn) {
+          if (nn != n && fa.minCut(nn) && (*_pred)[nn] == pn) {
+            (*_pred)[nn] = n;
+          }
+        }
+        if ((*_pred)[pn] != INVALID && fa.minCut((*_pred)[pn])) {
+          (*_pred)[n] = (*_pred)[pn];
+          (*_pred)[pn] = n;
+          (*_weight)[n] = (*_weight)[pn];
+          (*_weight)[pn] = fa.flowValue();
+        }
+      }
+
+      (*_order)[_root] = 0;
       int index = 1;
 
       for (NodeIt n(_graph); n != INVALID; ++n) {
-	std::vector<Node> st;
-	Node nn = n;
-	while ((*_order)[nn] == -1) {
-	  st.push_back(nn);
-	  nn = (*_pred)[nn];
-	}
-	while (!st.empty()) {
-	  _order->set(st.back(), index++);
-	  st.pop_back();
-	}
+        std::vector<Node> st;
+        Node nn = n;
+        while ((*_order)[nn] == -1) {
+          st.push_back(nn);
+          nn = (*_pred)[nn];
+        }
+        while (!st.empty()) {
+          (*_order)[st.back()] = index++;
+          st.pop_back();
+        }
       }
     }
@@ -200,5 +198,5 @@
 
     ///\name Execution Control
- 
+
     ///@{
 
@@ -210,5 +208,5 @@
       start();
     }
-    
+
     /// @}
 
@@ -216,5 +214,5 @@
     ///The results of the algorithm can be obtained using these
     ///functions.\n
-    ///\ref run() "run()" should be called before using them.\n
+    ///\ref run() should be called before using them.\n
     ///See also \ref MinCutNodeIt and \ref MinCutEdgeIt.
 
@@ -223,17 +221,11 @@
     /// \brief Return the predecessor node in the Gomory-Hu tree.
     ///
-    /// This function returns the predecessor node in the Gomory-Hu tree.
-    /// If the node is
-    /// the root of the Gomory-Hu tree, then it returns \c INVALID.
-    Node predNode(const Node& node) {
+    /// This function returns the predecessor node of the given node
+    /// in the Gomory-Hu tree.
+    /// If \c node is the root of the tree, then it returns \c INVALID.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Node predNode(const Node& node) const {
       return (*_pred)[node];
-    }
-
-    /// \brief Return the distance from the root node in the Gomory-Hu tree.
-    ///
-    /// This function returns the distance of \c node from the root node
-    /// in the Gomory-Hu tree.
-    int rootDist(const Node& node) {
-      return (*_order)[node];
     }
 
@@ -241,28 +233,44 @@
     /// Gomory-Hu tree.
     ///
-    /// This function returns the weight of the predecessor edge in the
-    /// Gomory-Hu tree.  If the node is the root, the result is undefined.
-    Value predValue(const Node& node) {
+    /// This function returns the weight of the predecessor edge of the
+    /// given node in the Gomory-Hu tree.
+    /// If \c node is the root of the tree, the result is undefined.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Value predValue(const Node& node) const {
       return (*_weight)[node];
     }
 
+    /// \brief Return the distance from the root node in the Gomory-Hu tree.
+    ///
+    /// This function returns the distance of the given node from the root
+    /// node in the Gomory-Hu tree.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    int rootDist(const Node& node) const {
+      return (*_order)[node];
+    }
+
     /// \brief Return the minimum cut value between two nodes
     ///
-    /// This function returns the minimum cut value between two nodes. The
-    /// algorithm finds the nearest common ancestor in the Gomory-Hu
-    /// tree and calculates the minimum weight edge on the paths to
-    /// the ancestor.
+    /// This function returns the minimum cut value between the nodes
+    /// \c s and \c t.
+    /// It finds the nearest common ancestor of the given nodes in the
+    /// Gomory-Hu tree and calculates the minimum weight edge on the
+    /// paths to the ancestor.
+    ///
+    /// \pre \ref run() must be called before using this function.
     Value minCutValue(const Node& s, const Node& t) const {
       Node sn = s, tn = t;
       Value value = std::numeric_limits<Value>::max();
-      
+
       while (sn != tn) {
-	if ((*_order)[sn] < (*_order)[tn]) {
-	  if ((*_weight)[tn] <= value) value = (*_weight)[tn];
-	  tn = (*_pred)[tn];
-	} else {
-	  if ((*_weight)[sn] <= value) value = (*_weight)[sn];
-	  sn = (*_pred)[sn];
-	}
+        if ((*_order)[sn] < (*_order)[tn]) {
+          if ((*_weight)[tn] <= value) value = (*_weight)[tn];
+          tn = (*_pred)[tn];
+        } else {
+          if ((*_weight)[sn] <= value) value = (*_weight)[sn];
+          sn = (*_pred)[sn];
+        }
       }
       return value;
@@ -275,14 +283,19 @@
     /// \c s to \c true and the other nodes to \c false.
     ///
-    /// For higher level interfaces, see MinCutNodeIt and MinCutEdgeIt.
+    /// For higher level interfaces see MinCutNodeIt and MinCutEdgeIt.
+    ///
+    /// \param s The base node.
+    /// \param t The node you want to separate from node \c s.
+    /// \param cutMap The cut will be returned in this map.
+    /// It must be a \c bool (or convertible) \ref concepts::ReadWriteMap
+    /// "ReadWriteMap" on the graph nodes.
+    ///
+    /// \return The value of the minimum cut between \c s and \c t.
+    ///
+    /// \pre \ref run() must be called before using this function.
     template <typename CutMap>
-    Value minCutMap(const Node& s, ///< The base node.
+    Value minCutMap(const Node& s,
                     const Node& t,
-                    ///< The node you want to separate from node \c s.
                     CutMap& cutMap
-                    ///< The cut will be returned in this map.
-                    /// It must be a \c bool (or convertible) 
-                    /// \ref concepts::ReadWriteMap "ReadWriteMap"
-                    /// on the graph nodes.
                     ) const {
       Node sn = s, tn = t;
@@ -290,43 +303,43 @@
       Node rn = INVALID;
       Value value = std::numeric_limits<Value>::max();
-      
+
       while (sn != tn) {
-	if ((*_order)[sn] < (*_order)[tn]) {
-	  if ((*_weight)[tn] <= value) {
-	    rn = tn;
+        if ((*_order)[sn] < (*_order)[tn]) {
+          if ((*_weight)[tn] <= value) {
+            rn = tn;
             s_root = false;
-	    value = (*_weight)[tn];
-	  }
-	  tn = (*_pred)[tn];
-	} else {
-	  if ((*_weight)[sn] <= value) {
-	    rn = sn;
+            value = (*_weight)[tn];
+          }
+          tn = (*_pred)[tn];
+        } else {
+          if ((*_weight)[sn] <= value) {
+            rn = sn;
             s_root = true;
-	    value = (*_weight)[sn];
-	  }
-	  sn = (*_pred)[sn];
-	}
+            value = (*_weight)[sn];
+          }
+          sn = (*_pred)[sn];
+        }
       }
 
       typename Graph::template NodeMap<bool> reached(_graph, false);
-      reached.set(_root, true);
+      reached[_root] = true;
       cutMap.set(_root, !s_root);
-      reached.set(rn, true);
+      reached[rn] = true;
       cutMap.set(rn, s_root);
 
       std::vector<Node> st;
       for (NodeIt n(_graph); n != INVALID; ++n) {
-	st.clear();
+        st.clear();
         Node nn = n;
-	while (!reached[nn]) {
-	  st.push_back(nn);
-	  nn = (*_pred)[nn];
-	}
-	while (!st.empty()) {
-	  cutMap.set(st.back(), cutMap[nn]);
-	  st.pop_back();
-	}
-      }
-      
+        while (!reached[nn]) {
+          st.push_back(nn);
+          nn = (*_pred)[nn];
+        }
+        while (!st.empty()) {
+          cutMap.set(st.back(), cutMap[nn]);
+          st.pop_back();
+        }
+      }
+
       return value;
     }
@@ -337,7 +350,7 @@
 
     /// Iterate on the nodes of a minimum cut
-    
+
     /// This iterator class lists the nodes of a minimum cut found by
-    /// GomoryHu. Before using it, you must allocate a GomoryHu class,
+    /// GomoryHu. Before using it, you must allocate a GomoryHu class
     /// and call its \ref GomoryHu::run() "run()" method.
     ///
@@ -345,8 +358,8 @@
     /// \c t.
     /// \code
-    /// GomoruHu<Graph> gom(g, capacities);
+    /// GomoryHu<Graph> gom(g, capacities);
     /// gom.run();
     /// int cnt=0;
-    /// for(GomoruHu<Graph>::MinCutNodeIt n(gom,s,t); n!=INVALID; ++n) ++cnt;
+    /// for(GomoryHu<Graph>::MinCutNodeIt n(gom,s,t); n!=INVALID; ++n) ++cnt;
     /// \endcode
     class MinCutNodeIt
@@ -380,5 +393,5 @@
                    /// \endcode
                    /// does not necessarily give the same set of nodes.
-                   /// However it is ensured that
+                   /// However, it is ensured that
                    /// \code
                    /// MinCutNodeIt(gomory, s, t, true);
@@ -430,11 +443,11 @@
       }
     };
-    
+
     friend class MinCutEdgeIt;
-    
+
     /// Iterate on the edges of a minimum cut
-    
+
     /// This iterator class lists the edges of a minimum cut found by
-    /// GomoryHu. Before using it, you must allocate a GomoryHu class,
+    /// GomoryHu. Before using it, you must allocate a GomoryHu class
     /// and call its \ref GomoryHu::run() "run()" method.
     ///
@@ -442,12 +455,12 @@
     /// \c t.
     /// \code
-    /// GomoruHu<Graph> gom(g, capacities);
+    /// GomoryHu<Graph> gom(g, capacities);
     /// gom.run();
     /// int value=0;
-    /// for(GomoruHu<Graph>::MinCutEdgeIt e(gom,s,t); e!=INVALID; ++e)
+    /// for(GomoryHu<Graph>::MinCutEdgeIt e(gom,s,t); e!=INVALID; ++e)
     ///   value+=capacities[e];
     /// \endcode
-    /// the result will be the same as it is returned by
-    /// \ref GomoryHu::minCutValue() "gom.minCutValue(s,t)"
+    /// The result will be the same as the value returned by
+    /// \ref GomoryHu::minCutValue() "gom.minCutValue(s,t)".
     class MinCutEdgeIt
     {
@@ -467,6 +480,10 @@
           }
       }
-      
+
     public:
+      /// Constructor
+
+      /// Constructor.
+      ///
       MinCutEdgeIt(GomoryHu const &gomory,
                    ///< The GomoryHu class. You must call its
@@ -479,5 +496,5 @@
                    ///< If it is \c true (default) then the listed arcs
                    ///  will be oriented from the
-                   ///  the nodes of the component containing \c s,
+                   ///  nodes of the component containing \c s,
                    ///  otherwise they will be oriented in the opposite
                    ///  direction.
@@ -532,5 +549,5 @@
       }
       /// Postfix incrementation
-      
+
       /// Postfix incrementation.
       ///
Index: lemon/graph_to_eps.h
===================================================================
--- lemon/graph_to_eps.h	(revision 559)
+++ lemon/graph_to_eps.h	(revision 996)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -70,4 +70,5 @@
 {
   typedef GR Graph;
+  typedef GR Digraph;
   typedef typename Graph::Node Node;
   typedef typename Graph::NodeIt NodeIt;
@@ -142,5 +143,5 @@
   ///\param gr  Reference to the graph to be printed.
   ///\param ost Reference to the output stream.
-  ///By default it is <tt>std::cout</tt>.
+  ///By default, it is <tt>std::cout</tt>.
   ///\param pros If it is \c true, then the \c ostream referenced by \c os
   ///will be explicitly deallocated by the destructor.
@@ -222,5 +223,4 @@
   using T::_copyright;
 
-  using T::NodeTextColorType;
   using T::CUST_COL;
   using T::DIST_COL;
@@ -242,4 +242,5 @@
 
   typedef typename T::Graph Graph;
+  typedef typename T::Digraph Digraph;
   typedef typename Graph::Node Node;
   typedef typename Graph::NodeIt NodeIt;
@@ -269,20 +270,16 @@
     ///\image html nodeshape_1.png
     ///\image latex nodeshape_1.eps "SQUARE shape (1)" width=2cm
-    ///
     SQUARE=1,
     /// = 2
     ///\image html nodeshape_2.png
     ///\image latex nodeshape_2.eps "DIAMOND shape (2)" width=2cm
-    ///
     DIAMOND=2,
     /// = 3
     ///\image html nodeshape_3.png
-    ///\image latex nodeshape_2.eps "MALE shape (4)" width=2cm
-    ///
+    ///\image latex nodeshape_3.eps "MALE shape (3)" width=2cm
     MALE=3,
     /// = 4
     ///\image html nodeshape_4.png
-    ///\image latex nodeshape_2.eps "FEMALE shape (4)" width=2cm
-    ///
+    ///\image latex nodeshape_4.eps "FEMALE shape (4)" width=2cm
     FEMALE=4
   };
@@ -515,5 +512,5 @@
   ///Turn on/off pre-scaling
 
-  ///By default graphToEps() rescales the whole image in order to avoid
+  ///By default, graphToEps() rescales the whole image in order to avoid
   ///very big or very small bounding boxes.
   ///
@@ -687,7 +684,7 @@
 #else
       os << bits::getWinFormattedDate();
+      os << std::endl;
 #endif
     }
-    os << std::endl;
 
     if (_autoArcWidthScale) {
@@ -1117,5 +1114,5 @@
 ///\param g Reference to the graph to be printed.
 ///\param os Reference to the output stream.
-///By default it is <tt>std::cout</tt>.
+///By default, it is <tt>std::cout</tt>.
 ///
 ///This function also has a lot of
@@ -1129,5 +1126,5 @@
 ///\endcode
 ///
-///For more detailed examples see the \ref graph_to_eps_demo.cc demo file.
+///For more detailed examples, see the \ref graph_to_eps_demo.cc demo file.
 ///
 ///\warning Don't forget to put the \ref GraphToEps::run() "run()"
Index: lemon/grid_graph.h
===================================================================
--- lemon/grid_graph.h	(revision 559)
+++ lemon/grid_graph.h	(revision 787)
@@ -471,15 +471,19 @@
   /// \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
+  /// GridGraph implements a special graph type. The nodes of the
+  /// graph can be indexed by two integer values \c (i,j) where \c i is
+  /// in the range <tt>[0..width()-1]</tt> and j is in the range
+  /// <tt>[0..height()-1]</tt>. Two nodes are connected in the graph if
+  /// the indices differ exactly on one position and the difference is
+  /// also exactly one. The nodes of the graph can be obtained by position
+  /// using the \c operator()() function and the indices of the nodes can
+  /// be obtained using \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.
+  ///
+  /// This class is completely static and it needs constant memory space.
+  /// Thus you can neither add nor delete nodes or edges, however
+  /// the structure can be resized using resize().
   ///
   /// \image html grid_graph.png
@@ -497,16 +501,19 @@
   ///\endcode
   ///
-  /// This graph type fully 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.
+  /// This type fully conforms to the \ref concepts::Graph "Graph concept".
+  /// Most of its member functions and nested classes are documented
+  /// only in the concept class.
+  ///
+  /// This class provides constant time counting for nodes, edges and arcs.
   class GridGraph : public ExtendedGridGraphBase {
+    typedef ExtendedGridGraphBase Parent;
+
   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>.
+    /// \brief Map to get the indices of the nodes as \ref dim2::Point
+    /// "dim2::Point<int>".
+    ///
+    /// Map to get the indices of the nodes as \ref dim2::Point
+    /// "dim2::Point<int>".
     class IndexMap {
     public:
@@ -517,11 +524,7 @@
 
       /// \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);
@@ -543,11 +546,7 @@
 
       /// \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);
@@ -569,11 +568,7 @@
 
       /// \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);
@@ -586,13 +581,12 @@
     /// \brief Constructor
     ///
-    /// Construct a grid graph with given size.
+    /// Construct a grid graph with the 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.
+    /// \brief Resizes the graph
+    ///
+    /// This function resizes the graph. It fully destroys and
+    /// rebuilds the structure, therefore the maps of the graph will be
+    /// reallocated automatically and the previous values will be lost.
     void resize(int width, int height) {
       Parent::notifier(Arc()).clear();
@@ -612,5 +606,5 @@
     }
 
-    /// \brief Gives back the column index of the node.
+    /// \brief The column index of the node.
     ///
     /// Gives back the column index of the node.
@@ -619,5 +613,5 @@
     }
 
-    /// \brief Gives back the row index of the node.
+    /// \brief The row index of the node.
     ///
     /// Gives back the row index of the node.
@@ -626,5 +620,5 @@
     }
 
-    /// \brief Gives back the position of the node.
+    /// \brief The position of the node.
     ///
     /// Gives back the position of the node, ie. the <tt>(col,row)</tt> pair.
@@ -633,5 +627,5 @@
     }
 
-    /// \brief Gives back the number of the columns.
+    /// \brief The number of the columns.
     ///
     /// Gives back the number of the columns.
@@ -640,5 +634,5 @@
     }
 
-    /// \brief Gives back the number of the rows.
+    /// \brief The number of the rows.
     ///
     /// Gives back the number of the rows.
@@ -647,5 +641,5 @@
     }
 
-    /// \brief Gives back the arc goes right from the node.
+    /// \brief The arc goes right from the node.
     ///
     /// Gives back the arc goes right from the node. If there is not
@@ -655,5 +649,5 @@
     }
 
-    /// \brief Gives back the arc goes left from the node.
+    /// \brief The arc goes left from the node.
     ///
     /// Gives back the arc goes left from the node. If there is not
@@ -663,5 +657,5 @@
     }
 
-    /// \brief Gives back the arc goes up from the node.
+    /// \brief The arc goes up from the node.
     ///
     /// Gives back the arc goes up from the node. If there is not
@@ -671,5 +665,5 @@
     }
 
-    /// \brief Gives back the arc goes down from the node.
+    /// \brief The arc goes down from the node.
     ///
     /// Gives back the arc goes down from the node. If there is not
Index: lemon/hao_orlin.h
===================================================================
--- lemon/hao_orlin.h	(revision 559)
+++ lemon/hao_orlin.h	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -32,6 +32,6 @@
 /// \brief Implementation of the Hao-Orlin algorithm.
 ///
-/// Implementation of the Hao-Orlin algorithm class for testing network
-/// reliability.
+/// Implementation of the Hao-Orlin algorithm for finding a minimum cut
+/// in a digraph.
 
 namespace lemon {
@@ -39,30 +39,32 @@
   /// \ingroup min_cut
   ///
-  /// \brief %Hao-Orlin algorithm to find a minimum cut in directed graphs.
+  /// \brief Hao-Orlin algorithm for finding a minimum cut in a digraph.
   ///
-  /// 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
+  /// This class implements the Hao-Orlin algorithm for finding a minimum
+  /// value 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
+  /// \f$ X\subsetneq V \f$ with \f$ source \in X \f$ and minimal outgoing
+  /// capacity) 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
+  /// \f$ X\subsetneq V \f$ with \f$ source \notin X \f$ and minimal outgoing
+  /// capacity). 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
+  /// preflow push-relabel algorithm. 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.
+  /// purpose of such algorithm is e.g. testing network reliability.
   ///
-  /// \param GR The digraph class the algorithm runs on.
-  /// \param CAP An arc map of capacities which can be any numreric type.
-  /// The default type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
-  /// \param TOL Tolerance class for handling inexact computations. The
+  /// 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.
+  ///
+  /// \tparam GR The type of the digraph the algorithm runs on.
+  /// \tparam CAP The type of the arc map containing the capacities,
+  /// which can be any numreric type. The default map type is
+  /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+  /// \tparam TOL Tolerance class for handling inexact computations. The
   /// default tolerance type is \ref Tolerance "Tolerance<CAP::Value>".
 #ifdef DOXYGEN
@@ -74,13 +76,18 @@
 #endif
   class HaoOrlin {
+  public:
+
+    /// The digraph type of the algorithm
+    typedef GR Digraph;
+    /// The capacity map type of the algorithm
+    typedef CAP CapacityMap;
+    /// The tolerance type of the algorithm
+    typedef TOL Tolerance;
+
   private:
 
-    typedef GR Digraph;
-    typedef CAP CapacityMap;
-    typedef TOL Tolerance;
-
     typedef typename CapacityMap::Value Value;
 
-    TEMPLATE_GRAPH_TYPEDEFS(Digraph);
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
 
     const Digraph& _graph;
@@ -159,8 +166,25 @@
     }
 
+    /// \brief Set the tolerance used by the algorithm.
+    ///
+    /// This function sets the tolerance object used by the algorithm.
+    /// \return <tt>(*this)</tt>
+    HaoOrlin& tolerance(const Tolerance& tolerance) {
+      _tolerance = tolerance;
+      return *this;
+    }
+
+    /// \brief Returns a const reference to the tolerance.
+    ///
+    /// This function returns a const reference to the tolerance object
+    /// used by the algorithm.
+    const Tolerance& tolerance() const {
+      return _tolerance;
+    }
+
   private:
 
     void activate(const Node& i) {
-      _active->set(i, true);
+      (*_active)[i] = true;
 
       int bucket = (*_bucket)[i];
@@ -168,19 +192,19 @@
       if ((*_prev)[i] == INVALID || (*_active)[(*_prev)[i]]) return;
       //unlace
-      _next->set((*_prev)[i], (*_next)[i]);
+      (*_next)[(*_prev)[i]] = (*_next)[i];
       if ((*_next)[i] != INVALID) {
-        _prev->set((*_next)[i], (*_prev)[i]);
+        (*_prev)[(*_next)[i]] = (*_prev)[i];
       } else {
         _last[bucket] = (*_prev)[i];
       }
       //lace
-      _next->set(i, _first[bucket]);
-      _prev->set(_first[bucket], i);
-      _prev->set(i, INVALID);
+      (*_next)[i] = _first[bucket];
+      (*_prev)[_first[bucket]] = i;
+      (*_prev)[i] = INVALID;
       _first[bucket] = i;
     }
 
     void deactivate(const Node& i) {
-      _active->set(i, false);
+      (*_active)[i] = false;
       int bucket = (*_bucket)[i];
 
@@ -188,14 +212,14 @@
 
       //unlace
-      _prev->set((*_next)[i], (*_prev)[i]);
+      (*_prev)[(*_next)[i]] = (*_prev)[i];
       if ((*_prev)[i] != INVALID) {
-        _next->set((*_prev)[i], (*_next)[i]);
+        (*_next)[(*_prev)[i]] = (*_next)[i];
       } else {
         _first[bucket] = (*_next)[i];
       }
       //lace
-      _prev->set(i, _last[bucket]);
-      _next->set(_last[bucket], i);
-      _next->set(i, INVALID);
+      (*_prev)[i] = _last[bucket];
+      (*_next)[_last[bucket]] = i;
+      (*_next)[i] = INVALID;
       _last[bucket] = i;
     }
@@ -204,12 +228,12 @@
       (*_bucket)[i] = bucket;
       if (_last[bucket] != INVALID) {
-        _prev->set(i, _last[bucket]);
-        _next->set(_last[bucket], i);
-        _next->set(i, INVALID);
+        (*_prev)[i] = _last[bucket];
+        (*_next)[_last[bucket]] = i;
+        (*_next)[i] = INVALID;
         _last[bucket] = i;
       } else {
-        _prev->set(i, INVALID);
+        (*_prev)[i] = INVALID;
         _first[bucket] = i;
-        _next->set(i, INVALID);
+        (*_next)[i] = INVALID;
         _last[bucket] = i;
       }
@@ -219,9 +243,10 @@
 
       for (NodeIt n(_graph); n != INVALID; ++n) {
-        _excess->set(n, 0);
+        (*_excess)[n] = 0;
+        (*_source_set)[n] = false;
       }
 
       for (ArcIt a(_graph); a != INVALID; ++a) {
-        _flow->set(a, 0);
+        (*_flow)[a] = 0;
       }
 
@@ -233,5 +258,5 @@
         typename Digraph::template NodeMap<bool> reached(_graph, false);
 
-        reached.set(_source, true);
+        reached[_source] = true;
         bool first_set = true;
 
@@ -241,5 +266,5 @@
 
           queue[qlast++] = t;
-          reached.set(t, true);
+          reached[t] = true;
 
           while (qfirst != qlast) {
@@ -258,5 +283,5 @@
               Node u = _graph.source(a);
               if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
-                reached.set(u, true);
+                reached[u] = true;
                 queue[qlast++] = u;
               }
@@ -267,8 +292,8 @@
 
         ++bucket_num;
-        _bucket->set(_source, 0);
+        (*_bucket)[_source] = 0;
         _dormant[0] = true;
       }
-      _source_set->set(_source, true);
+      (*_source_set)[_source] = true;
 
       Node target = _last[_sets.back().back()];
@@ -277,6 +302,6 @@
           if (_tolerance.positive((*_capacity)[a])) {
             Node u = _graph.target(a);
-            _flow->set(a, (*_capacity)[a]);
-            _excess->set(u, (*_excess)[u] + (*_capacity)[a]);
+            (*_flow)[a] = (*_capacity)[a];
+            (*_excess)[u] += (*_capacity)[a];
             if (!(*_active)[u] && u != _source) {
               activate(u);
@@ -319,12 +344,12 @@
               }
               if (!_tolerance.less(rem, excess)) {
-                _flow->set(a, (*_flow)[a] + excess);
-                _excess->set(v, (*_excess)[v] + excess);
+                (*_flow)[a] += excess;
+                (*_excess)[v] += excess;
                 excess = 0;
                 goto no_more_push;
               } else {
                 excess -= rem;
-                _excess->set(v, (*_excess)[v] + rem);
-                _flow->set(a, (*_capacity)[a]);
+                (*_excess)[v] += rem;
+                (*_flow)[a] = (*_capacity)[a];
               }
             } else if (next_bucket > (*_bucket)[v]) {
@@ -343,12 +368,12 @@
               }
               if (!_tolerance.less(rem, excess)) {
-                _flow->set(a, (*_flow)[a] - excess);
-                _excess->set(v, (*_excess)[v] + excess);
+                (*_flow)[a] -= excess;
+                (*_excess)[v] += excess;
                 excess = 0;
                 goto no_more_push;
               } else {
                 excess -= rem;
-                _excess->set(v, (*_excess)[v] + rem);
-                _flow->set(a, 0);
+                (*_excess)[v] += rem;
+                (*_flow)[a] = 0;
               }
             } else if (next_bucket > (*_bucket)[v]) {
@@ -359,5 +384,5 @@
         no_more_push:
 
-          _excess->set(n, excess);
+          (*_excess)[n] = excess;
 
           if (excess != 0) {
@@ -377,5 +402,5 @@
             } else if (next_bucket == _node_num) {
               _first[(*_bucket)[n]] = (*_next)[n];
-              _prev->set((*_next)[n], INVALID);
+              (*_prev)[(*_next)[n]] = INVALID;
 
               std::list<std::list<int> >::iterator new_set =
@@ -383,8 +408,8 @@
 
               new_set->push_front(bucket_num);
-              _bucket->set(n, bucket_num);
+              (*_bucket)[n] = bucket_num;
               _first[bucket_num] = _last[bucket_num] = n;
-              _next->set(n, INVALID);
-              _prev->set(n, INVALID);
+              (*_next)[n] = INVALID;
+              (*_prev)[n] = INVALID;
               _dormant[bucket_num] = true;
               ++bucket_num;
@@ -396,5 +421,5 @@
             } else {
               _first[*_highest] = (*_next)[n];
-              _prev->set((*_next)[n], INVALID);
+              (*_prev)[(*_next)[n]] = INVALID;
 
               while (next_bucket != *_highest) {
@@ -410,8 +435,8 @@
               --_highest;
 
-              _bucket->set(n, *_highest);
-              _next->set(n, _first[*_highest]);
+              (*_bucket)[n] = *_highest;
+              (*_next)[n] = _first[*_highest];
               if (_first[*_highest] != INVALID) {
-                _prev->set(_first[*_highest], n);
+                (*_prev)[_first[*_highest]] = n;
               } else {
                 _last[*_highest] = n;
@@ -435,5 +460,5 @@
           _min_cut = (*_excess)[target];
           for (NodeIt i(_graph); i != INVALID; ++i) {
-            _min_cut_map->set(i, true);
+            (*_min_cut_map)[i] = true;
           }
           for (std::list<int>::iterator it = _sets.back().begin();
@@ -441,5 +466,5 @@
             Node n = _first[*it];
             while (n != INVALID) {
-              _min_cut_map->set(n, false);
+              (*_min_cut_map)[n] = false;
               n = (*_next)[n];
             }
@@ -454,5 +479,5 @@
               new_target = (*_prev)[target];
             } else {
-              _prev->set((*_next)[target], (*_prev)[target]);
+              (*_prev)[(*_next)[target]] = (*_prev)[target];
               new_target = (*_next)[target];
             }
@@ -460,5 +485,5 @@
               _first[(*_bucket)[target]] = (*_next)[target];
             } else {
-              _next->set((*_prev)[target], (*_next)[target]);
+              (*_next)[(*_prev)[target]] = (*_next)[target];
             }
           } else {
@@ -476,7 +501,7 @@
           }
 
-          _bucket->set(target, 0);
-
-          _source_set->set(target, true);
+          (*_bucket)[target] = 0;
+
+          (*_source_set)[target] = true;
           for (OutArcIt a(_graph, target); a != INVALID; ++a) {
             Value rem = (*_capacity)[a] - (*_flow)[a];
@@ -486,6 +511,6 @@
               activate(v);
             }
-            _excess->set(v, (*_excess)[v] + rem);
-            _flow->set(a, (*_capacity)[a]);
+            (*_excess)[v] += rem;
+            (*_flow)[a] = (*_capacity)[a];
           }
 
@@ -497,6 +522,6 @@
               activate(v);
             }
-            _excess->set(v, (*_excess)[v] + rem);
-            _flow->set(a, 0);
+            (*_excess)[v] += rem;
+            (*_flow)[a] = 0;
           }
 
@@ -518,9 +543,10 @@
 
       for (NodeIt n(_graph); n != INVALID; ++n) {
-        _excess->set(n, 0);
+        (*_excess)[n] = 0;
+        (*_source_set)[n] = false;
       }
 
       for (ArcIt a(_graph); a != INVALID; ++a) {
-        _flow->set(a, 0);
+        (*_flow)[a] = 0;
       }
 
@@ -532,5 +558,5 @@
         typename Digraph::template NodeMap<bool> reached(_graph, false);
 
-        reached.set(_source, true);
+        reached[_source] = true;
 
         bool first_set = true;
@@ -541,5 +567,5 @@
 
           queue[qlast++] = t;
-          reached.set(t, true);
+          reached[t] = true;
 
           while (qfirst != qlast) {
@@ -558,5 +584,5 @@
               Node u = _graph.target(a);
               if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
-                reached.set(u, true);
+                reached[u] = true;
                 queue[qlast++] = u;
               }
@@ -567,8 +593,8 @@
 
         ++bucket_num;
-        _bucket->set(_source, 0);
+        (*_bucket)[_source] = 0;
         _dormant[0] = true;
       }
-      _source_set->set(_source, true);
+      (*_source_set)[_source] = true;
 
       Node target = _last[_sets.back().back()];
@@ -577,6 +603,6 @@
           if (_tolerance.positive((*_capacity)[a])) {
             Node u = _graph.source(a);
-            _flow->set(a, (*_capacity)[a]);
-            _excess->set(u, (*_excess)[u] + (*_capacity)[a]);
+            (*_flow)[a] = (*_capacity)[a];
+            (*_excess)[u] += (*_capacity)[a];
             if (!(*_active)[u] && u != _source) {
               activate(u);
@@ -619,12 +645,12 @@
               }
               if (!_tolerance.less(rem, excess)) {
-                _flow->set(a, (*_flow)[a] + excess);
-                _excess->set(v, (*_excess)[v] + excess);
+                (*_flow)[a] += excess;
+                (*_excess)[v] += excess;
                 excess = 0;
                 goto no_more_push;
               } else {
                 excess -= rem;
-                _excess->set(v, (*_excess)[v] + rem);
-                _flow->set(a, (*_capacity)[a]);
+                (*_excess)[v] += rem;
+                (*_flow)[a] = (*_capacity)[a];
               }
             } else if (next_bucket > (*_bucket)[v]) {
@@ -643,12 +669,12 @@
               }
               if (!_tolerance.less(rem, excess)) {
-                _flow->set(a, (*_flow)[a] - excess);
-                _excess->set(v, (*_excess)[v] + excess);
+                (*_flow)[a] -= excess;
+                (*_excess)[v] += excess;
                 excess = 0;
                 goto no_more_push;
               } else {
                 excess -= rem;
-                _excess->set(v, (*_excess)[v] + rem);
-                _flow->set(a, 0);
+                (*_excess)[v] += rem;
+                (*_flow)[a] = 0;
               }
             } else if (next_bucket > (*_bucket)[v]) {
@@ -659,5 +685,5 @@
         no_more_push:
 
-          _excess->set(n, excess);
+          (*_excess)[n] = excess;
 
           if (excess != 0) {
@@ -677,5 +703,5 @@
             } else if (next_bucket == _node_num) {
               _first[(*_bucket)[n]] = (*_next)[n];
-              _prev->set((*_next)[n], INVALID);
+              (*_prev)[(*_next)[n]] = INVALID;
 
               std::list<std::list<int> >::iterator new_set =
@@ -683,8 +709,8 @@
 
               new_set->push_front(bucket_num);
-              _bucket->set(n, bucket_num);
+              (*_bucket)[n] = bucket_num;
               _first[bucket_num] = _last[bucket_num] = n;
-              _next->set(n, INVALID);
-              _prev->set(n, INVALID);
+              (*_next)[n] = INVALID;
+              (*_prev)[n] = INVALID;
               _dormant[bucket_num] = true;
               ++bucket_num;
@@ -696,5 +722,5 @@
             } else {
               _first[*_highest] = (*_next)[n];
-              _prev->set((*_next)[n], INVALID);
+              (*_prev)[(*_next)[n]] = INVALID;
 
               while (next_bucket != *_highest) {
@@ -709,8 +735,8 @@
               --_highest;
 
-              _bucket->set(n, *_highest);
-              _next->set(n, _first[*_highest]);
+              (*_bucket)[n] = *_highest;
+              (*_next)[n] = _first[*_highest];
               if (_first[*_highest] != INVALID) {
-                _prev->set(_first[*_highest], n);
+                (*_prev)[_first[*_highest]] = n;
               } else {
                 _last[*_highest] = n;
@@ -734,5 +760,5 @@
           _min_cut = (*_excess)[target];
           for (NodeIt i(_graph); i != INVALID; ++i) {
-            _min_cut_map->set(i, false);
+            (*_min_cut_map)[i] = false;
           }
           for (std::list<int>::iterator it = _sets.back().begin();
@@ -740,5 +766,5 @@
             Node n = _first[*it];
             while (n != INVALID) {
-              _min_cut_map->set(n, true);
+              (*_min_cut_map)[n] = true;
               n = (*_next)[n];
             }
@@ -753,5 +779,5 @@
               new_target = (*_prev)[target];
             } else {
-              _prev->set((*_next)[target], (*_prev)[target]);
+              (*_prev)[(*_next)[target]] = (*_prev)[target];
               new_target = (*_next)[target];
             }
@@ -759,5 +785,5 @@
               _first[(*_bucket)[target]] = (*_next)[target];
             } else {
-              _next->set((*_prev)[target], (*_next)[target]);
+              (*_next)[(*_prev)[target]] = (*_next)[target];
             }
           } else {
@@ -775,7 +801,7 @@
           }
 
-          _bucket->set(target, 0);
-
-          _source_set->set(target, true);
+          (*_bucket)[target] = 0;
+
+          (*_source_set)[target] = true;
           for (InArcIt a(_graph, target); a != INVALID; ++a) {
             Value rem = (*_capacity)[a] - (*_flow)[a];
@@ -785,6 +811,6 @@
               activate(v);
             }
-            _excess->set(v, (*_excess)[v] + rem);
-            _flow->set(a, (*_capacity)[a]);
+            (*_excess)[v] += rem;
+            (*_flow)[a] = (*_capacity)[a];
           }
 
@@ -796,6 +822,6 @@
               activate(v);
             }
-            _excess->set(v, (*_excess)[v] + rem);
-            _flow->set(a, 0);
+            (*_excess)[v] += rem;
+            (*_flow)[a] = 0;
           }
 
@@ -816,29 +842,30 @@
   public:
 
-    /// \name Execution control
+    /// \name Execution Control
     /// The simplest way to execute the algorithm is to use
     /// one of the member functions called \ref run().
     /// \n
-    /// If you need more control on the execution,
-    /// first you must call \ref init(), then the \ref calculateIn() or
-    /// \ref calculateOut() functions.
+    /// If you need better control on the execution,
+    /// you have to call one of the \ref init() functions first, then
+    /// \ref calculateOut() and/or \ref calculateIn().
 
     /// @{
 
-    /// \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.
+    /// \brief Initialize the internal data structures.
+    ///
+    /// This function initializes the internal data structures. It creates
+    /// the maps and some bucket structures for the algorithm.
+    /// The first node is used as the source node for the push-relabel
+    /// 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.
+    /// \brief Initialize the internal data structures.
+    ///
+    /// This function initializes the internal data structures. It creates
+    /// the maps and some bucket structures for the algorithm.
+    /// The given node is used as the source node for the push-relabel
+    /// algorithm.
     void init(const Node& source) {
       _source = source;
@@ -880,20 +907,24 @@
 
 
-    /// \brief Calculates a minimum cut with \f$ source \f$ on the
+    /// \brief Calculate a minimum cut with \f$ source \f$ on the
     /// source-side.
     ///
-    /// Calculates a minimum cut with \f$ source \f$ on the
+    /// This function 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).
+    /// \f$ source \in X \f$ and minimal outgoing capacity).
+    ///
+    /// \pre \ref init() must be called before using this function.
     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).
+    /// \brief Calculate a minimum cut with \f$ source \f$ on the
+    /// sink-side.
+    ///
+    /// This function calculates 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 outgoing capacity).
+    ///
+    /// \pre \ref init() must be called before using this function.
     void calculateIn() {
       findMinCutIn();
@@ -901,8 +932,8 @@
 
 
-    /// \brief Runs the algorithm.
-    ///
-    /// Runs the algorithm. It finds nodes \c source and \c target
-    /// arbitrarily and then calls \ref init(), \ref calculateOut()
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm. It finds nodes \c source and
+    /// \c target arbitrarily and then calls \ref init(), \ref calculateOut()
     /// and \ref calculateIn().
     void run() {
@@ -912,9 +943,9 @@
     }
 
-    /// \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().
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm. It uses the given \c source node,
+    /// finds a proper \c target node and then calls the \ref init(),
+    /// \ref calculateOut() and \ref calculateIn().
     void run(const Node& s) {
       init(s);
@@ -927,14 +958,16 @@
     /// \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.
+    /// can be obtained using these functions.\n
+    /// \ref run(), \ref calculateOut() or \ref calculateIn()
+    /// should be called before using them.
 
     /// @{
 
-    /// \brief Returns the value of the minimum value cut.
-    ///
-    /// Returns the value of the minimum value cut.
+    /// \brief Return the value of the minimum cut.
+    ///
+    /// This function returns the value of the minimum cut.
+    ///
+    /// \pre \ref run(), \ref calculateOut() or \ref calculateIn()
+    /// must be called before using this function.
     Value minCutValue() const {
       return _min_cut;
@@ -942,15 +975,22 @@
 
 
-    /// \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 {
+    /// \brief Return a minimum cut.
+    ///
+    /// This function sets \c cutMap to the characteristic vector of a
+    /// minimum value cut: it will give a non-empty set \f$ X\subsetneq V \f$
+    /// with minimal outgoing capacity (i.e. \c cutMap will be \c true exactly
+    /// for the nodes of \f$ X \f$).
+    ///
+    /// \param cutMap A \ref concepts::WriteMap "writable" node map with
+    /// \c bool (or convertible) value type.
+    ///
+    /// \return The value of the minimum cut.
+    ///
+    /// \pre \ref run(), \ref calculateOut() or \ref calculateIn()
+    /// must be called before using this function.
+    template <typename CutMap>
+    Value minCutMap(CutMap& cutMap) const {
       for (NodeIt it(_graph); it != INVALID; ++it) {
-        nodeMap.set(it, (*_min_cut_map)[it]);
+        cutMap.set(it, (*_min_cut_map)[it]);
       }
       return _min_cut;
@@ -961,5 +1001,4 @@
   }; //class HaoOrlin
 
-
 } //namespace lemon
 
Index: lemon/hartmann_orlin_mmc.h
===================================================================
--- lemon/hartmann_orlin_mmc.h	(revision 880)
+++ lemon/hartmann_orlin_mmc.h	(revision 880)
@@ -0,0 +1,650 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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_HARTMANN_ORLIN_MMC_H
+#define LEMON_HARTMANN_ORLIN_MMC_H
+
+/// \ingroup min_mean_cycle
+///
+/// \file
+/// \brief Hartmann-Orlin's algorithm for finding a minimum mean cycle.
+
+#include <vector>
+#include <limits>
+#include <lemon/core.h>
+#include <lemon/path.h>
+#include <lemon/tolerance.h>
+#include <lemon/connectivity.h>
+
+namespace lemon {
+
+  /// \brief Default traits class of HartmannOrlinMmc class.
+  ///
+  /// Default traits class of HartmannOrlinMmc class.
+  /// \tparam GR The type of the digraph.
+  /// \tparam CM The type of the cost map.
+  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+#ifdef DOXYGEN
+  template <typename GR, typename CM>
+#else
+  template <typename GR, typename CM,
+    bool integer = std::numeric_limits<typename CM::Value>::is_integer>
+#endif
+  struct HartmannOrlinMmcDefaultTraits
+  {
+    /// The type of the digraph
+    typedef GR Digraph;
+    /// The type of the cost map
+    typedef CM CostMap;
+    /// The type of the arc costs
+    typedef typename CostMap::Value Cost;
+
+    /// \brief The large cost type used for internal computations
+    ///
+    /// The large cost type used for internal computations.
+    /// It is \c long \c long if the \c Cost type is integer,
+    /// otherwise it is \c double.
+    /// \c Cost must be convertible to \c LargeCost.
+    typedef double LargeCost;
+
+    /// The tolerance type used for internal computations
+    typedef lemon::Tolerance<LargeCost> Tolerance;
+
+    /// \brief The path type of the found cycles
+    ///
+    /// The path type of the found cycles.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addFront() function.
+    typedef lemon::Path<Digraph> Path;
+  };
+
+  // Default traits class for integer cost types
+  template <typename GR, typename CM>
+  struct HartmannOrlinMmcDefaultTraits<GR, CM, true>
+  {
+    typedef GR Digraph;
+    typedef CM CostMap;
+    typedef typename CostMap::Value Cost;
+#ifdef LEMON_HAVE_LONG_LONG
+    typedef long long LargeCost;
+#else
+    typedef long LargeCost;
+#endif
+    typedef lemon::Tolerance<LargeCost> Tolerance;
+    typedef lemon::Path<Digraph> Path;
+  };
+
+
+  /// \addtogroup min_mean_cycle
+  /// @{
+
+  /// \brief Implementation of the Hartmann-Orlin algorithm for finding
+  /// a minimum mean cycle.
+  ///
+  /// This class implements the Hartmann-Orlin algorithm for finding
+  /// a directed cycle of minimum mean cost in a digraph
+  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
+  /// It is an improved version of \ref KarpMmc "Karp"'s original algorithm,
+  /// it applies an efficient early termination scheme.
+  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
+  ///
+  /// \tparam GR The type of the digraph the algorithm runs on.
+  /// \tparam CM The type of the cost map. The default
+  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm. By default, it is \ref HartmannOrlinMmcDefaultTraits
+  /// "HartmannOrlinMmcDefaultTraits<GR, CM>".
+  /// In most cases, this parameter should not be set directly,
+  /// consider to use the named template parameters instead.
+#ifdef DOXYGEN
+  template <typename GR, typename CM, typename TR>
+#else
+  template < typename GR,
+             typename CM = typename GR::template ArcMap<int>,
+             typename TR = HartmannOrlinMmcDefaultTraits<GR, CM> >
+#endif
+  class HartmannOrlinMmc
+  {
+  public:
+
+    /// The type of the digraph
+    typedef typename TR::Digraph Digraph;
+    /// The type of the cost map
+    typedef typename TR::CostMap CostMap;
+    /// The type of the arc costs
+    typedef typename TR::Cost Cost;
+
+    /// \brief The large cost type
+    ///
+    /// The large cost type used for internal computations.
+    /// By default, it is \c long \c long if the \c Cost type is integer,
+    /// otherwise it is \c double.
+    typedef typename TR::LargeCost LargeCost;
+
+    /// The tolerance type
+    typedef typename TR::Tolerance Tolerance;
+
+    /// \brief The path type of the found cycles
+    ///
+    /// The path type of the found cycles.
+    /// Using the \ref HartmannOrlinMmcDefaultTraits "default traits class",
+    /// it is \ref lemon::Path "Path<Digraph>".
+    typedef typename TR::Path Path;
+
+    /// The \ref HartmannOrlinMmcDefaultTraits "traits class" of the algorithm
+    typedef TR Traits;
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+    // Data sturcture for path data
+    struct PathData
+    {
+      LargeCost dist;
+      Arc pred;
+      PathData(LargeCost d, Arc p = INVALID) :
+        dist(d), pred(p) {}
+    };
+
+    typedef typename Digraph::template NodeMap<std::vector<PathData> >
+      PathDataNodeMap;
+
+  private:
+
+    // The digraph the algorithm runs on
+    const Digraph &_gr;
+    // The cost of the arcs
+    const CostMap &_cost;
+
+    // Data for storing the strongly connected components
+    int _comp_num;
+    typename Digraph::template NodeMap<int> _comp;
+    std::vector<std::vector<Node> > _comp_nodes;
+    std::vector<Node>* _nodes;
+    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
+
+    // Data for the found cycles
+    bool _curr_found, _best_found;
+    LargeCost _curr_cost, _best_cost;
+    int _curr_size, _best_size;
+    Node _curr_node, _best_node;
+    int _curr_level, _best_level;
+
+    Path *_cycle_path;
+    bool _local_path;
+
+    // Node map for storing path data
+    PathDataNodeMap _data;
+    // The processed nodes in the last round
+    std::vector<Node> _process;
+
+    Tolerance _tolerance;
+
+    // Infinite constant
+    const LargeCost INF;
+
+  public:
+
+    /// \name Named Template Parameters
+    /// @{
+
+    template <typename T>
+    struct SetLargeCostTraits : public Traits {
+      typedef T LargeCost;
+      typedef lemon::Tolerance<T> Tolerance;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c LargeCost type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
+    /// type. It is used for internal computations in the algorithm.
+    template <typename T>
+    struct SetLargeCost
+      : public HartmannOrlinMmc<GR, CM, SetLargeCostTraits<T> > {
+      typedef HartmannOrlinMmc<GR, CM, SetLargeCostTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetPathTraits : public Traits {
+      typedef T Path;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c %Path type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting the \c %Path
+    /// type of the found cycles.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addFront() function.
+    template <typename T>
+    struct SetPath
+      : public HartmannOrlinMmc<GR, CM, SetPathTraits<T> > {
+      typedef HartmannOrlinMmc<GR, CM, SetPathTraits<T> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    HartmannOrlinMmc() {}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// The constructor of the class.
+    ///
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param cost The costs of the arcs.
+    HartmannOrlinMmc( const Digraph &digraph,
+                      const CostMap &cost ) :
+      _gr(digraph), _cost(cost), _comp(digraph), _out_arcs(digraph),
+      _best_found(false), _best_cost(0), _best_size(1),
+      _cycle_path(NULL), _local_path(false), _data(digraph),
+      INF(std::numeric_limits<LargeCost>::has_infinity ?
+          std::numeric_limits<LargeCost>::infinity() :
+          std::numeric_limits<LargeCost>::max())
+    {}
+
+    /// Destructor.
+    ~HartmannOrlinMmc() {
+      if (_local_path) delete _cycle_path;
+    }
+
+    /// \brief Set the path structure for storing the found cycle.
+    ///
+    /// This function sets an external path structure for storing the
+    /// found cycle.
+    ///
+    /// If you don't call this function before calling \ref run() or
+    /// \ref findCycleMean(), it will allocate a local \ref Path "path"
+    /// structure. The destuctor deallocates this automatically
+    /// allocated object, of course.
+    ///
+    /// \note The algorithm calls only the \ref lemon::Path::addFront()
+    /// "addFront()" function of the given path structure.
+    ///
+    /// \return <tt>(*this)</tt>
+    HartmannOrlinMmc& cycle(Path &path) {
+      if (_local_path) {
+        delete _cycle_path;
+        _local_path = false;
+      }
+      _cycle_path = &path;
+      return *this;
+    }
+
+    /// \brief Set the tolerance used by the algorithm.
+    ///
+    /// This function sets the tolerance object used by the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    HartmannOrlinMmc& tolerance(const Tolerance& tolerance) {
+      _tolerance = tolerance;
+      return *this;
+    }
+
+    /// \brief Return a const reference to the tolerance.
+    ///
+    /// This function returns a const reference to the tolerance object
+    /// used by the algorithm.
+    const Tolerance& tolerance() const {
+      return _tolerance;
+    }
+
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to call the \ref run()
+    /// function.\n
+    /// If you only need the minimum mean cost, you may call
+    /// \ref findCycleMean().
+
+    /// @{
+
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm.
+    /// It can be called more than once (e.g. if the underlying digraph
+    /// and/or the arc costs have been modified).
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    ///
+    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
+    /// \code
+    ///   return mmc.findCycleMean() && mmc.findCycle();
+    /// \endcode
+    bool run() {
+      return findCycleMean() && findCycle();
+    }
+
+    /// \brief Find the minimum cycle mean.
+    ///
+    /// This function finds the minimum mean cost of the directed
+    /// cycles in the digraph.
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    bool findCycleMean() {
+      // Initialization and find strongly connected components
+      init();
+      findComponents();
+
+      // Find the minimum cycle mean in the components
+      for (int comp = 0; comp < _comp_num; ++comp) {
+        if (!initComponent(comp)) continue;
+        processRounds();
+
+        // Update the best cycle (global minimum mean cycle)
+        if ( _curr_found && (!_best_found ||
+             _curr_cost * _best_size < _best_cost * _curr_size) ) {
+          _best_found = true;
+          _best_cost = _curr_cost;
+          _best_size = _curr_size;
+          _best_node = _curr_node;
+          _best_level = _curr_level;
+        }
+      }
+      return _best_found;
+    }
+
+    /// \brief Find a minimum mean directed cycle.
+    ///
+    /// This function finds a directed cycle of minimum mean cost
+    /// in the digraph using the data computed by findCycleMean().
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    ///
+    /// \pre \ref findCycleMean() must be called before using this function.
+    bool findCycle() {
+      if (!_best_found) return false;
+      IntNodeMap reached(_gr, -1);
+      int r = _best_level + 1;
+      Node u = _best_node;
+      while (reached[u] < 0) {
+        reached[u] = --r;
+        u = _gr.source(_data[u][r].pred);
+      }
+      r = reached[u];
+      Arc e = _data[u][r].pred;
+      _cycle_path->addFront(e);
+      _best_cost = _cost[e];
+      _best_size = 1;
+      Node v;
+      while ((v = _gr.source(e)) != u) {
+        e = _data[v][--r].pred;
+        _cycle_path->addFront(e);
+        _best_cost += _cost[e];
+        ++_best_size;
+      }
+      return true;
+    }
+
+    /// @}
+
+    /// \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 the total cost of the found cycle.
+    ///
+    /// This function returns the total cost of the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    Cost cycleCost() const {
+      return static_cast<Cost>(_best_cost);
+    }
+
+    /// \brief Return the number of arcs on the found cycle.
+    ///
+    /// This function returns the number of arcs on the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    int cycleSize() const {
+      return _best_size;
+    }
+
+    /// \brief Return the mean cost of the found cycle.
+    ///
+    /// This function returns the mean cost of the found cycle.
+    ///
+    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
+    /// following code.
+    /// \code
+    ///   return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
+    /// \endcode
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    double cycleMean() const {
+      return static_cast<double>(_best_cost) / _best_size;
+    }
+
+    /// \brief Return the found cycle.
+    ///
+    /// This function returns a const reference to the path structure
+    /// storing the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycle() must be called before using
+    /// this function.
+    const Path& cycle() const {
+      return *_cycle_path;
+    }
+
+    ///@}
+
+  private:
+
+    // Initialization
+    void init() {
+      if (!_cycle_path) {
+        _local_path = true;
+        _cycle_path = new Path;
+      }
+      _cycle_path->clear();
+      _best_found = false;
+      _best_cost = 0;
+      _best_size = 1;
+      _cycle_path->clear();
+      for (NodeIt u(_gr); u != INVALID; ++u)
+        _data[u].clear();
+    }
+
+    // Find strongly connected components and initialize _comp_nodes
+    // and _out_arcs
+    void findComponents() {
+      _comp_num = stronglyConnectedComponents(_gr, _comp);
+      _comp_nodes.resize(_comp_num);
+      if (_comp_num == 1) {
+        _comp_nodes[0].clear();
+        for (NodeIt n(_gr); n != INVALID; ++n) {
+          _comp_nodes[0].push_back(n);
+          _out_arcs[n].clear();
+          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
+            _out_arcs[n].push_back(a);
+          }
+        }
+      } else {
+        for (int i = 0; i < _comp_num; ++i)
+          _comp_nodes[i].clear();
+        for (NodeIt n(_gr); n != INVALID; ++n) {
+          int k = _comp[n];
+          _comp_nodes[k].push_back(n);
+          _out_arcs[n].clear();
+          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
+            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
+          }
+        }
+      }
+    }
+
+    // Initialize path data for the current component
+    bool initComponent(int comp) {
+      _nodes = &(_comp_nodes[comp]);
+      int n = _nodes->size();
+      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
+        return false;
+      }
+      for (int i = 0; i < n; ++i) {
+        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
+      }
+      return true;
+    }
+
+    // Process all rounds of computing path data for the current component.
+    // _data[v][k] is the cost of a shortest directed walk from the root
+    // node to node v containing exactly k arcs.
+    void processRounds() {
+      Node start = (*_nodes)[0];
+      _data[start][0] = PathData(0);
+      _process.clear();
+      _process.push_back(start);
+
+      int k, n = _nodes->size();
+      int next_check = 4;
+      bool terminate = false;
+      for (k = 1; k <= n && int(_process.size()) < n && !terminate; ++k) {
+        processNextBuildRound(k);
+        if (k == next_check || k == n) {
+          terminate = checkTermination(k);
+          next_check = next_check * 3 / 2;
+        }
+      }
+      for ( ; k <= n && !terminate; ++k) {
+        processNextFullRound(k);
+        if (k == next_check || k == n) {
+          terminate = checkTermination(k);
+          next_check = next_check * 3 / 2;
+        }
+      }
+    }
+
+    // Process one round and rebuild _process
+    void processNextBuildRound(int k) {
+      std::vector<Node> next;
+      Node u, v;
+      Arc e;
+      LargeCost d;
+      for (int i = 0; i < int(_process.size()); ++i) {
+        u = _process[i];
+        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
+          e = _out_arcs[u][j];
+          v = _gr.target(e);
+          d = _data[u][k-1].dist + _cost[e];
+          if (_tolerance.less(d, _data[v][k].dist)) {
+            if (_data[v][k].dist == INF) next.push_back(v);
+            _data[v][k] = PathData(d, e);
+          }
+        }
+      }
+      _process.swap(next);
+    }
+
+    // Process one round using _nodes instead of _process
+    void processNextFullRound(int k) {
+      Node u, v;
+      Arc e;
+      LargeCost d;
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        u = (*_nodes)[i];
+        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
+          e = _out_arcs[u][j];
+          v = _gr.target(e);
+          d = _data[u][k-1].dist + _cost[e];
+          if (_tolerance.less(d, _data[v][k].dist)) {
+            _data[v][k] = PathData(d, e);
+          }
+        }
+      }
+    }
+
+    // Check early termination
+    bool checkTermination(int k) {
+      typedef std::pair<int, int> Pair;
+      typename GR::template NodeMap<Pair> level(_gr, Pair(-1, 0));
+      typename GR::template NodeMap<LargeCost> pi(_gr);
+      int n = _nodes->size();
+      LargeCost cost;
+      int size;
+      Node u;
+
+      // Search for cycles that are already found
+      _curr_found = false;
+      for (int i = 0; i < n; ++i) {
+        u = (*_nodes)[i];
+        if (_data[u][k].dist == INF) continue;
+        for (int j = k; j >= 0; --j) {
+          if (level[u].first == i && level[u].second > 0) {
+            // A cycle is found
+            cost = _data[u][level[u].second].dist - _data[u][j].dist;
+            size = level[u].second - j;
+            if (!_curr_found || cost * _curr_size < _curr_cost * size) {
+              _curr_cost = cost;
+              _curr_size = size;
+              _curr_node = u;
+              _curr_level = level[u].second;
+              _curr_found = true;
+            }
+          }
+          level[u] = Pair(i, j);
+          if (j != 0) {
+            u = _gr.source(_data[u][j].pred);
+          }
+        }
+      }
+
+      // If at least one cycle is found, check the optimality condition
+      LargeCost d;
+      if (_curr_found && k < n) {
+        // Find node potentials
+        for (int i = 0; i < n; ++i) {
+          u = (*_nodes)[i];
+          pi[u] = INF;
+          for (int j = 0; j <= k; ++j) {
+            if (_data[u][j].dist < INF) {
+              d = _data[u][j].dist * _curr_size - j * _curr_cost;
+              if (_tolerance.less(d, pi[u])) pi[u] = d;
+            }
+          }
+        }
+
+        // Check the optimality condition for all arcs
+        bool done = true;
+        for (ArcIt a(_gr); a != INVALID; ++a) {
+          if (_tolerance.less(_cost[a] * _curr_size - _curr_cost,
+                              pi[_gr.target(a)] - pi[_gr.source(a)]) ) {
+            done = false;
+            break;
+          }
+        }
+        return done;
+      }
+      return (k == n);
+    }
+
+  }; //class HartmannOrlinMmc
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_HARTMANN_ORLIN_MMC_H
Index: lemon/howard_mmc.h
===================================================================
--- lemon/howard_mmc.h	(revision 877)
+++ lemon/howard_mmc.h	(revision 877)
@@ -0,0 +1,605 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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_HOWARD_MMC_H
+#define LEMON_HOWARD_MMC_H
+
+/// \ingroup min_mean_cycle
+///
+/// \file
+/// \brief Howard's algorithm for finding a minimum mean cycle.
+
+#include <vector>
+#include <limits>
+#include <lemon/core.h>
+#include <lemon/path.h>
+#include <lemon/tolerance.h>
+#include <lemon/connectivity.h>
+
+namespace lemon {
+
+  /// \brief Default traits class of HowardMmc class.
+  ///
+  /// Default traits class of HowardMmc class.
+  /// \tparam GR The type of the digraph.
+  /// \tparam CM The type of the cost map.
+  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+#ifdef DOXYGEN
+  template <typename GR, typename CM>
+#else
+  template <typename GR, typename CM,
+    bool integer = std::numeric_limits<typename CM::Value>::is_integer>
+#endif
+  struct HowardMmcDefaultTraits
+  {
+    /// The type of the digraph
+    typedef GR Digraph;
+    /// The type of the cost map
+    typedef CM CostMap;
+    /// The type of the arc costs
+    typedef typename CostMap::Value Cost;
+
+    /// \brief The large cost type used for internal computations
+    ///
+    /// The large cost type used for internal computations.
+    /// It is \c long \c long if the \c Cost type is integer,
+    /// otherwise it is \c double.
+    /// \c Cost must be convertible to \c LargeCost.
+    typedef double LargeCost;
+
+    /// The tolerance type used for internal computations
+    typedef lemon::Tolerance<LargeCost> Tolerance;
+
+    /// \brief The path type of the found cycles
+    ///
+    /// The path type of the found cycles.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addBack() function.
+    typedef lemon::Path<Digraph> Path;
+  };
+
+  // Default traits class for integer cost types
+  template <typename GR, typename CM>
+  struct HowardMmcDefaultTraits<GR, CM, true>
+  {
+    typedef GR Digraph;
+    typedef CM CostMap;
+    typedef typename CostMap::Value Cost;
+#ifdef LEMON_HAVE_LONG_LONG
+    typedef long long LargeCost;
+#else
+    typedef long LargeCost;
+#endif
+    typedef lemon::Tolerance<LargeCost> Tolerance;
+    typedef lemon::Path<Digraph> Path;
+  };
+
+
+  /// \addtogroup min_mean_cycle
+  /// @{
+
+  /// \brief Implementation of Howard's algorithm for finding a minimum
+  /// mean cycle.
+  ///
+  /// This class implements Howard's policy iteration algorithm for finding
+  /// a directed cycle of minimum mean cost in a digraph
+  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
+  /// This class provides the most efficient algorithm for the
+  /// minimum mean cycle problem, though the best known theoretical
+  /// bound on its running time is exponential.
+  ///
+  /// \tparam GR The type of the digraph the algorithm runs on.
+  /// \tparam CM The type of the cost map. The default
+  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm. By default, it is \ref HowardMmcDefaultTraits
+  /// "HowardMmcDefaultTraits<GR, CM>".
+  /// In most cases, this parameter should not be set directly,
+  /// consider to use the named template parameters instead.
+#ifdef DOXYGEN
+  template <typename GR, typename CM, typename TR>
+#else
+  template < typename GR,
+             typename CM = typename GR::template ArcMap<int>,
+             typename TR = HowardMmcDefaultTraits<GR, CM> >
+#endif
+  class HowardMmc
+  {
+  public:
+
+    /// The type of the digraph
+    typedef typename TR::Digraph Digraph;
+    /// The type of the cost map
+    typedef typename TR::CostMap CostMap;
+    /// The type of the arc costs
+    typedef typename TR::Cost Cost;
+
+    /// \brief The large cost type
+    ///
+    /// The large cost type used for internal computations.
+    /// By default, it is \c long \c long if the \c Cost type is integer,
+    /// otherwise it is \c double.
+    typedef typename TR::LargeCost LargeCost;
+
+    /// The tolerance type
+    typedef typename TR::Tolerance Tolerance;
+
+    /// \brief The path type of the found cycles
+    ///
+    /// The path type of the found cycles.
+    /// Using the \ref HowardMmcDefaultTraits "default traits class",
+    /// it is \ref lemon::Path "Path<Digraph>".
+    typedef typename TR::Path Path;
+
+    /// The \ref HowardMmcDefaultTraits "traits class" of the algorithm
+    typedef TR Traits;
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+    // The digraph the algorithm runs on
+    const Digraph &_gr;
+    // The cost of the arcs
+    const CostMap &_cost;
+
+    // Data for the found cycles
+    bool _curr_found, _best_found;
+    LargeCost _curr_cost, _best_cost;
+    int _curr_size, _best_size;
+    Node _curr_node, _best_node;
+
+    Path *_cycle_path;
+    bool _local_path;
+
+    // Internal data used by the algorithm
+    typename Digraph::template NodeMap<Arc> _policy;
+    typename Digraph::template NodeMap<bool> _reached;
+    typename Digraph::template NodeMap<int> _level;
+    typename Digraph::template NodeMap<LargeCost> _dist;
+
+    // Data for storing the strongly connected components
+    int _comp_num;
+    typename Digraph::template NodeMap<int> _comp;
+    std::vector<std::vector<Node> > _comp_nodes;
+    std::vector<Node>* _nodes;
+    typename Digraph::template NodeMap<std::vector<Arc> > _in_arcs;
+
+    // Queue used for BFS search
+    std::vector<Node> _queue;
+    int _qfront, _qback;
+
+    Tolerance _tolerance;
+
+    // Infinite constant
+    const LargeCost INF;
+
+  public:
+
+    /// \name Named Template Parameters
+    /// @{
+
+    template <typename T>
+    struct SetLargeCostTraits : public Traits {
+      typedef T LargeCost;
+      typedef lemon::Tolerance<T> Tolerance;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c LargeCost type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
+    /// type. It is used for internal computations in the algorithm.
+    template <typename T>
+    struct SetLargeCost
+      : public HowardMmc<GR, CM, SetLargeCostTraits<T> > {
+      typedef HowardMmc<GR, CM, SetLargeCostTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetPathTraits : public Traits {
+      typedef T Path;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c %Path type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting the \c %Path
+    /// type of the found cycles.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addBack() function.
+    template <typename T>
+    struct SetPath
+      : public HowardMmc<GR, CM, SetPathTraits<T> > {
+      typedef HowardMmc<GR, CM, SetPathTraits<T> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    HowardMmc() {}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// The constructor of the class.
+    ///
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param cost The costs of the arcs.
+    HowardMmc( const Digraph &digraph,
+               const CostMap &cost ) :
+      _gr(digraph), _cost(cost), _best_found(false),
+      _best_cost(0), _best_size(1), _cycle_path(NULL), _local_path(false),
+      _policy(digraph), _reached(digraph), _level(digraph), _dist(digraph),
+      _comp(digraph), _in_arcs(digraph),
+      INF(std::numeric_limits<LargeCost>::has_infinity ?
+          std::numeric_limits<LargeCost>::infinity() :
+          std::numeric_limits<LargeCost>::max())
+    {}
+
+    /// Destructor.
+    ~HowardMmc() {
+      if (_local_path) delete _cycle_path;
+    }
+
+    /// \brief Set the path structure for storing the found cycle.
+    ///
+    /// This function sets an external path structure for storing the
+    /// found cycle.
+    ///
+    /// If you don't call this function before calling \ref run() or
+    /// \ref findCycleMean(), it will allocate a local \ref Path "path"
+    /// structure. The destuctor deallocates this automatically
+    /// allocated object, of course.
+    ///
+    /// \note The algorithm calls only the \ref lemon::Path::addBack()
+    /// "addBack()" function of the given path structure.
+    ///
+    /// \return <tt>(*this)</tt>
+    HowardMmc& cycle(Path &path) {
+      if (_local_path) {
+        delete _cycle_path;
+        _local_path = false;
+      }
+      _cycle_path = &path;
+      return *this;
+    }
+
+    /// \brief Set the tolerance used by the algorithm.
+    ///
+    /// This function sets the tolerance object used by the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    HowardMmc& tolerance(const Tolerance& tolerance) {
+      _tolerance = tolerance;
+      return *this;
+    }
+
+    /// \brief Return a const reference to the tolerance.
+    ///
+    /// This function returns a const reference to the tolerance object
+    /// used by the algorithm.
+    const Tolerance& tolerance() const {
+      return _tolerance;
+    }
+
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to call the \ref run()
+    /// function.\n
+    /// If you only need the minimum mean cost, you may call
+    /// \ref findCycleMean().
+
+    /// @{
+
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm.
+    /// It can be called more than once (e.g. if the underlying digraph
+    /// and/or the arc costs have been modified).
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    ///
+    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
+    /// \code
+    ///   return mmc.findCycleMean() && mmc.findCycle();
+    /// \endcode
+    bool run() {
+      return findCycleMean() && findCycle();
+    }
+
+    /// \brief Find the minimum cycle mean.
+    ///
+    /// This function finds the minimum mean cost of the directed
+    /// cycles in the digraph.
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    bool findCycleMean() {
+      // Initialize and find strongly connected components
+      init();
+      findComponents();
+
+      // Find the minimum cycle mean in the components
+      for (int comp = 0; comp < _comp_num; ++comp) {
+        // Find the minimum mean cycle in the current component
+        if (!buildPolicyGraph(comp)) continue;
+        while (true) {
+          findPolicyCycle();
+          if (!computeNodeDistances()) break;
+        }
+        // Update the best cycle (global minimum mean cycle)
+        if ( _curr_found && (!_best_found ||
+             _curr_cost * _best_size < _best_cost * _curr_size) ) {
+          _best_found = true;
+          _best_cost = _curr_cost;
+          _best_size = _curr_size;
+          _best_node = _curr_node;
+        }
+      }
+      return _best_found;
+    }
+
+    /// \brief Find a minimum mean directed cycle.
+    ///
+    /// This function finds a directed cycle of minimum mean cost
+    /// in the digraph using the data computed by findCycleMean().
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    ///
+    /// \pre \ref findCycleMean() must be called before using this function.
+    bool findCycle() {
+      if (!_best_found) return false;
+      _cycle_path->addBack(_policy[_best_node]);
+      for ( Node v = _best_node;
+            (v = _gr.target(_policy[v])) != _best_node; ) {
+        _cycle_path->addBack(_policy[v]);
+      }
+      return true;
+    }
+
+    /// @}
+
+    /// \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 the total cost of the found cycle.
+    ///
+    /// This function returns the total cost of the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    Cost cycleCost() const {
+      return static_cast<Cost>(_best_cost);
+    }
+
+    /// \brief Return the number of arcs on the found cycle.
+    ///
+    /// This function returns the number of arcs on the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    int cycleSize() const {
+      return _best_size;
+    }
+
+    /// \brief Return the mean cost of the found cycle.
+    ///
+    /// This function returns the mean cost of the found cycle.
+    ///
+    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
+    /// following code.
+    /// \code
+    ///   return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
+    /// \endcode
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    double cycleMean() const {
+      return static_cast<double>(_best_cost) / _best_size;
+    }
+
+    /// \brief Return the found cycle.
+    ///
+    /// This function returns a const reference to the path structure
+    /// storing the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycle() must be called before using
+    /// this function.
+    const Path& cycle() const {
+      return *_cycle_path;
+    }
+
+    ///@}
+
+  private:
+
+    // Initialize
+    void init() {
+      if (!_cycle_path) {
+        _local_path = true;
+        _cycle_path = new Path;
+      }
+      _queue.resize(countNodes(_gr));
+      _best_found = false;
+      _best_cost = 0;
+      _best_size = 1;
+      _cycle_path->clear();
+    }
+
+    // Find strongly connected components and initialize _comp_nodes
+    // and _in_arcs
+    void findComponents() {
+      _comp_num = stronglyConnectedComponents(_gr, _comp);
+      _comp_nodes.resize(_comp_num);
+      if (_comp_num == 1) {
+        _comp_nodes[0].clear();
+        for (NodeIt n(_gr); n != INVALID; ++n) {
+          _comp_nodes[0].push_back(n);
+          _in_arcs[n].clear();
+          for (InArcIt a(_gr, n); a != INVALID; ++a) {
+            _in_arcs[n].push_back(a);
+          }
+        }
+      } else {
+        for (int i = 0; i < _comp_num; ++i)
+          _comp_nodes[i].clear();
+        for (NodeIt n(_gr); n != INVALID; ++n) {
+          int k = _comp[n];
+          _comp_nodes[k].push_back(n);
+          _in_arcs[n].clear();
+          for (InArcIt a(_gr, n); a != INVALID; ++a) {
+            if (_comp[_gr.source(a)] == k) _in_arcs[n].push_back(a);
+          }
+        }
+      }
+    }
+
+    // Build the policy graph in the given strongly connected component
+    // (the out-degree of every node is 1)
+    bool buildPolicyGraph(int comp) {
+      _nodes = &(_comp_nodes[comp]);
+      if (_nodes->size() < 1 ||
+          (_nodes->size() == 1 && _in_arcs[(*_nodes)[0]].size() == 0)) {
+        return false;
+      }
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        _dist[(*_nodes)[i]] = INF;
+      }
+      Node u, v;
+      Arc e;
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        v = (*_nodes)[i];
+        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
+          e = _in_arcs[v][j];
+          u = _gr.source(e);
+          if (_cost[e] < _dist[u]) {
+            _dist[u] = _cost[e];
+            _policy[u] = e;
+          }
+        }
+      }
+      return true;
+    }
+
+    // Find the minimum mean cycle in the policy graph
+    void findPolicyCycle() {
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        _level[(*_nodes)[i]] = -1;
+      }
+      LargeCost ccost;
+      int csize;
+      Node u, v;
+      _curr_found = false;
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        u = (*_nodes)[i];
+        if (_level[u] >= 0) continue;
+        for (; _level[u] < 0; u = _gr.target(_policy[u])) {
+          _level[u] = i;
+        }
+        if (_level[u] == i) {
+          // A cycle is found
+          ccost = _cost[_policy[u]];
+          csize = 1;
+          for (v = u; (v = _gr.target(_policy[v])) != u; ) {
+            ccost += _cost[_policy[v]];
+            ++csize;
+          }
+          if ( !_curr_found ||
+               (ccost * _curr_size < _curr_cost * csize) ) {
+            _curr_found = true;
+            _curr_cost = ccost;
+            _curr_size = csize;
+            _curr_node = u;
+          }
+        }
+      }
+    }
+
+    // Contract the policy graph and compute node distances
+    bool computeNodeDistances() {
+      // Find the component of the main cycle and compute node distances
+      // using reverse BFS
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        _reached[(*_nodes)[i]] = false;
+      }
+      _qfront = _qback = 0;
+      _queue[0] = _curr_node;
+      _reached[_curr_node] = true;
+      _dist[_curr_node] = 0;
+      Node u, v;
+      Arc e;
+      while (_qfront <= _qback) {
+        v = _queue[_qfront++];
+        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
+          e = _in_arcs[v][j];
+          u = _gr.source(e);
+          if (_policy[u] == e && !_reached[u]) {
+            _reached[u] = true;
+            _dist[u] = _dist[v] + _cost[e] * _curr_size - _curr_cost;
+            _queue[++_qback] = u;
+          }
+        }
+      }
+
+      // Connect all other nodes to this component and compute node
+      // distances using reverse BFS
+      _qfront = 0;
+      while (_qback < int(_nodes->size())-1) {
+        v = _queue[_qfront++];
+        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
+          e = _in_arcs[v][j];
+          u = _gr.source(e);
+          if (!_reached[u]) {
+            _reached[u] = true;
+            _policy[u] = e;
+            _dist[u] = _dist[v] + _cost[e] * _curr_size - _curr_cost;
+            _queue[++_qback] = u;
+          }
+        }
+      }
+
+      // Improve node distances
+      bool improved = false;
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        v = (*_nodes)[i];
+        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
+          e = _in_arcs[v][j];
+          u = _gr.source(e);
+          LargeCost delta = _dist[v] + _cost[e] * _curr_size - _curr_cost;
+          if (_tolerance.less(delta, _dist[u])) {
+            _dist[u] = delta;
+            _policy[u] = e;
+            improved = true;
+          }
+        }
+      }
+      return improved;
+    }
+
+  }; //class HowardMmc
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_HOWARD_MMC_H
Index: lemon/hypercube_graph.h
===================================================================
--- lemon/hypercube_graph.h	(revision 559)
+++ lemon/hypercube_graph.h	(revision 788)
@@ -263,5 +263,5 @@
     }
 
-    int index(Node node) const {
+    static int index(Node node) {
       return node._id;
     }
@@ -283,21 +283,25 @@
   /// \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.
+  /// HypercubeGraph implements a special graph type. The nodes of the
+  /// graph are indexed with integers having 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.
+  /// This class is completely static and it needs constant memory space.
+  /// Thus you can neither add nor delete nodes or edges, however,
+  /// the structure can be resized using resize().
+  ///
+  /// This type fully conforms to the \ref concepts::Graph "Graph concept".
+  /// Most of its member functions and nested classes are documented
+  /// only in the concept class.
+  ///
+  /// This class provides constant time counting for nodes, edges and arcs.
   ///
   /// \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 fully 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.
   class HypercubeGraph : public ExtendedHypercubeGraphBase {
+    typedef ExtendedHypercubeGraphBase Parent;
+
   public:
-
-    typedef ExtendedHypercubeGraphBase Parent;
 
     /// \brief Constructs a hypercube graph with \c dim dimensions.
@@ -305,4 +309,19 @@
     /// Constructs a hypercube graph with \c dim dimensions.
     HypercubeGraph(int dim) { construct(dim); }
+
+    /// \brief Resizes the graph
+    ///
+    /// This function resizes the graph. It fully destroys and
+    /// rebuilds the structure, therefore the maps of the graph will be
+    /// reallocated automatically and the previous values will be lost.
+    void resize(int dim) {
+      Parent::notifier(Arc()).clear();
+      Parent::notifier(Edge()).clear();
+      Parent::notifier(Node()).clear();
+      construct(dim);
+      Parent::notifier(Node()).build();
+      Parent::notifier(Edge()).build();
+      Parent::notifier(Arc()).build();
+    }
 
     /// \brief The number of dimensions.
@@ -323,5 +342,5 @@
     ///
     /// Gives back the dimension id of the given edge.
-    /// It is in the [0..dim-1] range.
+    /// It is in the range <tt>[0..dim-1]</tt>.
     int dimension(Edge edge) const {
       return Parent::dimension(edge);
@@ -331,5 +350,5 @@
     ///
     /// Gives back the dimension id of the given arc.
-    /// It is in the [0..dim-1] range.
+    /// It is in the range <tt>[0..dim-1]</tt>.
     int dimension(Arc arc) const {
       return Parent::dimension(arc);
@@ -340,5 +359,5 @@
     /// Gives back the index of the given node.
     /// The lower bits of the integer describes the node.
-    int index(Node node) const {
+    static int index(Node node) {
       return Parent::index(node);
     }
Index: lemon/karp_mmc.h
===================================================================
--- lemon/karp_mmc.h	(revision 877)
+++ lemon/karp_mmc.h	(revision 877)
@@ -0,0 +1,590 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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_KARP_MMC_H
+#define LEMON_KARP_MMC_H
+
+/// \ingroup min_mean_cycle
+///
+/// \file
+/// \brief Karp's algorithm for finding a minimum mean cycle.
+
+#include <vector>
+#include <limits>
+#include <lemon/core.h>
+#include <lemon/path.h>
+#include <lemon/tolerance.h>
+#include <lemon/connectivity.h>
+
+namespace lemon {
+
+  /// \brief Default traits class of KarpMmc class.
+  ///
+  /// Default traits class of KarpMmc class.
+  /// \tparam GR The type of the digraph.
+  /// \tparam CM The type of the cost map.
+  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+#ifdef DOXYGEN
+  template <typename GR, typename CM>
+#else
+  template <typename GR, typename CM,
+    bool integer = std::numeric_limits<typename CM::Value>::is_integer>
+#endif
+  struct KarpMmcDefaultTraits
+  {
+    /// The type of the digraph
+    typedef GR Digraph;
+    /// The type of the cost map
+    typedef CM CostMap;
+    /// The type of the arc costs
+    typedef typename CostMap::Value Cost;
+
+    /// \brief The large cost type used for internal computations
+    ///
+    /// The large cost type used for internal computations.
+    /// It is \c long \c long if the \c Cost type is integer,
+    /// otherwise it is \c double.
+    /// \c Cost must be convertible to \c LargeCost.
+    typedef double LargeCost;
+
+    /// The tolerance type used for internal computations
+    typedef lemon::Tolerance<LargeCost> Tolerance;
+
+    /// \brief The path type of the found cycles
+    ///
+    /// The path type of the found cycles.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addFront() function.
+    typedef lemon::Path<Digraph> Path;
+  };
+
+  // Default traits class for integer cost types
+  template <typename GR, typename CM>
+  struct KarpMmcDefaultTraits<GR, CM, true>
+  {
+    typedef GR Digraph;
+    typedef CM CostMap;
+    typedef typename CostMap::Value Cost;
+#ifdef LEMON_HAVE_LONG_LONG
+    typedef long long LargeCost;
+#else
+    typedef long LargeCost;
+#endif
+    typedef lemon::Tolerance<LargeCost> Tolerance;
+    typedef lemon::Path<Digraph> Path;
+  };
+
+
+  /// \addtogroup min_mean_cycle
+  /// @{
+
+  /// \brief Implementation of Karp's algorithm for finding a minimum
+  /// mean cycle.
+  ///
+  /// This class implements Karp's algorithm for finding a directed
+  /// cycle of minimum mean cost in a digraph
+  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
+  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
+  ///
+  /// \tparam GR The type of the digraph the algorithm runs on.
+  /// \tparam CM The type of the cost map. The default
+  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm. By default, it is \ref KarpMmcDefaultTraits
+  /// "KarpMmcDefaultTraits<GR, CM>".
+  /// In most cases, this parameter should not be set directly,
+  /// consider to use the named template parameters instead.
+#ifdef DOXYGEN
+  template <typename GR, typename CM, typename TR>
+#else
+  template < typename GR,
+             typename CM = typename GR::template ArcMap<int>,
+             typename TR = KarpMmcDefaultTraits<GR, CM> >
+#endif
+  class KarpMmc
+  {
+  public:
+
+    /// The type of the digraph
+    typedef typename TR::Digraph Digraph;
+    /// The type of the cost map
+    typedef typename TR::CostMap CostMap;
+    /// The type of the arc costs
+    typedef typename TR::Cost Cost;
+
+    /// \brief The large cost type
+    ///
+    /// The large cost type used for internal computations.
+    /// By default, it is \c long \c long if the \c Cost type is integer,
+    /// otherwise it is \c double.
+    typedef typename TR::LargeCost LargeCost;
+
+    /// The tolerance type
+    typedef typename TR::Tolerance Tolerance;
+
+    /// \brief The path type of the found cycles
+    ///
+    /// The path type of the found cycles.
+    /// Using the \ref KarpMmcDefaultTraits "default traits class",
+    /// it is \ref lemon::Path "Path<Digraph>".
+    typedef typename TR::Path Path;
+
+    /// The \ref KarpMmcDefaultTraits "traits class" of the algorithm
+    typedef TR Traits;
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+    // Data sturcture for path data
+    struct PathData
+    {
+      LargeCost dist;
+      Arc pred;
+      PathData(LargeCost d, Arc p = INVALID) :
+        dist(d), pred(p) {}
+    };
+
+    typedef typename Digraph::template NodeMap<std::vector<PathData> >
+      PathDataNodeMap;
+
+  private:
+
+    // The digraph the algorithm runs on
+    const Digraph &_gr;
+    // The cost of the arcs
+    const CostMap &_cost;
+
+    // Data for storing the strongly connected components
+    int _comp_num;
+    typename Digraph::template NodeMap<int> _comp;
+    std::vector<std::vector<Node> > _comp_nodes;
+    std::vector<Node>* _nodes;
+    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
+
+    // Data for the found cycle
+    LargeCost _cycle_cost;
+    int _cycle_size;
+    Node _cycle_node;
+
+    Path *_cycle_path;
+    bool _local_path;
+
+    // Node map for storing path data
+    PathDataNodeMap _data;
+    // The processed nodes in the last round
+    std::vector<Node> _process;
+
+    Tolerance _tolerance;
+
+    // Infinite constant
+    const LargeCost INF;
+
+  public:
+
+    /// \name Named Template Parameters
+    /// @{
+
+    template <typename T>
+    struct SetLargeCostTraits : public Traits {
+      typedef T LargeCost;
+      typedef lemon::Tolerance<T> Tolerance;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c LargeCost type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
+    /// type. It is used for internal computations in the algorithm.
+    template <typename T>
+    struct SetLargeCost
+      : public KarpMmc<GR, CM, SetLargeCostTraits<T> > {
+      typedef KarpMmc<GR, CM, SetLargeCostTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetPathTraits : public Traits {
+      typedef T Path;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c %Path type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting the \c %Path
+    /// type of the found cycles.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addFront() function.
+    template <typename T>
+    struct SetPath
+      : public KarpMmc<GR, CM, SetPathTraits<T> > {
+      typedef KarpMmc<GR, CM, SetPathTraits<T> > Create;
+    };
+
+    /// @}
+
+  protected:
+
+    KarpMmc() {}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// The constructor of the class.
+    ///
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param cost The costs of the arcs.
+    KarpMmc( const Digraph &digraph,
+             const CostMap &cost ) :
+      _gr(digraph), _cost(cost), _comp(digraph), _out_arcs(digraph),
+      _cycle_cost(0), _cycle_size(1), _cycle_node(INVALID),
+      _cycle_path(NULL), _local_path(false), _data(digraph),
+      INF(std::numeric_limits<LargeCost>::has_infinity ?
+          std::numeric_limits<LargeCost>::infinity() :
+          std::numeric_limits<LargeCost>::max())
+    {}
+
+    /// Destructor.
+    ~KarpMmc() {
+      if (_local_path) delete _cycle_path;
+    }
+
+    /// \brief Set the path structure for storing the found cycle.
+    ///
+    /// This function sets an external path structure for storing the
+    /// found cycle.
+    ///
+    /// If you don't call this function before calling \ref run() or
+    /// \ref findCycleMean(), it will allocate a local \ref Path "path"
+    /// structure. The destuctor deallocates this automatically
+    /// allocated object, of course.
+    ///
+    /// \note The algorithm calls only the \ref lemon::Path::addFront()
+    /// "addFront()" function of the given path structure.
+    ///
+    /// \return <tt>(*this)</tt>
+    KarpMmc& cycle(Path &path) {
+      if (_local_path) {
+        delete _cycle_path;
+        _local_path = false;
+      }
+      _cycle_path = &path;
+      return *this;
+    }
+
+    /// \brief Set the tolerance used by the algorithm.
+    ///
+    /// This function sets the tolerance object used by the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    KarpMmc& tolerance(const Tolerance& tolerance) {
+      _tolerance = tolerance;
+      return *this;
+    }
+
+    /// \brief Return a const reference to the tolerance.
+    ///
+    /// This function returns a const reference to the tolerance object
+    /// used by the algorithm.
+    const Tolerance& tolerance() const {
+      return _tolerance;
+    }
+
+    /// \name Execution control
+    /// The simplest way to execute the algorithm is to call the \ref run()
+    /// function.\n
+    /// If you only need the minimum mean cost, you may call
+    /// \ref findCycleMean().
+
+    /// @{
+
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm.
+    /// It can be called more than once (e.g. if the underlying digraph
+    /// and/or the arc costs have been modified).
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    ///
+    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
+    /// \code
+    ///   return mmc.findCycleMean() && mmc.findCycle();
+    /// \endcode
+    bool run() {
+      return findCycleMean() && findCycle();
+    }
+
+    /// \brief Find the minimum cycle mean.
+    ///
+    /// This function finds the minimum mean cost of the directed
+    /// cycles in the digraph.
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    bool findCycleMean() {
+      // Initialization and find strongly connected components
+      init();
+      findComponents();
+
+      // Find the minimum cycle mean in the components
+      for (int comp = 0; comp < _comp_num; ++comp) {
+        if (!initComponent(comp)) continue;
+        processRounds();
+        updateMinMean();
+      }
+      return (_cycle_node != INVALID);
+    }
+
+    /// \brief Find a minimum mean directed cycle.
+    ///
+    /// This function finds a directed cycle of minimum mean cost
+    /// in the digraph using the data computed by findCycleMean().
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    ///
+    /// \pre \ref findCycleMean() must be called before using this function.
+    bool findCycle() {
+      if (_cycle_node == INVALID) return false;
+      IntNodeMap reached(_gr, -1);
+      int r = _data[_cycle_node].size();
+      Node u = _cycle_node;
+      while (reached[u] < 0) {
+        reached[u] = --r;
+        u = _gr.source(_data[u][r].pred);
+      }
+      r = reached[u];
+      Arc e = _data[u][r].pred;
+      _cycle_path->addFront(e);
+      _cycle_cost = _cost[e];
+      _cycle_size = 1;
+      Node v;
+      while ((v = _gr.source(e)) != u) {
+        e = _data[v][--r].pred;
+        _cycle_path->addFront(e);
+        _cycle_cost += _cost[e];
+        ++_cycle_size;
+      }
+      return true;
+    }
+
+    /// @}
+
+    /// \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 the total cost of the found cycle.
+    ///
+    /// This function returns the total cost of the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    Cost cycleCost() const {
+      return static_cast<Cost>(_cycle_cost);
+    }
+
+    /// \brief Return the number of arcs on the found cycle.
+    ///
+    /// This function returns the number of arcs on the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    int cycleSize() const {
+      return _cycle_size;
+    }
+
+    /// \brief Return the mean cost of the found cycle.
+    ///
+    /// This function returns the mean cost of the found cycle.
+    ///
+    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
+    /// following code.
+    /// \code
+    ///   return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
+    /// \endcode
+    ///
+    /// \pre \ref run() or \ref findCycleMean() must be called before
+    /// using this function.
+    double cycleMean() const {
+      return static_cast<double>(_cycle_cost) / _cycle_size;
+    }
+
+    /// \brief Return the found cycle.
+    ///
+    /// This function returns a const reference to the path structure
+    /// storing the found cycle.
+    ///
+    /// \pre \ref run() or \ref findCycle() must be called before using
+    /// this function.
+    const Path& cycle() const {
+      return *_cycle_path;
+    }
+
+    ///@}
+
+  private:
+
+    // Initialization
+    void init() {
+      if (!_cycle_path) {
+        _local_path = true;
+        _cycle_path = new Path;
+      }
+      _cycle_path->clear();
+      _cycle_cost = 0;
+      _cycle_size = 1;
+      _cycle_node = INVALID;
+      for (NodeIt u(_gr); u != INVALID; ++u)
+        _data[u].clear();
+    }
+
+    // Find strongly connected components and initialize _comp_nodes
+    // and _out_arcs
+    void findComponents() {
+      _comp_num = stronglyConnectedComponents(_gr, _comp);
+      _comp_nodes.resize(_comp_num);
+      if (_comp_num == 1) {
+        _comp_nodes[0].clear();
+        for (NodeIt n(_gr); n != INVALID; ++n) {
+          _comp_nodes[0].push_back(n);
+          _out_arcs[n].clear();
+          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
+            _out_arcs[n].push_back(a);
+          }
+        }
+      } else {
+        for (int i = 0; i < _comp_num; ++i)
+          _comp_nodes[i].clear();
+        for (NodeIt n(_gr); n != INVALID; ++n) {
+          int k = _comp[n];
+          _comp_nodes[k].push_back(n);
+          _out_arcs[n].clear();
+          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
+            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
+          }
+        }
+      }
+    }
+
+    // Initialize path data for the current component
+    bool initComponent(int comp) {
+      _nodes = &(_comp_nodes[comp]);
+      int n = _nodes->size();
+      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
+        return false;
+      }
+      for (int i = 0; i < n; ++i) {
+        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
+      }
+      return true;
+    }
+
+    // Process all rounds of computing path data for the current component.
+    // _data[v][k] is the cost of a shortest directed walk from the root
+    // node to node v containing exactly k arcs.
+    void processRounds() {
+      Node start = (*_nodes)[0];
+      _data[start][0] = PathData(0);
+      _process.clear();
+      _process.push_back(start);
+
+      int k, n = _nodes->size();
+      for (k = 1; k <= n && int(_process.size()) < n; ++k) {
+        processNextBuildRound(k);
+      }
+      for ( ; k <= n; ++k) {
+        processNextFullRound(k);
+      }
+    }
+
+    // Process one round and rebuild _process
+    void processNextBuildRound(int k) {
+      std::vector<Node> next;
+      Node u, v;
+      Arc e;
+      LargeCost d;
+      for (int i = 0; i < int(_process.size()); ++i) {
+        u = _process[i];
+        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
+          e = _out_arcs[u][j];
+          v = _gr.target(e);
+          d = _data[u][k-1].dist + _cost[e];
+          if (_tolerance.less(d, _data[v][k].dist)) {
+            if (_data[v][k].dist == INF) next.push_back(v);
+            _data[v][k] = PathData(d, e);
+          }
+        }
+      }
+      _process.swap(next);
+    }
+
+    // Process one round using _nodes instead of _process
+    void processNextFullRound(int k) {
+      Node u, v;
+      Arc e;
+      LargeCost d;
+      for (int i = 0; i < int(_nodes->size()); ++i) {
+        u = (*_nodes)[i];
+        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
+          e = _out_arcs[u][j];
+          v = _gr.target(e);
+          d = _data[u][k-1].dist + _cost[e];
+          if (_tolerance.less(d, _data[v][k].dist)) {
+            _data[v][k] = PathData(d, e);
+          }
+        }
+      }
+    }
+
+    // Update the minimum cycle mean
+    void updateMinMean() {
+      int n = _nodes->size();
+      for (int i = 0; i < n; ++i) {
+        Node u = (*_nodes)[i];
+        if (_data[u][n].dist == INF) continue;
+        LargeCost cost, max_cost = 0;
+        int size, max_size = 1;
+        bool found_curr = false;
+        for (int k = 0; k < n; ++k) {
+          if (_data[u][k].dist == INF) continue;
+          cost = _data[u][n].dist - _data[u][k].dist;
+          size = n - k;
+          if (!found_curr || cost * max_size > max_cost * size) {
+            found_curr = true;
+            max_cost = cost;
+            max_size = size;
+          }
+        }
+        if ( found_curr && (_cycle_node == INVALID ||
+             max_cost * _cycle_size < _cycle_cost * max_size) ) {
+          _cycle_cost = max_cost;
+          _cycle_size = max_size;
+          _cycle_node = u;
+        }
+      }
+    }
+
+  }; //class KarpMmc
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_KARP_MMC_H
Index: lemon/kruskal.h
===================================================================
--- lemon/kruskal.h	(revision 440)
+++ lemon/kruskal.h	(revision 584)
@@ -249,9 +249,9 @@
   /// \ingroup spantree
   ///
-  /// \brief Kruskal algorithm to find a minimum cost spanning tree of
+  /// \brief Kruskal's algorithm for finding a minimum cost spanning tree of
   /// a graph.
   ///
   /// This function runs Kruskal's algorithm to find a minimum cost
-  /// spanning tree.
+  /// spanning tree of a graph.
   /// Due to some C++ hacking, it accepts various input and output types.
   ///
@@ -265,7 +265,7 @@
   /// It can be one of the following choices.
   /// - An STL compatible 'Forward Container' with
-  /// <tt>std::pair<GR::Arc,X></tt> or
-  /// <tt>std::pair<GR::Edge,X></tt> as its <tt>value_type</tt>, where
-  /// \c X is the type of the costs. The pairs indicates the arcs/edges
+  /// <tt>std::pair<GR::Arc,C></tt> or
+  /// <tt>std::pair<GR::Edge,C></tt> as its <tt>value_type</tt>, where
+  /// \c C is the type of the costs. The pairs indicates the arcs/edges
   /// along with the assigned cost. <em>They must be in a
   /// cost-ascending order.</em>
@@ -274,6 +274,6 @@
   ///
   /// \retval out Here we also have a choice.
-  /// - It can be a writable \c bool arc/edge map. After running the
-  /// algorithm it will contain the found minimum cost spanning
+  /// - It can be a writable arc/edge map with \c bool value type. After
+  /// running the algorithm it will contain the found minimum cost spanning
   /// tree: the value of an arc/edge will be set to \c true if it belongs
   /// to the tree, otherwise it will be set to \c false. The value of
@@ -302,6 +302,6 @@
 
 #ifdef DOXYGEN
-  template <class Graph, class In, class Out>
-  Value kruskal(GR const& g, const In& in, Out& out)
+  template <typename Graph, typename In, typename Out>
+  Value kruskal(const Graph& g, const In& in, Out& out)
 #else
   template <class Graph, class In, class Out>
@@ -315,6 +315,4 @@
 
 
-
-
   template <class Graph, class In, class Out>
   inline typename _kruskal_bits::KruskalValueSelector<In>::Value
Index: lemon/lemon.pc.cmake
===================================================================
--- lemon/lemon.pc.cmake	(revision 904)
+++ lemon/lemon.pc.cmake	(revision 904)
@@ -0,0 +1,10 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=@CMAKE_INSTALL_PREFIX@/bin
+libdir=@CMAKE_INSTALL_PREFIX@/lib
+includedir=@CMAKE_INSTALL_PREFIX@/include
+
+Name: @PROJECT_NAME@
+Description: Library for Efficient Modeling and Optimization in Networks
+Version: @PROJECT_VERSION@
+Libs: -L${libdir} -lemon @GLPK_LIBS@ @CPLEX_LIBS@ @SOPLEX_LIBS@ @CLP_LIBS@ @CBC_LIBS@
+Cflags: -I${includedir}
Index: lemon/lemon.pc.in
===================================================================
--- lemon/lemon.pc.in	(revision 259)
+++ lemon/lemon.pc.in	(revision 658)
@@ -5,6 +5,6 @@
 
 Name: @PACKAGE_NAME@
-Description: Library of Efficient Models and Optimization in Networks
+Description: Library for Efficient Modeling and Optimization in Networks
 Version: @PACKAGE_VERSION@
-Libs: -L${libdir} -lemon
+Libs: -L${libdir} -lemon @GLPK_LIBS@ @CPLEX_LIBS@ @SOPLEX_LIBS@ @CLP_LIBS@ @CBC_LIBS@
 Cflags: -I${includedir}
Index: lemon/lgf_reader.h
===================================================================
--- lemon/lgf_reader.h	(revision 559)
+++ lemon/lgf_reader.h	(revision 944)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2011
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -102,21 +102,21 @@
     };
 
-    template <typename _Graph, bool _dir, typename _Map,
+    template <typename _GR, bool _dir, typename _Map,
               typename _Converter = DefaultConverter<typename _Map::Value> >
-    class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
+    class GraphArcMapStorage : public MapStorageBase<typename _GR::Edge> {
     public:
       typedef _Map Map;
       typedef _Converter Converter;
-      typedef _Graph Graph;
-      typedef typename Graph::Edge Item;
+      typedef _GR GR;
+      typedef typename GR::Edge Item;
       static const bool dir = _dir;
 
     private:
-      const Graph& _graph;
+      const GR& _graph;
       Map& _map;
       Converter _converter;
 
     public:
-      GraphArcMapStorage(const Graph& graph, Map& map,
+      GraphArcMapStorage(const GR& graph, Map& map,
                          const Converter& converter = Converter())
         : _graph(graph), _map(map), _converter(converter) {}
@@ -174,19 +174,19 @@
     };
 
-    template <typename Graph>
+    template <typename GR>
     struct GraphArcLookUpConverter {
-      const Graph& _graph;
-      const std::map<std::string, typename Graph::Edge>& _map;
-
-      GraphArcLookUpConverter(const Graph& graph,
+      const GR& _graph;
+      const std::map<std::string, typename GR::Edge>& _map;
+
+      GraphArcLookUpConverter(const GR& graph,
                               const std::map<std::string,
-                                             typename Graph::Edge>& map)
+                                             typename GR::Edge>& map)
         : _graph(graph), _map(map) {}
 
-      typename Graph::Arc operator()(const std::string& str) {
+      typename GR::Arc operator()(const std::string& str) {
         if (str.empty() || (str[0] != '+' && str[0] != '-')) {
           throw FormatError("Item must start with '+' or '-'");
         }
-        typename std::map<std::string, typename Graph::Edge>
+        typename std::map<std::string, typename GR::Edge>
           ::const_iterator it = _map.find(str.substr(1));
         if (it == _map.end()) {
@@ -388,14 +388,13 @@
   }
 
-  template <typename Digraph>
+  template <typename DGR>
   class DigraphReader;
 
-  template <typename Digraph>
-  DigraphReader<Digraph> digraphReader(Digraph& digraph, 
-                                       std::istream& is = std::cin);
-  template <typename Digraph>
-  DigraphReader<Digraph> digraphReader(Digraph& digraph, const std::string& fn);
-  template <typename Digraph>
-  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char *fn);
+  template <typename TDGR>
+  DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is = std::cin);
+  template <typename TDGR>
+  DigraphReader<TDGR> digraphReader(TDGR& digraph, const std::string& fn);
+  template <typename TDGR>
+  DigraphReader<TDGR> digraphReader(TDGR& digraph, const char *fn);
 
   /// \ingroup lemon_io
@@ -420,5 +419,5 @@
   ///
   ///\code
-  /// DigraphReader<Digraph>(digraph, std::cin).
+  /// DigraphReader<DGR>(digraph, std::cin).
   ///   nodeMap("coordinates", coord_map).
   ///   arcMap("capacity", cap_map).
@@ -429,5 +428,5 @@
   ///\endcode
   ///
-  /// By default the reader uses the first section in the file of the
+  /// By default, the reader uses the first section in the file of the
   /// proper type. If a section has an optional name, then it can be
   /// selected for reading by giving an optional name parameter to the
@@ -449,13 +448,13 @@
   /// a single pass, because the arcs are not constructed when the node
   /// maps are read.
-  template <typename GR>
+  template <typename DGR>
   class DigraphReader {
   public:
 
-    typedef GR Digraph;
+    typedef DGR Digraph;
 
   private:
 
-    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+    TEMPLATE_DIGRAPH_TYPEDEFS(DGR);
 
     std::istream* _is;
@@ -463,5 +462,5 @@
     std::string _filename;
 
-    Digraph& _digraph;
+    DGR& _digraph;
 
     std::string _nodes_caption;
@@ -501,5 +500,5 @@
     /// Construct a directed graph reader, which reads from the given
     /// input stream.
-    DigraphReader(Digraph& digraph, std::istream& is = std::cin)
+    DigraphReader(DGR& digraph, std::istream& is = std::cin)
       : _is(&is), local_is(false), _digraph(digraph),
         _use_nodes(false), _use_arcs(false),
@@ -510,5 +509,5 @@
     /// Construct a directed graph reader, which reads from the given
     /// file.
-    DigraphReader(Digraph& digraph, const std::string& fn)
+    DigraphReader(DGR& digraph, const std::string& fn)
       : _is(new std::ifstream(fn.c_str())), local_is(true),
         _filename(fn), _digraph(digraph),
@@ -525,5 +524,5 @@
     /// Construct a directed graph reader, which reads from the given
     /// file.
-    DigraphReader(Digraph& digraph, const char* fn)
+    DigraphReader(DGR& digraph, const char* fn)
       : _is(new std::ifstream(fn)), local_is(true),
         _filename(fn), _digraph(digraph),
@@ -561,11 +560,11 @@
   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);
+    template <typename TDGR>
+    friend DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is);
+    template <typename TDGR>
+    friend DigraphReader<TDGR> digraphReader(TDGR& digraph,
+                                             const std::string& fn);
+    template <typename TDGR>
+    friend DigraphReader<TDGR> digraphReader(TDGR& digraph, const char *fn);
 
     DigraphReader(DigraphReader& other)
@@ -594,5 +593,5 @@
   public:
 
-    /// \name Reading rules
+    /// \name Reading Rules
     /// @{
 
@@ -699,5 +698,5 @@
     /// @}
 
-    /// \name Select section by name
+    /// \name Select Section by Name
     /// @{
 
@@ -728,5 +727,5 @@
     /// @}
 
-    /// \name Using previously constructed node or arc set
+    /// \name Using Previously Constructed Node or Arc Set
     /// @{
 
@@ -966,4 +965,11 @@
         int index = 0;
         while (_reader_bits::readToken(line, map)) {
+          if(map == "-") {
+              if(index!=0)
+                throw FormatError("'-' is not allowed as a map name");
+              else if (line >> std::ws >> c)
+                throw FormatError("Extra character at the end of line");
+              else break;
+            }
           if (maps.find(map) != maps.end()) {
             std::ostringstream msg;
@@ -1117,5 +1123,5 @@
   public:
 
-    /// \name Execution of the reader
+    /// \name Execution of the Reader
     /// @{
 
@@ -1190,11 +1196,49 @@
   };
 
+  /// \ingroup lemon_io
+  ///
+  /// \brief Return a \ref DigraphReader class
+  ///
+  /// This function just returns a \ref DigraphReader class.
+  ///
+  /// With this function a digraph can be read from an
+  /// \ref lgf-format "LGF" file or input stream with several maps and
+  /// attributes. For example, there is network flow problem on a
+  /// digraph, i.e. a digraph with a \e capacity map on the arcs and
+  /// \e source and \e target nodes. This digraph can be read with the
+  /// following code:
+  ///
+  ///\code
+  ///ListDigraph digraph;
+  ///ListDigraph::ArcMap<int> cm(digraph);
+  ///ListDigraph::Node src, trg;
+  ///digraphReader(digraph, std::cin).
+  ///  arcMap("capacity", cap).
+  ///  node("source", src).
+  ///  node("target", trg).
+  ///  run();
+  ///\endcode
+  ///
+  /// For a complete documentation, please see the \ref DigraphReader
+  /// class documentation.
+  /// \warning Don't forget to put the \ref DigraphReader::run() "run()"
+  /// to the end of the parameter list.
+  /// \relates DigraphReader
+  /// \sa digraphReader(TDGR& digraph, const std::string& fn)
+  /// \sa digraphReader(TDGR& digraph, const char* fn)
+  template <typename TDGR>
+  DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is) {
+    DigraphReader<TDGR> 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, std::istream& is) {
-    DigraphReader<Digraph> tmp(digraph, is);
+  /// \sa digraphReader(TDGR& digraph, std::istream& is)
+  template <typename TDGR>
+  DigraphReader<TDGR> digraphReader(TDGR& digraph, const std::string& fn) {
+    DigraphReader<TDGR> tmp(digraph, fn);
     return tmp;
   }
@@ -1204,31 +1248,20 @@
   /// 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);
+  /// \sa digraphReader(TDGR& digraph, std::istream& is)
+  template <typename TDGR>
+  DigraphReader<TDGR> digraphReader(TDGR& digraph, const char* fn) {
+    DigraphReader<TDGR> 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> tmp(digraph, fn);
-    return tmp;
-  }
-
-  template <typename Graph>
+  template <typename GR>
   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);
+
+  template <typename TGR>
+  GraphReader<TGR> graphReader(TGR& graph, std::istream& is = std::cin);
+  template <typename TGR>
+  GraphReader<TGR> graphReader(TGR& graph, const std::string& fn);
+  template <typename TGR>
+  GraphReader<TGR> graphReader(TGR& graph, const char *fn);
 
   /// \ingroup lemon_io
@@ -1255,5 +1288,5 @@
   private:
 
-    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+    TEMPLATE_GRAPH_TYPEDEFS(GR);
 
     std::istream* _is;
@@ -1261,5 +1294,5 @@
     std::string _filename;
 
-    Graph& _graph;
+    GR& _graph;
 
     std::string _nodes_caption;
@@ -1299,5 +1332,5 @@
     /// Construct an undirected graph reader, which reads from the given
     /// input stream.
-    GraphReader(Graph& graph, std::istream& is = std::cin)
+    GraphReader(GR& graph, std::istream& is = std::cin)
       : _is(&is), local_is(false), _graph(graph),
         _use_nodes(false), _use_edges(false),
@@ -1308,5 +1341,5 @@
     /// Construct an undirected graph reader, which reads from the given
     /// file.
-    GraphReader(Graph& graph, const std::string& fn)
+    GraphReader(GR& graph, const std::string& fn)
       : _is(new std::ifstream(fn.c_str())), local_is(true),
         _filename(fn), _graph(graph),
@@ -1323,5 +1356,5 @@
     /// Construct an undirected graph reader, which reads from the given
     /// file.
-    GraphReader(Graph& graph, const char* fn)
+    GraphReader(GR& graph, const char* fn)
       : _is(new std::ifstream(fn)), local_is(true),
         _filename(fn), _graph(graph),
@@ -1358,10 +1391,10 @@
 
   private:
-    template <typename Graph>
-    friend GraphReader<Graph> graphReader(Graph& graph, std::istream& is);
-    template <typename Graph>
-    friend GraphReader<Graph> graphReader(Graph& graph, const std::string& fn); 
-    template <typename Graph>
-    friend GraphReader<Graph> graphReader(Graph& graph, const char *fn);
+    template <typename TGR>
+    friend GraphReader<TGR> graphReader(TGR& graph, std::istream& is);
+    template <typename TGR>
+    friend GraphReader<TGR> graphReader(TGR& graph, const std::string& fn);
+    template <typename TGR>
+    friend GraphReader<TGR> graphReader(TGR& graph, const char *fn);
 
     GraphReader(GraphReader& other)
@@ -1390,5 +1423,5 @@
   public:
 
-    /// \name Reading rules
+    /// \name Reading Rules
     /// @{
 
@@ -1455,5 +1488,5 @@
       _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
       _reader_bits::MapStorageBase<Edge>* backward_storage =
-        new _reader_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
+        new _reader_bits::GraphArcMapStorage<GR, false, Map>(_graph, map);
       _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
       return *this;
@@ -1469,9 +1502,9 @@
       checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
       _reader_bits::MapStorageBase<Edge>* forward_storage =
-        new _reader_bits::GraphArcMapStorage<Graph, true, Map, Converter>
+        new _reader_bits::GraphArcMapStorage<GR, true, Map, Converter>
         (_graph, map, converter);
       _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
       _reader_bits::MapStorageBase<Edge>* backward_storage =
-        new _reader_bits::GraphArcMapStorage<Graph, false, Map, Converter>
+        new _reader_bits::GraphArcMapStorage<GR, false, Map, Converter>
         (_graph, map, converter);
       _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
@@ -1531,5 +1564,5 @@
     /// Add an arc reading rule to reader.
     GraphReader& arc(const std::string& caption, Arc& arc) {
-      typedef _reader_bits::GraphArcLookUpConverter<Graph> Converter;
+      typedef _reader_bits::GraphArcLookUpConverter<GR> Converter;
       Converter converter(_graph, _edge_index);
       _reader_bits::ValueStorageBase* storage =
@@ -1541,5 +1574,5 @@
     /// @}
 
-    /// \name Select section by name
+    /// \name Select Section by Name
     /// @{
 
@@ -1570,5 +1603,5 @@
     /// @}
 
-    /// \name Using previously constructed node or edge set
+    /// \name Using Previously Constructed Node or Edge Set
     /// @{
 
@@ -1809,4 +1842,11 @@
         int index = 0;
         while (_reader_bits::readToken(line, map)) {
+          if(map == "-") {
+              if(index!=0)
+                throw FormatError("'-' is not allowed as a map name");
+              else if (line >> std::ws >> c)
+                throw FormatError("Extra character at the end of line");
+              else break;
+            }
           if (maps.find(map) != maps.end()) {
             std::ostringstream msg;
@@ -1960,5 +2000,5 @@
   public:
 
-    /// \name Execution of the reader
+    /// \name Execution of the Reader
     /// @{
 
@@ -2034,11 +2074,45 @@
   };
 
+  /// \ingroup lemon_io
+  ///
+  /// \brief Return a \ref GraphReader class
+  ///
+  /// This function just returns a \ref GraphReader class.
+  ///
+  /// With this function a graph can be read from an
+  /// \ref lgf-format "LGF" file or input stream with several maps and
+  /// attributes. For example, there is weighted matching problem on a
+  /// graph, i.e. a graph with a \e weight map on the edges. This
+  /// graph can be read with the following code:
+  ///
+  ///\code
+  ///ListGraph graph;
+  ///ListGraph::EdgeMap<int> weight(graph);
+  ///graphReader(graph, std::cin).
+  ///  edgeMap("weight", weight).
+  ///  run();
+  ///\endcode
+  ///
+  /// For a complete documentation, please see the \ref GraphReader
+  /// class documentation.
+  /// \warning Don't forget to put the \ref GraphReader::run() "run()"
+  /// to the end of the parameter list.
+  /// \relates GraphReader
+  /// \sa graphReader(TGR& graph, const std::string& fn)
+  /// \sa graphReader(TGR& graph, const char* fn)
+  template <typename TGR>
+  GraphReader<TGR> graphReader(TGR& graph, std::istream& is) {
+    GraphReader<TGR> 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, std::istream& is) {
-    GraphReader<Graph> tmp(graph, is);
+  /// \sa graphReader(TGR& graph, std::istream& is)
+  template <typename TGR>
+  GraphReader<TGR> graphReader(TGR& graph, const std::string& fn) {
+    GraphReader<TGR> tmp(graph, fn);
     return tmp;
   }
@@ -2048,17 +2122,8 @@
   /// 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);
+  /// \sa graphReader(TGR& graph, std::istream& is)
+  template <typename TGR>
+  GraphReader<TGR> graphReader(TGR& graph, const char* fn) {
+    GraphReader<TGR> tmp(graph, fn);
     return tmp;
   }
@@ -2159,5 +2224,5 @@
   public:
 
-    /// \name Section readers
+    /// \name Section Readers
     /// @{
 
@@ -2171,5 +2236,5 @@
     /// whitespaces are trimmed from each processed string.
     ///
-    /// For example let's see a section, which contain several
+    /// For example, let's see a section, which contain several
     /// integers, which should be inserted into a vector.
     ///\code
@@ -2258,5 +2323,5 @@
 
 
-    /// \name Execution of the reader
+    /// \name Execution of the Reader
     /// @{
 
@@ -2317,8 +2382,16 @@
   };
 
+  /// \ingroup lemon_io
+  ///
   /// \brief Return a \ref SectionReader class
   ///
   /// This function just returns a \ref SectionReader class.
+  ///
+  /// Please see SectionReader documentation about the custom section
+  /// input.
+  ///
   /// \relates SectionReader
+  /// \sa sectionReader(const std::string& fn)
+  /// \sa sectionReader(const char *fn)
   inline SectionReader sectionReader(std::istream& is) {
     SectionReader tmp(is);
@@ -2330,4 +2403,5 @@
   /// This function just returns a \ref SectionReader class.
   /// \relates SectionReader
+  /// \sa sectionReader(std::istream& is)
   inline SectionReader sectionReader(const std::string& fn) {
     SectionReader tmp(fn);
@@ -2339,4 +2413,5 @@
   /// This function just returns a \ref SectionReader class.
   /// \relates SectionReader
+  /// \sa sectionReader(std::istream& is)
   inline SectionReader sectionReader(const char* fn) {
     SectionReader tmp(fn);
@@ -2440,5 +2515,5 @@
 
 
-    /// \name Node sections
+    /// \name Node Sections
     /// @{
 
@@ -2466,5 +2541,5 @@
     /// @}
 
-    /// \name Arc/Edge sections
+    /// \name Arc/Edge Sections
     /// @{
 
@@ -2524,5 +2599,5 @@
     /// @}
 
-    /// \name Attribute sections
+    /// \name Attribute Sections
     /// @{
 
@@ -2550,5 +2625,5 @@
     /// @}
 
-    /// \name Extra sections
+    /// \name Extra Sections
     /// @{
 
@@ -2626,5 +2701,5 @@
   public:
 
-    /// \name Execution of the contents reader
+    /// \name Execution of the Contents Reader
     /// @{
 
Index: lemon/lgf_writer.h
===================================================================
--- lemon/lgf_writer.h	(revision 559)
+++ lemon/lgf_writer.h	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -348,17 +348,15 @@
   }
 
-  template <typename Digraph>
+  template <typename DGR>
   class DigraphWriter;
 
-  template <typename Digraph>
-  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
-                                       std::ostream& os = std::cout);
-  template <typename Digraph>
-  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
-                                       const std::string& fn);
-
-  template <typename Digraph>
-  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
-                                       const char* fn);
+  template <typename TDGR>
+  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
+                                   std::ostream& os = std::cout);
+  template <typename TDGR>
+  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const std::string& fn);
+
+  template <typename TDGR>
+  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const char* fn);
 
 
@@ -382,5 +380,5 @@
   ///
   ///\code
-  /// DigraphWriter<Digraph>(digraph, std::cout).
+  /// DigraphWriter<DGR>(digraph, std::cout).
   ///   nodeMap("coordinates", coord_map).
   ///   nodeMap("size", size).
@@ -407,10 +405,10 @@
   /// the \c ostream() function, hence the second pass can append its
   /// output to the output of the first pass.
-  template <typename GR>
+  template <typename DGR>
   class DigraphWriter {
   public:
 
-    typedef GR Digraph;
-    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+    typedef DGR Digraph;
+    TEMPLATE_DIGRAPH_TYPEDEFS(DGR);
 
   private:
@@ -420,5 +418,5 @@
     bool local_os;
 
-    const Digraph& _digraph;
+    const DGR& _digraph;
 
     std::string _nodes_caption;
@@ -452,5 +450,5 @@
     /// Construct a directed graph writer, which writes to the given
     /// output stream.
-    DigraphWriter(const Digraph& digraph, std::ostream& os = std::cout)
+    DigraphWriter(const DGR& digraph, std::ostream& os = std::cout)
       : _os(&os), local_os(false), _digraph(digraph),
         _skip_nodes(false), _skip_arcs(false) {}
@@ -460,5 +458,5 @@
     /// Construct a directed graph writer, which writes to the given
     /// output file.
-    DigraphWriter(const Digraph& digraph, const std::string& fn)
+    DigraphWriter(const DGR& digraph, const std::string& fn)
       : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
         _skip_nodes(false), _skip_arcs(false) {
@@ -473,5 +471,5 @@
     /// Construct a directed graph writer, which writes to the given
     /// output file.
-    DigraphWriter(const Digraph& digraph, const char* fn)
+    DigraphWriter(const DGR& digraph, const char* fn)
       : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
         _skip_nodes(false), _skip_arcs(false) {
@@ -506,13 +504,13 @@
   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);
+    template <typename TDGR>
+    friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
+                                             std::ostream& os);
+    template <typename TDGR>
+    friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
+                                             const std::string& fn);
+    template <typename TDGR>
+    friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
+                                             const char *fn);
 
     DigraphWriter(DigraphWriter& other)
@@ -539,5 +537,5 @@
   public:
 
-    /// \name Writing rules
+    /// \name Writing Rules
     /// @{
 
@@ -642,5 +640,5 @@
     }
 
-    /// \name Section captions
+    /// \name Section Captions
     /// @{
 
@@ -669,5 +667,5 @@
     }
 
-    /// \name Skipping section
+    /// \name Skipping Section
     /// @{
 
@@ -725,6 +723,6 @@
 
       if (label == 0) {
-        IdMap<Digraph, Node> id_map(_digraph);
-        _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
+        IdMap<DGR, Node> id_map(_digraph);
+        _writer_bits::MapLess<IdMap<DGR, Node> > id_less(id_map);
         std::sort(nodes.begin(), nodes.end(), id_less);
       } else {
@@ -810,6 +808,6 @@
 
       if (label == 0) {
-        IdMap<Digraph, Arc> id_map(_digraph);
-        _writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map);
+        IdMap<DGR, Arc> id_map(_digraph);
+        _writer_bits::MapLess<IdMap<DGR, Arc> > id_less(id_map);
         std::sort(arcs.begin(), arcs.end(), id_less);
       } else {
@@ -886,5 +884,5 @@
   public:
 
-    /// \name Execution of the writer
+    /// \name Execution of the Writer
     /// @{
 
@@ -916,12 +914,51 @@
   };
 
+  /// \ingroup lemon_io
+  ///
+  /// \brief Return a \ref DigraphWriter class
+  ///
+  /// This function just returns a \ref DigraphWriter class.
+  ///
+  /// With this function a digraph can be write to a file or output
+  /// stream in \ref lgf-format "LGF" format with several maps and
+  /// attributes. For example, with the following code a network flow
+  /// problem can be written to the standard output, i.e. a digraph
+  /// with a \e capacity map on the arcs and \e source and \e target
+  /// nodes:
+  ///
+  ///\code
+  ///ListDigraph digraph;
+  ///ListDigraph::ArcMap<int> cap(digraph);
+  ///ListDigraph::Node src, trg;
+  ///  // Setting the capacity map and source and target nodes
+  ///digraphWriter(digraph, std::cout).
+  ///  arcMap("capacity", cap).
+  ///  node("source", src).
+  ///  node("target", trg).
+  ///  run();
+  ///\endcode
+  ///
+  /// For a complete documentation, please see the \ref DigraphWriter
+  /// class documentation.
+  /// \warning Don't forget to put the \ref DigraphWriter::run() "run()"
+  /// to the end of the parameter list.
+  /// \relates DigraphWriter
+  /// \sa digraphWriter(const TDGR& digraph, const std::string& fn)
+  /// \sa digraphWriter(const TDGR& digraph, const char* fn)
+  template <typename TDGR>
+  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, std::ostream& os) {
+    DigraphWriter<TDGR> 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,
-                                       std::ostream& os) {
-    DigraphWriter<Digraph> tmp(digraph, os);
+  /// \sa digraphWriter(const TDGR& digraph, std::ostream& os)
+  template <typename TDGR>
+  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
+                                    const std::string& fn) {
+    DigraphWriter<TDGR> tmp(digraph, fn);
     return tmp;
   }
@@ -931,32 +968,20 @@
   /// 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);
+  /// \sa digraphWriter(const TDGR& digraph, std::ostream& os)
+  template <typename TDGR>
+  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const char* fn) {
+    DigraphWriter<TDGR> 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) {
-    DigraphWriter<Digraph> tmp(digraph, fn);
-    return tmp;
-  }
-
-  template <typename Graph>
+  template <typename GR>
   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);
+  template <typename TGR>
+  GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os = std::cout);
+  template <typename TGR>
+  GraphWriter<TGR> graphWriter(const TGR& graph, const std::string& fn);
+  template <typename TGR>
+  GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn);
 
   /// \ingroup lemon_io
@@ -980,5 +1005,5 @@
 
     typedef GR Graph;
-    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+    TEMPLATE_GRAPH_TYPEDEFS(GR);
 
   private:
@@ -988,5 +1013,5 @@
     bool local_os;
 
-    const Graph& _graph;
+    const GR& _graph;
 
     std::string _nodes_caption;
@@ -1020,5 +1045,5 @@
     /// Construct a directed graph writer, which writes to the given
     /// output stream.
-    GraphWriter(const Graph& graph, std::ostream& os = std::cout)
+    GraphWriter(const GR& graph, std::ostream& os = std::cout)
       : _os(&os), local_os(false), _graph(graph),
         _skip_nodes(false), _skip_edges(false) {}
@@ -1028,5 +1053,5 @@
     /// Construct a directed graph writer, which writes to the given
     /// output file.
-    GraphWriter(const Graph& graph, const std::string& fn)
+    GraphWriter(const GR& graph, const std::string& fn)
       : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
         _skip_nodes(false), _skip_edges(false) {
@@ -1041,5 +1066,5 @@
     /// Construct a directed graph writer, which writes to the given
     /// output file.
-    GraphWriter(const Graph& graph, const char* fn)
+    GraphWriter(const GR& graph, const char* fn)
       : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
         _skip_nodes(false), _skip_edges(false) {
@@ -1074,14 +1099,12 @@
   private:
 
-    template <typename Graph>
-    friend GraphWriter<Graph> graphWriter(const Graph& graph,
-                                          std::ostream& os);
-    template <typename Graph>
-    friend GraphWriter<Graph> graphWriter(const Graph& graph,
-                                          const std::string& fn);
-    template <typename Graph>
-    friend GraphWriter<Graph> graphWriter(const Graph& graph,
-                                          const char *fn);
-    
+    template <typename TGR>
+    friend GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os);
+    template <typename TGR>
+    friend GraphWriter<TGR> graphWriter(const TGR& graph,
+                                        const std::string& fn);
+    template <typename TGR>
+    friend GraphWriter<TGR> graphWriter(const TGR& graph, const char *fn);
+
     GraphWriter(GraphWriter& other)
       : _os(other._os), local_os(other.local_os), _graph(other._graph),
@@ -1107,5 +1130,5 @@
   public:
 
-    /// \name Writing rules
+    /// \name Writing Rules
     /// @{
 
@@ -1169,8 +1192,8 @@
       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
       _writer_bits::MapStorageBase<Edge>* forward_storage =
-        new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
+        new _writer_bits::GraphArcMapStorage<GR, true, Map>(_graph, map);
       _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
       _writer_bits::MapStorageBase<Edge>* backward_storage =
-        new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
+        new _writer_bits::GraphArcMapStorage<GR, false, Map>(_graph, map);
       _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
       return *this;
@@ -1186,9 +1209,9 @@
       checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
       _writer_bits::MapStorageBase<Edge>* forward_storage =
-        new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter>
+        new _writer_bits::GraphArcMapStorage<GR, true, Map, Converter>
         (_graph, map, converter);
       _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
       _writer_bits::MapStorageBase<Edge>* backward_storage =
-        new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter>
+        new _writer_bits::GraphArcMapStorage<GR, false, Map, Converter>
         (_graph, map, converter);
       _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
@@ -1248,5 +1271,5 @@
     /// Add an arc writing rule to writer.
     GraphWriter& arc(const std::string& caption, const Arc& arc) {
-      typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter;
+      typedef _writer_bits::GraphArcLookUpConverter<GR> Converter;
       Converter converter(_graph, _edge_index);
       _writer_bits::ValueStorageBase* storage =
@@ -1256,5 +1279,5 @@
     }
 
-    /// \name Section captions
+    /// \name Section Captions
     /// @{
 
@@ -1283,5 +1306,5 @@
     }
 
-    /// \name Skipping section
+    /// \name Skipping Section
     /// @{
 
@@ -1339,6 +1362,6 @@
 
       if (label == 0) {
-        IdMap<Graph, Node> id_map(_graph);
-        _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map);
+        IdMap<GR, Node> id_map(_graph);
+        _writer_bits::MapLess<IdMap<GR, Node> > id_less(id_map);
         std::sort(nodes.begin(), nodes.end(), id_less);
       } else {
@@ -1424,6 +1447,6 @@
 
       if (label == 0) {
-        IdMap<Graph, Edge> id_map(_graph);
-        _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map);
+        IdMap<GR, Edge> id_map(_graph);
+        _writer_bits::MapLess<IdMap<GR, Edge> > id_less(id_map);
         std::sort(edges.begin(), edges.end(), id_less);
       } else {
@@ -1500,5 +1523,5 @@
   public:
 
-    /// \name Execution of the writer
+    /// \name Execution of the Writer
     /// @{
 
@@ -1530,12 +1553,46 @@
   };
 
+  /// \ingroup lemon_io
+  ///
+  /// \brief Return a \ref GraphWriter class
+  ///
+  /// This function just returns a \ref GraphWriter class.
+  ///
+  /// With this function a graph can be write to a file or output
+  /// stream in \ref lgf-format "LGF" format with several maps and
+  /// attributes. For example, with the following code a weighted
+  /// matching problem can be written to the standard output, i.e. a
+  /// graph with a \e weight map on the edges:
+  ///
+  ///\code
+  ///ListGraph graph;
+  ///ListGraph::EdgeMap<int> weight(graph);
+  ///  // Setting the weight map
+  ///graphWriter(graph, std::cout).
+  ///  edgeMap("weight", weight).
+  ///  run();
+  ///\endcode
+  ///
+  /// For a complete documentation, please see the \ref GraphWriter
+  /// class documentation.
+  /// \warning Don't forget to put the \ref GraphWriter::run() "run()"
+  /// to the end of the parameter list.
+  /// \relates GraphWriter
+  /// \sa graphWriter(const TGR& graph, const std::string& fn)
+  /// \sa graphWriter(const TGR& graph, const char* fn)
+  template <typename TGR>
+  GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os) {
+    GraphWriter<TGR> 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,
-                                 std::ostream& os) {
-    GraphWriter<Graph> tmp(graph, os);
+  /// \sa graphWriter(const TGR& graph, std::ostream& os)
+  template <typename TGR>
+  GraphWriter<TGR> graphWriter(const TGR& graph, const std::string& fn) {
+    GraphWriter<TGR> tmp(graph, fn);
     return tmp;
   }
@@ -1545,17 +1602,8 @@
   /// 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);
+  /// \sa graphWriter(const TGR& graph, std::ostream& os)
+  template <typename TGR>
+  GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn) {
+    GraphWriter<TGR> tmp(graph, fn);
     return tmp;
   }
@@ -1652,5 +1700,5 @@
   public:
 
-    /// \name Section writers
+    /// \name Section Writers
     /// @{
 
@@ -1719,5 +1767,5 @@
 
 
-    /// \name Execution of the writer
+    /// \name Execution of the Writer
     /// @{
 
@@ -1747,8 +1795,16 @@
   };
 
+  /// \ingroup lemon_io
+  ///
   /// \brief Return a \ref SectionWriter class
   ///
   /// This function just returns a \ref SectionWriter class.
+  ///
+  /// Please see SectionWriter documentation about the custom section
+  /// output.
+  ///
   /// \relates SectionWriter
+  /// \sa sectionWriter(const std::string& fn)
+  /// \sa sectionWriter(const char *fn)
   inline SectionWriter sectionWriter(std::ostream& os) {
     SectionWriter tmp(os);
@@ -1760,4 +1816,5 @@
   /// This function just returns a \ref SectionWriter class.
   /// \relates SectionWriter
+  /// \sa sectionWriter(std::ostream& os)
   inline SectionWriter sectionWriter(const std::string& fn) {
     SectionWriter tmp(fn);
@@ -1769,4 +1826,5 @@
   /// This function just returns a \ref SectionWriter class.
   /// \relates SectionWriter
+  /// \sa sectionWriter(std::ostream& os)
   inline SectionWriter sectionWriter(const char* fn) {
     SectionWriter tmp(fn);
Index: lemon/list_graph.h
===================================================================
--- lemon/list_graph.h	(revision 559)
+++ lemon/list_graph.h	(revision 999)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -22,5 +22,5 @@
 ///\ingroup graphs
 ///\file
-///\brief ListDigraph, ListGraph classes.
+///\brief ListDigraph and ListGraph classes.
 
 #include <lemon/core.h>
@@ -32,4 +32,6 @@
 
 namespace lemon {
+
+  class ListDigraph;
 
   class ListDigraphBase {
@@ -63,4 +65,5 @@
     class Node {
       friend class ListDigraphBase;
+      friend class ListDigraph;
     protected:
 
@@ -78,4 +81,5 @@
     class Arc {
       friend class ListDigraphBase;
+      friend class ListDigraph;
     protected:
 
@@ -117,18 +121,18 @@
       int n;
       for(n = first_node;
-          n!=-1 && nodes[n].first_in == -1;
+          n != -1 && nodes[n].first_out == -1;
           n = nodes[n].next) {}
-      arc.id = (n == -1) ? -1 : nodes[n].first_in;
+      arc.id = (n == -1) ? -1 : nodes[n].first_out;
     }
 
     void next(Arc& arc) const {
-      if (arcs[arc.id].next_in != -1) {
-        arc.id = arcs[arc.id].next_in;
+      if (arcs[arc.id].next_out != -1) {
+        arc.id = arcs[arc.id].next_out;
       } else {
         int n;
-        for(n = nodes[arcs[arc.id].target].next;
-            n!=-1 && nodes[n].first_in == -1;
+        for(n = nodes[arcs[arc.id].source].next;
+            n != -1 && nodes[n].first_out == -1;
             n = nodes[n].next) {}
-        arc.id = (n == -1) ? -1 : nodes[n].first_in;
+        arc.id = (n == -1) ? -1 : nodes[n].first_out;
       }
     }
@@ -312,35 +316,28 @@
   ///A general directed graph structure.
 
-  ///\ref ListDigraph is a simple and fast <em>directed graph</em>
-  ///implementation based on static linked lists that are stored in
+  ///\ref ListDigraph is a versatile and fast directed graph
+  ///implementation based on linked lists that are stored in
   ///\c std::vector structures.
   ///
-  ///It conforms to the \ref concepts::Digraph "Digraph concept" and it
-  ///also provides several useful additional functionalities.
-  ///Most of the member functions and nested classes are documented
+  ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
+  ///and it also provides several useful additional functionalities.
+  ///Most of its member functions and nested classes are documented
   ///only in the concept class.
   ///
-  ///An important extra feature of this digraph implementation is that
-  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
+  ///This class provides only linear time counting for nodes and arcs.
   ///
   ///\sa concepts::Digraph
-
+  ///\sa ListGraph
   class ListDigraph : public ExtendedListDigraphBase {
+    typedef ExtendedListDigraphBase Parent;
+
   private:
-    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
-
-    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
-    ///
+    /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
     ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
-    ///\brief Assignment of ListDigraph to another one is \e not allowed.
-    ///Use copyDigraph() instead.
-
-    ///Assignment of ListDigraph to another one is \e not allowed.
-    ///Use copyDigraph() instead.
+    /// \brief Assignment of a digraph to another one is \e not allowed.
+    /// Use DigraphCopy instead.
     void operator=(const ListDigraph &) {}
   public:
 
-    typedef ExtendedListDigraphBase Parent;
-
     /// Constructor
 
@@ -351,5 +348,5 @@
     ///Add a new node to the digraph.
 
-    ///Add a new node to the digraph.
+    ///This function adds a new node to the digraph.
     ///\return The new node.
     Node addNode() { return Parent::addNode(); }
@@ -357,8 +354,8 @@
     ///Add a new arc to the digraph.
 
-    ///Add a new arc to the digraph with source node \c s
+    ///This function adds a new arc to the digraph with source node \c s
     ///and target node \c t.
     ///\return The new arc.
-    Arc addArc(const Node& s, const Node& t) {
+    Arc addArc(Node s, Node t) {
       return Parent::addArc(s, t);
     }
@@ -366,41 +363,43 @@
     ///\brief Erase a node from the digraph.
     ///
-    ///Erase a node from the digraph.
-    ///
-    void erase(const Node& n) { Parent::erase(n); }
+    ///This function erases the given node along with its outgoing and
+    ///incoming arcs from the digraph.
+    ///
+    ///\note All iterators referencing the removed node or the connected
+    ///arcs are invalidated, of course.
+    void erase(Node n) { Parent::erase(n); }
 
     ///\brief Erase an arc from the digraph.
     ///
-    ///Erase an arc from the digraph.
-    ///
-    void erase(const Arc& a) { Parent::erase(a); }
+    ///This function erases the given arc from the digraph.
+    ///
+    ///\note All iterators referencing the removed arc are invalidated,
+    ///of course.
+    void erase(Arc a) { Parent::erase(a); }
 
     /// Node validity check
 
-    /// This function gives back true if the given node is valid,
-    /// ie. it is a real node of the graph.
-    ///
-    /// \warning A Node pointing to a removed item
-    /// could become valid again later if new nodes are
-    /// added to the graph.
+    /// This function gives back \c true if the given node is valid,
+    /// i.e. it is a real node of the digraph.
+    ///
+    /// \warning A removed node could become valid again if new nodes are
+    /// added to the digraph.
     bool valid(Node n) const { return Parent::valid(n); }
 
     /// Arc validity check
 
-    /// This function gives back true if the given arc is valid,
-    /// ie. it is a real arc of the graph.
-    ///
-    /// \warning An Arc pointing to a removed item
-    /// could become valid again later if new nodes are
-    /// added to the graph.
+    /// This function gives back \c true if the given arc is valid,
+    /// i.e. it is a real arc of the digraph.
+    ///
+    /// \warning A removed arc could become valid again if new arcs are
+    /// added to the digraph.
     bool valid(Arc a) const { return Parent::valid(a); }
 
-    /// Change the target of \c a to \c n
-
-    /// Change the target of \c a to \c n
-    ///
-    ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
-    ///the changed arc remain valid. However <tt>InArcIt</tt>s are
-    ///invalidated.
+    /// Change the target node of an arc
+
+    /// This function changes the target node of the given arc \c a to \c n.
+    ///
+    ///\note \c ArcIt and \c OutArcIt iterators referencing the changed
+    ///arc remain valid, but \c InArcIt iterators are invalidated.
     ///
     ///\warning This functionality cannot be used together with the Snapshot
@@ -409,11 +408,10 @@
       Parent::changeTarget(a,n);
     }
-    /// Change the source of \c a to \c n
-
-    /// Change the source of \c a to \c n
-    ///
-    ///\note The <tt>InArcIt</tt>s referencing the changed arc remain
-    ///valid. However the <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s are
-    ///invalidated.
+    /// Change the source node of an arc
+
+    /// This function changes the source node of the given arc \c a to \c n.
+    ///
+    ///\note \c InArcIt iterators referencing the changed arc remain
+    ///valid, but \c ArcIt and \c OutArcIt iterators are invalidated.
     ///
     ///\warning This functionality cannot be used together with the Snapshot
@@ -423,92 +421,74 @@
     }
 
-    /// Invert the direction of an arc.
-
-    ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
-    ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
-    ///invalidated.
+    /// Reverse the direction of an arc.
+
+    /// This function reverses the direction of the given arc.
+    ///\note \c ArcIt, \c OutArcIt and \c InArcIt iterators referencing
+    ///the changed arc are invalidated.
     ///
     ///\warning This functionality cannot be used together with the Snapshot
     ///feature.
-    void reverseArc(Arc e) {
-      Node t=target(e);
-      changeTarget(e,source(e));
-      changeSource(e,t);
-    }
-
-    /// Reserve memory for nodes.
-
-    /// Using this function it is possible to avoid the superfluous memory
-    /// allocation: if you know that the digraph you want to build will
-    /// be very large (e.g. it will contain millions of nodes and/or arcs)
-    /// then it is worth reserving space for this amount before starting
-    /// to build the digraph.
-    /// \sa reserveArc
-    void reserveNode(int n) { nodes.reserve(n); };
-
-    /// Reserve memory for arcs.
-
-    /// Using this function it is possible to avoid the superfluous memory
-    /// allocation: if you know that the digraph you want to build will
-    /// be very large (e.g. it will contain millions of nodes and/or arcs)
-    /// then it is worth reserving space for this amount before starting
-    /// to build the digraph.
-    /// \sa reserveNode
-    void reserveArc(int m) { arcs.reserve(m); };
+    void reverseArc(Arc a) {
+      Node t=target(a);
+      changeTarget(a,source(a));
+      changeSource(a,t);
+    }
 
     ///Contract two nodes.
 
-    ///This function contracts two nodes.
-    ///Node \p b will be removed but instead of deleting
-    ///incident arcs, they will be joined to \p a.
-    ///The last parameter \p r controls whether to remove loops. \c true
-    ///means that loops will be removed.
-    ///
-    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
-    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
-    ///may be invalidated.
+    ///This function contracts the given two nodes.
+    ///Node \c v is removed, but instead of deleting its
+    ///incident arcs, they are joined to node \c u.
+    ///If the last parameter \c r is \c true (this is the default value),
+    ///then the newly created loops are removed.
+    ///
+    ///\note The moved arcs are joined to node \c u using changeSource()
+    ///or changeTarget(), thus \c ArcIt and \c OutArcIt iterators are
+    ///invalidated for the outgoing arcs of node \c v and \c InArcIt
+    ///iterators are invalidated for the incomming arcs of \c v.
+    ///Moreover all iterators referencing node \c v or the removed
+    ///loops are also invalidated. Other iterators remain valid.
     ///
     ///\warning This functionality cannot be used together with the Snapshot
     ///feature.
-    void contract(Node a, Node b, bool r = true)
+    void contract(Node u, Node v, bool r = true)
     {
-      for(OutArcIt e(*this,b);e!=INVALID;) {
+      for(OutArcIt e(*this,v);e!=INVALID;) {
         OutArcIt f=e;
         ++f;
-        if(r && target(e)==a) erase(e);
-        else changeSource(e,a);
+        if(r && target(e)==u) erase(e);
+        else changeSource(e,u);
         e=f;
       }
-      for(InArcIt e(*this,b);e!=INVALID;) {
+      for(InArcIt e(*this,v);e!=INVALID;) {
         InArcIt f=e;
         ++f;
-        if(r && source(e)==a) erase(e);
-        else changeTarget(e,a);
+        if(r && source(e)==u) erase(e);
+        else changeTarget(e,u);
         e=f;
       }
-      erase(b);
+      erase(v);
     }
 
     ///Split a node.
 
-    ///This function splits a node. First a new node is added to the digraph,
-    ///then the source of each outgoing arc of \c n is moved to this new node.
-    ///If \c connect is \c true (this is the default value), then a new arc
-    ///from \c n to the newly created node is also added.
+    ///This function splits the given node. First, a new node is added
+    ///to the digraph, then the source of each outgoing arc of node \c n
+    ///is moved to this new node.
+    ///If the second parameter \c connect is \c true (this is the default
+    ///value), then a new arc from node \c n to the newly created node
+    ///is also added.
     ///\return The newly created node.
     ///
-    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
-    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
-    ///be invalidated.
-    ///
-    ///\warning This functionality cannot be used in conjunction with the
+    ///\note All iterators remain valid.
+    ///
+    ///\warning This functionality cannot be used together with the
     ///Snapshot feature.
     Node split(Node n, bool connect = true) {
       Node b = addNode();
-      for(OutArcIt e(*this,n);e!=INVALID;) {
-        OutArcIt f=e;
-        ++f;
-        changeSource(e,b);
-        e=f;
+      nodes[b.id].first_out=nodes[n.id].first_out;
+      nodes[n.id].first_out=-1;
+      for(int i=nodes[b.id].first_out; i!=-1; i=arcs[i].next_out) {
+        arcs[i].source=b.id;
       }
       if (connect) addArc(n,b);
@@ -518,18 +498,50 @@
     ///Split an arc.
 
-    ///This function splits an arc. First a new node \c b is added to
-    ///the digraph, then the original arc is re-targeted to \c
-    ///b. Finally an arc from \c b to the original target is added.
-    ///
+    ///This function splits the given arc. First, a new node \c v is
+    ///added to the digraph, then the target node of the original arc
+    ///is set to \c v. Finally, an arc from \c v to the original target
+    ///is added.
     ///\return The newly created node.
+    ///
+    ///\note \c InArcIt iterators referencing the original arc are
+    ///invalidated. Other iterators remain valid.
     ///
     ///\warning This functionality cannot be used together with the
     ///Snapshot feature.
-    Node split(Arc e) {
-      Node b = addNode();
-      addArc(b,target(e));
-      changeTarget(e,b);
-      return b;
-    }
+    Node split(Arc a) {
+      Node v = addNode();
+      addArc(v,target(a));
+      changeTarget(a,v);
+      return v;
+    }
+
+    ///Clear the digraph.
+
+    ///This function erases all nodes and arcs from the digraph.
+    ///
+    ///\note All iterators of the digraph are invalidated, of course.
+    void clear() {
+      Parent::clear();
+    }
+
+    /// Reserve memory for nodes.
+
+    /// Using this function, it is possible to avoid superfluous memory
+    /// allocation: if you know that the digraph you want to build will
+    /// be large (e.g. it will contain millions of nodes and/or arcs),
+    /// then it is worth reserving space for this amount before starting
+    /// to build the digraph.
+    /// \sa reserveArc()
+    void reserveNode(int n) { nodes.reserve(n); };
+
+    /// Reserve memory for arcs.
+
+    /// Using this function, it is possible to avoid superfluous memory
+    /// allocation: if you know that the digraph you want to build will
+    /// be large (e.g. it will contain millions of nodes and/or arcs),
+    /// then it is worth reserving space for this amount before starting
+    /// to build the digraph.
+    /// \sa reserveNode()
+    void reserveArc(int m) { arcs.reserve(m); };
 
     /// \brief Class to make a snapshot of the digraph and restore
@@ -541,7 +553,13 @@
     /// restore() function.
     ///
-    /// \warning Arc and node deletions and other modifications (e.g.
-    /// contracting, splitting, reversing arcs or nodes) cannot be
+    /// \note After a state is restored, you cannot restore a later state,
+    /// i.e. you cannot add the removed nodes and arcs again using
+    /// another Snapshot instance.
+    ///
+    /// \warning Node and arc deletions and other modifications (e.g.
+    /// reversing, contracting, splitting arcs or nodes) cannot be
     /// restored. These events invalidate the snapshot.
+    /// However, the arcs and nodes that were added to the digraph after
+    /// making the current snapshot can be removed without invalidating it.
     class Snapshot {
     protected:
@@ -565,5 +583,5 @@
         }
         virtual void add(const std::vector<Node>& nodes) {
-          for (int i = nodes.size() - 1; i >= 0; ++i) {
+          for (int i = nodes.size() - 1; i >= 0; --i) {
             snapshot.addNode(nodes[i]);
           }
@@ -615,5 +633,5 @@
         }
         virtual void add(const std::vector<Arc>& arcs) {
-          for (int i = arcs.size() - 1; i >= 0; ++i) {
+          for (int i = arcs.size() - 1; i >= 0; --i) {
             snapshot.addArc(arcs[i]);
           }
@@ -713,5 +731,5 @@
       ///
       /// Default constructor.
-      /// To actually make a snapshot you must call save().
+      /// You have to call save() to actually make a snapshot.
       Snapshot()
         : digraph(0), node_observer_proxy(*this),
@@ -720,30 +738,31 @@
       /// \brief Constructor that immediately makes a snapshot.
       ///
-      /// This constructor immediately makes a snapshot of the digraph.
-      /// \param _digraph The digraph we make a snapshot of.
-      Snapshot(ListDigraph &_digraph)
+      /// This constructor immediately makes a snapshot of the given digraph.
+      Snapshot(ListDigraph &gr)
         : node_observer_proxy(*this),
           arc_observer_proxy(*this) {
-        attach(_digraph);
+        attach(gr);
       }
 
       /// \brief Make a snapshot.
       ///
-      /// Make a snapshot of the digraph.
-      ///
-      /// This function can be called more than once. In case of a repeated
+      /// This function makes a snapshot of the given digraph.
+      /// It can be called more than once. In case of a repeated
       /// call, the previous snapshot gets lost.
-      /// \param _digraph The digraph we make the snapshot of.
-      void save(ListDigraph &_digraph) {
+      void save(ListDigraph &gr) {
         if (attached()) {
           detach();
           clear();
         }
-        attach(_digraph);
+        attach(gr);
       }
 
       /// \brief Undo the changes until the last snapshot.
-      //
-      /// Undo the changes until the last snapshot created by save().
+      ///
+      /// This function undos the changes until the last snapshot
+      /// created by save() or Snapshot(ListDigraph&).
+      ///
+      /// \warning This method invalidates the snapshot, i.e. repeated
+      /// restoring is not supported unless you call save() again.
       void restore() {
         detach();
@@ -759,7 +778,7 @@
       }
 
-      /// \brief Gives back true when the snapshot is valid.
+      /// \brief Returns \c true if the snapshot is valid.
       ///
-      /// Gives back true when the snapshot is valid.
+      /// This function returns \c true if the snapshot is valid.
       bool valid() const {
         return attached();
@@ -797,9 +816,5 @@
   public:
 
-    typedef ListGraphBase Digraph;
-
-    class Node;
-    class Arc;
-    class Edge;
+    typedef ListGraphBase Graph;
 
     class Node {
@@ -851,6 +866,4 @@
       bool operator<(const Arc& arc) const {return id < arc.id;}
     };
-
-
 
     ListGraphBase()
@@ -1168,30 +1181,25 @@
   ///A general undirected graph structure.
 
-  ///\ref ListGraph is a simple and fast <em>undirected graph</em>
-  ///implementation based on static linked lists that are stored in
+  ///\ref ListGraph is a versatile and fast undirected graph
+  ///implementation based on linked lists that are stored in
   ///\c std::vector structures.
   ///
-  ///It conforms to the \ref concepts::Graph "Graph concept" and it
-  ///also provides several useful additional functionalities.
-  ///Most of the member functions and nested classes are documented
+  ///This type fully conforms to the \ref concepts::Graph "Graph concept"
+  ///and it also provides several useful additional functionalities.
+  ///Most of its member functions and nested classes are documented
   ///only in the concept class.
   ///
-  ///An important extra feature of this graph implementation is that
-  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
+  ///This class provides only linear time counting for nodes, edges and arcs.
   ///
   ///\sa concepts::Graph
-
+  ///\sa ListDigraph
   class ListGraph : public ExtendedListGraphBase {
+    typedef ExtendedListGraphBase Parent;
+
   private:
-    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
-
-    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
-    ///
+    /// Graphs are \e not copy constructible. Use GraphCopy instead.
     ListGraph(const ListGraph &) :ExtendedListGraphBase()  {};
-    ///\brief Assignment of ListGraph to another one is \e not allowed.
-    ///Use copyGraph() instead.
-
-    ///Assignment of ListGraph to another one is \e not allowed.
-    ///Use copyGraph() instead.
+    /// \brief Assignment of a graph to another one is \e not allowed.
+    /// Use GraphCopy instead.
     void operator=(const ListGraph &) {}
   public:
@@ -1202,11 +1210,9 @@
     ListGraph() {}
 
-    typedef ExtendedListGraphBase Parent;
-
     typedef Parent::OutArcIt IncEdgeIt;
 
     /// \brief Add a new node to the graph.
     ///
-    /// Add a new node to the graph.
+    /// This function adds a new node to the graph.
     /// \return The new node.
     Node addNode() { return Parent::addNode(); }
@@ -1214,57 +1220,60 @@
     /// \brief Add a new edge to the graph.
     ///
-    /// Add a new edge to the graph with source node \c s
-    /// and target node \c t.
+    /// This function adds a new edge to the graph between nodes
+    /// \c u and \c v with inherent orientation from node \c u to
+    /// node \c v.
     /// \return The new edge.
-    Edge addEdge(const Node& s, const Node& t) {
-      return Parent::addEdge(s, t);
-    }
-
-    /// \brief Erase a node from the graph.
-    ///
-    /// Erase a node from the graph.
-    ///
-    void erase(const Node& n) { Parent::erase(n); }
-
-    /// \brief Erase an edge from the graph.
-    ///
-    /// Erase an edge from the graph.
-    ///
-    void erase(const Edge& e) { Parent::erase(e); }
+    Edge addEdge(Node u, Node v) {
+      return Parent::addEdge(u, v);
+    }
+
+    ///\brief Erase a node from the graph.
+    ///
+    /// This function erases the given node along with its incident arcs
+    /// from the graph.
+    ///
+    /// \note All iterators referencing the removed node or the incident
+    /// edges are invalidated, of course.
+    void erase(Node n) { Parent::erase(n); }
+
+    ///\brief Erase an edge from the graph.
+    ///
+    /// This function erases the given edge from the graph.
+    ///
+    /// \note All iterators referencing the removed edge are invalidated,
+    /// of course.
+    void erase(Edge e) { Parent::erase(e); }
     /// Node validity check
 
-    /// This function gives back true if the given node is valid,
-    /// ie. it is a real node of the graph.
-    ///
-    /// \warning A Node pointing to a removed item
-    /// could become valid again later if new nodes are
+    /// This function gives back \c true if the given node is valid,
+    /// i.e. it is a real node of the graph.
+    ///
+    /// \warning A removed node could become valid again if new nodes are
     /// added to the graph.
     bool valid(Node n) const { return Parent::valid(n); }
+    /// Edge validity check
+
+    /// This function gives back \c true if the given edge is valid,
+    /// i.e. it is a real edge of the graph.
+    ///
+    /// \warning A removed edge could become valid again if new edges are
+    /// added to the graph.
+    bool valid(Edge e) const { return Parent::valid(e); }
     /// Arc validity check
 
-    /// This function gives back true if the given arc is valid,
-    /// ie. it is a real arc of the graph.
-    ///
-    /// \warning An Arc pointing to a removed item
-    /// could become valid again later if new edges are
+    /// This function gives back \c true if the given arc is valid,
+    /// i.e. it is a real arc of the graph.
+    ///
+    /// \warning A removed arc could become valid again if new edges are
     /// added to the graph.
     bool valid(Arc a) const { return Parent::valid(a); }
-    /// Edge validity check
-
-    /// This function gives back true if the given edge is valid,
-    /// ie. it is a real arc of the graph.
-    ///
-    /// \warning A Edge pointing to a removed item
-    /// could become valid again later if new edges are
-    /// added to the graph.
-    bool valid(Edge e) const { return Parent::valid(e); }
-    /// \brief Change the end \c u of \c e to \c n
-    ///
-    /// This function changes the end \c u of \c e to node \c n.
-    ///
-    ///\note The <tt>EdgeIt</tt>s and <tt>ArcIt</tt>s referencing the
-    ///changed edge are invalidated and if the changed node is the
-    ///base node of an iterator then this iterator is also
-    ///invalidated.
+
+    /// \brief Change the first node of an edge.
+    ///
+    /// This function changes the first node of the given edge \c e to \c n.
+    ///
+    ///\note \c EdgeIt and \c ArcIt iterators referencing the
+    ///changed edge are invalidated and all other iterators whose
+    ///base node is the changed node are also invalidated.
     ///
     ///\warning This functionality cannot be used together with the
@@ -1273,11 +1282,12 @@
       Parent::changeU(e,n);
     }
-    /// \brief Change the end \c v of \c e to \c n
-    ///
-    /// This function changes the end \c v of \c e to \c n.
-    ///
-    ///\note The <tt>EdgeIt</tt>s referencing the changed edge remain
-    ///valid, however <tt>ArcIt</tt>s and if the changed node is the
-    ///base node of an iterator then this iterator is invalidated.
+    /// \brief Change the second node of an edge.
+    ///
+    /// This function changes the second node of the given edge \c e to \c n.
+    ///
+    ///\note \c EdgeIt iterators referencing the changed edge remain
+    ///valid, but \c ArcIt iterators referencing the changed edge and
+    ///all other iterators whose base node is the changed node are also
+    ///invalidated.
     ///
     ///\warning This functionality cannot be used together with the
@@ -1286,14 +1296,18 @@
       Parent::changeV(e,n);
     }
+
     /// \brief Contract two nodes.
     ///
-    /// This function contracts two nodes.
-    /// Node \p b will be removed but instead of deleting
-    /// its neighboring arcs, they will be joined to \p a.
-    /// The last parameter \p r controls whether to remove loops. \c true
-    /// means that loops will be removed.
-    ///
-    /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
-    /// valid.
+    /// This function contracts the given two nodes.
+    /// Node \c b is removed, but instead of deleting
+    /// its incident edges, they are joined to node \c a.
+    /// If the last parameter \c r is \c true (this is the default value),
+    /// then the newly created loops are removed.
+    ///
+    /// \note The moved edges are joined to node \c a using changeU()
+    /// or changeV(), thus all edge and arc iterators whose base node is
+    /// \c b are invalidated.
+    /// Moreover all iterators referencing node \c b or the removed
+    /// loops are also invalidated. Other iterators remain valid.
     ///
     ///\warning This functionality cannot be used together with the
@@ -1314,4 +1328,32 @@
     }
 
+    ///Clear the graph.
+
+    ///This function erases all nodes and arcs from the graph.
+    ///
+    ///\note All iterators of the graph are invalidated, of course.
+    void clear() {
+      Parent::clear();
+    }
+
+    /// Reserve memory for nodes.
+
+    /// Using this function, it is possible to avoid superfluous memory
+    /// allocation: if you know that the graph you want to build will
+    /// be large (e.g. it will contain millions of nodes and/or edges),
+    /// then it is worth reserving space for this amount before starting
+    /// to build the graph.
+    /// \sa reserveEdge()
+    void reserveNode(int n) { nodes.reserve(n); };
+
+    /// Reserve memory for edges.
+
+    /// Using this function, it is possible to avoid superfluous memory
+    /// allocation: if you know that the graph you want to build will
+    /// be large (e.g. it will contain millions of nodes and/or edges),
+    /// then it is worth reserving space for this amount before starting
+    /// to build the graph.
+    /// \sa reserveNode()
+    void reserveEdge(int m) { arcs.reserve(2 * m); };
 
     /// \brief Class to make a snapshot of the graph and restore
@@ -1323,7 +1365,13 @@
     /// using the restore() function.
     ///
-    /// \warning Edge and node deletions and other modifications
-    /// (e.g. changing nodes of edges, contracting nodes) cannot be
-    /// restored. These events invalidate the snapshot.
+    /// \note After a state is restored, you cannot restore a later state,
+    /// i.e. you cannot add the removed nodes and edges again using
+    /// another Snapshot instance.
+    ///
+    /// \warning Node and edge deletions and other modifications
+    /// (e.g. changing the end-nodes of edges or contracting nodes)
+    /// cannot be restored. These events invalidate the snapshot.
+    /// However, the edges and nodes that were added to the graph after
+    /// making the current snapshot can be removed without invalidating it.
     class Snapshot {
     protected:
@@ -1347,5 +1395,5 @@
         }
         virtual void add(const std::vector<Node>& nodes) {
-          for (int i = nodes.size() - 1; i >= 0; ++i) {
+          for (int i = nodes.size() - 1; i >= 0; --i) {
             snapshot.addNode(nodes[i]);
           }
@@ -1397,5 +1445,5 @@
         }
         virtual void add(const std::vector<Edge>& edges) {
-          for (int i = edges.size() - 1; i >= 0; ++i) {
+          for (int i = edges.size() - 1; i >= 0; --i) {
             snapshot.addEdge(edges[i]);
           }
@@ -1495,5 +1543,5 @@
       ///
       /// Default constructor.
-      /// To actually make a snapshot you must call save().
+      /// You have to call save() to actually make a snapshot.
       Snapshot()
         : graph(0), node_observer_proxy(*this),
@@ -1502,30 +1550,31 @@
       /// \brief Constructor that immediately makes a snapshot.
       ///
-      /// This constructor immediately makes a snapshot of the graph.
-      /// \param _graph The graph we make a snapshot of.
-      Snapshot(ListGraph &_graph)
+      /// This constructor immediately makes a snapshot of the given graph.
+      Snapshot(ListGraph &gr)
         : node_observer_proxy(*this),
           edge_observer_proxy(*this) {
-        attach(_graph);
+        attach(gr);
       }
 
       /// \brief Make a snapshot.
       ///
-      /// Make a snapshot of the graph.
-      ///
-      /// This function can be called more than once. In case of a repeated
+      /// This function makes a snapshot of the given graph.
+      /// It can be called more than once. In case of a repeated
       /// call, the previous snapshot gets lost.
-      /// \param _graph The graph we make the snapshot of.
-      void save(ListGraph &_graph) {
+      void save(ListGraph &gr) {
         if (attached()) {
           detach();
           clear();
         }
-        attach(_graph);
+        attach(gr);
       }
 
       /// \brief Undo the changes until the last snapshot.
-      //
-      /// Undo the changes until the last snapshot created by save().
+      ///
+      /// This function undos the changes until the last snapshot
+      /// created by save() or Snapshot(ListGraph&).
+      ///
+      /// \warning This method invalidates the snapshot, i.e. repeated
+      /// restoring is not supported unless you call save() again.
       void restore() {
         detach();
@@ -1541,7 +1590,7 @@
       }
 
-      /// \brief Gives back true when the snapshot is valid.
+      /// \brief Returns \c true if the snapshot is valid.
       ///
-      /// Gives back true when the snapshot is valid.
+      /// This function returns \c true if the snapshot is valid.
       bool valid() const {
         return attached();
Index: lemon/lp.h
===================================================================
--- lemon/lp.h	(revision 462)
+++ lemon/lp.h	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -23,11 +23,11 @@
 
 
-#ifdef HAVE_GLPK
+#ifdef LEMON_HAVE_GLPK
 #include <lemon/glpk.h>
-#elif HAVE_CPLEX
+#elif LEMON_HAVE_CPLEX
 #include <lemon/cplex.h>
-#elif HAVE_SOPLEX
+#elif LEMON_HAVE_SOPLEX
 #include <lemon/soplex.h>
-#elif HAVE_CLP
+#elif LEMON_HAVE_CLP
 #include <lemon/clp.h>
 #endif
@@ -70,20 +70,20 @@
   typedef GlpkMip Mip;
 #else
-#ifdef HAVE_GLPK
+#ifdef LEMON_HAVE_GLPK
 # define LEMON_DEFAULT_LP GLPK
   typedef GlpkLp Lp;
 # define LEMON_DEFAULT_MIP GLPK
   typedef GlpkMip Mip;
-#elif HAVE_CPLEX
+#elif LEMON_HAVE_CPLEX
 # define LEMON_DEFAULT_LP CPLEX
   typedef CplexLp Lp;
 # define LEMON_DEFAULT_MIP CPLEX
   typedef CplexMip Mip;
-#elif HAVE_SOPLEX
+#elif LEMON_HAVE_SOPLEX
 # define DEFAULT_LP SOPLEX
   typedef SoplexLp Lp;
-#elif HAVE_CLP
+#elif LEMON_HAVE_CLP
 # define DEFAULT_LP CLP
-  typedef ClpLp Lp;  
+  typedef ClpLp Lp;
 #endif
 #endif
Index: lemon/lp_base.cc
===================================================================
--- lemon/lp_base.cc	(revision 510)
+++ lemon/lp_base.cc	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: lemon/lp_base.h
===================================================================
--- lemon/lp_base.h	(revision 540)
+++ lemon/lp_base.h	(revision 966)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2011
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -53,10 +53,10 @@
     ///Possible outcomes of an LP solving procedure
     enum SolveExitStatus {
-      ///This means that the problem has been successfully solved: either
+      /// = 0. It 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)
+      /// = 1. Any other case (including the case when some user specified
+      ///limit has been exceeded).
       UNSOLVED = 1
     };
@@ -69,4 +69,19 @@
       MAX
     };
+
+    ///Enum for \c messageLevel() parameter
+    enum MessageLevel {
+      /// No output (default value).
+      MESSAGE_NOTHING,
+      /// Error messages only.
+      MESSAGE_ERROR,
+      /// Warnings.
+      MESSAGE_WARNING,
+      /// Normal output.
+      MESSAGE_NORMAL,
+      /// Verbose output.
+      MESSAGE_VERBOSE
+    };
+
 
     ///The floating point type used by the solver
@@ -100,12 +115,12 @@
       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.      
+      /// \sa Invalid for more details.
       Col(const Invalid&) : _id(-1) {}
       /// Equality operator
@@ -132,5 +147,5 @@
     ///Iterator for iterate over the columns of an LP problem
 
-    /// Its usage is quite simple, for example you can count the number
+    /// Its usage is quite simple, for example, you can count the number
     /// of columns in an LP \c lp:
     ///\code
@@ -142,10 +157,10 @@
     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.
       ///
@@ -155,10 +170,10 @@
       }
       /// 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.
       ///
@@ -195,12 +210,12 @@
       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.      
+      /// \sa Invalid for more details.
       Row(const Invalid&) : _id(-1) {}
       /// Equality operator
@@ -210,5 +225,5 @@
       bool operator==(Row r) const  {return _id == r._id;}
       /// Inequality operator
-      
+
       /// \sa operator==(Row r)
       ///
@@ -227,5 +242,5 @@
     ///Iterator for iterate over the rows of an LP problem
 
-    /// Its usage is quite simple, for example you can count the number
+    /// Its usage is quite simple, for example, you can count the number
     /// of rows in an LP \c lp:
     ///\code
@@ -237,10 +252,10 @@
     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.
       ///
@@ -250,10 +265,10 @@
       }
       /// 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.
       ///
@@ -333,5 +348,5 @@
       typedef True SolverExpr;
       /// Default constructor
-      
+
       /// Construct an empty expression, the coefficients and
       /// the constant component are initialized to zero.
@@ -434,7 +449,7 @@
 
       ///Iterator over the expression
-      
-      ///The iterator iterates over the terms of the expression. 
-      /// 
+
+      ///The iterator iterates over the terms of the expression.
+      ///
       ///\code
       ///double s=0;
@@ -450,5 +465,5 @@
 
         /// Sets the iterator to the first term
-        
+
         /// Sets the iterator to the first term of the expression.
         ///
@@ -467,5 +482,5 @@
         const Value& operator*() const { return _it->second; }
         /// Next term
-        
+
         /// Assign the iterator to the next term.
         ///
@@ -479,7 +494,7 @@
 
       /// Const iterator over the expression
-      
-      ///The iterator iterates over the terms of the expression. 
-      /// 
+
+      ///The iterator iterates over the terms of the expression.
+      ///
       ///\code
       ///double s=0;
@@ -495,5 +510,5 @@
 
         /// Sets the iterator to the first term
-        
+
         /// Sets the iterator to the first term of the expression.
         ///
@@ -510,5 +525,5 @@
 
         /// Next term
-        
+
         /// Assign the iterator to the next term.
         ///
@@ -659,5 +674,5 @@
       typedef True SolverExpr;
       /// Default constructor
-      
+
       /// Construct an empty expression, the coefficients are
       /// initialized to zero.
@@ -694,5 +709,5 @@
       }
       /// \brief Removes the coefficients which's absolute value does
-      /// not exceed \c epsilon. 
+      /// not exceed \c epsilon.
       void simplify(Value epsilon = 0.0) {
         std::map<int, Value>::iterator it=comps.begin();
@@ -743,7 +758,7 @@
 
       ///Iterator over the expression
-      
-      ///The iterator iterates over the terms of the expression. 
-      /// 
+
+      ///The iterator iterates over the terms of the expression.
+      ///
       ///\code
       ///double s=0;
@@ -759,5 +774,5 @@
 
         /// Sets the iterator to the first term
-        
+
         /// Sets the iterator to the first term of the expression.
         ///
@@ -777,5 +792,5 @@
 
         /// Next term
-        
+
         /// Assign the iterator to the next term.
         ///
@@ -789,7 +804,7 @@
 
       ///Iterator over the expression
-      
-      ///The iterator iterates over the terms of the expression. 
-      /// 
+
+      ///The iterator iterates over the terms of the expression.
+      ///
       ///\code
       ///double s=0;
@@ -805,5 +820,5 @@
 
         /// Sets the iterator to the first term
-        
+
         /// Sets the iterator to the first term of the expression.
         ///
@@ -820,5 +835,5 @@
 
         /// Next term
-        
+
         /// Assign the iterator to the next term.
         ///
@@ -929,4 +944,12 @@
     virtual int _addRow() = 0;
 
+    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
+      int row = _addRow();
+      _setRowCoeffs(row, b, e);
+      _setRowLowerBound(row, l);
+      _setRowUpperBound(row, u);
+      return row;
+    }
+
     virtual void _eraseCol(int col) = 0;
     virtual void _eraseRow(int row) = 0;
@@ -974,4 +997,6 @@
     virtual const char* _solverName() const = 0;
 
+    virtual void _messageLevel(MessageLevel level) = 0;
+
     //Own protected stuff
 
@@ -989,5 +1014,5 @@
     const char* solverName() const {return _solverName();}
 
-    ///\name Build up and modify the LP
+    ///\name Build Up and Modify the LP
 
     ///@{
@@ -1191,6 +1216,8 @@
     ///\return The created row.
     Row addRow(Value l,const Expr &e, Value u) {
-      Row r=addRow();
-      row(r,l,e,u);
+      Row r;
+      e.simplify();
+      r._id = _addRowId(_addRow(l - *e, ExprIterator(e.comps.begin(), cols),
+                                ExprIterator(e.comps.end(), cols), u - *e));
       return r;
     }
@@ -1201,6 +1228,10 @@
     ///\return The created row.
     Row addRow(const Constr &c) {
-      Row r=addRow();
-      row(r,c);
+      Row r;
+      c.expr().simplify();
+      r._id = _addRowId(_addRow(c.lowerBounded()?c.lowerBound()-*c.expr():-INF,
+                                ExprIterator(c.expr().comps.begin(), cols),
+                                ExprIterator(c.expr().comps.end(), cols),
+                                c.upperBounded()?c.upperBound()-*c.expr():INF));
       return r;
     }
@@ -1526,5 +1557,8 @@
 
     ///Clears the problem
-    void clear() { _clear(); }
+    void clear() { _clear(); rows.clear(); cols.clear(); }
+
+    /// Sets the message level of the solver
+    void messageLevel(MessageLevel level) { _messageLevel(level); }
 
     ///@}
@@ -1585,5 +1619,5 @@
   inline LpBase::Constr operator<=(const LpBase::Expr &e,
                                    const LpBase::Expr &f) {
-    return LpBase::Constr(0, f - e, LpBase::INF);
+    return LpBase::Constr(0, f - e, LpBase::NaN);
   }
 
@@ -1603,5 +1637,5 @@
   inline LpBase::Constr operator<=(const LpBase::Expr &e,
                                    const LpBase::Value &f) {
-    return LpBase::Constr(- LpBase::INF, e, f);
+    return LpBase::Constr(LpBase::NaN, e, f);
   }
 
@@ -1612,5 +1646,5 @@
   inline LpBase::Constr operator>=(const LpBase::Expr &e,
                                    const LpBase::Expr &f) {
-    return LpBase::Constr(0, e - f, LpBase::INF);
+    return LpBase::Constr(0, e - f, LpBase::NaN);
   }
 
@@ -1632,5 +1666,5 @@
   inline LpBase::Constr operator>=(const LpBase::Expr &e,
                                    const LpBase::Value &f) {
-    return LpBase::Constr(f, e, LpBase::INF);
+    return LpBase::Constr(f, e, LpBase::NaN);
   }
 
@@ -1769,13 +1803,13 @@
     /// The problem types for primal and dual problems
     enum ProblemType {
-      ///Feasible solution hasn't been found (but may exist).
+      /// = 0. Feasible solution hasn't been found (but may exist).
       UNDEFINED = 0,
-      ///The problem has no feasible solution
+      /// = 1. The problem has no feasible solution.
       INFEASIBLE = 1,
-      ///Feasible solution found
+      /// = 2. Feasible solution found.
       FEASIBLE = 2,
-      ///Optimal solution exists and found
+      /// = 3. Optimal solution exists and found.
       OPTIMAL = 3,
-      ///The cost function is unbounded
+      /// = 4. The cost function is unbounded.
       UNBOUNDED = 4
     };
@@ -1784,8 +1818,8 @@
     enum VarStatus {
       /// The variable is in the basis
-      BASIC, 
+      BASIC,
       /// The variable is free, but not basic
       FREE,
-      /// The variable has active lower bound 
+      /// The variable has active lower bound
       LOWER,
       /// The variable has active upper bound
@@ -1833,5 +1867,5 @@
     ///@}
 
-    ///\name Obtain the solution
+    ///\name Obtain the Solution
 
     ///@{
@@ -1866,5 +1900,5 @@
     }
     /// 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
@@ -1900,5 +1934,5 @@
 
     /// 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
@@ -1955,15 +1989,14 @@
     /// The problem types for MIP problems
     enum ProblemType {
-      ///Feasible solution hasn't been found (but may exist).
+      /// = 0. Feasible solution hasn't been found (but may exist).
       UNDEFINED = 0,
-      ///The problem has no feasible solution
+      /// = 1. The problem has no feasible solution.
       INFEASIBLE = 1,
-      ///Feasible solution found
+      /// = 2. Feasible solution found.
       FEASIBLE = 2,
-      ///Optimal solution exists and found
+      /// = 3. Optimal solution exists and found.
       OPTIMAL = 3,
-      ///The cost function is unbounded
-      ///
-      ///The Mip or at least the relaxed problem is unbounded
+      /// = 4. The cost function is unbounded.
+      ///The Mip or at least the relaxed problem is unbounded.
       UNBOUNDED = 4
     };
@@ -1987,12 +2020,12 @@
     ///@}
 
-    ///\name Setting column type
+    ///\name Set Column Type
     ///@{
 
     ///Possible variable (column) types (e.g. real, integer, binary etc.)
     enum ColTypes {
-      ///Continuous variable (default)
+      /// = 0. Continuous variable (default).
       REAL = 0,
-      ///Integer variable
+      /// = 1. Integer variable.
       INTEGER = 1
     };
@@ -2015,5 +2048,5 @@
     ///@}
 
-    ///\name Obtain the solution
+    ///\name Obtain the Solution
 
     ///@{
@@ -2043,5 +2076,5 @@
     }
     ///The value of the objective function
-    
+
     ///\return
     ///- \ref INF or -\ref INF means either infeasibility or unboundedness
Index: lemon/lp_skeleton.cc
===================================================================
--- lemon/lp_skeleton.cc	(revision 540)
+++ lemon/lp_skeleton.cc	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -29,4 +29,9 @@
 
   int SkeletonSolverBase::_addRow()
+  {
+    return ++row_num;
+  }
+
+  int SkeletonSolverBase::_addRow(Value, ExprIterator, ExprIterator, Value)
   {
     return ++row_num;
@@ -85,4 +90,6 @@
   }
 
+  void SkeletonSolverBase::_messageLevel(MessageLevel) {}
+
   LpSkeleton::SolveExitStatus LpSkeleton::_solve() { return SOLVED; }
 
Index: lemon/lp_skeleton.h
===================================================================
--- lemon/lp_skeleton.h	(revision 541)
+++ lemon/lp_skeleton.h	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -24,5 +24,5 @@
 ///\file
 ///\brief Skeleton file to implement LP/MIP solver interfaces
-///  
+///
 ///The classes in this file do nothing, but they can serve as skeletons when
 ///implementing an interface to new solvers.
@@ -30,5 +30,5 @@
 
   ///A skeleton class to implement LP/MIP solver base interface
-  
+
   ///This class does nothing, but it can serve as a skeleton when
   ///implementing an interface to new solvers.
@@ -46,4 +46,6 @@
     virtual int _addRow();
     /// \e
+    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
+    /// \e
     virtual void _eraseCol(int i);
     /// \e
@@ -141,4 +143,6 @@
     virtual void _clear();
 
+    ///\e
+    virtual void _messageLevel(MessageLevel);
   };
 
Index: lemon/maps.h
===================================================================
--- lemon/maps.h	(revision 559)
+++ lemon/maps.h	(revision 927)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2011
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -23,4 +23,5 @@
 #include <functional>
 #include <vector>
+#include <map>
 
 #include <lemon/core.h>
@@ -29,6 +30,4 @@
 ///\ingroup maps
 ///\brief Miscellaneous property maps
-
-#include <map>
 
 namespace lemon {
@@ -58,5 +57,5 @@
   /// but data written to it is not required (i.e. it will be sent to
   /// <tt>/dev/null</tt>).
-  /// It conforms the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+  /// It conforms to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
   ///
   /// \sa ConstMap
@@ -91,5 +90,5 @@
   ///
   /// In other aspects it is equivalent to \c NullMap.
-  /// So it conforms the \ref concepts::ReadWriteMap "ReadWriteMap"
+  /// So it conforms to the \ref concepts::ReadWriteMap "ReadWriteMap"
   /// concept, but it absorbs the data written to it.
   ///
@@ -160,5 +159,5 @@
   ///
   /// In other aspects it is equivalent to \c NullMap.
-  /// So it conforms the \ref concepts::ReadWriteMap "ReadWriteMap"
+  /// So it conforms to the \ref concepts::ReadWriteMap "ReadWriteMap"
   /// concept, but it absorbs the data written to it.
   ///
@@ -232,7 +231,7 @@
   /// This map is essentially a wrapper for \c std::vector. It assigns
   /// values to integer keys from the range <tt>[0..size-1]</tt>.
-  /// It can be used with some data structures, for example
-  /// \c UnionFind, \c BinHeap, when the used items are small
-  /// integers. This map conforms the \ref concepts::ReferenceMap
+  /// It can be used together with some data structures, e.g.
+  /// heap types and \c UnionFind, when the used items are small
+  /// integers. This map conforms to the \ref concepts::ReferenceMap
   /// "ReferenceMap" concept.
   ///
@@ -342,5 +341,5 @@
   /// stored actually. This value can be different from the default
   /// contructed value (i.e. \c %Value()).
-  /// This type conforms the \ref concepts::ReferenceMap "ReferenceMap"
+  /// This type conforms to the \ref concepts::ReferenceMap "ReferenceMap"
   /// concept.
   ///
@@ -350,7 +349,7 @@
   /// The name of this type also refers to this important usage.
   ///
-  /// Apart form that this map can be used in many other cases since it
+  /// Apart form that, this map can be used in many other cases since it
   /// is based on \c std::map, which is a general associative container.
-  /// However keep in mind that it is usually not as efficient as other
+  /// However, keep in mind that it is usually not as efficient as other
   /// maps.
   ///
@@ -708,5 +707,5 @@
   /// The \c Key type of it is inherited from \c M and the \c Value
   /// type is \c V.
-  /// This type conforms the \ref concepts::ReadMap "ReadMap" concept.
+  /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
   ///
   /// The simplest way of using this map is through the convertMap()
@@ -1787,13 +1786,13 @@
   /// The most important usage of it is storing certain nodes or arcs
   /// that were marked \c true by an algorithm.
-  /// For example it makes easier to store the nodes in the processing
+  /// For example, it makes easier to store the nodes in the processing
   /// order of Dfs algorithm, as the following examples show.
   /// \code
   ///   std::vector<Node> v;
-  ///   dfs(g,s).processedMap(loggerBoolMap(std::back_inserter(v))).run();
+  ///   dfs(g).processedMap(loggerBoolMap(std::back_inserter(v))).run(s);
   /// \endcode
   /// \code
   ///   std::vector<Node> v(countNodes(g));
-  ///   dfs(g,s).processedMap(loggerBoolMap(v.begin())).run();
+  ///   dfs(g).processedMap(loggerBoolMap(v.begin())).run(s);
   /// \endcode
   ///
@@ -1802,5 +1801,5 @@
   ///
   /// \note LoggerBoolMap is just \ref concepts::WriteMap "writable", so
-  /// it cannot be used when a readable map is needed, for example as
+  /// it cannot be used when a readable map is needed, for example, as
   /// \c ReachedMap for \c Bfs, \c Dfs and \c Dijkstra algorithms.
   ///
@@ -1819,5 +1818,5 @@
   ///
   /// IdMap provides a unique and immutable id for each item of the
-  /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is 
+  /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is
   ///  - \b unique: different items get different ids,
   ///  - \b immutable: the id of an item does not change (even if you
@@ -1827,5 +1826,5 @@
   /// the items stored in the graph, which is returned by the \c id()
   /// function of the graph. This map can be inverted with its member
-  /// class \c InverseMap or with the \c operator() member.
+  /// class \c InverseMap or with the \c operator()() member.
   ///
   /// \tparam GR The graph type.
@@ -1833,5 +1832,5 @@
   /// \c GR::Edge).
   ///
-  /// \see DescriptorMap
+  /// \see RangeIdMap
   template <typename GR, typename K>
   class IdMap : public MapBase<K, int> {
@@ -1839,4 +1838,5 @@
     /// The graph type of IdMap.
     typedef GR Graph;
+    typedef GR Digraph;
     /// The key type of IdMap (\c Node, \c Arc or \c Edge).
     typedef K Item;
@@ -1866,7 +1866,9 @@
   public:
 
-    /// \brief This class represents the inverse of its owner (IdMap).
-    ///
-    /// This class represents the inverse of its owner (IdMap).
+    /// \brief The inverse map type of IdMap.
+    ///
+    /// The inverse map type of IdMap. The subscript operator gives back
+    /// an item by its id.
+    /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
     /// \see inverse()
     class InverseMap {
@@ -1883,7 +1885,7 @@
       explicit InverseMap(const IdMap& map) : _graph(map._graph) {}
 
-      /// \brief Gives back the given item from its id.
+      /// \brief Gives back an item by its id.
       ///
-      /// Gives back the given item from its id.
+      /// Gives back an item by its id.
       Item operator[](int id) const { return _graph->fromId(id, Item());}
 
@@ -1898,14 +1900,32 @@
   };
 
-
-  /// \brief General invertable graph map type.
+  /// \brief Returns an \c IdMap class.
+  ///
+  /// This function just returns an \c IdMap class.
+  /// \relates IdMap
+  template <typename K, typename GR>
+  inline IdMap<GR, K> idMap(const GR& graph) {
+    return IdMap<GR, K>(graph);
+  }
+
+  /// \brief General cross reference graph map type.
 
   /// This class provides simple invertable graph maps.
-  /// It wraps an arbitrary \ref concepts::ReadWriteMap "ReadWriteMap"
-  /// and if a key is set to a new value then store it
-  /// in the inverse map.
-  ///
-  /// The values of the map can be accessed
-  /// with stl compatible forward iterator.
+  /// It wraps a standard graph map (\c NodeMap, \c ArcMap or \c EdgeMap)
+  /// and if a key is set to a new value, then stores it in the inverse map.
+  /// The graph items can be accessed by their values either using
+  /// \c InverseMap or \c operator()(), and the values of the map can be
+  /// accessed with an STL compatible forward iterator (\c ValueIt).
+  ///
+  /// This map is intended to be used when all associated values are
+  /// different (the map is actually invertable) or there are only a few
+  /// items with the same value.
+  /// Otherwise consider to use \c IterableValueMap, which is more
+  /// suitable and more efficient for such cases. It provides iterators
+  /// to traverse the items with the same associated value, but
+  /// it does not have \c InverseMap.
+  ///
+  /// This type is not reference map, so it cannot be modified with
+  /// the subscript operator.
   ///
   /// \tparam GR The graph type.
@@ -1916,5 +1936,5 @@
   /// \see IterableValueMap
   template <typename GR, typename K, typename V>
-  class InvertableMap
+  class CrossRefMap
     : protected ItemSetTraits<GR, K>::template Map<V>::Type {
   private:
@@ -1923,50 +1943,60 @@
       template Map<V>::Type Map;
 
-    typedef std::map<V, K> Container;
+    typedef std::multimap<V, K> Container;
     Container _inv_map;
 
   public:
 
-    /// The graph type of InvertableMap.
+    /// The graph type of CrossRefMap.
     typedef GR Graph;
-    /// The key type of InvertableMap (\c Node, \c Arc or \c Edge).
+    typedef GR Digraph;
+    /// The key type of CrossRefMap (\c Node, \c Arc or \c Edge).
     typedef K Item;
-    /// The key type of InvertableMap (\c Node, \c Arc or \c Edge).
+    /// The key type of CrossRefMap (\c Node, \c Arc or \c Edge).
     typedef K Key;
-    /// The value type of InvertableMap.
+    /// The value type of CrossRefMap.
     typedef V Value;
 
     /// \brief Constructor.
     ///
-    /// Construct a new InvertableMap for the given graph.
-    explicit InvertableMap(const Graph& graph) : Map(graph) {}
+    /// Construct a new CrossRefMap for the given graph.
+    explicit CrossRefMap(const Graph& graph) : Map(graph) {}
 
     /// \brief Forward iterator for values.
     ///
-    /// This iterator is an stl compatible forward
+    /// This iterator is an STL compatible forward
     /// iterator on the values of the map. The values can
     /// be accessed in the <tt>[beginValue, endValue)</tt> range.
-    class ValueIterator
+    /// They are considered with multiplicity, so each value is
+    /// traversed for each item it is assigned to.
+    class ValueIt
       : public std::iterator<std::forward_iterator_tag, Value> {
-      friend class InvertableMap;
+      friend class CrossRefMap;
     private:
-      ValueIterator(typename Container::const_iterator _it)
+      ValueIt(typename Container::const_iterator _it)
         : it(_it) {}
     public:
 
-      ValueIterator() {}
-
-      ValueIterator& operator++() { ++it; return *this; }
-      ValueIterator operator++(int) {
-        ValueIterator tmp(*this);
+      /// Constructor
+      ValueIt() {}
+
+      /// \e
+      ValueIt& operator++() { ++it; return *this; }
+      /// \e
+      ValueIt operator++(int) {
+        ValueIt tmp(*this);
         operator++();
         return tmp;
       }
 
+      /// \e
       const Value& operator*() const { return it->first; }
+      /// \e
       const Value* operator->() const { return &(it->first); }
 
-      bool operator==(ValueIterator jt) const { return it == jt.it; }
-      bool operator!=(ValueIterator jt) const { return it != jt.it; }
+      /// \e
+      bool operator==(ValueIt jt) const { return it == jt.it; }
+      /// \e
+      bool operator!=(ValueIt jt) const { return it != jt.it; }
 
     private:
@@ -1974,22 +2004,25 @@
     };
 
+    /// Alias for \c ValueIt
+    typedef ValueIt ValueIterator;
+
     /// \brief Returns an iterator to the first value.
     ///
-    /// Returns an stl compatible iterator to the
+    /// Returns an STL compatible iterator to the
     /// first value of the map. The values of the
     /// map can be accessed in the <tt>[beginValue, endValue)</tt>
     /// range.
-    ValueIterator beginValue() const {
-      return ValueIterator(_inv_map.begin());
+    ValueIt beginValue() const {
+      return ValueIt(_inv_map.begin());
     }
 
     /// \brief Returns an iterator after the last value.
     ///
-    /// Returns an stl compatible iterator after the
+    /// Returns an STL compatible iterator after the
     /// last value of the map. The values of the
     /// map can be accessed in the <tt>[beginValue, endValue)</tt>
     /// range.
-    ValueIterator endValue() const {
-      return ValueIterator(_inv_map.end());
+    ValueIt endValue() const {
+      return ValueIt(_inv_map.end());
     }
 
@@ -1999,9 +2032,13 @@
     void set(const Key& key, const Value& val) {
       Value oldval = Map::operator[](key);
-      typename Container::iterator it = _inv_map.find(oldval);
-      if (it != _inv_map.end() && it->second == key) {
-        _inv_map.erase(it);
-      }
-      _inv_map.insert(make_pair(val, key));
+      typename Container::iterator it;
+      for (it = _inv_map.equal_range(oldval).first;
+           it != _inv_map.equal_range(oldval).second; ++it) {
+        if (it->second == key) {
+          _inv_map.erase(it);
+          break;
+        }
+      }
+      _inv_map.insert(std::make_pair(val, key));
       Map::set(key, val);
     }
@@ -2015,10 +2052,21 @@
     }
 
-    /// \brief Gives back the item by its value.
-    ///
-    /// Gives back the item by its value.
-    Key operator()(const Value& key) const {
-      typename Container::const_iterator it = _inv_map.find(key);
+    /// \brief Gives back an item by its value.
+    ///
+    /// This function gives back an item that is assigned to
+    /// the given value or \c INVALID if no such item exists.
+    /// If there are more items with the same associated value,
+    /// only one of them is returned.
+    Key operator()(const Value& val) const {
+      typename Container::const_iterator it = _inv_map.find(val);
       return it != _inv_map.end() ? it->second : INVALID;
+    }
+
+    /// \brief Returns the number of items with the given value.
+    ///
+    /// This function returns the number of items with the given value
+    /// associated with it.
+    int count(const Value &val) const {
+      return _inv_map.count(val);
     }
 
@@ -2031,7 +2079,11 @@
     virtual void erase(const Key& key) {
       Value val = Map::operator[](key);
-      typename Container::iterator it = _inv_map.find(val);
-      if (it != _inv_map.end() && it->second == key) {
-        _inv_map.erase(it);
+      typename Container::iterator it;
+      for (it = _inv_map.equal_range(val).first;
+           it != _inv_map.equal_range(val).second; ++it) {
+        if (it->second == key) {
+          _inv_map.erase(it);
+          break;
+        }
       }
       Map::erase(key);
@@ -2045,7 +2097,11 @@
       for (int i = 0; i < int(keys.size()); ++i) {
         Value val = Map::operator[](keys[i]);
-        typename Container::iterator it = _inv_map.find(val);
-        if (it != _inv_map.end() && it->second == keys[i]) {
-          _inv_map.erase(it);
+        typename Container::iterator it;
+        for (it = _inv_map.equal_range(val).first;
+             it != _inv_map.equal_range(val).second; ++it) {
+          if (it->second == keys[i]) {
+            _inv_map.erase(it);
+            break;
+          }
         }
       }
@@ -2064,8 +2120,10 @@
   public:
 
-    /// \brief The inverse map type.
-    ///
-    /// The inverse of this map. The subscript operator of the map
-    /// gives back the item that was last assigned to the value.
+    /// \brief The inverse map type of CrossRefMap.
+    ///
+    /// The inverse map type of CrossRefMap. The subscript operator gives
+    /// back an item by its value.
+    /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
+    /// \see inverse()
     class InverseMap {
     public:
@@ -2073,16 +2131,17 @@
       ///
       /// Constructor of the InverseMap.
-      explicit InverseMap(const InvertableMap& inverted)
+      explicit InverseMap(const CrossRefMap& inverted)
         : _inverted(inverted) {}
 
       /// The value type of the InverseMap.
-      typedef typename InvertableMap::Key Value;
+      typedef typename CrossRefMap::Key Value;
       /// The key type of the InverseMap.
-      typedef typename InvertableMap::Value Key;
+      typedef typename CrossRefMap::Value Key;
 
       /// \brief Subscript operator.
       ///
-      /// Subscript operator. It gives back the item
-      /// that was last assigned to the given value.
+      /// Subscript operator. It gives back an item
+      /// that is assigned to the given value or \c INVALID
+      /// if no such item exists.
       Value operator[](const Key& key) const {
         return _inverted(key);
@@ -2090,10 +2149,10 @@
 
     private:
-      const InvertableMap& _inverted;
+      const CrossRefMap& _inverted;
     };
 
-    /// \brief It gives back the read-only inverse map.
-    ///
-    /// It gives back the read-only inverse map.
+    /// \brief Gives back the inverse of the map.
+    ///
+    /// Gives back the inverse of the CrossRefMap.
     InverseMap inverse() const {
       return InverseMap(*this);
@@ -2102,21 +2161,20 @@
   };
 
-  /// \brief Provides a mutable, continuous and unique descriptor for each
-  /// item in a graph.
-  ///
-  /// DescriptorMap provides a unique and continuous (but mutable)
-  /// descriptor (id) for each item of the same type (\c Node, \c Arc or
+  /// \brief Provides continuous and unique id for the
+  /// items of a graph.
+  ///
+  /// RangeIdMap provides a unique and continuous
+  /// id for each item of a given type (\c Node, \c Arc or
   /// \c Edge) in a graph. This id is
   ///  - \b unique: different items get different ids,
   ///  - \b continuous: the range of the ids is the set of integers
   ///    between 0 and \c n-1, where \c n is the number of the items of
-  ///    this type (\c Node, \c Arc or \c Edge). So the id of an item can
-  ///    change if you delete an other item of the same type, i.e. this
-  ///    id is mutable.
+  ///    this type (\c Node, \c Arc or \c Edge).
+  ///  - So, the ids can change when deleting an item of the same type.
   ///
   /// Thus this id is not (necessarily) the same as what can get using
   /// the \c id() function of the graph or \ref IdMap.
   /// This map can be inverted with its member class \c InverseMap,
-  /// or with the \c operator() member.
+  /// or with the \c operator()() member.
   ///
   /// \tparam GR The graph type.
@@ -2126,5 +2184,5 @@
   /// \see IdMap
   template <typename GR, typename K>
-  class DescriptorMap
+  class RangeIdMap
     : protected ItemSetTraits<GR, K>::template Map<int>::Type {
 
@@ -2132,17 +2190,18 @@
 
   public:
-    /// The graph type of DescriptorMap.
+    /// The graph type of RangeIdMap.
     typedef GR Graph;
-    /// The key type of DescriptorMap (\c Node, \c Arc or \c Edge).
+    typedef GR Digraph;
+    /// The key type of RangeIdMap (\c Node, \c Arc or \c Edge).
     typedef K Item;
-    /// The key type of DescriptorMap (\c Node, \c Arc or \c Edge).
+    /// The key type of RangeIdMap (\c Node, \c Arc or \c Edge).
     typedef K Key;
-    /// The value type of DescriptorMap.
+    /// The value type of RangeIdMap.
     typedef int Value;
 
     /// \brief Constructor.
     ///
-    /// Constructor for descriptor map.
-    explicit DescriptorMap(const Graph& gr) : Map(gr) {
+    /// Constructor.
+    explicit RangeIdMap(const Graph& gr) : Map(gr) {
       Item it;
       const typename Map::Notifier* nf = Map::notifier();
@@ -2245,14 +2304,14 @@
     }
 
-    /// \brief Gives back the \e descriptor of the item.
-    ///
-    /// Gives back the mutable and unique \e descriptor of the map.
+    /// \brief Gives back the \e range \e id of the item
+    ///
+    /// Gives back the \e range \e id of the item.
     int operator[](const Item& item) const {
       return Map::operator[](item);
     }
 
-    /// \brief Gives back the item by its descriptor.
-    ///
-    /// Gives back th item by its descriptor.
+    /// \brief Gives back the item belonging to a \e range \e id
+    ///
+    /// Gives back the item belonging to the given \e range \e id.
     Item operator()(int id) const {
       return _inv_map[id];
@@ -2266,7 +2325,9 @@
   public:
 
-    /// \brief The inverse map type of DescriptorMap.
-    ///
-    /// The inverse map type of DescriptorMap.
+    /// \brief The inverse map type of RangeIdMap.
+    ///
+    /// The inverse map type of RangeIdMap. The subscript operator gives
+    /// back an item by its \e range \e id.
+    /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
     class InverseMap {
     public:
@@ -2274,17 +2335,17 @@
       ///
       /// Constructor of the InverseMap.
-      explicit InverseMap(const DescriptorMap& inverted)
+      explicit InverseMap(const RangeIdMap& inverted)
         : _inverted(inverted) {}
 
 
       /// The value type of the InverseMap.
-      typedef typename DescriptorMap::Key Value;
+      typedef typename RangeIdMap::Key Value;
       /// The key type of the InverseMap.
-      typedef typename DescriptorMap::Value Key;
+      typedef typename RangeIdMap::Value Key;
 
       /// \brief Subscript operator.
       ///
       /// Subscript operator. It gives back the item
-      /// that the descriptor currently belongs to.
+      /// that the given \e range \e id currently belongs to.
       Value operator[](const Key& key) const {
         return _inverted(key);
@@ -2299,13 +2360,933 @@
 
     private:
-      const DescriptorMap& _inverted;
+      const RangeIdMap& _inverted;
     };
 
     /// \brief Gives back the inverse of the map.
     ///
-    /// Gives back the inverse of the map.
+    /// Gives back the inverse of the RangeIdMap.
     const InverseMap inverse() const {
       return InverseMap(*this);
     }
+  };
+
+  /// \brief Returns a \c RangeIdMap class.
+  ///
+  /// This function just returns an \c RangeIdMap class.
+  /// \relates RangeIdMap
+  template <typename K, typename GR>
+  inline RangeIdMap<GR, K> rangeIdMap(const GR& graph) {
+    return RangeIdMap<GR, K>(graph);
+  }
+
+  /// \brief Dynamic iterable \c bool map.
+  ///
+  /// This class provides a special graph map type which can store a
+  /// \c bool value for graph items (\c Node, \c Arc or \c Edge).
+  /// For both \c true and \c false values it is possible to iterate on
+  /// the keys mapped to the value.
+  ///
+  /// This type is a reference map, so it can be modified with the
+  /// subscript operator.
+  ///
+  /// \tparam GR The graph type.
+  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
+  /// \c GR::Edge).
+  ///
+  /// \see IterableIntMap, IterableValueMap
+  /// \see CrossRefMap
+  template <typename GR, typename K>
+  class IterableBoolMap
+    : protected ItemSetTraits<GR, K>::template Map<int>::Type {
+  private:
+    typedef GR Graph;
+
+    typedef typename ItemSetTraits<GR, K>::ItemIt KeyIt;
+    typedef typename ItemSetTraits<GR, K>::template Map<int>::Type Parent;
+
+    std::vector<K> _array;
+    int _sep;
+
+  public:
+
+    /// Indicates that the map is reference map.
+    typedef True ReferenceMapTag;
+
+    /// The key type
+    typedef K Key;
+    /// The value type
+    typedef bool Value;
+    /// The const reference type.
+    typedef const Value& ConstReference;
+
+  private:
+
+    int position(const Key& key) const {
+      return Parent::operator[](key);
+    }
+
+  public:
+
+    /// \brief Reference to the value of the map.
+    ///
+    /// This class is similar to the \c bool type. It can be converted to
+    /// \c bool and it provides the same operators.
+    class Reference {
+      friend class IterableBoolMap;
+    private:
+      Reference(IterableBoolMap& map, const Key& key)
+        : _key(key), _map(map) {}
+    public:
+
+      Reference& operator=(const Reference& value) {
+        _map.set(_key, static_cast<bool>(value));
+         return *this;
+      }
+
+      operator bool() const {
+        return static_cast<const IterableBoolMap&>(_map)[_key];
+      }
+
+      Reference& operator=(bool value) {
+        _map.set(_key, value);
+        return *this;
+      }
+      Reference& operator&=(bool value) {
+        _map.set(_key, _map[_key] & value);
+        return *this;
+      }
+      Reference& operator|=(bool value) {
+        _map.set(_key, _map[_key] | value);
+        return *this;
+      }
+      Reference& operator^=(bool value) {
+        _map.set(_key, _map[_key] ^ value);
+        return *this;
+      }
+    private:
+      Key _key;
+      IterableBoolMap& _map;
+    };
+
+    /// \brief Constructor of the map with a default value.
+    ///
+    /// Constructor of the map with a default value.
+    explicit IterableBoolMap(const Graph& graph, bool def = false)
+      : Parent(graph) {
+      typename Parent::Notifier* nf = Parent::notifier();
+      Key it;
+      for (nf->first(it); it != INVALID; nf->next(it)) {
+        Parent::set(it, _array.size());
+        _array.push_back(it);
+      }
+      _sep = (def ? _array.size() : 0);
+    }
+
+    /// \brief Const subscript operator of the map.
+    ///
+    /// Const subscript operator of the map.
+    bool operator[](const Key& key) const {
+      return position(key) < _sep;
+    }
+
+    /// \brief Subscript operator of the map.
+    ///
+    /// Subscript operator of the map.
+    Reference operator[](const Key& key) {
+      return Reference(*this, key);
+    }
+
+    /// \brief Set operation of the map.
+    ///
+    /// Set operation of the map.
+    void set(const Key& key, bool value) {
+      int pos = position(key);
+      if (value) {
+        if (pos < _sep) return;
+        Key tmp = _array[_sep];
+        _array[_sep] = key;
+        Parent::set(key, _sep);
+        _array[pos] = tmp;
+        Parent::set(tmp, pos);
+        ++_sep;
+      } else {
+        if (pos >= _sep) return;
+        --_sep;
+        Key tmp = _array[_sep];
+        _array[_sep] = key;
+        Parent::set(key, _sep);
+        _array[pos] = tmp;
+        Parent::set(tmp, pos);
+      }
+    }
+
+    /// \brief Set all items.
+    ///
+    /// Set all items in the map.
+    /// \note Constant time operation.
+    void setAll(bool value) {
+      _sep = (value ? _array.size() : 0);
+    }
+
+    /// \brief Returns the number of the keys mapped to \c true.
+    ///
+    /// Returns the number of the keys mapped to \c true.
+    int trueNum() const {
+      return _sep;
+    }
+
+    /// \brief Returns the number of the keys mapped to \c false.
+    ///
+    /// Returns the number of the keys mapped to \c false.
+    int falseNum() const {
+      return _array.size() - _sep;
+    }
+
+    /// \brief Iterator for the keys mapped to \c true.
+    ///
+    /// Iterator for the keys mapped to \c true. It works
+    /// like a graph item iterator, it can be converted to
+    /// the key type of the map, incremented with \c ++ operator, and
+    /// if the iterator leaves the last valid key, it will be equal to
+    /// \c INVALID.
+    class TrueIt : public Key {
+    public:
+      typedef Key Parent;
+
+      /// \brief Creates an iterator.
+      ///
+      /// Creates an iterator. It iterates on the
+      /// keys mapped to \c true.
+      /// \param map The IterableBoolMap.
+      explicit TrueIt(const IterableBoolMap& map)
+        : Parent(map._sep > 0 ? map._array[map._sep - 1] : INVALID),
+          _map(&map) {}
+
+      /// \brief Invalid constructor \& conversion.
+      ///
+      /// This constructor initializes the iterator to be invalid.
+      /// \sa Invalid for more details.
+      TrueIt(Invalid) : Parent(INVALID), _map(0) {}
+
+      /// \brief Increment operator.
+      ///
+      /// Increment operator.
+      TrueIt& operator++() {
+        int pos = _map->position(*this);
+        Parent::operator=(pos > 0 ? _map->_array[pos - 1] : INVALID);
+        return *this;
+      }
+
+    private:
+      const IterableBoolMap* _map;
+    };
+
+    /// \brief Iterator for the keys mapped to \c false.
+    ///
+    /// Iterator for the keys mapped to \c false. It works
+    /// like a graph item iterator, it can be converted to
+    /// the key type of the map, incremented with \c ++ operator, and
+    /// if the iterator leaves the last valid key, it will be equal to
+    /// \c INVALID.
+    class FalseIt : public Key {
+    public:
+      typedef Key Parent;
+
+      /// \brief Creates an iterator.
+      ///
+      /// Creates an iterator. It iterates on the
+      /// keys mapped to \c false.
+      /// \param map The IterableBoolMap.
+      explicit FalseIt(const IterableBoolMap& map)
+        : Parent(map._sep < int(map._array.size()) ?
+                 map._array.back() : INVALID), _map(&map) {}
+
+      /// \brief Invalid constructor \& conversion.
+      ///
+      /// This constructor initializes the iterator to be invalid.
+      /// \sa Invalid for more details.
+      FalseIt(Invalid) : Parent(INVALID), _map(0) {}
+
+      /// \brief Increment operator.
+      ///
+      /// Increment operator.
+      FalseIt& operator++() {
+        int pos = _map->position(*this);
+        Parent::operator=(pos > _map->_sep ? _map->_array[pos - 1] : INVALID);
+        return *this;
+      }
+
+    private:
+      const IterableBoolMap* _map;
+    };
+
+    /// \brief Iterator for the keys mapped to a given value.
+    ///
+    /// Iterator for the keys mapped to a given value. It works
+    /// like a graph item iterator, it can be converted to
+    /// the key type of the map, incremented with \c ++ operator, and
+    /// if the iterator leaves the last valid key, it will be equal to
+    /// \c INVALID.
+    class ItemIt : public Key {
+    public:
+      typedef Key Parent;
+
+      /// \brief Creates an iterator with a value.
+      ///
+      /// Creates an iterator with a value. It iterates on the
+      /// keys mapped to the given value.
+      /// \param map The IterableBoolMap.
+      /// \param value The value.
+      ItemIt(const IterableBoolMap& map, bool value)
+        : Parent(value ?
+                 (map._sep > 0 ?
+                  map._array[map._sep - 1] : INVALID) :
+                 (map._sep < int(map._array.size()) ?
+                  map._array.back() : INVALID)), _map(&map) {}
+
+      /// \brief Invalid constructor \& conversion.
+      ///
+      /// This constructor initializes the iterator to be invalid.
+      /// \sa Invalid for more details.
+      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
+
+      /// \brief Increment operator.
+      ///
+      /// Increment operator.
+      ItemIt& operator++() {
+        int pos = _map->position(*this);
+        int _sep = pos >= _map->_sep ? _map->_sep : 0;
+        Parent::operator=(pos > _sep ? _map->_array[pos - 1] : INVALID);
+        return *this;
+      }
+
+    private:
+      const IterableBoolMap* _map;
+    };
+
+  protected:
+
+    virtual void add(const Key& key) {
+      Parent::add(key);
+      Parent::set(key, _array.size());
+      _array.push_back(key);
+    }
+
+    virtual void add(const std::vector<Key>& keys) {
+      Parent::add(keys);
+      for (int i = 0; i < int(keys.size()); ++i) {
+        Parent::set(keys[i], _array.size());
+        _array.push_back(keys[i]);
+      }
+    }
+
+    virtual void erase(const Key& key) {
+      int pos = position(key);
+      if (pos < _sep) {
+        --_sep;
+        Parent::set(_array[_sep], pos);
+        _array[pos] = _array[_sep];
+        Parent::set(_array.back(), _sep);
+        _array[_sep] = _array.back();
+        _array.pop_back();
+      } else {
+        Parent::set(_array.back(), pos);
+        _array[pos] = _array.back();
+        _array.pop_back();
+      }
+      Parent::erase(key);
+    }
+
+    virtual void erase(const std::vector<Key>& keys) {
+      for (int i = 0; i < int(keys.size()); ++i) {
+        int pos = position(keys[i]);
+        if (pos < _sep) {
+          --_sep;
+          Parent::set(_array[_sep], pos);
+          _array[pos] = _array[_sep];
+          Parent::set(_array.back(), _sep);
+          _array[_sep] = _array.back();
+          _array.pop_back();
+        } else {
+          Parent::set(_array.back(), pos);
+          _array[pos] = _array.back();
+          _array.pop_back();
+        }
+      }
+      Parent::erase(keys);
+    }
+
+    virtual void build() {
+      Parent::build();
+      typename Parent::Notifier* nf = Parent::notifier();
+      Key it;
+      for (nf->first(it); it != INVALID; nf->next(it)) {
+        Parent::set(it, _array.size());
+        _array.push_back(it);
+      }
+      _sep = 0;
+    }
+
+    virtual void clear() {
+      _array.clear();
+      _sep = 0;
+      Parent::clear();
+    }
+
+  };
+
+
+  namespace _maps_bits {
+    template <typename Item>
+    struct IterableIntMapNode {
+      IterableIntMapNode() : value(-1) {}
+      IterableIntMapNode(int _value) : value(_value) {}
+      Item prev, next;
+      int value;
+    };
+  }
+
+  /// \brief Dynamic iterable integer map.
+  ///
+  /// This class provides a special graph map type which can store an
+  /// integer value for graph items (\c Node, \c Arc or \c Edge).
+  /// For each non-negative value it is possible to iterate on the keys
+  /// mapped to the value.
+  ///
+  /// This map is intended to be used with small integer values, for which
+  /// it is efficient, and supports iteration only for non-negative values.
+  /// If you need large values and/or iteration for negative integers,
+  /// consider to use \ref IterableValueMap instead.
+  ///
+  /// This type is a reference map, so it can be modified with the
+  /// subscript operator.
+  ///
+  /// \note The size of the data structure depends on the largest
+  /// value in the map.
+  ///
+  /// \tparam GR The graph type.
+  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
+  /// \c GR::Edge).
+  ///
+  /// \see IterableBoolMap, IterableValueMap
+  /// \see CrossRefMap
+  template <typename GR, typename K>
+  class IterableIntMap
+    : protected ItemSetTraits<GR, K>::
+        template Map<_maps_bits::IterableIntMapNode<K> >::Type {
+  public:
+    typedef typename ItemSetTraits<GR, K>::
+      template Map<_maps_bits::IterableIntMapNode<K> >::Type Parent;
+
+    /// The key type
+    typedef K Key;
+    /// The value type
+    typedef int Value;
+    /// The graph type
+    typedef GR Graph;
+
+    /// \brief Constructor of the map.
+    ///
+    /// Constructor of the map. It sets all values to -1.
+    explicit IterableIntMap(const Graph& graph)
+      : Parent(graph) {}
+
+    /// \brief Constructor of the map with a given value.
+    ///
+    /// Constructor of the map with a given value.
+    explicit IterableIntMap(const Graph& graph, int value)
+      : Parent(graph, _maps_bits::IterableIntMapNode<K>(value)) {
+      if (value >= 0) {
+        for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
+          lace(it);
+        }
+      }
+    }
+
+  private:
+
+    void unlace(const Key& key) {
+      typename Parent::Value& node = Parent::operator[](key);
+      if (node.value < 0) return;
+      if (node.prev != INVALID) {
+        Parent::operator[](node.prev).next = node.next;
+      } else {
+        _first[node.value] = node.next;
+      }
+      if (node.next != INVALID) {
+        Parent::operator[](node.next).prev = node.prev;
+      }
+      while (!_first.empty() && _first.back() == INVALID) {
+        _first.pop_back();
+      }
+    }
+
+    void lace(const Key& key) {
+      typename Parent::Value& node = Parent::operator[](key);
+      if (node.value < 0) return;
+      if (node.value >= int(_first.size())) {
+        _first.resize(node.value + 1, INVALID);
+      }
+      node.prev = INVALID;
+      node.next = _first[node.value];
+      if (node.next != INVALID) {
+        Parent::operator[](node.next).prev = key;
+      }
+      _first[node.value] = key;
+    }
+
+  public:
+
+    /// Indicates that the map is reference map.
+    typedef True ReferenceMapTag;
+
+    /// \brief Reference to the value of the map.
+    ///
+    /// This class is similar to the \c int type. It can
+    /// be converted to \c int and it has the same operators.
+    class Reference {
+      friend class IterableIntMap;
+    private:
+      Reference(IterableIntMap& map, const Key& key)
+        : _key(key), _map(map) {}
+    public:
+
+      Reference& operator=(const Reference& value) {
+        _map.set(_key, static_cast<const int&>(value));
+         return *this;
+      }
+
+      operator const int&() const {
+        return static_cast<const IterableIntMap&>(_map)[_key];
+      }
+
+      Reference& operator=(int value) {
+        _map.set(_key, value);
+        return *this;
+      }
+      Reference& operator++() {
+        _map.set(_key, _map[_key] + 1);
+        return *this;
+      }
+      int operator++(int) {
+        int value = _map[_key];
+        _map.set(_key, value + 1);
+        return value;
+      }
+      Reference& operator--() {
+        _map.set(_key, _map[_key] - 1);
+        return *this;
+      }
+      int operator--(int) {
+        int value = _map[_key];
+        _map.set(_key, value - 1);
+        return value;
+      }
+      Reference& operator+=(int value) {
+        _map.set(_key, _map[_key] + value);
+        return *this;
+      }
+      Reference& operator-=(int value) {
+        _map.set(_key, _map[_key] - value);
+        return *this;
+      }
+      Reference& operator*=(int value) {
+        _map.set(_key, _map[_key] * value);
+        return *this;
+      }
+      Reference& operator/=(int value) {
+        _map.set(_key, _map[_key] / value);
+        return *this;
+      }
+      Reference& operator%=(int value) {
+        _map.set(_key, _map[_key] % value);
+        return *this;
+      }
+      Reference& operator&=(int value) {
+        _map.set(_key, _map[_key] & value);
+        return *this;
+      }
+      Reference& operator|=(int value) {
+        _map.set(_key, _map[_key] | value);
+        return *this;
+      }
+      Reference& operator^=(int value) {
+        _map.set(_key, _map[_key] ^ value);
+        return *this;
+      }
+      Reference& operator<<=(int value) {
+        _map.set(_key, _map[_key] << value);
+        return *this;
+      }
+      Reference& operator>>=(int value) {
+        _map.set(_key, _map[_key] >> value);
+        return *this;
+      }
+
+    private:
+      Key _key;
+      IterableIntMap& _map;
+    };
+
+    /// The const reference type.
+    typedef const Value& ConstReference;
+
+    /// \brief Gives back the maximal value plus one.
+    ///
+    /// Gives back the maximal value plus one.
+    int size() const {
+      return _first.size();
+    }
+
+    /// \brief Set operation of the map.
+    ///
+    /// Set operation of the map.
+    void set(const Key& key, const Value& value) {
+      unlace(key);
+      Parent::operator[](key).value = value;
+      lace(key);
+    }
+
+    /// \brief Const subscript operator of the map.
+    ///
+    /// Const subscript operator of the map.
+    const Value& operator[](const Key& key) const {
+      return Parent::operator[](key).value;
+    }
+
+    /// \brief Subscript operator of the map.
+    ///
+    /// Subscript operator of the map.
+    Reference operator[](const Key& key) {
+      return Reference(*this, key);
+    }
+
+    /// \brief Iterator for the keys with the same value.
+    ///
+    /// Iterator for the keys with the same value. It works
+    /// like a graph item iterator, it can be converted to
+    /// the item type of the map, incremented with \c ++ operator, and
+    /// if the iterator leaves the last valid item, it will be equal to
+    /// \c INVALID.
+    class ItemIt : public Key {
+    public:
+      typedef Key Parent;
+
+      /// \brief Invalid constructor \& conversion.
+      ///
+      /// This constructor initializes the iterator to be invalid.
+      /// \sa Invalid for more details.
+      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
+
+      /// \brief Creates an iterator with a value.
+      ///
+      /// Creates an iterator with a value. It iterates on the
+      /// keys mapped to the given value.
+      /// \param map The IterableIntMap.
+      /// \param value The value.
+      ItemIt(const IterableIntMap& map, int value) : _map(&map) {
+        if (value < 0 || value >= int(_map->_first.size())) {
+          Parent::operator=(INVALID);
+        } else {
+          Parent::operator=(_map->_first[value]);
+        }
+      }
+
+      /// \brief Increment operator.
+      ///
+      /// Increment operator.
+      ItemIt& operator++() {
+        Parent::operator=(_map->IterableIntMap::Parent::
+                          operator[](static_cast<Parent&>(*this)).next);
+        return *this;
+      }
+
+    private:
+      const IterableIntMap* _map;
+    };
+
+  protected:
+
+    virtual void erase(const Key& key) {
+      unlace(key);
+      Parent::erase(key);
+    }
+
+    virtual void erase(const std::vector<Key>& keys) {
+      for (int i = 0; i < int(keys.size()); ++i) {
+        unlace(keys[i]);
+      }
+      Parent::erase(keys);
+    }
+
+    virtual void clear() {
+      _first.clear();
+      Parent::clear();
+    }
+
+  private:
+    std::vector<Key> _first;
+  };
+
+  namespace _maps_bits {
+    template <typename Item, typename Value>
+    struct IterableValueMapNode {
+      IterableValueMapNode(Value _value = Value()) : value(_value) {}
+      Item prev, next;
+      Value value;
+    };
+  }
+
+  /// \brief Dynamic iterable map for comparable values.
+  ///
+  /// This class provides a special graph map type which can store a
+  /// comparable value for graph items (\c Node, \c Arc or \c Edge).
+  /// For each value it is possible to iterate on the keys mapped to
+  /// the value (\c ItemIt), and the values of the map can be accessed
+  /// with an STL compatible forward iterator (\c ValueIt).
+  /// The map stores a linked list for each value, which contains
+  /// the items mapped to the value, and the used values are stored
+  /// in balanced binary tree (\c std::map).
+  ///
+  /// \ref IterableBoolMap and \ref IterableIntMap are similar classes
+  /// specialized for \c bool and \c int values, respectively.
+  ///
+  /// This type is not reference map, so it cannot be modified with
+  /// the subscript operator.
+  ///
+  /// \tparam GR The graph type.
+  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
+  /// \c GR::Edge).
+  /// \tparam V The value type of the map. It can be any comparable
+  /// value type.
+  ///
+  /// \see IterableBoolMap, IterableIntMap
+  /// \see CrossRefMap
+  template <typename GR, typename K, typename V>
+  class IterableValueMap
+    : protected ItemSetTraits<GR, K>::
+        template Map<_maps_bits::IterableValueMapNode<K, V> >::Type {
+  public:
+    typedef typename ItemSetTraits<GR, K>::
+      template Map<_maps_bits::IterableValueMapNode<K, V> >::Type Parent;
+
+    /// The key type
+    typedef K Key;
+    /// The value type
+    typedef V Value;
+    /// The graph type
+    typedef GR Graph;
+
+  public:
+
+    /// \brief Constructor of the map with a given value.
+    ///
+    /// Constructor of the map with a given value.
+    explicit IterableValueMap(const Graph& graph,
+                              const Value& value = Value())
+      : Parent(graph, _maps_bits::IterableValueMapNode<K, V>(value)) {
+      for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
+        lace(it);
+      }
+    }
+
+  protected:
+
+    void unlace(const Key& key) {
+      typename Parent::Value& node = Parent::operator[](key);
+      if (node.prev != INVALID) {
+        Parent::operator[](node.prev).next = node.next;
+      } else {
+        if (node.next != INVALID) {
+          _first[node.value] = node.next;
+        } else {
+          _first.erase(node.value);
+        }
+      }
+      if (node.next != INVALID) {
+        Parent::operator[](node.next).prev = node.prev;
+      }
+    }
+
+    void lace(const Key& key) {
+      typename Parent::Value& node = Parent::operator[](key);
+      typename std::map<Value, Key>::iterator it = _first.find(node.value);
+      if (it == _first.end()) {
+        node.prev = node.next = INVALID;
+        _first.insert(std::make_pair(node.value, key));
+      } else {
+        node.prev = INVALID;
+        node.next = it->second;
+        if (node.next != INVALID) {
+          Parent::operator[](node.next).prev = key;
+        }
+        it->second = key;
+      }
+    }
+
+  public:
+
+    /// \brief Forward iterator for values.
+    ///
+    /// This iterator is an STL compatible forward
+    /// iterator on the values of the map. The values can
+    /// be accessed in the <tt>[beginValue, endValue)</tt> range.
+    class ValueIt
+      : public std::iterator<std::forward_iterator_tag, Value> {
+      friend class IterableValueMap;
+    private:
+      ValueIt(typename std::map<Value, Key>::const_iterator _it)
+        : it(_it) {}
+    public:
+
+      /// Constructor
+      ValueIt() {}
+
+      /// \e
+      ValueIt& operator++() { ++it; return *this; }
+      /// \e
+      ValueIt operator++(int) {
+        ValueIt tmp(*this);
+        operator++();
+        return tmp;
+      }
+
+      /// \e
+      const Value& operator*() const { return it->first; }
+      /// \e
+      const Value* operator->() const { return &(it->first); }
+
+      /// \e
+      bool operator==(ValueIt jt) const { return it == jt.it; }
+      /// \e
+      bool operator!=(ValueIt jt) const { return it != jt.it; }
+
+    private:
+      typename std::map<Value, Key>::const_iterator it;
+    };
+
+    /// \brief Returns an iterator to the first value.
+    ///
+    /// Returns an STL compatible iterator to the
+    /// first value of the map. The values of the
+    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
+    /// range.
+    ValueIt beginValue() const {
+      return ValueIt(_first.begin());
+    }
+
+    /// \brief Returns an iterator after the last value.
+    ///
+    /// Returns an STL compatible iterator after the
+    /// last value of the map. The values of the
+    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
+    /// range.
+    ValueIt endValue() const {
+      return ValueIt(_first.end());
+    }
+
+    /// \brief Set operation of the map.
+    ///
+    /// Set operation of the map.
+    void set(const Key& key, const Value& value) {
+      unlace(key);
+      Parent::operator[](key).value = value;
+      lace(key);
+    }
+
+    /// \brief Const subscript operator of the map.
+    ///
+    /// Const subscript operator of the map.
+    const Value& operator[](const Key& key) const {
+      return Parent::operator[](key).value;
+    }
+
+    /// \brief Iterator for the keys with the same value.
+    ///
+    /// Iterator for the keys with the same value. It works
+    /// like a graph item iterator, it can be converted to
+    /// the item type of the map, incremented with \c ++ operator, and
+    /// if the iterator leaves the last valid item, it will be equal to
+    /// \c INVALID.
+    class ItemIt : public Key {
+    public:
+      typedef Key Parent;
+
+      /// \brief Invalid constructor \& conversion.
+      ///
+      /// This constructor initializes the iterator to be invalid.
+      /// \sa Invalid for more details.
+      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
+
+      /// \brief Creates an iterator with a value.
+      ///
+      /// Creates an iterator with a value. It iterates on the
+      /// keys which have the given value.
+      /// \param map The IterableValueMap
+      /// \param value The value
+      ItemIt(const IterableValueMap& map, const Value& value) : _map(&map) {
+        typename std::map<Value, Key>::const_iterator it =
+          map._first.find(value);
+        if (it == map._first.end()) {
+          Parent::operator=(INVALID);
+        } else {
+          Parent::operator=(it->second);
+        }
+      }
+
+      /// \brief Increment operator.
+      ///
+      /// Increment Operator.
+      ItemIt& operator++() {
+        Parent::operator=(_map->IterableValueMap::Parent::
+                          operator[](static_cast<Parent&>(*this)).next);
+        return *this;
+      }
+
+
+    private:
+      const IterableValueMap* _map;
+    };
+
+  protected:
+
+    virtual void add(const Key& key) {
+      Parent::add(key);
+      lace(key);
+    }
+
+    virtual void add(const std::vector<Key>& keys) {
+      Parent::add(keys);
+      for (int i = 0; i < int(keys.size()); ++i) {
+        lace(keys[i]);
+      }
+    }
+
+    virtual void erase(const Key& key) {
+      unlace(key);
+      Parent::erase(key);
+    }
+
+    virtual void erase(const std::vector<Key>& keys) {
+      for (int i = 0; i < int(keys.size()); ++i) {
+        unlace(keys[i]);
+      }
+      Parent::erase(keys);
+    }
+
+    virtual void build() {
+      Parent::build();
+      for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
+        lace(it);
+      }
+    }
+
+    virtual void clear() {
+      _first.clear();
+      Parent::clear();
+    }
+
+  private:
+    std::map<Value, Key> _first;
   };
 
@@ -2320,7 +3301,7 @@
   public:
 
-    ///\e
+    /// The key type (the \c Arc type of the digraph).
     typedef typename GR::Arc Key;
-    ///\e
+    /// The value type (the \c Node type of the digraph).
     typedef typename GR::Node Value;
 
@@ -2361,7 +3342,7 @@
   public:
 
-    ///\e
+    /// The key type (the \c Arc type of the digraph).
     typedef typename GR::Arc Key;
-    ///\e
+    /// The value type (the \c Node type of the digraph).
     typedef typename GR::Node Value;
 
@@ -2403,6 +3384,8 @@
   public:
 
+    /// The key type (the \c Edge type of the digraph).
+    typedef typename GR::Edge Key;
+    /// The value type (the \c Arc type of the digraph).
     typedef typename GR::Arc Value;
-    typedef typename GR::Edge Key;
 
     /// \brief Constructor
@@ -2443,6 +3426,8 @@
   public:
 
+    /// The key type (the \c Edge type of the digraph).
+    typedef typename GR::Edge Key;
+    /// The value type (the \c Arc type of the digraph).
     typedef typename GR::Arc Value;
-    typedef typename GR::Edge Key;
 
     /// \brief Constructor
@@ -2479,8 +3464,8 @@
   /// whenever the digraph changes.
   ///
-  /// \warning Besides \c addNode() and \c addArc(), a digraph structure 
+  /// \warning Besides \c addNode() and \c addArc(), a digraph structure
   /// may provide alternative ways to modify the digraph.
   /// The correct behavior of InDegMap is not guarantied if these additional
-  /// features are used. For example the functions
+  /// features are used. For example, the functions
   /// \ref ListDigraph::changeSource() "changeSource()",
   /// \ref ListDigraph::changeTarget() "changeTarget()" and
@@ -2495,6 +3480,7 @@
 
   public:
-    
-    /// The digraph type
+
+    /// The graph type of InDegMap
+    typedef GR Graph;
     typedef GR Digraph;
     /// The key type
@@ -2608,8 +3594,8 @@
   /// whenever the digraph changes.
   ///
-  /// \warning Besides \c addNode() and \c addArc(), a digraph structure 
+  /// \warning Besides \c addNode() and \c addArc(), a digraph structure
   /// may provide alternative ways to modify the digraph.
   /// The correct behavior of OutDegMap is not guarantied if these additional
-  /// features are used. For example the functions
+  /// features are used. For example, the functions
   /// \ref ListDigraph::changeSource() "changeSource()",
   /// \ref ListDigraph::changeTarget() "changeTarget()" and
@@ -2625,5 +3611,6 @@
   public:
 
-    /// The digraph type
+    /// The graph type of OutDegMap
+    typedef GR Graph;
     typedef GR Digraph;
     /// The key type
@@ -2730,6 +3717,6 @@
   /// \brief Potential difference map
   ///
-  /// PotentialMap returns the difference between the potentials of the
-  /// source and target nodes of each arc in a digraph, i.e. it returns
+  /// PotentialDifferenceMap returns the difference between the potentials of
+  /// the source and target nodes of each arc in a digraph, i.e. it returns
   /// \code
   ///   potential[gr.target(arc)] - potential[gr.source(arc)].
@@ -2778,4 +3765,291 @@
   }
 
+
+  /// \brief Copy the values of a graph map to another map.
+  ///
+  /// This function copies the values of a graph map to another graph map.
+  /// \c To::Key must be equal or convertible to \c From::Key and
+  /// \c From::Value must be equal or convertible to \c To::Value.
+  ///
+  /// For example, an edge map of \c int value type can be copied to
+  /// an arc map of \c double value type in an undirected graph, but
+  /// an arc map cannot be copied to an edge map.
+  /// Note that even a \ref ConstMap can be copied to a standard graph map,
+  /// but \ref mapFill() can also be used for this purpose.
+  ///
+  /// \param gr The graph for which the maps are defined.
+  /// \param from The map from which the values have to be copied.
+  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+  /// \param to The map to which the values have to be copied.
+  /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+  template <typename GR, typename From, typename To>
+  void mapCopy(const GR& gr, const From& from, To& to) {
+    typedef typename To::Key Item;
+    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
+
+    for (ItemIt it(gr); it != INVALID; ++it) {
+      to.set(it, from[it]);
+    }
+  }
+
+  /// \brief Compare two graph maps.
+  ///
+  /// This function compares the values of two graph maps. It returns
+  /// \c true if the maps assign the same value for all items in the graph.
+  /// The \c Key type of the maps (\c Node, \c Arc or \c Edge) must be equal
+  /// and their \c Value types must be comparable using \c %operator==().
+  ///
+  /// \param gr The graph for which the maps are defined.
+  /// \param map1 The first map.
+  /// \param map2 The second map.
+  template <typename GR, typename Map1, typename Map2>
+  bool mapCompare(const GR& gr, const Map1& map1, const Map2& map2) {
+    typedef typename Map2::Key Item;
+    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
+
+    for (ItemIt it(gr); it != INVALID; ++it) {
+      if (!(map1[it] == map2[it])) return false;
+    }
+    return true;
+  }
+
+  /// \brief Return an item having minimum value of a graph map.
+  ///
+  /// This function returns an item (\c Node, \c Arc or \c Edge) having
+  /// minimum value of the given graph map.
+  /// If the item set is empty, it returns \c INVALID.
+  ///
+  /// \param gr The graph for which the map is defined.
+  /// \param map The graph map.
+  template <typename GR, typename Map>
+  typename Map::Key mapMin(const GR& gr, const Map& map) {
+    return mapMin(gr, map, std::less<typename Map::Value>());
+  }
+
+  /// \brief Return an item having minimum value of a graph map.
+  ///
+  /// This function returns an item (\c Node, \c Arc or \c Edge) having
+  /// minimum value of the given graph map.
+  /// If the item set is empty, it returns \c INVALID.
+  ///
+  /// \param gr The graph for which the map is defined.
+  /// \param map The graph map.
+  /// \param comp Comparison function object.
+  template <typename GR, typename Map, typename Comp>
+  typename Map::Key mapMin(const GR& gr, const Map& map, const Comp& comp) {
+    typedef typename Map::Key Item;
+    typedef typename Map::Value Value;
+    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
+
+    ItemIt min_item(gr);
+    if (min_item == INVALID) return INVALID;
+    Value min = map[min_item];
+    for (ItemIt it(gr); it != INVALID; ++it) {
+      if (comp(map[it], min)) {
+        min = map[it];
+        min_item = it;
+      }
+    }
+    return min_item;
+  }
+
+  /// \brief Return an item having maximum value of a graph map.
+  ///
+  /// This function returns an item (\c Node, \c Arc or \c Edge) having
+  /// maximum value of the given graph map.
+  /// If the item set is empty, it returns \c INVALID.
+  ///
+  /// \param gr The graph for which the map is defined.
+  /// \param map The graph map.
+  template <typename GR, typename Map>
+  typename Map::Key mapMax(const GR& gr, const Map& map) {
+    return mapMax(gr, map, std::less<typename Map::Value>());
+  }
+
+  /// \brief Return an item having maximum value of a graph map.
+  ///
+  /// This function returns an item (\c Node, \c Arc or \c Edge) having
+  /// maximum value of the given graph map.
+  /// If the item set is empty, it returns \c INVALID.
+  ///
+  /// \param gr The graph for which the map is defined.
+  /// \param map The graph map.
+  /// \param comp Comparison function object.
+  template <typename GR, typename Map, typename Comp>
+  typename Map::Key mapMax(const GR& gr, const Map& map, const Comp& comp) {
+    typedef typename Map::Key Item;
+    typedef typename Map::Value Value;
+    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
+
+    ItemIt max_item(gr);
+    if (max_item == INVALID) return INVALID;
+    Value max = map[max_item];
+    for (ItemIt it(gr); it != INVALID; ++it) {
+      if (comp(max, map[it])) {
+        max = map[it];
+        max_item = it;
+      }
+    }
+    return max_item;
+  }
+
+  /// \brief Return the minimum value of a graph map.
+  ///
+  /// This function returns the minimum value of the given graph map.
+  /// The corresponding item set of the graph must not be empty.
+  ///
+  /// \param gr The graph for which the map is defined.
+  /// \param map The graph map.
+  template <typename GR, typename Map>
+  typename Map::Value mapMinValue(const GR& gr, const Map& map) {
+    return map[mapMin(gr, map, std::less<typename Map::Value>())];
+  }
+
+  /// \brief Return the minimum value of a graph map.
+  ///
+  /// This function returns the minimum value of the given graph map.
+  /// The corresponding item set of the graph must not be empty.
+  ///
+  /// \param gr The graph for which the map is defined.
+  /// \param map The graph map.
+  /// \param comp Comparison function object.
+  template <typename GR, typename Map, typename Comp>
+  typename Map::Value
+  mapMinValue(const GR& gr, const Map& map, const Comp& comp) {
+    return map[mapMin(gr, map, comp)];
+  }
+
+  /// \brief Return the maximum value of a graph map.
+  ///
+  /// This function returns the maximum value of the given graph map.
+  /// The corresponding item set of the graph must not be empty.
+  ///
+  /// \param gr The graph for which the map is defined.
+  /// \param map The graph map.
+  template <typename GR, typename Map>
+  typename Map::Value mapMaxValue(const GR& gr, const Map& map) {
+    return map[mapMax(gr, map, std::less<typename Map::Value>())];
+  }
+
+  /// \brief Return the maximum value of a graph map.
+  ///
+  /// This function returns the maximum value of the given graph map.
+  /// The corresponding item set of the graph must not be empty.
+  ///
+  /// \param gr The graph for which the map is defined.
+  /// \param map The graph map.
+  /// \param comp Comparison function object.
+  template <typename GR, typename Map, typename Comp>
+  typename Map::Value
+  mapMaxValue(const GR& gr, const Map& map, const Comp& comp) {
+    return map[mapMax(gr, map, comp)];
+  }
+
+  /// \brief Return an item having a specified value in a graph map.
+  ///
+  /// This function returns an item (\c Node, \c Arc or \c Edge) having
+  /// the specified assigned value in the given graph map.
+  /// If no such item exists, it returns \c INVALID.
+  ///
+  /// \param gr The graph for which the map is defined.
+  /// \param map The graph map.
+  /// \param val The value that have to be found.
+  template <typename GR, typename Map>
+  typename Map::Key
+  mapFind(const GR& gr, const Map& map, const typename Map::Value& val) {
+    typedef typename Map::Key Item;
+    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
+
+    for (ItemIt it(gr); it != INVALID; ++it) {
+      if (map[it] == val) return it;
+    }
+    return INVALID;
+  }
+
+  /// \brief Return an item having value for which a certain predicate is
+  /// true in a graph map.
+  ///
+  /// This function returns an item (\c Node, \c Arc or \c Edge) having
+  /// such assigned value for which the specified predicate is true
+  /// in the given graph map.
+  /// If no such item exists, it returns \c INVALID.
+  ///
+  /// \param gr The graph for which the map is defined.
+  /// \param map The graph map.
+  /// \param pred The predicate function object.
+  template <typename GR, typename Map, typename Pred>
+  typename Map::Key
+  mapFindIf(const GR& gr, const Map& map, const Pred& pred) {
+    typedef typename Map::Key Item;
+    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
+
+    for (ItemIt it(gr); it != INVALID; ++it) {
+      if (pred(map[it])) return it;
+    }
+    return INVALID;
+  }
+
+  /// \brief Return the number of items having a specified value in a
+  /// graph map.
+  ///
+  /// This function returns the number of items (\c Node, \c Arc or \c Edge)
+  /// having the specified assigned value in the given graph map.
+  ///
+  /// \param gr The graph for which the map is defined.
+  /// \param map The graph map.
+  /// \param val The value that have to be counted.
+  template <typename GR, typename Map>
+  int mapCount(const GR& gr, const Map& map, const typename Map::Value& val) {
+    typedef typename Map::Key Item;
+    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
+
+    int cnt = 0;
+    for (ItemIt it(gr); it != INVALID; ++it) {
+      if (map[it] == val) ++cnt;
+    }
+    return cnt;
+  }
+
+  /// \brief Return the number of items having values for which a certain
+  /// predicate is true in a graph map.
+  ///
+  /// This function returns the number of items (\c Node, \c Arc or \c Edge)
+  /// having such assigned values for which the specified predicate is true
+  /// in the given graph map.
+  ///
+  /// \param gr The graph for which the map is defined.
+  /// \param map The graph map.
+  /// \param pred The predicate function object.
+  template <typename GR, typename Map, typename Pred>
+  int mapCountIf(const GR& gr, const Map& map, const Pred& pred) {
+    typedef typename Map::Key Item;
+    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
+
+    int cnt = 0;
+    for (ItemIt it(gr); it != INVALID; ++it) {
+      if (pred(map[it])) ++cnt;
+    }
+    return cnt;
+  }
+
+  /// \brief Fill a graph map with a certain value.
+  ///
+  /// This function sets the specified value for all items (\c Node,
+  /// \c Arc or \c Edge) in the given graph map.
+  ///
+  /// \param gr The graph for which the map is defined.
+  /// \param map The graph map. It must conform to the
+  /// \ref concepts::WriteMap "WriteMap" concept.
+  /// \param val The value.
+  template <typename GR, typename Map>
+  void mapFill(const GR& gr, Map& map, const typename Map::Value& val) {
+    typedef typename Map::Key Item;
+    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
+
+    for (ItemIt it(gr); it != INVALID; ++it) {
+      map.set(it, val);
+    }
+  }
+
   /// @}
 }
Index: lemon/matching.h
===================================================================
--- lemon/matching.h	(revision 877)
+++ lemon/matching.h	(revision 877)
@@ -0,0 +1,3505 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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_MATCHING_H
+#define LEMON_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>
+#include <lemon/fractional_matching.h>
+
+///\ingroup matching
+///\file
+///\brief Maximum matching algorithms in general graphs.
+
+namespace lemon {
+
+  /// \ingroup matching
+  ///
+  /// \brief Maximum cardinality matching in general graphs
+  ///
+  /// This class implements Edmonds' alternating forest matching algorithm
+  /// for finding a maximum cardinality matching in a general undirected graph.
+  /// It 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
+  /// \ref MaxMatching::Status "Status", having values \c EVEN (or \c D),
+  /// \c ODD (or \c A) and \c MATCHED (or \c C) defining the Gallai-Edmonds
+  /// decomposition of the graph. The nodes in \c EVEN/D induce a subgraph
+  /// 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. 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 obtained using \ref status() or
+  /// \ref statusMap() after running the algorithm.
+  ///
+  /// \tparam GR The undirected graph type the algorithm runs on.
+  template <typename GR>
+  class MaxMatching {
+  public:
+
+    /// The graph type of the algorithm
+    typedef GR Graph;
+    /// The type of the matching map
+    typedef typename Graph::template NodeMap<typename Graph::Arc>
+    MatchingMap;
+
+    ///\brief Status constants for Gallai-Edmonds decomposition.
+    ///
+    ///These constants are used for indicating the Gallai-Edmonds
+    ///decomposition of a graph. The nodes with status \c EVEN (or \c D)
+    ///induce a subgraph with factor-critical components, the nodes with
+    ///status \c ODD (or \c A) form the canonical barrier, and the nodes
+    ///with status \c MATCHED (or \c C) induce a subgraph having a
+    ///perfect matching.
+    enum Status {
+      EVEN = 1,       ///< = 1. (\c D is an alias for \c EVEN.)
+      D = 1,
+      MATCHED = 0,    ///< = 0. (\c C is an alias for \c MATCHED.)
+      C = 0,
+      ODD = -1,       ///< = -1. (\c A is an alias for \c ODD.)
+      A = -1,
+      UNMATCHED = -2  ///< = -2.
+    };
+
+    /// The type of the status map
+    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)[node] = arc;
+
+          Node n = node;
+          while (n != base) {
+            n = _graph.target((*_matching)[n]);
+            Arc a = (*_ear)[n];
+            n = _graph.target(a);
+            (*_ear)[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)[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)[_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)[node] = arc;
+
+          Node n = node;
+          while (n != base) {
+            n = _graph.target((*_matching)[n]);
+            Arc a = (*_ear)[n];
+            n = _graph.target(a);
+            (*_ear)[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)[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)[_blossom_set->find(nca)] = nca;
+    }
+
+    void extendOnArc(const Arc& a) {
+      Node base = _graph.source(a);
+      Node odd = _graph.target(a);
+
+      (*_ear)[odd] = _graph.oppositeArc(a);
+      Node even = _graph.target((*_matching)[odd]);
+      (*_blossom_rep)[_blossom_set->insert(even)] = even;
+      (*_status)[odd] = ODD;
+      (*_status)[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)[odd] = _graph.oppositeArc(a);
+      (*_status)[odd] = MATCHED;
+
+      Arc arc = (*_matching)[even];
+      (*_matching)[even] = a;
+
+      while (arc != INVALID) {
+        odd = _graph.target(arc);
+        arc = (*_ear)[odd];
+        even = _graph.target(arc);
+        (*_matching)[odd] = arc;
+        arc = (*_matching)[even];
+        (*_matching)[even] = _graph.oppositeArc((*_matching)[odd]);
+      }
+
+      for (typename TreeSet::ItemIt it(*_tree_set, tree);
+           it != INVALID; ++it) {
+        if ((*_status)[it] == ODD) {
+          (*_status)[it] = MATCHED;
+        } else {
+          int blossom = _blossom_set->find(it);
+          for (typename BlossomSet::ItemIt jt(*_blossom_set, blossom);
+               jt != INVALID; ++jt) {
+            (*_status)[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 have to call
+    /// one of the functions \ref init(), \ref greedyInit() or
+    /// \ref matchingInit() first, then you can start the algorithm with
+    /// \ref startSparse() or \ref startDense().
+
+    ///@{
+
+    /// \brief Set the initial matching to the empty matching.
+    ///
+    /// This function sets the initial matching to the empty matching.
+    void init() {
+      createStructures();
+      for(NodeIt n(_graph); n != INVALID; ++n) {
+        (*_matching)[n] = INVALID;
+        (*_status)[n] = UNMATCHED;
+      }
+    }
+
+    /// \brief Find an initial matching in a greedy way.
+    ///
+    /// This function finds an initial matching in a greedy way.
+    void greedyInit() {
+      createStructures();
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        (*_matching)[n] = INVALID;
+        (*_status)[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)[n] = a;
+              (*_status)[n] = MATCHED;
+              (*_matching)[v] = _graph.oppositeArc(a);
+              (*_status)[v] = MATCHED;
+              break;
+            }
+          }
+        }
+      }
+    }
+
+
+    /// \brief Initialize the matching from a map.
+    ///
+    /// This function initializes the matching from a \c bool valued edge
+    /// map. This map should have the property that there are no two incident
+    /// edges with \c true value, i.e. it really contains a matching.
+    /// \return \c true if the map contains a matching.
+    template <typename MatchingMap>
+    bool matchingInit(const MatchingMap& matching) {
+      createStructures();
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        (*_matching)[n] = INVALID;
+        (*_status)[n] = UNMATCHED;
+      }
+      for(EdgeIt e(_graph); e!=INVALID; ++e) {
+        if (matching[e]) {
+
+          Node u = _graph.u(e);
+          if ((*_matching)[u] != INVALID) return false;
+          (*_matching)[u] = _graph.direct(e, true);
+          (*_status)[u] = MATCHED;
+
+          Node v = _graph.v(e);
+          if ((*_matching)[v] != INVALID) return false;
+          (*_matching)[v] = _graph.direct(e, false);
+          (*_status)[v] = MATCHED;
+        }
+      }
+      return true;
+    }
+
+    /// \brief Start Edmonds' algorithm
+    ///
+    /// This function runs the original Edmonds' algorithm.
+    ///
+    /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be
+    /// called before using this function.
+    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)[n] = EVEN;
+          processSparse(n);
+        }
+      }
+    }
+
+    /// \brief Start Edmonds' algorithm with a heuristic improvement
+    /// for dense graphs
+    ///
+    /// This function runs Edmonds' algorithm with a heuristic of postponing
+    /// shrinks, therefore resulting in a faster algorithm for dense graphs.
+    ///
+    /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be
+    /// called before using this function.
+    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)[n] = EVEN;
+          processDense(n);
+        }
+      }
+    }
+
+
+    /// \brief Run Edmonds' algorithm
+    ///
+    /// This function runs Edmonds' algorithm. An additional heuristic of
+    /// postponing shrinks is used for relatively dense graphs
+    /// (for which <tt>m>=2*n</tt> holds).
+    void run() {
+      if (countEdges(_graph) < 2 * countNodes(_graph)) {
+        greedyInit();
+        startSparse();
+      } else {
+        init();
+        startDense();
+      }
+    }
+
+    /// @}
+
+    /// \name Primal Solution
+    /// Functions to get the primal solution, i.e. the maximum matching.
+
+    /// @{
+
+    /// \brief Return the size (cardinality) of the matching.
+    ///
+    /// This function returns the size (cardinality) of the current matching.
+    /// After 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 Return \c true if the given edge is in the matching.
+    ///
+    /// This function returns \c true if the given edge is in the current
+    /// matching.
+    bool matching(const Edge& edge) const {
+      return edge == (*_matching)[_graph.u(edge)];
+    }
+
+    /// \brief Return the matching arc (or edge) incident to the given node.
+    ///
+    /// This function returns the matching arc (or edge) incident to the
+    /// given node in the current matching or \c INVALID if the node is
+    /// not covered by the matching.
+    Arc matching(const Node& n) const {
+      return (*_matching)[n];
+    }
+
+    /// \brief Return a const reference to the matching map.
+    ///
+    /// This function returns a const reference to a node map that stores
+    /// the matching arc (or edge) incident to each node.
+    const MatchingMap& matchingMap() const {
+      return *_matching;
+    }
+
+    /// \brief Return the mate of the given node.
+    ///
+    /// This function returns the mate of the given node in the current
+    /// matching or \c INVALID if the node is not covered by the 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, i.e. the Gallai-Edmonds
+    /// decomposition.
+
+    /// @{
+
+    /// \brief Return the status of the given node in the Edmonds-Gallai
+    /// decomposition.
+    ///
+    /// This function returns the \ref Status "status" of the given node
+    /// in the Edmonds-Gallai decomposition.
+    Status status(const Node& n) const {
+      return (*_status)[n];
+    }
+
+    /// \brief Return a const reference to the status map, which stores
+    /// the Edmonds-Gallai decomposition.
+    ///
+    /// This function returns a const reference to a node map that stores the
+    /// \ref Status "status" of each node in the Edmonds-Gallai decomposition.
+    const StatusMap& statusMap() const {
+      return *_status;
+    }
+
+    /// \brief Return \c true if the given node is in the barrier.
+    ///
+    /// This function returns \c true if the given 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 a subset of the
+  /// edges in an undirected graph with maximum overall weight for which
+  /// each node has at most one incident edge.
+  /// It 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
+  /// following.
+  /** \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 the run() function.
+  /// After it the matching (the primal solution) and the dual solution
+  /// can be obtained using the query functions and the
+  /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class,
+  /// which is able to iterate on the nodes of a blossom.
+  /// If the value type is integer, then the dual solution is multiplied
+  /// by \ref MaxWeightedMatching::dualScale "4".
+  ///
+  /// \tparam GR The undirected graph type the algorithm runs on.
+  /// \tparam WM The type edge weight map. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
+#ifdef DOXYGEN
+  template <typename GR, typename WM>
+#else
+  template <typename GR,
+            typename WM = typename GR::template EdgeMap<int> >
+#endif
+  class MaxWeightedMatching {
+  public:
+
+    /// The graph type of the algorithm
+    typedef GR Graph;
+    /// The type of the edge weight map
+    typedef WM WeightMap;
+    /// The value type of the edge weights
+    typedef typename WeightMap::Value Value;
+
+    /// The type of the matching map
+    typedef typename Graph::template NodeMap<typename Graph::Arc>
+    MatchingMap;
+
+    /// \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;
+
+  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;
+      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;
+    int _unmatched;
+
+    typedef MaxWeightedFractionalMatching<Graph, WeightMap> FractionalMatching;
+    FractionalMatching *_fractional;
+
+    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);
+      } else if (_blossom_data->size() != _blossom_num) {
+        delete _blossom_data;
+        _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));
+      } else {
+        delete _node_data;
+        _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);
+      } else {
+        _tree_set_index->resize(_blossom_num);
+      }
+
+      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);
+      } else {
+        _delta2_index->resize(_blossom_num);
+      }
+
+      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);
+      } else {
+        _delta4_index->resize(_blossom_num);
+      }
+    }
+
+    void destroyStructures() {
+      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 {
+            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 {
+
+            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 {
+
+            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 unmatchNode(const Node& node) {
+      int blossom = _blossom_set->find(node);
+      int tree = _tree_set->find(blossom);
+
+      alternatePath(blossom, tree);
+      destroyTree(tree);
+
+      (*_blossom_data)[blossom].base = node;
+      (*_blossom_data)[blossom].next = INVALID;
+    }
+
+    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 augmentOnArc(const Arc& arc) {
+
+      int left = _blossom_set->find(_graph.source(arc));
+      int right = _blossom_set->find(_graph.target(arc));
+
+      (*_blossom_data)[left].status = MATCHED;
+
+      int right_tree = _tree_set->find(right);
+      alternatePath(right, right_tree);
+      destroyTree(right_tree);
+
+      (*_blossom_data)[left].next = arc;
+      (*_blossom_data)[right].next = _graph.oppositeArc(arc);
+    }
+
+    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)[base] = matching;
+        _blossom_node_list.push_back(base);
+        (*_node_potential)[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]].next != INVALID) {
+
+          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(), _unmatched(0),
+
+        _fractional(0)
+    {}
+
+    ~MaxWeightedMatching() {
+      destroyStructures();
+      if (_fractional) {
+        delete _fractional;
+      }
+    }
+
+    /// \name Execution Control
+    /// The simplest way to execute the algorithm is to use the
+    /// \ref run() member function.
+
+    ///@{
+
+    /// \brief Initialize the algorithm
+    ///
+    /// This function initializes the algorithm.
+    void init() {
+      createStructures();
+
+      _blossom_node_list.clear();
+      _blossom_potential.clear();
+
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
+      }
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        (*_delta1_index)[n] = _delta1->PRE_HEAP;
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        (*_delta3_index)[e] = _delta3->PRE_HEAP;
+      }
+      for (int i = 0; i < _blossom_num; ++i) {
+        (*_delta2_index)[i] = _delta2->PRE_HEAP;
+        (*_delta4_index)[i] = _delta4->PRE_HEAP;
+      }
+
+      _unmatched = _node_num;
+
+      _delta1->clear();
+      _delta2->clear();
+      _delta3->clear();
+      _delta4->clear();
+      _blossom_set->clear();
+      _tree_set->clear();
+
+      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)[n] = index;
+        (*_node_data)[index].heap_index.clear();
+        (*_node_data)[index].heap.clear();
+        (*_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 Initialize the algorithm with fractional matching
+    ///
+    /// This function initializes the algorithm with a fractional
+    /// matching. This initialization is also called jumpstart heuristic.
+    void fractionalInit() {
+      createStructures();
+
+      _blossom_node_list.clear();
+      _blossom_potential.clear();
+
+      if (_fractional == 0) {
+        _fractional = new FractionalMatching(_graph, _weight, false);
+      }
+      _fractional->run();
+
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
+      }
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        (*_delta1_index)[n] = _delta1->PRE_HEAP;
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        (*_delta3_index)[e] = _delta3->PRE_HEAP;
+      }
+      for (int i = 0; i < _blossom_num; ++i) {
+        (*_delta2_index)[i] = _delta2->PRE_HEAP;
+        (*_delta4_index)[i] = _delta4->PRE_HEAP;
+      }
+
+      _unmatched = 0;
+
+      _delta1->clear();
+      _delta2->clear();
+      _delta3->clear();
+      _delta4->clear();
+      _blossom_set->clear();
+      _tree_set->clear();
+
+      int index = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        Value pot = _fractional->nodeValue(n);
+        (*_node_index)[n] = index;
+        (*_node_data)[index].pot = pot;
+        (*_node_data)[index].heap_index.clear();
+        (*_node_data)[index].heap.clear();
+        int blossom =
+          _blossom_set->insert(n, std::numeric_limits<Value>::max());
+
+        (*_blossom_data)[blossom].status = MATCHED;
+        (*_blossom_data)[blossom].pred = INVALID;
+        (*_blossom_data)[blossom].next = _fractional->matching(n);
+        if (_fractional->matching(n) == INVALID) {
+          (*_blossom_data)[blossom].base = n;
+        }
+        (*_blossom_data)[blossom].pot = 0;
+        (*_blossom_data)[blossom].offset = 0;
+        ++index;
+      }
+
+      typename Graph::template NodeMap<bool> processed(_graph, false);
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if (processed[n]) continue;
+        processed[n] = true;
+        if (_fractional->matching(n) == INVALID) continue;
+        int num = 1;
+        Node v = _graph.target(_fractional->matching(n));
+        while (n != v) {
+          processed[v] = true;
+          v = _graph.target(_fractional->matching(v));
+          ++num;
+        }
+
+        if (num % 2 == 1) {
+          std::vector<int> subblossoms(num);
+
+          subblossoms[--num] = _blossom_set->find(n);
+          _delta1->push(n, _fractional->nodeValue(n));
+          v = _graph.target(_fractional->matching(n));
+          while (n != v) {
+            subblossoms[--num] = _blossom_set->find(v);
+            _delta1->push(v, _fractional->nodeValue(v));
+            v = _graph.target(_fractional->matching(v));
+          }
+
+          int surface =
+            _blossom_set->join(subblossoms.begin(), subblossoms.end());
+          (*_blossom_data)[surface].status = EVEN;
+          (*_blossom_data)[surface].pred = INVALID;
+          (*_blossom_data)[surface].next = INVALID;
+          (*_blossom_data)[surface].pot = 0;
+          (*_blossom_data)[surface].offset = 0;
+
+          _tree_set->insert(surface);
+          ++_unmatched;
+        }
+      }
+
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        int si = (*_node_index)[_graph.u(e)];
+        int sb = _blossom_set->find(_graph.u(e));
+        int ti = (*_node_index)[_graph.v(e)];
+        int tb = _blossom_set->find(_graph.v(e));
+        if ((*_blossom_data)[sb].status == EVEN &&
+            (*_blossom_data)[tb].status == EVEN && sb != tb) {
+          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
+                            dualScale * _weight[e]) / 2);
+        }
+      }
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        int nb = _blossom_set->find(n);
+        if ((*_blossom_data)[nb].status != MATCHED) continue;
+        int ni = (*_node_index)[n];
+
+        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) {
+
+            int vt = _tree_set->find(vb);
+
+            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, e);
+                (*_node_data)[ni].heap.decrease(e, rw);
+                it->second = e;
+              }
+            } else {
+              (*_node_data)[ni].heap.push(e, rw);
+              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e));
+            }
+          }
+        }
+
+        if (!(*_node_data)[ni].heap.empty()) {
+          _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
+          _delta2->push(nb, _blossom_set->classPrio(nb));
+        }
+      }
+    }
+
+    /// \brief Start the algorithm
+    ///
+    /// This function starts the algorithm.
+    ///
+    /// \pre \ref init() or \ref fractionalInit() must be called
+    /// before using this function.
+    void start() {
+      enum OpType {
+        D1, D2, D3, D4
+      };
+
+      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 = d3; OpType ot = D3;
+        if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
+        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
+        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 a = (*_node_data)[(*_node_index)[n]].heap.top();
+            if ((*_blossom_data)[blossom].next == INVALID) {
+              augmentOnArc(a);
+              --_unmatched;
+            } else {
+              extendOnArc(a);
+            }
+          }
+          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();
+    }
+
+    /// \brief Run the algorithm.
+    ///
+    /// This method runs the \c %MaxWeightedMatching algorithm.
+    ///
+    /// \note mwm.run() is just a shortcut of the following code.
+    /// \code
+    ///   mwm.fractionalInit();
+    ///   mwm.start();
+    /// \endcode
+    void run() {
+      fractionalInit();
+      start();
+    }
+
+    /// @}
+
+    /// \name Primal Solution
+    /// Functions to get the primal solution, i.e. the maximum weighted
+    /// matching.\n
+    /// Either \ref run() or \ref start() function should be called before
+    /// using them.
+
+    /// @{
+
+    /// \brief Return the weight of the matching.
+    ///
+    /// This function returns the weight of the found matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value matchingWeight() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          sum += _weight[(*_matching)[n]];
+        }
+      }
+      return sum / 2;
+    }
+
+    /// \brief Return the size (cardinality) of the matching.
+    ///
+    /// This function returns the size (cardinality) of the found matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    int matchingSize() const {
+      int num = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          ++num;
+        }
+      }
+      return num /= 2;
+    }
+
+    /// \brief Return \c true if the given edge is in the matching.
+    ///
+    /// This function returns \c true if the given edge is in the found
+    /// matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    bool matching(const Edge& edge) const {
+      return edge == (*_matching)[_graph.u(edge)];
+    }
+
+    /// \brief Return the matching arc (or edge) incident to the given node.
+    ///
+    /// This function returns the matching arc (or edge) incident to the
+    /// given node in the found matching or \c INVALID if the node is
+    /// not covered by the matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Arc matching(const Node& node) const {
+      return (*_matching)[node];
+    }
+
+    /// \brief Return a const reference to the matching map.
+    ///
+    /// This function returns a const reference to a node map that stores
+    /// the matching arc (or edge) incident to each node.
+    const MatchingMap& matchingMap() const {
+      return *_matching;
+    }
+
+    /// \brief Return the mate of the given node.
+    ///
+    /// This function returns the mate of the given node in the found
+    /// matching or \c INVALID if the node is not covered by the matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Node mate(const Node& node) const {
+      return (*_matching)[node] != INVALID ?
+        _graph.target((*_matching)[node]) : INVALID;
+    }
+
+    /// @}
+
+    /// \name Dual Solution
+    /// Functions to get the dual solution.\n
+    /// Either \ref run() or \ref start() function should be called before
+    /// using them.
+
+    /// @{
+
+    /// \brief Return the value of the dual solution.
+    ///
+    /// This function returns the value of the dual solution.
+    /// It should be equal to the primal value scaled by \ref dualScale
+    /// "dual scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    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 Return the dual value (potential) of the given node.
+    ///
+    /// This function returns the dual value (potential) of the given node.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value nodeValue(const Node& n) const {
+      return (*_node_potential)[n];
+    }
+
+    /// \brief Return the number of the blossoms in the basis.
+    ///
+    /// This function returns the number of the blossoms in the basis.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    /// \see BlossomIt
+    int blossomNum() const {
+      return _blossom_potential.size();
+    }
+
+    /// \brief Return the number of the nodes in the given blossom.
+    ///
+    /// This function returns the number of the nodes in the given blossom.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    /// \see BlossomIt
+    int blossomSize(int k) const {
+      return _blossom_potential[k].end - _blossom_potential[k].begin;
+    }
+
+    /// \brief Return the dual value (ptential) of the given blossom.
+    ///
+    /// This function returns the dual value (ptential) of the given blossom.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value blossomValue(int k) const {
+      return _blossom_potential[k].value;
+    }
+
+    /// \brief Iterator for obtaining the nodes of a blossom.
+    ///
+    /// This class provides an iterator for obtaining the nodes of the
+    /// given blossom. It lists a subset of the nodes.
+    /// Before using this iterator, you must allocate a
+    /// MaxWeightedMatching class and execute it.
+    class BlossomIt {
+    public:
+
+      /// \brief Constructor.
+      ///
+      /// Constructor to get the nodes of the given variable.
+      ///
+      /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or
+      /// \ref MaxWeightedMatching::start() "algorithm.start()" must be
+      /// called before initializing this iterator.
+      BlossomIt(const MaxWeightedMatching& algorithm, int variable)
+        : _algorithm(&algorithm)
+      {
+        _index = _algorithm->_blossom_potential[variable].begin;
+        _last = _algorithm->_blossom_potential[variable].end;
+      }
+
+      /// \brief Conversion to \c Node.
+      ///
+      /// Conversion to \c 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 perfect matching problem is to find a subset of
+  /// the edges in an undirected graph with maximum overall weight for which
+  /// each node has exactly one incident edge.
+  /// It 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
+  /// following.
+  /** \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 the run() function.
+  /// After it the matching (the primal solution) and the dual solution
+  /// can be obtained using the query functions and the
+  /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class,
+  /// which is able to iterate on the nodes of a blossom.
+  /// If the value type is integer, then the dual solution is multiplied
+  /// by \ref MaxWeightedMatching::dualScale "4".
+  ///
+  /// \tparam GR The undirected graph type the algorithm runs on.
+  /// \tparam WM The type edge weight map. The default type is
+  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
+#ifdef DOXYGEN
+  template <typename GR, typename WM>
+#else
+  template <typename GR,
+            typename WM = typename GR::template EdgeMap<int> >
+#endif
+  class MaxWeightedPerfectMatching {
+  public:
+
+    /// The graph type of the algorithm
+    typedef GR Graph;
+    /// The type of the edge weight map
+    typedef WM WeightMap;
+    /// The value type of the edge weights
+    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;
+
+    /// The type of the matching map
+    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;
+    int _unmatched;
+
+    typedef MaxWeightedPerfectFractionalMatching<Graph, WeightMap>
+    FractionalMatching;
+    FractionalMatching *_fractional;
+
+    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);
+      } else if (_blossom_data->size() != _blossom_num) {
+        delete _blossom_data;
+        _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));
+      } else if (_node_data->size() != _node_num) {
+        delete _node_data;
+        _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);
+      } else {
+        _tree_set_index->resize(_blossom_num);
+      }
+
+      if (!_delta2) {
+        _delta2_index = new IntIntMap(_blossom_num);
+        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
+      } else {
+        _delta2_index->resize(_blossom_num);
+      }
+
+      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);
+      } else {
+        _delta4_index->resize(_blossom_num);
+      }
+    }
+
+    void destroyStructures() {
+      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)[base] = matching;
+        _blossom_node_list.push_back(base);
+        (*_node_potential)[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(), _unmatched(0),
+
+        _fractional(0)
+    {}
+
+    ~MaxWeightedPerfectMatching() {
+      destroyStructures();
+      if (_fractional) {
+        delete _fractional;
+      }
+    }
+
+    /// \name Execution Control
+    /// The simplest way to execute the algorithm is to use the
+    /// \ref run() member function.
+
+    ///@{
+
+    /// \brief Initialize the algorithm
+    ///
+    /// This function initializes the algorithm.
+    void init() {
+      createStructures();
+
+      _blossom_node_list.clear();
+      _blossom_potential.clear();
+
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        (*_delta3_index)[e] = _delta3->PRE_HEAP;
+      }
+      for (int i = 0; i < _blossom_num; ++i) {
+        (*_delta2_index)[i] = _delta2->PRE_HEAP;
+        (*_delta4_index)[i] = _delta4->PRE_HEAP;
+      }
+
+      _unmatched = _node_num;
+
+      _delta2->clear();
+      _delta3->clear();
+      _delta4->clear();
+      _blossom_set->clear();
+      _tree_set->clear();
+
+      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)[n] = index;
+        (*_node_data)[index].heap_index.clear();
+        (*_node_data)[index].heap.clear();
+        (*_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 Initialize the algorithm with fractional matching
+    ///
+    /// This function initializes the algorithm with a fractional
+    /// matching. This initialization is also called jumpstart heuristic.
+    void fractionalInit() {
+      createStructures();
+
+      _blossom_node_list.clear();
+      _blossom_potential.clear();
+
+      if (_fractional == 0) {
+        _fractional = new FractionalMatching(_graph, _weight, false);
+      }
+      if (!_fractional->run()) {
+        _unmatched = -1;
+        return;
+      }
+
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
+      }
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        (*_delta3_index)[e] = _delta3->PRE_HEAP;
+      }
+      for (int i = 0; i < _blossom_num; ++i) {
+        (*_delta2_index)[i] = _delta2->PRE_HEAP;
+        (*_delta4_index)[i] = _delta4->PRE_HEAP;
+      }
+
+      _unmatched = 0;
+
+      _delta2->clear();
+      _delta3->clear();
+      _delta4->clear();
+      _blossom_set->clear();
+      _tree_set->clear();
+
+      int index = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        Value pot = _fractional->nodeValue(n);
+        (*_node_index)[n] = index;
+        (*_node_data)[index].pot = pot;
+        (*_node_data)[index].heap_index.clear();
+        (*_node_data)[index].heap.clear();
+        int blossom =
+          _blossom_set->insert(n, std::numeric_limits<Value>::max());
+
+        (*_blossom_data)[blossom].status = MATCHED;
+        (*_blossom_data)[blossom].pred = INVALID;
+        (*_blossom_data)[blossom].next = _fractional->matching(n);
+        (*_blossom_data)[blossom].pot = 0;
+        (*_blossom_data)[blossom].offset = 0;
+        ++index;
+      }
+
+      typename Graph::template NodeMap<bool> processed(_graph, false);
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if (processed[n]) continue;
+        processed[n] = true;
+        if (_fractional->matching(n) == INVALID) continue;
+        int num = 1;
+        Node v = _graph.target(_fractional->matching(n));
+        while (n != v) {
+          processed[v] = true;
+          v = _graph.target(_fractional->matching(v));
+          ++num;
+        }
+
+        if (num % 2 == 1) {
+          std::vector<int> subblossoms(num);
+
+          subblossoms[--num] = _blossom_set->find(n);
+          v = _graph.target(_fractional->matching(n));
+          while (n != v) {
+            subblossoms[--num] = _blossom_set->find(v);
+            v = _graph.target(_fractional->matching(v));
+          }
+
+          int surface =
+            _blossom_set->join(subblossoms.begin(), subblossoms.end());
+          (*_blossom_data)[surface].status = EVEN;
+          (*_blossom_data)[surface].pred = INVALID;
+          (*_blossom_data)[surface].next = INVALID;
+          (*_blossom_data)[surface].pot = 0;
+          (*_blossom_data)[surface].offset = 0;
+
+          _tree_set->insert(surface);
+          ++_unmatched;
+        }
+      }
+
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        int si = (*_node_index)[_graph.u(e)];
+        int sb = _blossom_set->find(_graph.u(e));
+        int ti = (*_node_index)[_graph.v(e)];
+        int tb = _blossom_set->find(_graph.v(e));
+        if ((*_blossom_data)[sb].status == EVEN &&
+            (*_blossom_data)[tb].status == EVEN && sb != tb) {
+          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
+                            dualScale * _weight[e]) / 2);
+        }
+      }
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        int nb = _blossom_set->find(n);
+        if ((*_blossom_data)[nb].status != MATCHED) continue;
+        int ni = (*_node_index)[n];
+
+        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) {
+
+            int vt = _tree_set->find(vb);
+
+            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, e);
+                (*_node_data)[ni].heap.decrease(e, rw);
+                it->second = e;
+              }
+            } else {
+              (*_node_data)[ni].heap.push(e, rw);
+              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e));
+            }
+          }
+        }
+
+        if (!(*_node_data)[ni].heap.empty()) {
+          _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
+          _delta2->push(nb, _blossom_set->classPrio(nb));
+        }
+      }
+    }
+
+    /// \brief Start the algorithm
+    ///
+    /// This function starts the algorithm.
+    ///
+    /// \pre \ref init() or \ref fractionalInit() must be called before
+    /// using this function.
+    bool start() {
+      enum OpType {
+        D2, D3, D4
+      };
+
+      if (_unmatched == -1) return false;
+
+      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 = d3; OpType ot = D3;
+        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
+        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 Run the algorithm.
+    ///
+    /// This method runs the \c %MaxWeightedPerfectMatching algorithm.
+    ///
+    /// \note mwpm.run() is just a shortcut of the following code.
+    /// \code
+    ///   mwpm.fractionalInit();
+    ///   mwpm.start();
+    /// \endcode
+    bool run() {
+      fractionalInit();
+      return start();
+    }
+
+    /// @}
+
+    /// \name Primal Solution
+    /// Functions to get the primal solution, i.e. the maximum weighted
+    /// perfect matching.\n
+    /// Either \ref run() or \ref start() function should be called before
+    /// using them.
+
+    /// @{
+
+    /// \brief Return the weight of the matching.
+    ///
+    /// This function returns the weight of the found matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value matchingWeight() const {
+      Value sum = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        if ((*_matching)[n] != INVALID) {
+          sum += _weight[(*_matching)[n]];
+        }
+      }
+      return sum / 2;
+    }
+
+    /// \brief Return \c true if the given edge is in the matching.
+    ///
+    /// This function returns \c true if the given edge is in the found
+    /// matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    bool matching(const Edge& edge) const {
+      return static_cast<const Edge&>((*_matching)[_graph.u(edge)]) == edge;
+    }
+
+    /// \brief Return the matching arc (or edge) incident to the given node.
+    ///
+    /// This function returns the matching arc (or edge) incident to the
+    /// given node in the found matching or \c INVALID if the node is
+    /// not covered by the matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Arc matching(const Node& node) const {
+      return (*_matching)[node];
+    }
+
+    /// \brief Return a const reference to the matching map.
+    ///
+    /// This function returns a const reference to a node map that stores
+    /// the matching arc (or edge) incident to each node.
+    const MatchingMap& matchingMap() const {
+      return *_matching;
+    }
+
+    /// \brief Return the mate of the given node.
+    ///
+    /// This function returns the mate of the given node in the found
+    /// matching or \c INVALID if the node is not covered by the matching.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Node mate(const Node& node) const {
+      return _graph.target((*_matching)[node]);
+    }
+
+    /// @}
+
+    /// \name Dual Solution
+    /// Functions to get the dual solution.\n
+    /// Either \ref run() or \ref start() function should be called before
+    /// using them.
+
+    /// @{
+
+    /// \brief Return the value of the dual solution.
+    ///
+    /// This function returns the value of the dual solution.
+    /// It should be equal to the primal value scaled by \ref dualScale
+    /// "dual scale".
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    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 Return the dual value (potential) of the given node.
+    ///
+    /// This function returns the dual value (potential) of the given node.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value nodeValue(const Node& n) const {
+      return (*_node_potential)[n];
+    }
+
+    /// \brief Return the number of the blossoms in the basis.
+    ///
+    /// This function returns the number of the blossoms in the basis.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    /// \see BlossomIt
+    int blossomNum() const {
+      return _blossom_potential.size();
+    }
+
+    /// \brief Return the number of the nodes in the given blossom.
+    ///
+    /// This function returns the number of the nodes in the given blossom.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    /// \see BlossomIt
+    int blossomSize(int k) const {
+      return _blossom_potential[k].end - _blossom_potential[k].begin;
+    }
+
+    /// \brief Return the dual value (ptential) of the given blossom.
+    ///
+    /// This function returns the dual value (ptential) of the given blossom.
+    ///
+    /// \pre Either run() or start() must be called before using this function.
+    Value blossomValue(int k) const {
+      return _blossom_potential[k].value;
+    }
+
+    /// \brief Iterator for obtaining the nodes of a blossom.
+    ///
+    /// This class provides an iterator for obtaining the nodes of the
+    /// given blossom. It lists a subset of the nodes.
+    /// Before using this iterator, you must allocate a
+    /// MaxWeightedPerfectMatching class and execute it.
+    class BlossomIt {
+    public:
+
+      /// \brief Constructor.
+      ///
+      /// Constructor to get the nodes of the given variable.
+      ///
+      /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()"
+      /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()"
+      /// must be called before initializing this iterator.
+      BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable)
+        : _algorithm(&algorithm)
+      {
+        _index = _algorithm->_blossom_potential[variable].begin;
+        _last = _algorithm->_blossom_potential[variable].end;
+      }
+
+      /// \brief Conversion to \c Node.
+      ///
+      /// Conversion to \c Node.
+      operator Node() const {
+        return _algorithm->_blossom_node_list[_index];
+      }
+
+      /// \brief Increment operator.
+      ///
+      /// Increment operator.
+      BlossomIt& operator++() {
+        ++_index;
+        return *this;
+      }
+
+      /// \brief Validity checking
+      ///
+      /// This function checks whether the iterator is invalid.
+      bool operator==(Invalid) const { return _index == _last; }
+
+      /// \brief Validity checking
+      ///
+      /// This function 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_MATCHING_H
Index: lemon/math.h
===================================================================
--- lemon/math.h	(revision 511)
+++ lemon/math.h	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -57,5 +57,5 @@
 
   ///Check whether the parameter is NaN or not
-  
+
   ///This function checks whether the parameter is NaN or not.
   ///Is should be equivalent with std::isnan(), but it is not
Index: mon/max_matching.h
===================================================================
--- lemon/max_matching.h	(revision 559)
+++ 	(revision )
@@ -1,3107 +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_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 GR The graph type the algorithm runs on.
-  template <typename GR>
-  class MaxMatching {
-  public:
-
-    typedef GR 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 \c 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 GR,
-            typename WM = typename GR::template EdgeMap<int> >
-  class MaxWeightedMatching {
-  public:
-
-    ///\e
-    typedef GR Graph;
-    ///\e
-    typedef WM WeightMap;
-    ///\e
-    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 GR,
-            typename WM = typename GR::template EdgeMap<int> >
-  class MaxWeightedPerfectMatching {
-  public:
-
-    typedef GR Graph;
-    typedef WM 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/min_cost_arborescence.h
===================================================================
--- lemon/min_cost_arborescence.h	(revision 559)
+++ lemon/min_cost_arborescence.h	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -37,5 +37,5 @@
   /// Default traits class for MinCostArborescence class.
   /// \param GR Digraph type.
-  /// \param CM Type of cost map.
+  /// \param CM Type of the cost map.
   template <class GR, class CM>
   struct MinCostArborescenceDefaultTraits{
@@ -47,5 +47,5 @@
     ///
     /// The type of the map that stores the arc costs.
-    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
+    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
     typedef CM CostMap;
 
@@ -59,7 +59,8 @@
     ///
     /// The type of the map that stores which arcs are in the
-    /// arborescence.  It must meet the \ref concepts::WriteMap
-    /// "WriteMap" concept.  Initially it will be set to false on each
-    /// arc. After it will set all arborescence arcs once.
+    /// arborescence.  It must conform to the \ref concepts::WriteMap
+    /// "WriteMap" concept, and its value type must be \c bool
+    /// (or convertible). Initially it will be set to \c false on each
+    /// arc, then it will be set on each arborescence arc once.
     typedef typename Digraph::template ArcMap<bool> ArborescenceMap;
 
@@ -67,6 +68,6 @@
     ///
     /// This function instantiates a \c ArborescenceMap.
-    /// \param digraph is the graph, to which we would like to
-    /// calculate the \c ArborescenceMap.
+    /// \param digraph The digraph to which we would like to calculate
+    /// the \c ArborescenceMap.
     static ArborescenceMap *createArborescenceMap(const Digraph &digraph){
       return new ArborescenceMap(digraph);
@@ -75,5 +76,7 @@
     /// \brief The type of the \c PredMap
     ///
-    /// The type of the \c PredMap. It is a node map with an arc value type.
+    /// The type of the \c PredMap. It must confrom to the
+    /// \ref concepts::WriteMap "WriteMap" concept, and its value type
+    /// must be the \c Arc type of the digraph.
     typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
 
@@ -91,42 +94,41 @@
   /// \ingroup spantree
   ///
-  /// \brief %MinCostArborescence algorithm class.
+  /// \brief Minimum Cost Arborescence algorithm class.
   ///
-  /// This class provides an efficient implementation of
-  /// %MinCostArborescence algorithm. The arborescence is a tree
+  /// This class provides an efficient implementation of the
+  /// Minimum Cost Arborescence algorithm. The arborescence is a tree
   /// which is directed from a given source node of the digraph. One or
-  /// more sources should be given for the algorithm and it will calculate
-  /// the minimum cost subgraph which are union of arborescences with the
+  /// more sources should be given to the algorithm and it will calculate
+  /// the minimum cost subgraph that is the union of arborescences with the
   /// given sources and spans all the nodes which are reachable from the
   /// sources. The time complexity of the algorithm is O(n<sup>2</sup>+e).
   ///
-  /// The algorithm provides also an optimal dual solution, therefore
+  /// The algorithm also provides an optimal dual solution, therefore
   /// the optimality of the solution can be checked.
   ///
-  /// \param GR The digraph type the algorithm runs on. The default value
-  /// is \ref ListDigraph.
-  /// \param CM This read-only ArcMap determines the costs of the
+  /// \param GR The digraph type the algorithm runs on.
+  /// \param CM A read-only arc map storing the costs of the
   /// arcs. It is read once for each arc, so the map may involve in
-  /// relatively time consuming process to compute the arc cost if
+  /// relatively time consuming process to compute the arc costs if
   /// it is necessary. The default map type is \ref
   /// concepts::Digraph::ArcMap "Digraph::ArcMap<int>".
-  /// \param TR Traits class to set various data types used
-  /// by the algorithm. The default traits class is
-  /// \ref MinCostArborescenceDefaultTraits
-  /// "MinCostArborescenceDefaultTraits<GR, CM>".  See \ref
-  /// MinCostArborescenceDefaultTraits for the documentation of a
-  /// MinCostArborescence traits class.
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm. By default, it is \ref MinCostArborescenceDefaultTraits
+  /// "MinCostArborescenceDefaultTraits<GR, CM>".
+  /// In most cases, this parameter should not be set directly,
+  /// consider to use the named template parameters instead.
 #ifndef DOXYGEN
-  template <typename GR = ListDigraph,
+  template <typename GR,
             typename CM = typename GR::template ArcMap<int>,
             typename TR =
               MinCostArborescenceDefaultTraits<GR, CM> >
 #else
-  template <typename GR, typename CM, typedef TR>
+  template <typename GR, typename CM, typename TR>
 #endif
   class MinCostArborescence {
   public:
 
-    /// The traits.
+    /// \brief The \ref MinCostArborescenceDefaultTraits "traits class"
+    /// of the algorithm.
     typedef TR Traits;
     /// The type of the underlying digraph.
@@ -294,5 +296,5 @@
         }
       }
-      _arc_order->set(minimum.arc, _dual_variables.size());
+      (*_arc_order)[minimum.arc] = _dual_variables.size();
       DualVariable var(_dual_node_list.size() - 1,
                        _dual_node_list.size(), minimum.value);
@@ -336,5 +338,5 @@
         }
       }
-      _arc_order->set(minimum.arc, _dual_variables.size());
+      (*_arc_order)[minimum.arc] = _dual_variables.size();
       DualVariable var(node_bottom, _dual_node_list.size(), minimum.value);
       _dual_variables.push_back(var);
@@ -365,5 +367,5 @@
         Node source = _heap->top();
         _heap->pop();
-        _node_order->set(source, -1);
+        (*_node_order)[source] = -1;
         for (OutArcIt it(*_digraph, source); it != INVALID; ++it) {
           if ((*_arc_order)[it] < 0) continue;
@@ -391,10 +393,10 @@
   public:
 
-    /// \name Named template parameters
+    /// \name Named Template Parameters
 
     /// @{
 
     template <class T>
-    struct DefArborescenceMapTraits : public Traits {
+    struct SetArborescenceMapTraits : public Traits {
       typedef T ArborescenceMap;
       static ArborescenceMap *createArborescenceMap(const Digraph &)
@@ -406,31 +408,38 @@
 
     /// \brief \ref named-templ-param "Named parameter" for
-    /// setting ArborescenceMap type
+    /// setting \c ArborescenceMap type
     ///
     /// \ref named-templ-param "Named parameter" for setting
-    /// ArborescenceMap type
+    /// \c ArborescenceMap type.
+    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept,
+    /// and its value type must be \c bool (or convertible).
+    /// Initially it will be set to \c false on each arc,
+    /// then it will be set on each arborescence arc once.
     template <class T>
-    struct DefArborescenceMap
+    struct SetArborescenceMap
       : public MinCostArborescence<Digraph, CostMap,
-                                   DefArborescenceMapTraits<T> > {
+                                   SetArborescenceMapTraits<T> > {
     };
 
     template <class T>
-    struct DefPredMapTraits : public Traits {
+    struct SetPredMapTraits : public Traits {
       typedef T PredMap;
       static PredMap *createPredMap(const Digraph &)
       {
         LEMON_ASSERT(false, "PredMap is not initialized");
+        return 0; // ignore warnings
       }
     };
 
     /// \brief \ref named-templ-param "Named parameter" for
-    /// setting PredMap type
+    /// setting \c PredMap type
     ///
     /// \ref named-templ-param "Named parameter" for setting
-    /// PredMap type
+    /// \c PredMap type.
+    /// It must meet the \ref concepts::WriteMap "WriteMap" concept,
+    /// and its value type must be the \c Arc type of the digraph.
     template <class T>
-    struct DefPredMap
-      : public MinCostArborescence<Digraph, CostMap, DefPredMapTraits<T> > {
+    struct SetPredMap
+      : public MinCostArborescence<Digraph, CostMap, SetPredMapTraits<T> > {
     };
 
@@ -465,7 +474,7 @@
     }
 
-    /// \brief Sets the arborescence map.
-    ///
-    /// Sets the arborescence map.
+    /// \brief Sets the predecessor map.
+    ///
+    /// Sets the predecessor map.
     /// \return <tt>(*this)</tt>
     MinCostArborescence& predMap(PredMap& m) {
@@ -478,162 +487,9 @@
     }
 
-    /// \name Query Functions
-    /// The result of the %MinCostArborescence algorithm can be obtained
-    /// using these functions.\n
-    /// Before the use of these functions,
-    /// either run() or start() must be called.
-
-    /// @{
-
-    /// \brief Returns a reference to the arborescence map.
-    ///
-    /// Returns a reference to the arborescence map.
-    const ArborescenceMap& arborescenceMap() const {
-      return *_arborescence;
-    }
-
-    /// \brief Returns true if the arc is in the arborescence.
-    ///
-    /// Returns true if the arc is in the arborescence.
-    /// \param arc The arc of the digraph.
-    /// \pre \ref run() must be called before using this function.
-    bool arborescence(Arc arc) const {
-      return (*_pred)[_digraph->target(arc)] == arc;
-    }
-
-    /// \brief Returns a reference to the pred map.
-    ///
-    /// Returns a reference to the pred map.
-    const PredMap& predMap() const {
-      return *_pred;
-    }
-
-    /// \brief Returns the predecessor arc of the given node.
-    ///
-    /// Returns the predecessor arc of the given node.
-    Arc pred(Node node) const {
-      return (*_pred)[node];
-    }
-
-    /// \brief Returns the cost of the arborescence.
-    ///
-    /// Returns the cost of the arborescence.
-    Value arborescenceValue() const {
-      Value sum = 0;
-      for (ArcIt it(*_digraph); it != INVALID; ++it) {
-        if (arborescence(it)) {
-          sum += (*_cost)[it];
-        }
-      }
-      return sum;
-    }
-
-    /// \brief Indicates that a node is reachable from the sources.
-    ///
-    /// Indicates that a node is reachable from the sources.
-    bool reached(Node node) const {
-      return (*_node_order)[node] != -3;
-    }
-
-    /// \brief Indicates that a node is processed.
-    ///
-    /// Indicates that a node is processed. The arborescence path exists
-    /// from the source to the given node.
-    bool processed(Node node) const {
-      return (*_node_order)[node] == -1;
-    }
-
-    /// \brief Returns the number of the dual variables in basis.
-    ///
-    /// Returns the number of the dual variables in basis.
-    int dualNum() const {
-      return _dual_variables.size();
-    }
-
-    /// \brief Returns the value of the dual solution.
-    ///
-    /// Returns the value of the dual solution. It should be
-    /// equal to the arborescence value.
-    Value dualValue() const {
-      Value sum = 0;
-      for (int i = 0; i < int(_dual_variables.size()); ++i) {
-        sum += _dual_variables[i].value;
-      }
-      return sum;
-    }
-
-    /// \brief Returns the number of the nodes in the dual variable.
-    ///
-    /// Returns the number of the nodes in the dual variable.
-    int dualSize(int k) const {
-      return _dual_variables[k].end - _dual_variables[k].begin;
-    }
-
-    /// \brief Returns the value of the dual variable.
-    ///
-    /// Returns the the value of the dual variable.
-    const Value& dualValue(int k) const {
-      return _dual_variables[k].value;
-    }
-
-    /// \brief Lemon iterator for get a dual variable.
-    ///
-    /// Lemon iterator for get a dual variable. This class provides
-    /// a common style lemon iterator which gives back a subset of
-    /// the nodes.
-    class DualIt {
-    public:
-
-      /// \brief Constructor.
-      ///
-      /// Constructor for get the nodeset of the variable.
-      DualIt(const MinCostArborescence& algorithm, int variable)
-        : _algorithm(&algorithm)
-      {
-        _index = _algorithm->_dual_variables[variable].begin;
-        _last = _algorithm->_dual_variables[variable].end;
-      }
-
-      /// \brief Conversion to node.
-      ///
-      /// Conversion to node.
-      operator Node() const {
-        return _algorithm->_dual_node_list[_index];
-      }
-
-      /// \brief Increment operator.
-      ///
-      /// Increment operator.
-      DualIt& 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 MinCostArborescence* _algorithm;
-      int _index, _last;
-    };
-
-    /// @}
-
-    /// \name Execution control
+    /// \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 you can add several
+    /// If you need better control on the execution,
+    /// you have to call \ref init() first, then you can add several
     /// source nodes with \ref addSource().
     /// Finally \ref start() will perform the arborescence
@@ -651,11 +507,11 @@
       for (NodeIt it(*_digraph); it != INVALID; ++it) {
         (*_cost_arcs)[it].arc = INVALID;
-        _node_order->set(it, -3);
-        _heap_cross_ref->set(it, Heap::PRE_HEAP);
+        (*_node_order)[it] = -3;
+        (*_heap_cross_ref)[it] = Heap::PRE_HEAP;
         _pred->set(it, INVALID);
       }
       for (ArcIt it(*_digraph); it != INVALID; ++it) {
         _arborescence->set(it, false);
-        _arc_order->set(it, -1);
+        (*_arc_order)[it] = -1;
       }
       _dual_node_list.clear();
@@ -690,5 +546,5 @@
     /// \return The processed node.
     ///
-    /// \warning The queue must not be empty!
+    /// \warning The queue must not be empty.
     Node processNextNode() {
       Node node = queue.back();
@@ -713,5 +569,6 @@
     /// \brief Returns the number of the nodes to be processed.
     ///
-    /// Returns the number of the nodes to be processed.
+    /// Returns the number of the nodes to be processed in the priority
+    /// queue.
     int queueSize() const {
       return queue.size();
@@ -755,11 +612,167 @@
     /// mca.start();
     /// \endcode
-    void run(Node node) {
+    void run(Node s) {
       init();
-      addSource(node);
+      addSource(s);
       start();
     }
 
     ///@}
+
+    /// \name Query Functions
+    /// The result of the %MinCostArborescence algorithm can be obtained
+    /// using these functions.\n
+    /// Either run() or start() must be called before using them.
+
+    /// @{
+
+    /// \brief Returns the cost of the arborescence.
+    ///
+    /// Returns the cost of the arborescence.
+    Value arborescenceCost() const {
+      Value sum = 0;
+      for (ArcIt it(*_digraph); it != INVALID; ++it) {
+        if (arborescence(it)) {
+          sum += (*_cost)[it];
+        }
+      }
+      return sum;
+    }
+
+    /// \brief Returns \c true if the arc is in the arborescence.
+    ///
+    /// Returns \c true if the given arc is in the arborescence.
+    /// \param arc An arc of the digraph.
+    /// \pre \ref run() must be called before using this function.
+    bool arborescence(Arc arc) const {
+      return (*_pred)[_digraph->target(arc)] == arc;
+    }
+
+    /// \brief Returns a const reference to the arborescence map.
+    ///
+    /// Returns a const reference to the arborescence map.
+    /// \pre \ref run() must be called before using this function.
+    const ArborescenceMap& arborescenceMap() const {
+      return *_arborescence;
+    }
+
+    /// \brief Returns the predecessor arc of the given node.
+    ///
+    /// Returns the predecessor arc of the given node.
+    /// \pre \ref run() must be called before using this function.
+    Arc pred(Node node) const {
+      return (*_pred)[node];
+    }
+
+    /// \brief Returns a const reference to the pred map.
+    ///
+    /// Returns a const reference to the pred map.
+    /// \pre \ref run() must be called before using this function.
+    const PredMap& predMap() const {
+      return *_pred;
+    }
+
+    /// \brief Indicates that a node is reachable from the sources.
+    ///
+    /// Indicates that a node is reachable from the sources.
+    bool reached(Node node) const {
+      return (*_node_order)[node] != -3;
+    }
+
+    /// \brief Indicates that a node is processed.
+    ///
+    /// Indicates that a node is processed. The arborescence path exists
+    /// from the source to the given node.
+    bool processed(Node node) const {
+      return (*_node_order)[node] == -1;
+    }
+
+    /// \brief Returns the number of the dual variables in basis.
+    ///
+    /// Returns the number of the dual variables in basis.
+    int dualNum() const {
+      return _dual_variables.size();
+    }
+
+    /// \brief Returns the value of the dual solution.
+    ///
+    /// Returns the value of the dual solution. It should be
+    /// equal to the arborescence value.
+    Value dualValue() const {
+      Value sum = 0;
+      for (int i = 0; i < int(_dual_variables.size()); ++i) {
+        sum += _dual_variables[i].value;
+      }
+      return sum;
+    }
+
+    /// \brief Returns the number of the nodes in the dual variable.
+    ///
+    /// Returns the number of the nodes in the dual variable.
+    int dualSize(int k) const {
+      return _dual_variables[k].end - _dual_variables[k].begin;
+    }
+
+    /// \brief Returns the value of the dual variable.
+    ///
+    /// Returns the the value of the dual variable.
+    Value dualValue(int k) const {
+      return _dual_variables[k].value;
+    }
+
+    /// \brief LEMON iterator for getting a dual variable.
+    ///
+    /// This class provides a common style LEMON iterator for getting a
+    /// dual variable of \ref MinCostArborescence algorithm.
+    /// It iterates over a subset of the nodes.
+    class DualIt {
+    public:
+
+      /// \brief Constructor.
+      ///
+      /// Constructor for getting the nodeset of the dual variable
+      /// of \ref MinCostArborescence algorithm.
+      DualIt(const MinCostArborescence& algorithm, int variable)
+        : _algorithm(&algorithm)
+      {
+        _index = _algorithm->_dual_variables[variable].begin;
+        _last = _algorithm->_dual_variables[variable].end;
+      }
+
+      /// \brief Conversion to \c Node.
+      ///
+      /// Conversion to \c Node.
+      operator Node() const {
+        return _algorithm->_dual_node_list[_index];
+      }
+
+      /// \brief Increment operator.
+      ///
+      /// Increment operator.
+      DualIt& 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 MinCostArborescence* _algorithm;
+      int _index, _last;
+    };
+
+    /// @}
 
   };
@@ -770,9 +783,10 @@
   ///
   /// Function type interface for MinCostArborescence algorithm.
-  /// \param digraph The Digraph that the algorithm runs on.
-  /// \param cost The CostMap of the arcs.
-  /// \param source The source of the arborescence.
-  /// \retval arborescence The bool ArcMap which stores the arborescence.
-  /// \return The cost of the arborescence.
+  /// \param digraph The digraph the algorithm runs on.
+  /// \param cost An arc map storing the costs.
+  /// \param source The source node of the arborescence.
+  /// \retval arborescence An arc map with \c bool (or convertible) value
+  /// type that stores the arborescence.
+  /// \return The total cost of the arborescence.
   ///
   /// \sa MinCostArborescence
@@ -783,9 +797,9 @@
                                               ArborescenceMap& arborescence) {
     typename MinCostArborescence<Digraph, CostMap>
-      ::template DefArborescenceMap<ArborescenceMap>
+      ::template SetArborescenceMap<ArborescenceMap>
       ::Create mca(digraph, cost);
     mca.arborescenceMap(arborescence);
     mca.run(source);
-    return mca.arborescenceValue();
+    return mca.arborescenceCost();
   }
 
Index: lemon/network_simplex.h
===================================================================
--- lemon/network_simplex.h	(revision 892)
+++ lemon/network_simplex.h	(revision 892)
@@ -0,0 +1,1621 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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_NETWORK_SIMPLEX_H
+#define LEMON_NETWORK_SIMPLEX_H
+
+/// \ingroup min_cost_flow_algs
+///
+/// \file
+/// \brief Network Simplex algorithm for finding a minimum cost flow.
+
+#include <vector>
+#include <limits>
+#include <algorithm>
+
+#include <lemon/core.h>
+#include <lemon/math.h>
+
+namespace lemon {
+
+  /// \addtogroup min_cost_flow_algs
+  /// @{
+
+  /// \brief Implementation of the primal Network Simplex algorithm
+  /// for finding a \ref min_cost_flow "minimum cost flow".
+  ///
+  /// \ref NetworkSimplex implements the primal Network Simplex algorithm
+  /// for finding a \ref min_cost_flow "minimum cost flow"
+  /// \ref amo93networkflows, \ref dantzig63linearprog,
+  /// \ref kellyoneill91netsimplex.
+  /// This algorithm is a highly efficient specialized version of the
+  /// linear programming simplex method directly for the minimum cost
+  /// flow problem.
+  ///
+  /// In general, %NetworkSimplex is the fastest implementation available
+  /// in LEMON for this problem.
+  /// Moreover, it supports both directions of the supply/demand inequality
+  /// constraints. For more information, see \ref SupplyType.
+  ///
+  /// Most of the parameters of the problem (except for the digraph)
+  /// can be given using separate functions, and the algorithm can be
+  /// executed using the \ref run() function. If some parameters are not
+  /// specified, then default values will be used.
+  ///
+  /// \tparam GR The digraph type the algorithm runs on.
+  /// \tparam V The number type used for flow amounts, capacity bounds
+  /// and supply values in the algorithm. By default, it is \c int.
+  /// \tparam C The number type used for costs and potentials in the
+  /// algorithm. By default, it is the same as \c V.
+  ///
+  /// \warning Both number types must be signed and all input data must
+  /// be integer.
+  ///
+  /// \note %NetworkSimplex provides five different pivot rule
+  /// implementations, from which the most efficient one is used
+  /// by default. For more information, see \ref PivotRule.
+  template <typename GR, typename V = int, typename C = V>
+  class NetworkSimplex
+  {
+  public:
+
+    /// The type of the flow amounts, capacity bounds and supply values
+    typedef V Value;
+    /// The type of the arc costs
+    typedef C Cost;
+
+  public:
+
+    /// \brief Problem type constants for the \c run() function.
+    ///
+    /// Enum type containing the problem type constants that can be
+    /// returned by the \ref run() function of the algorithm.
+    enum ProblemType {
+      /// The problem has no feasible solution (flow).
+      INFEASIBLE,
+      /// The problem has optimal solution (i.e. it is feasible and
+      /// bounded), and the algorithm has found optimal flow and node
+      /// potentials (primal and dual solutions).
+      OPTIMAL,
+      /// The objective function of the problem is unbounded, i.e.
+      /// there is a directed cycle having negative total cost and
+      /// infinite upper bound.
+      UNBOUNDED
+    };
+
+    /// \brief Constants for selecting the type of the supply constraints.
+    ///
+    /// Enum type containing constants for selecting the supply type,
+    /// i.e. the direction of the inequalities in the supply/demand
+    /// constraints of the \ref min_cost_flow "minimum cost flow problem".
+    ///
+    /// The default supply type is \c GEQ, the \c LEQ type can be
+    /// selected using \ref supplyType().
+    /// The equality form is a special case of both supply types.
+    enum SupplyType {
+      /// This option means that there are <em>"greater or equal"</em>
+      /// supply/demand constraints in the definition of the problem.
+      GEQ,
+      /// This option means that there are <em>"less or equal"</em>
+      /// supply/demand constraints in the definition of the problem.
+      LEQ
+    };
+
+    /// \brief Constants for selecting the pivot rule.
+    ///
+    /// Enum type containing constants for selecting the pivot rule for
+    /// the \ref run() function.
+    ///
+    /// \ref NetworkSimplex provides five different pivot rule
+    /// implementations that significantly affect the running time
+    /// of the algorithm.
+    /// By default, \ref BLOCK_SEARCH "Block Search" is used, which
+    /// proved to be the most efficient and the most robust on various
+    /// test inputs.
+    /// However, another pivot rule can be selected using the \ref run()
+    /// function with the proper parameter.
+    enum PivotRule {
+
+      /// The \e First \e Eligible pivot rule.
+      /// The next eligible arc is selected in a wraparound fashion
+      /// in every iteration.
+      FIRST_ELIGIBLE,
+
+      /// The \e Best \e Eligible pivot rule.
+      /// The best eligible arc is selected in every iteration.
+      BEST_ELIGIBLE,
+
+      /// The \e Block \e Search pivot rule.
+      /// A specified number of arcs are examined in every iteration
+      /// in a wraparound fashion and the best eligible arc is selected
+      /// from this block.
+      BLOCK_SEARCH,
+
+      /// The \e Candidate \e List pivot rule.
+      /// In a major iteration a candidate list is built from eligible arcs
+      /// in a wraparound fashion and in the following minor iterations
+      /// the best eligible arc is selected from this list.
+      CANDIDATE_LIST,
+
+      /// The \e Altering \e Candidate \e List pivot rule.
+      /// It is a modified version of the Candidate List method.
+      /// It keeps only the several best eligible arcs from the former
+      /// candidate list and extends this list in every iteration.
+      ALTERING_LIST
+    };
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
+
+    typedef std::vector<int> IntVector;
+    typedef std::vector<Value> ValueVector;
+    typedef std::vector<Cost> CostVector;
+    typedef std::vector<char> BoolVector;
+    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
+
+    // State constants for arcs
+    enum ArcState {
+      STATE_UPPER = -1,
+      STATE_TREE  =  0,
+      STATE_LOWER =  1
+    };
+
+    typedef std::vector<signed char> StateVector;
+    // Note: vector<signed char> is used instead of vector<ArcState> for
+    // efficiency reasons
+
+  private:
+
+    // Data related to the underlying digraph
+    const GR &_graph;
+    int _node_num;
+    int _arc_num;
+    int _all_arc_num;
+    int _search_arc_num;
+
+    // Parameters of the problem
+    bool _have_lower;
+    SupplyType _stype;
+    Value _sum_supply;
+
+    // Data structures for storing the digraph
+    IntNodeMap _node_id;
+    IntArcMap _arc_id;
+    IntVector _source;
+    IntVector _target;
+    bool _arc_mixing;
+
+    // Node and arc data
+    ValueVector _lower;
+    ValueVector _upper;
+    ValueVector _cap;
+    CostVector _cost;
+    ValueVector _supply;
+    ValueVector _flow;
+    CostVector _pi;
+
+    // Data for storing the spanning tree structure
+    IntVector _parent;
+    IntVector _pred;
+    IntVector _thread;
+    IntVector _rev_thread;
+    IntVector _succ_num;
+    IntVector _last_succ;
+    IntVector _dirty_revs;
+    BoolVector _forward;
+    StateVector _state;
+    int _root;
+
+    // Temporary data used in the current pivot iteration
+    int in_arc, join, u_in, v_in, u_out, v_out;
+    int first, second, right, last;
+    int stem, par_stem, new_stem;
+    Value delta;
+
+    const Value MAX;
+
+  public:
+
+    /// \brief Constant for infinite upper bounds (capacities).
+    ///
+    /// Constant for infinite upper bounds (capacities).
+    /// It is \c std::numeric_limits<Value>::infinity() if available,
+    /// \c std::numeric_limits<Value>::max() otherwise.
+    const Value INF;
+
+  private:
+
+    // Implementation of the First Eligible pivot rule
+    class FirstEligiblePivotRule
+    {
+    private:
+
+      // References to the NetworkSimplex class
+      const IntVector  &_source;
+      const IntVector  &_target;
+      const CostVector &_cost;
+      const StateVector &_state;
+      const CostVector &_pi;
+      int &_in_arc;
+      int _search_arc_num;
+
+      // Pivot rule data
+      int _next_arc;
+
+    public:
+
+      // Constructor
+      FirstEligiblePivotRule(NetworkSimplex &ns) :
+        _source(ns._source), _target(ns._target),
+        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
+        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
+        _next_arc(0)
+      {}
+
+      // Find next entering arc
+      bool findEnteringArc() {
+        Cost c;
+        for (int e = _next_arc; e != _search_arc_num; ++e) {
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < 0) {
+            _in_arc = e;
+            _next_arc = e + 1;
+            return true;
+          }
+        }
+        for (int e = 0; e != _next_arc; ++e) {
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < 0) {
+            _in_arc = e;
+            _next_arc = e + 1;
+            return true;
+          }
+        }
+        return false;
+      }
+
+    }; //class FirstEligiblePivotRule
+
+
+    // Implementation of the Best Eligible pivot rule
+    class BestEligiblePivotRule
+    {
+    private:
+
+      // References to the NetworkSimplex class
+      const IntVector  &_source;
+      const IntVector  &_target;
+      const CostVector &_cost;
+      const StateVector &_state;
+      const CostVector &_pi;
+      int &_in_arc;
+      int _search_arc_num;
+
+    public:
+
+      // Constructor
+      BestEligiblePivotRule(NetworkSimplex &ns) :
+        _source(ns._source), _target(ns._target),
+        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
+        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num)
+      {}
+
+      // Find next entering arc
+      bool findEnteringArc() {
+        Cost c, min = 0;
+        for (int e = 0; e != _search_arc_num; ++e) {
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < min) {
+            min = c;
+            _in_arc = e;
+          }
+        }
+        return min < 0;
+      }
+
+    }; //class BestEligiblePivotRule
+
+
+    // Implementation of the Block Search pivot rule
+    class BlockSearchPivotRule
+    {
+    private:
+
+      // References to the NetworkSimplex class
+      const IntVector  &_source;
+      const IntVector  &_target;
+      const CostVector &_cost;
+      const StateVector &_state;
+      const CostVector &_pi;
+      int &_in_arc;
+      int _search_arc_num;
+
+      // Pivot rule data
+      int _block_size;
+      int _next_arc;
+
+    public:
+
+      // Constructor
+      BlockSearchPivotRule(NetworkSimplex &ns) :
+        _source(ns._source), _target(ns._target),
+        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
+        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
+        _next_arc(0)
+      {
+        // The main parameters of the pivot rule
+        const double BLOCK_SIZE_FACTOR = 1.0;
+        const int MIN_BLOCK_SIZE = 10;
+
+        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
+                                    std::sqrt(double(_search_arc_num))),
+                                MIN_BLOCK_SIZE );
+      }
+
+      // Find next entering arc
+      bool findEnteringArc() {
+        Cost c, min = 0;
+        int cnt = _block_size;
+        int e;
+        for (e = _next_arc; e != _search_arc_num; ++e) {
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < min) {
+            min = c;
+            _in_arc = e;
+          }
+          if (--cnt == 0) {
+            if (min < 0) goto search_end;
+            cnt = _block_size;
+          }
+        }
+        for (e = 0; e != _next_arc; ++e) {
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < min) {
+            min = c;
+            _in_arc = e;
+          }
+          if (--cnt == 0) {
+            if (min < 0) goto search_end;
+            cnt = _block_size;
+          }
+        }
+        if (min >= 0) return false;
+
+      search_end:
+        _next_arc = e;
+        return true;
+      }
+
+    }; //class BlockSearchPivotRule
+
+
+    // Implementation of the Candidate List pivot rule
+    class CandidateListPivotRule
+    {
+    private:
+
+      // References to the NetworkSimplex class
+      const IntVector  &_source;
+      const IntVector  &_target;
+      const CostVector &_cost;
+      const StateVector &_state;
+      const CostVector &_pi;
+      int &_in_arc;
+      int _search_arc_num;
+
+      // Pivot rule data
+      IntVector _candidates;
+      int _list_length, _minor_limit;
+      int _curr_length, _minor_count;
+      int _next_arc;
+
+    public:
+
+      /// Constructor
+      CandidateListPivotRule(NetworkSimplex &ns) :
+        _source(ns._source), _target(ns._target),
+        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
+        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
+        _next_arc(0)
+      {
+        // The main parameters of the pivot rule
+        const double LIST_LENGTH_FACTOR = 0.25;
+        const int MIN_LIST_LENGTH = 10;
+        const double MINOR_LIMIT_FACTOR = 0.1;
+        const int MIN_MINOR_LIMIT = 3;
+
+        _list_length = std::max( int(LIST_LENGTH_FACTOR *
+                                     std::sqrt(double(_search_arc_num))),
+                                 MIN_LIST_LENGTH );
+        _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length),
+                                 MIN_MINOR_LIMIT );
+        _curr_length = _minor_count = 0;
+        _candidates.resize(_list_length);
+      }
+
+      /// Find next entering arc
+      bool findEnteringArc() {
+        Cost min, c;
+        int e;
+        if (_curr_length > 0 && _minor_count < _minor_limit) {
+          // Minor iteration: select the best eligible arc from the
+          // current candidate list
+          ++_minor_count;
+          min = 0;
+          for (int i = 0; i < _curr_length; ++i) {
+            e = _candidates[i];
+            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+            if (c < min) {
+              min = c;
+              _in_arc = e;
+            }
+            else if (c >= 0) {
+              _candidates[i--] = _candidates[--_curr_length];
+            }
+          }
+          if (min < 0) return true;
+        }
+
+        // Major iteration: build a new candidate list
+        min = 0;
+        _curr_length = 0;
+        for (e = _next_arc; e != _search_arc_num; ++e) {
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < 0) {
+            _candidates[_curr_length++] = e;
+            if (c < min) {
+              min = c;
+              _in_arc = e;
+            }
+            if (_curr_length == _list_length) goto search_end;
+          }
+        }
+        for (e = 0; e != _next_arc; ++e) {
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < 0) {
+            _candidates[_curr_length++] = e;
+            if (c < min) {
+              min = c;
+              _in_arc = e;
+            }
+            if (_curr_length == _list_length) goto search_end;
+          }
+        }
+        if (_curr_length == 0) return false;
+
+      search_end:
+        _minor_count = 1;
+        _next_arc = e;
+        return true;
+      }
+
+    }; //class CandidateListPivotRule
+
+
+    // Implementation of the Altering Candidate List pivot rule
+    class AlteringListPivotRule
+    {
+    private:
+
+      // References to the NetworkSimplex class
+      const IntVector  &_source;
+      const IntVector  &_target;
+      const CostVector &_cost;
+      const StateVector &_state;
+      const CostVector &_pi;
+      int &_in_arc;
+      int _search_arc_num;
+
+      // Pivot rule data
+      int _block_size, _head_length, _curr_length;
+      int _next_arc;
+      IntVector _candidates;
+      CostVector _cand_cost;
+
+      // Functor class to compare arcs during sort of the candidate list
+      class SortFunc
+      {
+      private:
+        const CostVector &_map;
+      public:
+        SortFunc(const CostVector &map) : _map(map) {}
+        bool operator()(int left, int right) {
+          return _map[left] > _map[right];
+        }
+      };
+
+      SortFunc _sort_func;
+
+    public:
+
+      // Constructor
+      AlteringListPivotRule(NetworkSimplex &ns) :
+        _source(ns._source), _target(ns._target),
+        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
+        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
+        _next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost)
+      {
+        // The main parameters of the pivot rule
+        const double BLOCK_SIZE_FACTOR = 1.0;
+        const int MIN_BLOCK_SIZE = 10;
+        const double HEAD_LENGTH_FACTOR = 0.1;
+        const int MIN_HEAD_LENGTH = 3;
+
+        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
+                                    std::sqrt(double(_search_arc_num))),
+                                MIN_BLOCK_SIZE );
+        _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size),
+                                 MIN_HEAD_LENGTH );
+        _candidates.resize(_head_length + _block_size);
+        _curr_length = 0;
+      }
+
+      // Find next entering arc
+      bool findEnteringArc() {
+        // Check the current candidate list
+        int e;
+        for (int i = 0; i != _curr_length; ++i) {
+          e = _candidates[i];
+          _cand_cost[e] = _state[e] *
+            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (_cand_cost[e] >= 0) {
+            _candidates[i--] = _candidates[--_curr_length];
+          }
+        }
+
+        // Extend the list
+        int cnt = _block_size;
+        int limit = _head_length;
+
+        for (e = _next_arc; e != _search_arc_num; ++e) {
+          _cand_cost[e] = _state[e] *
+            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (_cand_cost[e] < 0) {
+            _candidates[_curr_length++] = e;
+          }
+          if (--cnt == 0) {
+            if (_curr_length > limit) goto search_end;
+            limit = 0;
+            cnt = _block_size;
+          }
+        }
+        for (e = 0; e != _next_arc; ++e) {
+          _cand_cost[e] = _state[e] *
+            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (_cand_cost[e] < 0) {
+            _candidates[_curr_length++] = e;
+          }
+          if (--cnt == 0) {
+            if (_curr_length > limit) goto search_end;
+            limit = 0;
+            cnt = _block_size;
+          }
+        }
+        if (_curr_length == 0) return false;
+
+      search_end:
+
+        // Make heap of the candidate list (approximating a partial sort)
+        make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
+                   _sort_func );
+
+        // Pop the first element of the heap
+        _in_arc = _candidates[0];
+        _next_arc = e;
+        pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
+                  _sort_func );
+        _curr_length = std::min(_head_length, _curr_length - 1);
+        return true;
+      }
+
+    }; //class AlteringListPivotRule
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// The constructor of the class.
+    ///
+    /// \param graph The digraph the algorithm runs on.
+    /// \param arc_mixing Indicate if the arcs have to be stored in a
+    /// mixed order in the internal data structure.
+    /// In special cases, it could lead to better overall performance,
+    /// but it is usually slower. Therefore it is disabled by default.
+    NetworkSimplex(const GR& graph, bool arc_mixing = false) :
+      _graph(graph), _node_id(graph), _arc_id(graph),
+      _arc_mixing(arc_mixing),
+      MAX(std::numeric_limits<Value>::max()),
+      INF(std::numeric_limits<Value>::has_infinity ?
+          std::numeric_limits<Value>::infinity() : MAX)
+    {
+      // Check the number types
+      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
+        "The flow type of NetworkSimplex must be signed");
+      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
+        "The cost type of NetworkSimplex must be signed");
+
+      // Reset data structures
+      reset();
+    }
+
+    /// \name Parameters
+    /// The parameters of the algorithm can be specified using these
+    /// functions.
+
+    /// @{
+
+    /// \brief Set the lower bounds on the arcs.
+    ///
+    /// This function sets the lower bounds on the arcs.
+    /// If it is not used before calling \ref run(), the lower bounds
+    /// will be set to zero on all arcs.
+    ///
+    /// \param map An arc map storing the lower bounds.
+    /// Its \c Value type must be convertible to the \c Value type
+    /// of the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    template <typename LowerMap>
+    NetworkSimplex& lowerMap(const LowerMap& map) {
+      _have_lower = true;
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        _lower[_arc_id[a]] = map[a];
+      }
+      return *this;
+    }
+
+    /// \brief Set the upper bounds (capacities) on the arcs.
+    ///
+    /// This function sets the upper bounds (capacities) on the arcs.
+    /// If it is not used before calling \ref run(), the upper bounds
+    /// will be set to \ref INF on all arcs (i.e. the flow value will be
+    /// unbounded from above).
+    ///
+    /// \param map An arc map storing the upper bounds.
+    /// Its \c Value type must be convertible to the \c Value type
+    /// of the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    template<typename UpperMap>
+    NetworkSimplex& upperMap(const UpperMap& map) {
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        _upper[_arc_id[a]] = map[a];
+      }
+      return *this;
+    }
+
+    /// \brief Set the costs of the arcs.
+    ///
+    /// This function sets the costs of the arcs.
+    /// If it is not used before calling \ref run(), the costs
+    /// will be set to \c 1 on all arcs.
+    ///
+    /// \param map An arc map storing the costs.
+    /// Its \c Value type must be convertible to the \c Cost type
+    /// of the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    template<typename CostMap>
+    NetworkSimplex& costMap(const CostMap& map) {
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        _cost[_arc_id[a]] = map[a];
+      }
+      return *this;
+    }
+
+    /// \brief Set the supply values of the nodes.
+    ///
+    /// This function sets the supply values of the nodes.
+    /// If neither this function nor \ref stSupply() is used before
+    /// calling \ref run(), the supply of each node will be set to zero.
+    ///
+    /// \param map A node map storing the supply values.
+    /// Its \c Value type must be convertible to the \c Value type
+    /// of the algorithm.
+    ///
+    /// \return <tt>(*this)</tt>
+    template<typename SupplyMap>
+    NetworkSimplex& supplyMap(const SupplyMap& map) {
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _supply[_node_id[n]] = map[n];
+      }
+      return *this;
+    }
+
+    /// \brief Set single source and target nodes and a supply value.
+    ///
+    /// This function sets a single source node and a single target node
+    /// and the required flow value.
+    /// If neither this function nor \ref supplyMap() is used before
+    /// calling \ref run(), the supply of each node will be set to zero.
+    ///
+    /// Using this function has the same effect as using \ref supplyMap()
+    /// with such a map in which \c k is assigned to \c s, \c -k is
+    /// assigned to \c t and all other nodes have zero supply value.
+    ///
+    /// \param s The source node.
+    /// \param t The target node.
+    /// \param k The required amount of flow from node \c s to node \c t
+    /// (i.e. the supply of \c s and the demand of \c t).
+    ///
+    /// \return <tt>(*this)</tt>
+    NetworkSimplex& stSupply(const Node& s, const Node& t, Value k) {
+      for (int i = 0; i != _node_num; ++i) {
+        _supply[i] = 0;
+      }
+      _supply[_node_id[s]] =  k;
+      _supply[_node_id[t]] = -k;
+      return *this;
+    }
+
+    /// \brief Set the type of the supply constraints.
+    ///
+    /// This function sets the type of the supply/demand constraints.
+    /// If it is not used before calling \ref run(), the \ref GEQ supply
+    /// type will be used.
+    ///
+    /// For more information, see \ref SupplyType.
+    ///
+    /// \return <tt>(*this)</tt>
+    NetworkSimplex& supplyType(SupplyType supply_type) {
+      _stype = supply_type;
+      return *this;
+    }
+
+    /// @}
+
+    /// \name Execution Control
+    /// The algorithm can be executed using \ref run().
+
+    /// @{
+
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm.
+    /// The paramters can be specified using functions \ref lowerMap(),
+    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(),
+    /// \ref supplyType().
+    /// For example,
+    /// \code
+    ///   NetworkSimplex<ListDigraph> ns(graph);
+    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
+    ///     .supplyMap(sup).run();
+    /// \endcode
+    ///
+    /// This function can be called more than once. All the given parameters
+    /// are kept for the next call, unless \ref resetParams() or \ref reset()
+    /// is used, thus only the modified parameters have to be set again.
+    /// If the underlying digraph was also modified after the construction
+    /// of the class (or the last \ref reset() call), then the \ref reset()
+    /// function must be called.
+    ///
+    /// \param pivot_rule The pivot rule that will be used during the
+    /// algorithm. For more information, see \ref PivotRule.
+    ///
+    /// \return \c INFEASIBLE if no feasible flow exists,
+    /// \n \c OPTIMAL if the problem has optimal solution
+    /// (i.e. it is feasible and bounded), and the algorithm has found
+    /// optimal flow and node potentials (primal and dual solutions),
+    /// \n \c UNBOUNDED if the objective function of the problem is
+    /// unbounded, i.e. there is a directed cycle having negative total
+    /// cost and infinite upper bound.
+    ///
+    /// \see ProblemType, PivotRule
+    /// \see resetParams(), reset()
+    ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH) {
+      if (!init()) return INFEASIBLE;
+      return start(pivot_rule);
+    }
+
+    /// \brief Reset all the parameters that have been given before.
+    ///
+    /// This function resets all the paramaters that have been given
+    /// before using functions \ref lowerMap(), \ref upperMap(),
+    /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType().
+    ///
+    /// It is useful for multiple \ref run() calls. Basically, all the given
+    /// parameters are kept for the next \ref run() call, unless
+    /// \ref resetParams() or \ref reset() is used.
+    /// If the underlying digraph was also modified after the construction
+    /// of the class or the last \ref reset() call, then the \ref reset()
+    /// function must be used, otherwise \ref resetParams() is sufficient.
+    ///
+    /// For example,
+    /// \code
+    ///   NetworkSimplex<ListDigraph> ns(graph);
+    ///
+    ///   // First run
+    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
+    ///     .supplyMap(sup).run();
+    ///
+    ///   // Run again with modified cost map (resetParams() is not called,
+    ///   // so only the cost map have to be set again)
+    ///   cost[e] += 100;
+    ///   ns.costMap(cost).run();
+    ///
+    ///   // Run again from scratch using resetParams()
+    ///   // (the lower bounds will be set to zero on all arcs)
+    ///   ns.resetParams();
+    ///   ns.upperMap(capacity).costMap(cost)
+    ///     .supplyMap(sup).run();
+    /// \endcode
+    ///
+    /// \return <tt>(*this)</tt>
+    ///
+    /// \see reset(), run()
+    NetworkSimplex& resetParams() {
+      for (int i = 0; i != _node_num; ++i) {
+        _supply[i] = 0;
+      }
+      for (int i = 0; i != _arc_num; ++i) {
+        _lower[i] = 0;
+        _upper[i] = INF;
+        _cost[i] = 1;
+      }
+      _have_lower = false;
+      _stype = GEQ;
+      return *this;
+    }
+
+    /// \brief Reset the internal data structures and all the parameters
+    /// that have been given before.
+    ///
+    /// This function resets the internal data structures and all the
+    /// paramaters that have been given before using functions \ref lowerMap(),
+    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(),
+    /// \ref supplyType().
+    ///
+    /// It is useful for multiple \ref run() calls. Basically, all the given
+    /// parameters are kept for the next \ref run() call, unless
+    /// \ref resetParams() or \ref reset() is used.
+    /// If the underlying digraph was also modified after the construction
+    /// of the class or the last \ref reset() call, then the \ref reset()
+    /// function must be used, otherwise \ref resetParams() is sufficient.
+    ///
+    /// See \ref resetParams() for examples.
+    ///
+    /// \return <tt>(*this)</tt>
+    ///
+    /// \see resetParams(), run()
+    NetworkSimplex& reset() {
+      // Resize vectors
+      _node_num = countNodes(_graph);
+      _arc_num = countArcs(_graph);
+      int all_node_num = _node_num + 1;
+      int max_arc_num = _arc_num + 2 * _node_num;
+
+      _source.resize(max_arc_num);
+      _target.resize(max_arc_num);
+
+      _lower.resize(_arc_num);
+      _upper.resize(_arc_num);
+      _cap.resize(max_arc_num);
+      _cost.resize(max_arc_num);
+      _supply.resize(all_node_num);
+      _flow.resize(max_arc_num);
+      _pi.resize(all_node_num);
+
+      _parent.resize(all_node_num);
+      _pred.resize(all_node_num);
+      _forward.resize(all_node_num);
+      _thread.resize(all_node_num);
+      _rev_thread.resize(all_node_num);
+      _succ_num.resize(all_node_num);
+      _last_succ.resize(all_node_num);
+      _state.resize(max_arc_num);
+
+      // Copy the graph
+      int i = 0;
+      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
+        _node_id[n] = i;
+      }
+      if (_arc_mixing) {
+        // Store the arcs in a mixed order
+        int k = std::max(int(std::sqrt(double(_arc_num))), 10);
+        int i = 0, j = 0;
+        for (ArcIt a(_graph); a != INVALID; ++a) {
+          _arc_id[a] = i;
+          _source[i] = _node_id[_graph.source(a)];
+          _target[i] = _node_id[_graph.target(a)];
+          if ((i += k) >= _arc_num) i = ++j;
+        }
+      } else {
+        // Store the arcs in the original order
+        int i = 0;
+        for (ArcIt a(_graph); a != INVALID; ++a, ++i) {
+          _arc_id[a] = i;
+          _source[i] = _node_id[_graph.source(a)];
+          _target[i] = _node_id[_graph.target(a)];
+        }
+      }
+
+      // Reset parameters
+      resetParams();
+      return *this;
+    }
+
+    /// @}
+
+    /// \name Query Functions
+    /// The results of the algorithm can be obtained using these
+    /// functions.\n
+    /// The \ref run() function must be called before using them.
+
+    /// @{
+
+    /// \brief Return the total cost of the found flow.
+    ///
+    /// This function returns the total cost of the found flow.
+    /// Its complexity is O(e).
+    ///
+    /// \note The return type of the function can be specified as a
+    /// template parameter. For example,
+    /// \code
+    ///   ns.totalCost<double>();
+    /// \endcode
+    /// It is useful if the total cost cannot be stored in the \c Cost
+    /// type of the algorithm, which is the default return type of the
+    /// function.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    template <typename Number>
+    Number totalCost() const {
+      Number c = 0;
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        int i = _arc_id[a];
+        c += Number(_flow[i]) * Number(_cost[i]);
+      }
+      return c;
+    }
+
+#ifndef DOXYGEN
+    Cost totalCost() const {
+      return totalCost<Cost>();
+    }
+#endif
+
+    /// \brief Return the flow on the given arc.
+    ///
+    /// This function returns the flow on the given arc.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Value flow(const Arc& a) const {
+      return _flow[_arc_id[a]];
+    }
+
+    /// \brief Return the flow map (the primal solution).
+    ///
+    /// This function copies the flow value on each arc into the given
+    /// map. The \c Value type of the algorithm must be convertible to
+    /// the \c Value type of the map.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    template <typename FlowMap>
+    void flowMap(FlowMap &map) const {
+      for (ArcIt a(_graph); a != INVALID; ++a) {
+        map.set(a, _flow[_arc_id[a]]);
+      }
+    }
+
+    /// \brief Return the potential (dual value) of the given node.
+    ///
+    /// This function returns the potential (dual value) of the
+    /// given node.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    Cost potential(const Node& n) const {
+      return _pi[_node_id[n]];
+    }
+
+    /// \brief Return the potential map (the dual solution).
+    ///
+    /// This function copies the potential (dual value) of each node
+    /// into the given map.
+    /// The \c Cost type of the algorithm must be convertible to the
+    /// \c Value type of the map.
+    ///
+    /// \pre \ref run() must be called before using this function.
+    template <typename PotentialMap>
+    void potentialMap(PotentialMap &map) const {
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        map.set(n, _pi[_node_id[n]]);
+      }
+    }
+
+    /// @}
+
+  private:
+
+    // Initialize internal data structures
+    bool init() {
+      if (_node_num == 0) return false;
+
+      // Check the sum of supply values
+      _sum_supply = 0;
+      for (int i = 0; i != _node_num; ++i) {
+        _sum_supply += _supply[i];
+      }
+      if ( !((_stype == GEQ && _sum_supply <= 0) ||
+             (_stype == LEQ && _sum_supply >= 0)) ) return false;
+
+      // Remove non-zero lower bounds
+      if (_have_lower) {
+        for (int i = 0; i != _arc_num; ++i) {
+          Value c = _lower[i];
+          if (c >= 0) {
+            _cap[i] = _upper[i] < MAX ? _upper[i] - c : INF;
+          } else {
+            _cap[i] = _upper[i] < MAX + c ? _upper[i] - c : INF;
+          }
+          _supply[_source[i]] -= c;
+          _supply[_target[i]] += c;
+        }
+      } else {
+        for (int i = 0; i != _arc_num; ++i) {
+          _cap[i] = _upper[i];
+        }
+      }
+
+      // Initialize artifical cost
+      Cost ART_COST;
+      if (std::numeric_limits<Cost>::is_exact) {
+        ART_COST = std::numeric_limits<Cost>::max() / 2 + 1;
+      } else {
+        ART_COST = 0;
+        for (int i = 0; i != _arc_num; ++i) {
+          if (_cost[i] > ART_COST) ART_COST = _cost[i];
+        }
+        ART_COST = (ART_COST + 1) * _node_num;
+      }
+
+      // Initialize arc maps
+      for (int i = 0; i != _arc_num; ++i) {
+        _flow[i] = 0;
+        _state[i] = STATE_LOWER;
+      }
+
+      // Set data for the artificial root node
+      _root = _node_num;
+      _parent[_root] = -1;
+      _pred[_root] = -1;
+      _thread[_root] = 0;
+      _rev_thread[0] = _root;
+      _succ_num[_root] = _node_num + 1;
+      _last_succ[_root] = _root - 1;
+      _supply[_root] = -_sum_supply;
+      _pi[_root] = 0;
+
+      // Add artificial arcs and initialize the spanning tree data structure
+      if (_sum_supply == 0) {
+        // EQ supply constraints
+        _search_arc_num = _arc_num;
+        _all_arc_num = _arc_num + _node_num;
+        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
+          _parent[u] = _root;
+          _pred[u] = e;
+          _thread[u] = u + 1;
+          _rev_thread[u + 1] = u;
+          _succ_num[u] = 1;
+          _last_succ[u] = u;
+          _cap[e] = INF;
+          _state[e] = STATE_TREE;
+          if (_supply[u] >= 0) {
+            _forward[u] = true;
+            _pi[u] = 0;
+            _source[e] = u;
+            _target[e] = _root;
+            _flow[e] = _supply[u];
+            _cost[e] = 0;
+          } else {
+            _forward[u] = false;
+            _pi[u] = ART_COST;
+            _source[e] = _root;
+            _target[e] = u;
+            _flow[e] = -_supply[u];
+            _cost[e] = ART_COST;
+          }
+        }
+      }
+      else if (_sum_supply > 0) {
+        // LEQ supply constraints
+        _search_arc_num = _arc_num + _node_num;
+        int f = _arc_num + _node_num;
+        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
+          _parent[u] = _root;
+          _thread[u] = u + 1;
+          _rev_thread[u + 1] = u;
+          _succ_num[u] = 1;
+          _last_succ[u] = u;
+          if (_supply[u] >= 0) {
+            _forward[u] = true;
+            _pi[u] = 0;
+            _pred[u] = e;
+            _source[e] = u;
+            _target[e] = _root;
+            _cap[e] = INF;
+            _flow[e] = _supply[u];
+            _cost[e] = 0;
+            _state[e] = STATE_TREE;
+          } else {
+            _forward[u] = false;
+            _pi[u] = ART_COST;
+            _pred[u] = f;
+            _source[f] = _root;
+            _target[f] = u;
+            _cap[f] = INF;
+            _flow[f] = -_supply[u];
+            _cost[f] = ART_COST;
+            _state[f] = STATE_TREE;
+            _source[e] = u;
+            _target[e] = _root;
+            _cap[e] = INF;
+            _flow[e] = 0;
+            _cost[e] = 0;
+            _state[e] = STATE_LOWER;
+            ++f;
+          }
+        }
+        _all_arc_num = f;
+      }
+      else {
+        // GEQ supply constraints
+        _search_arc_num = _arc_num + _node_num;
+        int f = _arc_num + _node_num;
+        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
+          _parent[u] = _root;
+          _thread[u] = u + 1;
+          _rev_thread[u + 1] = u;
+          _succ_num[u] = 1;
+          _last_succ[u] = u;
+          if (_supply[u] <= 0) {
+            _forward[u] = false;
+            _pi[u] = 0;
+            _pred[u] = e;
+            _source[e] = _root;
+            _target[e] = u;
+            _cap[e] = INF;
+            _flow[e] = -_supply[u];
+            _cost[e] = 0;
+            _state[e] = STATE_TREE;
+          } else {
+            _forward[u] = true;
+            _pi[u] = -ART_COST;
+            _pred[u] = f;
+            _source[f] = u;
+            _target[f] = _root;
+            _cap[f] = INF;
+            _flow[f] = _supply[u];
+            _state[f] = STATE_TREE;
+            _cost[f] = ART_COST;
+            _source[e] = _root;
+            _target[e] = u;
+            _cap[e] = INF;
+            _flow[e] = 0;
+            _cost[e] = 0;
+            _state[e] = STATE_LOWER;
+            ++f;
+          }
+        }
+        _all_arc_num = f;
+      }
+
+      return true;
+    }
+
+    // Find the join node
+    void findJoinNode() {
+      int u = _source[in_arc];
+      int v = _target[in_arc];
+      while (u != v) {
+        if (_succ_num[u] < _succ_num[v]) {
+          u = _parent[u];
+        } else {
+          v = _parent[v];
+        }
+      }
+      join = u;
+    }
+
+    // Find the leaving arc of the cycle and returns true if the
+    // leaving arc is not the same as the entering arc
+    bool findLeavingArc() {
+      // Initialize first and second nodes according to the direction
+      // of the cycle
+      if (_state[in_arc] == STATE_LOWER) {
+        first  = _source[in_arc];
+        second = _target[in_arc];
+      } else {
+        first  = _target[in_arc];
+        second = _source[in_arc];
+      }
+      delta = _cap[in_arc];
+      int result = 0;
+      Value d;
+      int e;
+
+      // Search the cycle along the path form the first node to the root
+      for (int u = first; u != join; u = _parent[u]) {
+        e = _pred[u];
+        d = _forward[u] ?
+          _flow[e] : (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]);
+        if (d < delta) {
+          delta = d;
+          u_out = u;
+          result = 1;
+        }
+      }
+      // Search the cycle along the path form the second node to the root
+      for (int u = second; u != join; u = _parent[u]) {
+        e = _pred[u];
+        d = _forward[u] ?
+          (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]) : _flow[e];
+        if (d <= delta) {
+          delta = d;
+          u_out = u;
+          result = 2;
+        }
+      }
+
+      if (result == 1) {
+        u_in = first;
+        v_in = second;
+      } else {
+        u_in = second;
+        v_in = first;
+      }
+      return result != 0;
+    }
+
+    // Change _flow and _state vectors
+    void changeFlow(bool change) {
+      // Augment along the cycle
+      if (delta > 0) {
+        Value val = _state[in_arc] * delta;
+        _flow[in_arc] += val;
+        for (int u = _source[in_arc]; u != join; u = _parent[u]) {
+          _flow[_pred[u]] += _forward[u] ? -val : val;
+        }
+        for (int u = _target[in_arc]; u != join; u = _parent[u]) {
+          _flow[_pred[u]] += _forward[u] ? val : -val;
+        }
+      }
+      // Update the state of the entering and leaving arcs
+      if (change) {
+        _state[in_arc] = STATE_TREE;
+        _state[_pred[u_out]] =
+          (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
+      } else {
+        _state[in_arc] = -_state[in_arc];
+      }
+    }
+
+    // Update the tree structure
+    void updateTreeStructure() {
+      int u, w;
+      int old_rev_thread = _rev_thread[u_out];
+      int old_succ_num = _succ_num[u_out];
+      int old_last_succ = _last_succ[u_out];
+      v_out = _parent[u_out];
+
+      u = _last_succ[u_in];  // the last successor of u_in
+      right = _thread[u];    // the node after it
+
+      // Handle the case when old_rev_thread equals to v_in
+      // (it also means that join and v_out coincide)
+      if (old_rev_thread == v_in) {
+        last = _thread[_last_succ[u_out]];
+      } else {
+        last = _thread[v_in];
+      }
+
+      // Update _thread and _parent along the stem nodes (i.e. the nodes
+      // between u_in and u_out, whose parent have to be changed)
+      _thread[v_in] = stem = u_in;
+      _dirty_revs.clear();
+      _dirty_revs.push_back(v_in);
+      par_stem = v_in;
+      while (stem != u_out) {
+        // Insert the next stem node into the thread list
+        new_stem = _parent[stem];
+        _thread[u] = new_stem;
+        _dirty_revs.push_back(u);
+
+        // Remove the subtree of stem from the thread list
+        w = _rev_thread[stem];
+        _thread[w] = right;
+        _rev_thread[right] = w;
+
+        // Change the parent node and shift stem nodes
+        _parent[stem] = par_stem;
+        par_stem = stem;
+        stem = new_stem;
+
+        // Update u and right
+        u = _last_succ[stem] == _last_succ[par_stem] ?
+          _rev_thread[par_stem] : _last_succ[stem];
+        right = _thread[u];
+      }
+      _parent[u_out] = par_stem;
+      _thread[u] = last;
+      _rev_thread[last] = u;
+      _last_succ[u_out] = u;
+
+      // Remove the subtree of u_out from the thread list except for
+      // the case when old_rev_thread equals to v_in
+      // (it also means that join and v_out coincide)
+      if (old_rev_thread != v_in) {
+        _thread[old_rev_thread] = right;
+        _rev_thread[right] = old_rev_thread;
+      }
+
+      // Update _rev_thread using the new _thread values
+      for (int i = 0; i != int(_dirty_revs.size()); ++i) {
+        u = _dirty_revs[i];
+        _rev_thread[_thread[u]] = u;
+      }
+
+      // Update _pred, _forward, _last_succ and _succ_num for the
+      // stem nodes from u_out to u_in
+      int tmp_sc = 0, tmp_ls = _last_succ[u_out];
+      u = u_out;
+      while (u != u_in) {
+        w = _parent[u];
+        _pred[u] = _pred[w];
+        _forward[u] = !_forward[w];
+        tmp_sc += _succ_num[u] - _succ_num[w];
+        _succ_num[u] = tmp_sc;
+        _last_succ[w] = tmp_ls;
+        u = w;
+      }
+      _pred[u_in] = in_arc;
+      _forward[u_in] = (u_in == _source[in_arc]);
+      _succ_num[u_in] = old_succ_num;
+
+      // Set limits for updating _last_succ form v_in and v_out
+      // towards the root
+      int up_limit_in = -1;
+      int up_limit_out = -1;
+      if (_last_succ[join] == v_in) {
+        up_limit_out = join;
+      } else {
+        up_limit_in = join;
+      }
+
+      // Update _last_succ from v_in towards the root
+      for (u = v_in; u != up_limit_in && _last_succ[u] == v_in;
+           u = _parent[u]) {
+        _last_succ[u] = _last_succ[u_out];
+      }
+      // Update _last_succ from v_out towards the root
+      if (join != old_rev_thread && v_in != old_rev_thread) {
+        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
+             u = _parent[u]) {
+          _last_succ[u] = old_rev_thread;
+        }
+      } else {
+        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
+             u = _parent[u]) {
+          _last_succ[u] = _last_succ[u_out];
+        }
+      }
+
+      // Update _succ_num from v_in to join
+      for (u = v_in; u != join; u = _parent[u]) {
+        _succ_num[u] += old_succ_num;
+      }
+      // Update _succ_num from v_out to join
+      for (u = v_out; u != join; u = _parent[u]) {
+        _succ_num[u] -= old_succ_num;
+      }
+    }
+
+    // Update potentials
+    void updatePotential() {
+      Cost sigma = _forward[u_in] ?
+        _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] :
+        _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]];
+      // Update potentials in the subtree, which has been moved
+      int end = _thread[_last_succ[u_in]];
+      for (int u = u_in; u != end; u = _thread[u]) {
+        _pi[u] += sigma;
+      }
+    }
+
+    // Heuristic initial pivots
+    bool initialPivots() {
+      Value curr, total = 0;
+      std::vector<Node> supply_nodes, demand_nodes;
+      for (NodeIt u(_graph); u != INVALID; ++u) {
+        curr = _supply[_node_id[u]];
+        if (curr > 0) {
+          total += curr;
+          supply_nodes.push_back(u);
+        }
+        else if (curr < 0) {
+          demand_nodes.push_back(u);
+        }
+      }
+      if (_sum_supply > 0) total -= _sum_supply;
+      if (total <= 0) return true;
+
+      IntVector arc_vector;
+      if (_sum_supply >= 0) {
+        if (supply_nodes.size() == 1 && demand_nodes.size() == 1) {
+          // Perform a reverse graph search from the sink to the source
+          typename GR::template NodeMap<bool> reached(_graph, false);
+          Node s = supply_nodes[0], t = demand_nodes[0];
+          std::vector<Node> stack;
+          reached[t] = true;
+          stack.push_back(t);
+          while (!stack.empty()) {
+            Node u, v = stack.back();
+            stack.pop_back();
+            if (v == s) break;
+            for (InArcIt a(_graph, v); a != INVALID; ++a) {
+              if (reached[u = _graph.source(a)]) continue;
+              int j = _arc_id[a];
+              if (_cap[j] >= total) {
+                arc_vector.push_back(j);
+                reached[u] = true;
+                stack.push_back(u);
+              }
+            }
+          }
+        } else {
+          // Find the min. cost incomming arc for each demand node
+          for (int i = 0; i != int(demand_nodes.size()); ++i) {
+            Node v = demand_nodes[i];
+            Cost c, min_cost = std::numeric_limits<Cost>::max();
+            Arc min_arc = INVALID;
+            for (InArcIt a(_graph, v); a != INVALID; ++a) {
+              c = _cost[_arc_id[a]];
+              if (c < min_cost) {
+                min_cost = c;
+                min_arc = a;
+              }
+            }
+            if (min_arc != INVALID) {
+              arc_vector.push_back(_arc_id[min_arc]);
+            }
+          }
+        }
+      } else {
+        // Find the min. cost outgoing arc for each supply node
+        for (int i = 0; i != int(supply_nodes.size()); ++i) {
+          Node u = supply_nodes[i];
+          Cost c, min_cost = std::numeric_limits<Cost>::max();
+          Arc min_arc = INVALID;
+          for (OutArcIt a(_graph, u); a != INVALID; ++a) {
+            c = _cost[_arc_id[a]];
+            if (c < min_cost) {
+              min_cost = c;
+              min_arc = a;
+            }
+          }
+          if (min_arc != INVALID) {
+            arc_vector.push_back(_arc_id[min_arc]);
+          }
+        }
+      }
+
+      // Perform heuristic initial pivots
+      for (int i = 0; i != int(arc_vector.size()); ++i) {
+        in_arc = arc_vector[i];
+        if (_state[in_arc] * (_cost[in_arc] + _pi[_source[in_arc]] -
+            _pi[_target[in_arc]]) >= 0) continue;
+        findJoinNode();
+        bool change = findLeavingArc();
+        if (delta >= MAX) return false;
+        changeFlow(change);
+        if (change) {
+          updateTreeStructure();
+          updatePotential();
+        }
+      }
+      return true;
+    }
+
+    // Execute the algorithm
+    ProblemType start(PivotRule pivot_rule) {
+      // Select the pivot rule implementation
+      switch (pivot_rule) {
+        case FIRST_ELIGIBLE:
+          return start<FirstEligiblePivotRule>();
+        case BEST_ELIGIBLE:
+          return start<BestEligiblePivotRule>();
+        case BLOCK_SEARCH:
+          return start<BlockSearchPivotRule>();
+        case CANDIDATE_LIST:
+          return start<CandidateListPivotRule>();
+        case ALTERING_LIST:
+          return start<AlteringListPivotRule>();
+      }
+      return INFEASIBLE; // avoid warning
+    }
+
+    template <typename PivotRuleImpl>
+    ProblemType start() {
+      PivotRuleImpl pivot(*this);
+
+      // Perform heuristic initial pivots
+      if (!initialPivots()) return UNBOUNDED;
+
+      // Execute the Network Simplex algorithm
+      while (pivot.findEnteringArc()) {
+        findJoinNode();
+        bool change = findLeavingArc();
+        if (delta >= MAX) return UNBOUNDED;
+        changeFlow(change);
+        if (change) {
+          updateTreeStructure();
+          updatePotential();
+        }
+      }
+
+      // Check feasibility
+      for (int e = _search_arc_num; e != _all_arc_num; ++e) {
+        if (_flow[e] != 0) return INFEASIBLE;
+      }
+
+      // Transform the solution and the supply map to the original form
+      if (_have_lower) {
+        for (int i = 0; i != _arc_num; ++i) {
+          Value c = _lower[i];
+          if (c != 0) {
+            _flow[i] += c;
+            _supply[_source[i]] += c;
+            _supply[_target[i]] -= c;
+          }
+        }
+      }
+
+      // Shift potentials to meet the requirements of the GEQ/LEQ type
+      // optimality conditions
+      if (_sum_supply == 0) {
+        if (_stype == GEQ) {
+          Cost max_pot = -std::numeric_limits<Cost>::max();
+          for (int i = 0; i != _node_num; ++i) {
+            if (_pi[i] > max_pot) max_pot = _pi[i];
+          }
+          if (max_pot > 0) {
+            for (int i = 0; i != _node_num; ++i)
+              _pi[i] -= max_pot;
+          }
+        } else {
+          Cost min_pot = std::numeric_limits<Cost>::max();
+          for (int i = 0; i != _node_num; ++i) {
+            if (_pi[i] < min_pot) min_pot = _pi[i];
+          }
+          if (min_pot < 0) {
+            for (int i = 0; i != _node_num; ++i)
+              _pi[i] -= min_pot;
+          }
+        }
+      }
+
+      return OPTIMAL;
+    }
+
+  }; //class NetworkSimplex
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_NETWORK_SIMPLEX_H
Index: lemon/pairing_heap.h
===================================================================
--- lemon/pairing_heap.h	(revision 705)
+++ lemon/pairing_heap.h	(revision 705)
@@ -0,0 +1,474 @@
+/* -*- 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_PAIRING_HEAP_H
+#define LEMON_PAIRING_HEAP_H
+
+///\file
+///\ingroup heaps
+///\brief Pairing heap implementation.
+
+#include <vector>
+#include <utility>
+#include <functional>
+#include <lemon/math.h>
+
+namespace lemon {
+
+  /// \ingroup heaps
+  ///
+  ///\brief Pairing Heap.
+  ///
+  /// This class implements the \e pairing \e heap data structure.
+  /// It fully conforms to the \ref concepts::Heap "heap concept".
+  ///
+  /// The methods \ref increase() and \ref erase() are not efficient
+  /// in a pairing heap. In case of many calls of these operations,
+  /// it is better to use other heap structure, e.g. \ref BinHeap
+  /// "binary heap".
+  ///
+  /// \tparam PR Type of the priorities of the items.
+  /// \tparam IM A read-writable item map with \c int values, used
+  /// internally to handle the cross references.
+  /// \tparam CMP A functor class for comparing the priorities.
+  /// The default is \c std::less<PR>.
+#ifdef DOXYGEN
+  template <typename PR, typename IM, typename CMP>
+#else
+  template <typename PR, typename IM, typename CMP = std::less<PR> >
+#endif
+  class PairingHeap {
+  public:
+    /// Type of the item-int map.
+    typedef IM ItemIntMap;
+    /// Type of the priorities.
+    typedef PR Prio;
+    /// Type of the items stored in the heap.
+    typedef typename ItemIntMap::Key Item;
+    /// Functor type for comparing the priorities.
+    typedef CMP Compare;
+
+    /// \brief Type to represent the states of the items.
+    ///
+    /// Each item has a state associated to it. It can be "in heap",
+    /// "pre-heap" or "post-heap". The latter two are indifferent from the
+    /// heap's point of view, but may be useful to the user.
+    ///
+    /// The item-int map must be initialized in such way that it assigns
+    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
+    enum State {
+      IN_HEAP = 0,    ///< = 0.
+      PRE_HEAP = -1,  ///< = -1.
+      POST_HEAP = -2  ///< = -2.
+    };
+
+  private:
+    class store;
+
+    std::vector<store> _data;
+    int _min;
+    ItemIntMap &_iim;
+    Compare _comp;
+    int _num_items;
+
+  public:
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    explicit PairingHeap(ItemIntMap &map)
+      : _min(0), _iim(map), _num_items(0) {}
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    /// \param comp The function object used for comparing the priorities.
+    PairingHeap(ItemIntMap &map, const Compare &comp)
+      : _min(0), _iim(map), _comp(comp), _num_items(0) {}
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// This function returns the number of items stored in the heap.
+    int size() const { return _num_items; }
+
+    /// \brief Check if the heap is empty.
+    ///
+    /// This function returns \c true if the heap is empty.
+    bool empty() const { return _num_items==0; }
+
+    /// \brief Make the heap empty.
+    ///
+    /// This functon makes the heap empty.
+    /// It does not change the cross reference map. If you want to reuse
+    /// a heap that is not surely empty, you should first clear it and
+    /// then you should set the cross reference map to \c PRE_HEAP
+    /// for each item.
+    void clear() {
+      _data.clear();
+      _min = 0;
+      _num_items = 0;
+    }
+
+    /// \brief Set the priority of an item or insert it, if it is
+    /// not stored in the heap.
+    ///
+    /// This method sets the priority of the given item if it is
+    /// already stored in the heap. Otherwise it inserts the given
+    /// item into the heap with the given priority.
+    /// \param item The item.
+    /// \param value The priority.
+    void set (const Item& item, const Prio& value) {
+      int i=_iim[item];
+      if ( i>=0 && _data[i].in ) {
+        if ( _comp(value, _data[i].prio) ) decrease(item, value);
+        if ( _comp(_data[i].prio, value) ) increase(item, value);
+      } else push(item, value);
+    }
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// This function inserts the given item into the heap with the
+    /// given priority.
+    /// \param item The item to insert.
+    /// \param value The priority of the item.
+    /// \pre \e item must not be stored in the heap.
+    void push (const Item& item, const Prio& value) {
+      int i=_iim[item];
+      if( i<0 ) {
+        int s=_data.size();
+        _iim.set(item, s);
+        store st;
+        st.name=item;
+        _data.push_back(st);
+        i=s;
+      } else {
+        _data[i].parent=_data[i].child=-1;
+        _data[i].left_child=false;
+        _data[i].degree=0;
+        _data[i].in=true;
+      }
+
+      _data[i].prio=value;
+
+      if ( _num_items!=0 ) {
+        if ( _comp( value, _data[_min].prio) ) {
+          fuse(i,_min);
+          _min=i;
+        }
+        else fuse(_min,i);
+      }
+      else _min=i;
+
+      ++_num_items;
+    }
+
+    /// \brief Return the item having minimum priority.
+    ///
+    /// This function returns the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    Item top() const { return _data[_min].name; }
+
+    /// \brief The minimum priority.
+    ///
+    /// This function returns the minimum priority.
+    /// \pre The heap must be non-empty.
+    const Prio& prio() const { return _data[_min].prio; }
+
+    /// \brief The priority of the given item.
+    ///
+    /// This function returns the priority of the given item.
+    /// \param item The item.
+    /// \pre \e item must be in the heap.
+    const Prio& operator[](const Item& item) const {
+      return _data[_iim[item]].prio;
+    }
+
+    /// \brief Remove the item having minimum priority.
+    ///
+    /// This function removes the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      std::vector<int> trees;
+      int i=0, child_right = 0;
+      _data[_min].in=false;
+
+      if( -1!=_data[_min].child ) {
+        i=_data[_min].child;
+        trees.push_back(i);
+        _data[i].parent = -1;
+        _data[_min].child = -1;
+
+        int ch=-1;
+        while( _data[i].child!=-1 ) {
+          ch=_data[i].child;
+          if( _data[ch].left_child && i==_data[ch].parent ) {
+            break;
+          } else {
+            if( _data[ch].left_child ) {
+              child_right=_data[ch].parent;
+              _data[ch].parent = i;
+              --_data[i].degree;
+            }
+            else {
+              child_right=ch;
+              _data[i].child=-1;
+              _data[i].degree=0;
+            }
+            _data[child_right].parent = -1;
+            trees.push_back(child_right);
+            i = child_right;
+          }
+        }
+
+        int num_child = trees.size();
+        int other;
+        for( i=0; i<num_child-1; i+=2 ) {
+          if ( !_comp(_data[trees[i]].prio, _data[trees[i+1]].prio) ) {
+            other=trees[i];
+            trees[i]=trees[i+1];
+            trees[i+1]=other;
+          }
+          fuse( trees[i], trees[i+1] );
+        }
+
+        i = (0==(num_child % 2)) ? num_child-2 : num_child-1;
+        while(i>=2) {
+          if ( _comp(_data[trees[i]].prio, _data[trees[i-2]].prio) ) {
+            other=trees[i];
+            trees[i]=trees[i-2];
+            trees[i-2]=other;
+          }
+          fuse( trees[i-2], trees[i] );
+          i-=2;
+        }
+        _min = trees[0];
+      }
+      else {
+        _min = _data[_min].child;
+      }
+
+      if (_min >= 0) _data[_min].left_child = false;
+      --_num_items;
+    }
+
+    /// \brief Remove the given item from the heap.
+    ///
+    /// This function removes the given item from the heap if it is
+    /// already stored.
+    /// \param item The item to delete.
+    /// \pre \e item must be in the heap.
+    void erase (const Item& item) {
+      int i=_iim[item];
+      if ( i>=0 && _data[i].in ) {
+        decrease( item, _data[_min].prio-1 );
+        pop();
+      }
+    }
+
+    /// \brief Decrease the priority of an item to the given value.
+    ///
+    /// This function decreases the priority of an item to the given value.
+    /// \param item The item.
+    /// \param value The priority.
+    /// \pre \e item must be stored in the heap with priority at least \e value.
+    void decrease (Item item, const Prio& value) {
+      int i=_iim[item];
+      _data[i].prio=value;
+      int p=_data[i].parent;
+
+      if( _data[i].left_child && i!=_data[p].child ) {
+        p=_data[p].parent;
+      }
+
+      if ( p!=-1 && _comp(value,_data[p].prio) ) {
+        cut(i,p);
+        if ( _comp(_data[_min].prio,value) ) {
+          fuse(_min,i);
+        } else {
+          fuse(i,_min);
+          _min=i;
+        }
+      }
+    }
+
+    /// \brief Increase the priority of an item to the given value.
+    ///
+    /// This function increases the priority of an item to the given value.
+    /// \param item The item.
+    /// \param value The priority.
+    /// \pre \e item must be stored in the heap with priority at most \e value.
+    void increase (Item item, const Prio& value) {
+      erase(item);
+      push(item,value);
+    }
+
+    /// \brief Return the state of an item.
+    ///
+    /// This method returns \c PRE_HEAP if the given item has never
+    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
+    /// and \c POST_HEAP otherwise.
+    /// In the latter case it is possible that the item will get back
+    /// to the heap again.
+    /// \param item The item.
+    State state(const Item &item) const {
+      int i=_iim[item];
+      if( i>=0 ) {
+        if( _data[i].in ) i=0;
+        else i=-2;
+      }
+      return State(i);
+    }
+
+    /// \brief Set the state of an item in the heap.
+    ///
+    /// This function sets the state of the given item in the heap.
+    /// It can be used to manually clear the heap when it is important
+    /// to achive better time complexity.
+    /// \param i The item.
+    /// \param st The state. It should not be \c IN_HEAP.
+    void state(const Item& i, State st) {
+      switch (st) {
+      case POST_HEAP:
+      case PRE_HEAP:
+        if (state(i) == IN_HEAP) erase(i);
+        _iim[i]=st;
+        break;
+      case IN_HEAP:
+        break;
+      }
+    }
+
+  private:
+
+    void cut(int a, int b) {
+      int child_a;
+      switch (_data[a].degree) {
+        case 2:
+          child_a = _data[_data[a].child].parent;
+          if( _data[a].left_child ) {
+            _data[child_a].left_child=true;
+            _data[b].child=child_a;
+            _data[child_a].parent=_data[a].parent;
+          }
+          else {
+            _data[child_a].left_child=false;
+            _data[child_a].parent=b;
+            if( a!=_data[b].child )
+              _data[_data[b].child].parent=child_a;
+            else
+              _data[b].child=child_a;
+          }
+          --_data[a].degree;
+          _data[_data[a].child].parent=a;
+          break;
+
+        case 1:
+          child_a = _data[a].child;
+          if( !_data[child_a].left_child ) {
+            --_data[a].degree;
+            if( _data[a].left_child ) {
+              _data[child_a].left_child=true;
+              _data[child_a].parent=_data[a].parent;
+              _data[b].child=child_a;
+            }
+            else {
+              _data[child_a].left_child=false;
+              _data[child_a].parent=b;
+              if( a!=_data[b].child )
+                _data[_data[b].child].parent=child_a;
+              else
+                _data[b].child=child_a;
+            }
+            _data[a].child=-1;
+          }
+          else {
+            --_data[b].degree;
+            if( _data[a].left_child ) {
+              _data[b].child =
+                (1==_data[b].degree) ? _data[a].parent : -1;
+            } else {
+              if (1==_data[b].degree)
+                _data[_data[b].child].parent=b;
+              else
+                _data[b].child=-1;
+            }
+          }
+          break;
+
+        case 0:
+          --_data[b].degree;
+          if( _data[a].left_child ) {
+            _data[b].child =
+              (0!=_data[b].degree) ? _data[a].parent : -1;
+          } else {
+            if( 0!=_data[b].degree )
+              _data[_data[b].child].parent=b;
+            else
+              _data[b].child=-1;
+          }
+          break;
+      }
+      _data[a].parent=-1;
+      _data[a].left_child=false;
+    }
+
+    void fuse(int a, int b) {
+      int child_a = _data[a].child;
+      int child_b = _data[b].child;
+      _data[a].child=b;
+      _data[b].parent=a;
+      _data[b].left_child=true;
+
+      if( -1!=child_a ) {
+        _data[b].child=child_a;
+        _data[child_a].parent=b;
+        _data[child_a].left_child=false;
+        ++_data[b].degree;
+
+        if( -1!=child_b ) {
+           _data[b].child=child_b;
+           _data[child_b].parent=child_a;
+        }
+      }
+      else { ++_data[a].degree; }
+    }
+
+    class store {
+      friend class PairingHeap;
+
+      Item name;
+      int parent;
+      int child;
+      bool left_child;
+      int degree;
+      bool in;
+      Prio prio;
+
+      store() : parent(-1), child(-1), left_child(false), degree(0), in(true) {}
+    };
+  };
+
+} //namespace lemon
+
+#endif //LEMON_PAIRING_HEAP_H
+
Index: lemon/path.h
===================================================================
--- lemon/path.h	(revision 559)
+++ lemon/path.h	(revision 958)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -65,4 +65,10 @@
     Path() {}
 
+    /// \brief Copy constructor
+    ///
+    Path(const Path& cpath) {
+      pathCopy(cpath, *this);
+    }
+
     /// \brief Template copy constructor
     ///
@@ -71,5 +77,12 @@
     template <typename CPath>
     Path(const CPath& cpath) {
-      copyPath(*this, cpath);
+      pathCopy(cpath, *this);
+    }
+
+    /// \brief Copy assignment
+    ///
+    Path& operator=(const Path& cpath) {
+      pathCopy(cpath, *this);
+      return *this;
     }
 
@@ -79,5 +92,5 @@
     template <typename CPath>
     Path& operator=(const CPath& cpath) {
-      copyPath(*this, cpath);
+      pathCopy(cpath, *this);
       return *this;
     }
@@ -253,4 +266,10 @@
     SimplePath() {}
 
+    /// \brief Copy constructor
+    ///
+    SimplePath(const SimplePath& cpath) {
+      pathCopy(cpath, *this);
+    }
+
     /// \brief Template copy constructor
     ///
@@ -259,5 +278,12 @@
     template <typename CPath>
     SimplePath(const CPath& cpath) {
-      copyPath(*this, cpath);
+      pathCopy(cpath, *this);
+    }
+
+    /// \brief Copy assignment
+    ///
+    SimplePath& operator=(const SimplePath& cpath) {
+      pathCopy(cpath, *this);
+      return *this;
     }
 
@@ -268,5 +294,5 @@
     template <typename CPath>
     SimplePath& operator=(const CPath& cpath) {
-      copyPath(*this, cpath);
+      pathCopy(cpath, *this);
       return *this;
     }
@@ -432,4 +458,10 @@
     ListPath() : first(0), last(0) {}
 
+    /// \brief Copy constructor
+    ///
+    ListPath(const ListPath& cpath) : first(0), last(0) {
+      pathCopy(cpath, *this);
+    }
+
     /// \brief Template copy constructor
     ///
@@ -438,5 +470,5 @@
     template <typename CPath>
     ListPath(const CPath& cpath) : first(0), last(0) {
-      copyPath(*this, cpath);
+      pathCopy(cpath, *this);
     }
 
@@ -448,4 +480,11 @@
     }
 
+    /// \brief Copy assignment
+    ///
+    ListPath& operator=(const ListPath& cpath) {
+      pathCopy(cpath, *this);
+      return *this;
+    }
+
     /// \brief Template copy assignment
     ///
@@ -454,5 +493,5 @@
     template <typename CPath>
     ListPath& operator=(const CPath& cpath) {
-      copyPath(*this, cpath);
+      pathCopy(cpath, *this);
       return *this;
     }
@@ -759,4 +798,10 @@
     StaticPath() : len(0), arcs(0) {}
 
+    /// \brief Copy constructor
+    ///
+    StaticPath(const StaticPath& cpath) : arcs(0) {
+      pathCopy(cpath, *this);
+    }
+
     /// \brief Template copy constructor
     ///
@@ -764,5 +809,5 @@
     template <typename CPath>
     StaticPath(const CPath& cpath) : arcs(0) {
-      copyPath(*this, cpath);
+      pathCopy(cpath, *this);
     }
 
@@ -774,4 +819,11 @@
     }
 
+    /// \brief Copy assignment
+    ///
+    StaticPath& operator=(const StaticPath& cpath) {
+      pathCopy(cpath, *this);
+      return *this;
+    }
+
     /// \brief Template copy assignment
     ///
@@ -780,5 +832,5 @@
     template <typename CPath>
     StaticPath& operator=(const CPath& cpath) {
-      copyPath(*this, cpath);
+      pathCopy(cpath, *this);
       return *this;
     }
@@ -929,56 +981,56 @@
     };
 
-    template <typename Target, typename Source,
-              bool buildEnable = BuildTagIndicator<Target>::value>
+    template <typename From, typename To,
+              bool buildEnable = BuildTagIndicator<To>::value>
     struct PathCopySelectorForward {
-      static void copy(Target& target, const Source& source) {
-        target.clear();
-        for (typename Source::ArcIt it(source); it != INVALID; ++it) {
-          target.addBack(it);
+      static void copy(const From& from, To& to) {
+        to.clear();
+        for (typename From::ArcIt it(from); it != INVALID; ++it) {
+          to.addBack(it);
         }
       }
     };
 
-    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>
+    template <typename From, typename To>
+    struct PathCopySelectorForward<From, To, true> {
+      static void copy(const From& from, To& to) {
+        to.clear();
+        to.build(from);
+      }
+    };
+
+    template <typename From, typename To,
+              bool buildEnable = BuildTagIndicator<To>::value>
     struct PathCopySelectorBackward {
-      static void copy(Target& target, const Source& source) {
-        target.clear();
-        for (typename Source::RevArcIt it(source); it != INVALID; ++it) {
-          target.addFront(it);
+      static void copy(const From& from, To& to) {
+        to.clear();
+        for (typename From::RevArcIt it(from); it != INVALID; ++it) {
+          to.addFront(it);
         }
       }
     };
 
-    template <typename Target, typename Source>
-    struct PathCopySelectorBackward<Target, Source, true> {
-      static void copy(Target& target, const Source& source) {
-        target.clear();
-        target.buildRev(source);
-      }
-    };
-
-    
-    template <typename Target, typename Source,
-              bool revEnable = RevPathTagIndicator<Source>::value>
+    template <typename From, typename To>
+    struct PathCopySelectorBackward<From, To, true> {
+      static void copy(const From& from, To& to) {
+        to.clear();
+        to.buildRev(from);
+      }
+    };
+
+
+    template <typename From, typename To,
+              bool revEnable = RevPathTagIndicator<From>::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);
-      }      
+      static void copy(const From& from, To& to) {
+        PathCopySelectorForward<From, To>::copy(from, to);
+      }
+    };
+
+    template <typename From, typename To>
+    struct PathCopySelector<From, To, true> {
+      static void copy(const From& from, To& to) {
+        PathCopySelectorBackward<From, To>::copy(from, to);
+      }
     };
 
@@ -988,9 +1040,17 @@
   /// \brief Make a copy of a path.
   ///
-  ///  This function makes a copy of a path.
-  template <typename Target, typename Source>
-  void copyPath(Target& target, const Source& source) {
-    checkConcept<concepts::PathDumper<typename Source::Digraph>, Source>();
-    _path_bits::PathCopySelector<Target, Source>::copy(target, source);
+  /// This function makes a copy of a path.
+  template <typename From, typename To>
+  void pathCopy(const From& from, To& to) {
+    checkConcept<concepts::PathDumper<typename From::Digraph>, From>();
+    _path_bits::PathCopySelector<From, To>::copy(from, to);
+  }
+
+  /// \brief Deprecated version of \ref pathCopy().
+  ///
+  /// Deprecated version of \ref pathCopy() (only for reverse compatibility).
+  template <typename To, typename From>
+  void copyPath(To& to, const From& from) {
+    pathCopy(from, to);
   }
 
@@ -1016,16 +1076,18 @@
   /// \brief The source of a path
   ///
-  /// This function returns the source of the given path.
+  /// This function returns the source node of the given path.
+  /// If the path is empty, then it returns \c INVALID.
   template <typename Digraph, typename Path>
   typename Digraph::Node pathSource(const Digraph& digraph, const Path& path) {
-    return digraph.source(path.front());
+    return path.empty() ? INVALID : digraph.source(path.front());
   }
 
   /// \brief The target of a path
   ///
-  /// This function returns the target of the given path.
+  /// This function returns the target node of the given path.
+  /// If the path is empty, then it returns \c INVALID.
   template <typename Digraph, typename Path>
   typename Digraph::Node pathTarget(const Digraph& digraph, const Path& path) {
-    return digraph.target(path.back());
+    return path.empty() ? INVALID : digraph.target(path.back());
   }
 
Index: lemon/planarity.h
===================================================================
--- lemon/planarity.h	(revision 965)
+++ lemon/planarity.h	(revision 965)
@@ -0,0 +1,2754 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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_PLANARITY_H
+#define LEMON_PLANARITY_H
+
+/// \ingroup planar
+/// \file
+/// \brief Planarity checking, embedding, drawing and coloring
+
+#include <vector>
+#include <list>
+
+#include <lemon/dfs.h>
+#include <lemon/bfs.h>
+#include <lemon/radix_sort.h>
+#include <lemon/maps.h>
+#include <lemon/path.h>
+#include <lemon/bucket_heap.h>
+#include <lemon/adaptors.h>
+#include <lemon/edge_set.h>
+#include <lemon/color.h>
+#include <lemon/dim2.h>
+
+namespace lemon {
+
+  namespace _planarity_bits {
+
+    template <typename Graph>
+    struct PlanarityVisitor : DfsVisitor<Graph> {
+
+      TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+      typedef typename Graph::template NodeMap<Arc> PredMap;
+
+      typedef typename Graph::template EdgeMap<bool> TreeMap;
+
+      typedef typename Graph::template NodeMap<int> OrderMap;
+      typedef std::vector<Node> OrderList;
+
+      typedef typename Graph::template NodeMap<int> LowMap;
+      typedef typename Graph::template NodeMap<int> AncestorMap;
+
+      PlanarityVisitor(const Graph& graph,
+                       PredMap& pred_map, TreeMap& tree_map,
+                       OrderMap& order_map, OrderList& order_list,
+                       AncestorMap& ancestor_map, LowMap& low_map)
+        : _graph(graph), _pred_map(pred_map), _tree_map(tree_map),
+          _order_map(order_map), _order_list(order_list),
+          _ancestor_map(ancestor_map), _low_map(low_map) {}
+
+      void reach(const Node& node) {
+        _order_map[node] = _order_list.size();
+        _low_map[node] = _order_list.size();
+        _ancestor_map[node] = _order_list.size();
+        _order_list.push_back(node);
+      }
+
+      void discover(const Arc& arc) {
+        Node target = _graph.target(arc);
+
+        _tree_map[arc] = true;
+        _pred_map[target] = arc;
+      }
+
+      void examine(const Arc& arc) {
+        Node source = _graph.source(arc);
+        Node target = _graph.target(arc);
+
+        if (_order_map[target] < _order_map[source] && !_tree_map[arc]) {
+          if (_low_map[source] > _order_map[target]) {
+            _low_map[source] = _order_map[target];
+          }
+          if (_ancestor_map[source] > _order_map[target]) {
+            _ancestor_map[source] = _order_map[target];
+          }
+        }
+      }
+
+      void backtrack(const Arc& arc) {
+        Node source = _graph.source(arc);
+        Node target = _graph.target(arc);
+
+        if (_low_map[source] > _low_map[target]) {
+          _low_map[source] = _low_map[target];
+        }
+      }
+
+      const Graph& _graph;
+      PredMap& _pred_map;
+      TreeMap& _tree_map;
+      OrderMap& _order_map;
+      OrderList& _order_list;
+      AncestorMap& _ancestor_map;
+      LowMap& _low_map;
+    };
+
+    template <typename Graph, bool embedding = true>
+    struct NodeDataNode {
+      int prev, next;
+      int visited;
+      typename Graph::Arc first;
+      bool inverted;
+    };
+
+    template <typename Graph>
+    struct NodeDataNode<Graph, false> {
+      int prev, next;
+      int visited;
+    };
+
+    template <typename Graph>
+    struct ChildListNode {
+      typedef typename Graph::Node Node;
+      Node first;
+      Node prev, next;
+    };
+
+    template <typename Graph>
+    struct ArcListNode {
+      typename Graph::Arc prev, next;
+    };
+
+    template <typename Graph>
+    class PlanarityChecking {
+    private:
+
+      TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+      const Graph& _graph;
+
+    private:
+
+      typedef typename Graph::template NodeMap<Arc> PredMap;
+
+      typedef typename Graph::template EdgeMap<bool> TreeMap;
+
+      typedef typename Graph::template NodeMap<int> OrderMap;
+      typedef std::vector<Node> OrderList;
+
+      typedef typename Graph::template NodeMap<int> LowMap;
+      typedef typename Graph::template NodeMap<int> AncestorMap;
+
+      typedef _planarity_bits::NodeDataNode<Graph> NodeDataNode;
+      typedef std::vector<NodeDataNode> NodeData;
+
+      typedef _planarity_bits::ChildListNode<Graph> ChildListNode;
+      typedef typename Graph::template NodeMap<ChildListNode> ChildLists;
+
+      typedef typename Graph::template NodeMap<std::list<int> > MergeRoots;
+
+      typedef typename Graph::template NodeMap<bool> EmbedArc;
+
+    public:
+
+      PlanarityChecking(const Graph& graph) : _graph(graph) {}
+
+      bool run() {
+        typedef _planarity_bits::PlanarityVisitor<Graph> Visitor;
+
+        PredMap pred_map(_graph, INVALID);
+        TreeMap tree_map(_graph, false);
+
+        OrderMap order_map(_graph, -1);
+        OrderList order_list;
+
+        AncestorMap ancestor_map(_graph, -1);
+        LowMap low_map(_graph, -1);
+
+        Visitor visitor(_graph, pred_map, tree_map,
+                        order_map, order_list, ancestor_map, low_map);
+        DfsVisit<Graph, Visitor> visit(_graph, visitor);
+        visit.run();
+
+        ChildLists child_lists(_graph);
+        createChildLists(tree_map, order_map, low_map, child_lists);
+
+        NodeData node_data(2 * order_list.size());
+
+        EmbedArc embed_arc(_graph, false);
+
+        MergeRoots merge_roots(_graph);
+
+        for (int i = order_list.size() - 1; i >= 0; --i) {
+
+          Node node = order_list[i];
+
+          Node source = node;
+          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
+            Node target = _graph.target(e);
+
+            if (order_map[source] < order_map[target] && tree_map[e]) {
+              initFace(target, node_data, order_map, order_list);
+            }
+          }
+
+          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
+            Node target = _graph.target(e);
+
+            if (order_map[source] < order_map[target] && !tree_map[e]) {
+              embed_arc[target] = true;
+              walkUp(target, source, i, pred_map, low_map,
+                     order_map, order_list, node_data, merge_roots);
+            }
+          }
+
+          for (typename MergeRoots::Value::iterator it =
+                 merge_roots[node].begin();
+               it != merge_roots[node].end(); ++it) {
+            int rn = *it;
+            walkDown(rn, i, node_data, order_list, child_lists,
+                     ancestor_map, low_map, embed_arc, merge_roots);
+          }
+          merge_roots[node].clear();
+
+          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
+            Node target = _graph.target(e);
+
+            if (order_map[source] < order_map[target] && !tree_map[e]) {
+              if (embed_arc[target]) {
+                return false;
+              }
+            }
+          }
+        }
+
+        return true;
+      }
+
+    private:
+
+      void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
+                            const LowMap& low_map, ChildLists& child_lists) {
+
+        for (NodeIt n(_graph); n != INVALID; ++n) {
+          Node source = n;
+
+          std::vector<Node> targets;
+          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+            Node target = _graph.target(e);
+
+            if (order_map[source] < order_map[target] && tree_map[e]) {
+              targets.push_back(target);
+            }
+          }
+
+          if (targets.size() == 0) {
+            child_lists[source].first = INVALID;
+          } else if (targets.size() == 1) {
+            child_lists[source].first = targets[0];
+            child_lists[targets[0]].prev = INVALID;
+            child_lists[targets[0]].next = INVALID;
+          } else {
+            radixSort(targets.begin(), targets.end(), mapToFunctor(low_map));
+            for (int i = 1; i < int(targets.size()); ++i) {
+              child_lists[targets[i]].prev = targets[i - 1];
+              child_lists[targets[i - 1]].next = targets[i];
+            }
+            child_lists[targets.back()].next = INVALID;
+            child_lists[targets.front()].prev = INVALID;
+            child_lists[source].first = targets.front();
+          }
+        }
+      }
+
+      void walkUp(const Node& node, Node root, int rorder,
+                  const PredMap& pred_map, const LowMap& low_map,
+                  const OrderMap& order_map, const OrderList& order_list,
+                  NodeData& node_data, MergeRoots& merge_roots) {
+
+        int na, nb;
+        bool da, db;
+
+        na = nb = order_map[node];
+        da = true; db = false;
+
+        while (true) {
+
+          if (node_data[na].visited == rorder) break;
+          if (node_data[nb].visited == rorder) break;
+
+          node_data[na].visited = rorder;
+          node_data[nb].visited = rorder;
+
+          int rn = -1;
+
+          if (na >= int(order_list.size())) {
+            rn = na;
+          } else if (nb >= int(order_list.size())) {
+            rn = nb;
+          }
+
+          if (rn == -1) {
+            int nn;
+
+            nn = da ? node_data[na].prev : node_data[na].next;
+            da = node_data[nn].prev != na;
+            na = nn;
+
+            nn = db ? node_data[nb].prev : node_data[nb].next;
+            db = node_data[nn].prev != nb;
+            nb = nn;
+
+          } else {
+
+            Node rep = order_list[rn - order_list.size()];
+            Node parent = _graph.source(pred_map[rep]);
+
+            if (low_map[rep] < rorder) {
+              merge_roots[parent].push_back(rn);
+            } else {
+              merge_roots[parent].push_front(rn);
+            }
+
+            if (parent != root) {
+              na = nb = order_map[parent];
+              da = true; db = false;
+            } else {
+              break;
+            }
+          }
+        }
+      }
+
+      void walkDown(int rn, int rorder, NodeData& node_data,
+                    OrderList& order_list, ChildLists& child_lists,
+                    AncestorMap& ancestor_map, LowMap& low_map,
+                    EmbedArc& embed_arc, MergeRoots& merge_roots) {
+
+        std::vector<std::pair<int, bool> > merge_stack;
+
+        for (int di = 0; di < 2; ++di) {
+          bool rd = di == 0;
+          int pn = rn;
+          int n = rd ? node_data[rn].next : node_data[rn].prev;
+
+          while (n != rn) {
+
+            Node node = order_list[n];
+
+            if (embed_arc[node]) {
+
+              // Merging components on the critical path
+              while (!merge_stack.empty()) {
+
+                // Component root
+                int cn = merge_stack.back().first;
+                bool cd = merge_stack.back().second;
+                merge_stack.pop_back();
+
+                // Parent of component
+                int dn = merge_stack.back().first;
+                bool dd = merge_stack.back().second;
+                merge_stack.pop_back();
+
+                Node parent = order_list[dn];
+
+                // Erasing from merge_roots
+                merge_roots[parent].pop_front();
+
+                Node child = order_list[cn - order_list.size()];
+
+                // Erasing from child_lists
+                if (child_lists[child].prev != INVALID) {
+                  child_lists[child_lists[child].prev].next =
+                    child_lists[child].next;
+                } else {
+                  child_lists[parent].first = child_lists[child].next;
+                }
+
+                if (child_lists[child].next != INVALID) {
+                  child_lists[child_lists[child].next].prev =
+                    child_lists[child].prev;
+                }
+
+                // Merging external faces
+                {
+                  int en = cn;
+                  cn = cd ? node_data[cn].prev : node_data[cn].next;
+                  cd = node_data[cn].next == en;
+
+                }
+
+                if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
+                if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
+
+              }
+
+              bool d = pn == node_data[n].prev;
+
+              if (node_data[n].prev == node_data[n].next &&
+                  node_data[n].inverted) {
+                d = !d;
+              }
+
+              // Embedding arc into external face
+              if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
+              if (d) node_data[n].prev = rn; else node_data[n].next = rn;
+              pn = rn;
+
+              embed_arc[order_list[n]] = false;
+            }
+
+            if (!merge_roots[node].empty()) {
+
+              bool d = pn == node_data[n].prev;
+
+              merge_stack.push_back(std::make_pair(n, d));
+
+              int rn = merge_roots[node].front();
+
+              int xn = node_data[rn].next;
+              Node xnode = order_list[xn];
+
+              int yn = node_data[rn].prev;
+              Node ynode = order_list[yn];
+
+              bool rd;
+              if (!external(xnode, rorder, child_lists,
+                            ancestor_map, low_map)) {
+                rd = true;
+              } else if (!external(ynode, rorder, child_lists,
+                                   ancestor_map, low_map)) {
+                rd = false;
+              } else if (pertinent(xnode, embed_arc, merge_roots)) {
+                rd = true;
+              } else {
+                rd = false;
+              }
+
+              merge_stack.push_back(std::make_pair(rn, rd));
+
+              pn = rn;
+              n = rd ? xn : yn;
+
+            } else if (!external(node, rorder, child_lists,
+                                 ancestor_map, low_map)) {
+              int nn = (node_data[n].next != pn ?
+                        node_data[n].next : node_data[n].prev);
+
+              bool nd = n == node_data[nn].prev;
+
+              if (nd) node_data[nn].prev = pn;
+              else node_data[nn].next = pn;
+
+              if (n == node_data[pn].prev) node_data[pn].prev = nn;
+              else node_data[pn].next = nn;
+
+              node_data[nn].inverted =
+                (node_data[nn].prev == node_data[nn].next && nd != rd);
+
+              n = nn;
+            }
+            else break;
+
+          }
+
+          if (!merge_stack.empty() || n == rn) {
+            break;
+          }
+        }
+      }
+
+      void initFace(const Node& node, NodeData& node_data,
+                    const OrderMap& order_map, const OrderList& order_list) {
+        int n = order_map[node];
+        int rn = n + order_list.size();
+
+        node_data[n].next = node_data[n].prev = rn;
+        node_data[rn].next = node_data[rn].prev = n;
+
+        node_data[n].visited = order_list.size();
+        node_data[rn].visited = order_list.size();
+
+      }
+
+      bool external(const Node& node, int rorder,
+                    ChildLists& child_lists, AncestorMap& ancestor_map,
+                    LowMap& low_map) {
+        Node child = child_lists[node].first;
+
+        if (child != INVALID) {
+          if (low_map[child] < rorder) return true;
+        }
+
+        if (ancestor_map[node] < rorder) return true;
+
+        return false;
+      }
+
+      bool pertinent(const Node& node, const EmbedArc& embed_arc,
+                     const MergeRoots& merge_roots) {
+        return !merge_roots[node].empty() || embed_arc[node];
+      }
+
+    };
+
+  }
+
+  /// \ingroup planar
+  ///
+  /// \brief Planarity checking of an undirected simple graph
+  ///
+  /// This function implements the Boyer-Myrvold algorithm for
+  /// planarity checking of an undirected simple graph. It is a simplified
+  /// version of the PlanarEmbedding algorithm class because neither
+  /// the embedding nor the Kuratowski subdivisons are computed.
+  template <typename GR>
+  bool checkPlanarity(const GR& graph) {
+    _planarity_bits::PlanarityChecking<GR> pc(graph);
+    return pc.run();
+  }
+
+  /// \ingroup planar
+  ///
+  /// \brief Planar embedding of an undirected simple graph
+  ///
+  /// This class implements the Boyer-Myrvold algorithm for planar
+  /// embedding of an undirected simple graph. The planar embedding is an
+  /// ordering of the outgoing edges of the nodes, which is a possible
+  /// configuration to draw the graph in the plane. If there is not
+  /// such ordering then the graph contains a K<sub>5</sub> (full graph
+  /// with 5 nodes) or a K<sub>3,3</sub> (complete bipartite graph on
+  /// 3 Red and 3 Blue nodes) subdivision.
+  ///
+  /// The current implementation calculates either an embedding or a
+  /// Kuratowski subdivision. The running time of the algorithm is O(n).
+  ///
+  /// \see PlanarDrawing, checkPlanarity()
+  template <typename Graph>
+  class PlanarEmbedding {
+  private:
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    const Graph& _graph;
+    typename Graph::template ArcMap<Arc> _embedding;
+
+    typename Graph::template EdgeMap<bool> _kuratowski;
+
+  private:
+
+    typedef typename Graph::template NodeMap<Arc> PredMap;
+
+    typedef typename Graph::template EdgeMap<bool> TreeMap;
+
+    typedef typename Graph::template NodeMap<int> OrderMap;
+    typedef std::vector<Node> OrderList;
+
+    typedef typename Graph::template NodeMap<int> LowMap;
+    typedef typename Graph::template NodeMap<int> AncestorMap;
+
+    typedef _planarity_bits::NodeDataNode<Graph> NodeDataNode;
+    typedef std::vector<NodeDataNode> NodeData;
+
+    typedef _planarity_bits::ChildListNode<Graph> ChildListNode;
+    typedef typename Graph::template NodeMap<ChildListNode> ChildLists;
+
+    typedef typename Graph::template NodeMap<std::list<int> > MergeRoots;
+
+    typedef typename Graph::template NodeMap<Arc> EmbedArc;
+
+    typedef _planarity_bits::ArcListNode<Graph> ArcListNode;
+    typedef typename Graph::template ArcMap<ArcListNode> ArcLists;
+
+    typedef typename Graph::template NodeMap<bool> FlipMap;
+
+    typedef typename Graph::template NodeMap<int> TypeMap;
+
+    enum IsolatorNodeType {
+      HIGHX = 6, LOWX = 7,
+      HIGHY = 8, LOWY = 9,
+      ROOT = 10, PERTINENT = 11,
+      INTERNAL = 12
+    };
+
+  public:
+
+    /// \brief The map type for storing the embedding
+    ///
+    /// The map type for storing the embedding.
+    /// \see embeddingMap()
+    typedef typename Graph::template ArcMap<Arc> EmbeddingMap;
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    /// \pre The graph must be simple, i.e. it should not
+    /// contain parallel or loop arcs.
+    PlanarEmbedding(const Graph& graph)
+      : _graph(graph), _embedding(_graph), _kuratowski(graph, false) {}
+
+    /// \brief Run the algorithm.
+    ///
+    /// This function runs the algorithm.
+    /// \param kuratowski If this parameter is set to \c false, then the
+    /// algorithm does not compute a Kuratowski subdivision.
+    /// \return \c true if the graph is planar.
+    bool run(bool kuratowski = true) {
+      typedef _planarity_bits::PlanarityVisitor<Graph> Visitor;
+
+      PredMap pred_map(_graph, INVALID);
+      TreeMap tree_map(_graph, false);
+
+      OrderMap order_map(_graph, -1);
+      OrderList order_list;
+
+      AncestorMap ancestor_map(_graph, -1);
+      LowMap low_map(_graph, -1);
+
+      Visitor visitor(_graph, pred_map, tree_map,
+                      order_map, order_list, ancestor_map, low_map);
+      DfsVisit<Graph, Visitor> visit(_graph, visitor);
+      visit.run();
+
+      ChildLists child_lists(_graph);
+      createChildLists(tree_map, order_map, low_map, child_lists);
+
+      NodeData node_data(2 * order_list.size());
+
+      EmbedArc embed_arc(_graph, INVALID);
+
+      MergeRoots merge_roots(_graph);
+
+      ArcLists arc_lists(_graph);
+
+      FlipMap flip_map(_graph, false);
+
+      for (int i = order_list.size() - 1; i >= 0; --i) {
+
+        Node node = order_list[i];
+
+        node_data[i].first = INVALID;
+
+        Node source = node;
+        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
+          Node target = _graph.target(e);
+
+          if (order_map[source] < order_map[target] && tree_map[e]) {
+            initFace(target, arc_lists, node_data,
+                     pred_map, order_map, order_list);
+          }
+        }
+
+        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
+          Node target = _graph.target(e);
+
+          if (order_map[source] < order_map[target] && !tree_map[e]) {
+            embed_arc[target] = e;
+            walkUp(target, source, i, pred_map, low_map,
+                   order_map, order_list, node_data, merge_roots);
+          }
+        }
+
+        for (typename MergeRoots::Value::iterator it =
+               merge_roots[node].begin(); it != merge_roots[node].end(); ++it) {
+          int rn = *it;
+          walkDown(rn, i, node_data, arc_lists, flip_map, order_list,
+                   child_lists, ancestor_map, low_map, embed_arc, merge_roots);
+        }
+        merge_roots[node].clear();
+
+        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
+          Node target = _graph.target(e);
+
+          if (order_map[source] < order_map[target] && !tree_map[e]) {
+            if (embed_arc[target] != INVALID) {
+              if (kuratowski) {
+                isolateKuratowski(e, node_data, arc_lists, flip_map,
+                                  order_map, order_list, pred_map, child_lists,
+                                  ancestor_map, low_map,
+                                  embed_arc, merge_roots);
+              }
+              return false;
+            }
+          }
+        }
+      }
+
+      for (int i = 0; i < int(order_list.size()); ++i) {
+
+        mergeRemainingFaces(order_list[i], node_data, order_list, order_map,
+                            child_lists, arc_lists);
+        storeEmbedding(order_list[i], node_data, order_map, pred_map,
+                       arc_lists, flip_map);
+      }
+
+      return true;
+    }
+
+    /// \brief Give back the successor of an arc
+    ///
+    /// This function gives back the successor of an arc. It makes
+    /// possible to query the cyclic order of the outgoing arcs from
+    /// a node.
+    Arc next(const Arc& arc) const {
+      return _embedding[arc];
+    }
+
+    /// \brief Give back the calculated embedding map
+    ///
+    /// This function gives back the calculated embedding map, which
+    /// contains the successor of each arc in the cyclic order of the
+    /// outgoing arcs of its source node.
+    const EmbeddingMap& embeddingMap() const {
+      return _embedding;
+    }
+
+    /// \brief Give back \c true if the given edge is in the Kuratowski
+    /// subdivision
+    ///
+    /// This function gives back \c true if the given edge is in the found
+    /// Kuratowski subdivision.
+    /// \pre The \c run() function must be called with \c true parameter
+    /// before using this function.
+    bool kuratowski(const Edge& edge) const {
+      return _kuratowski[edge];
+    }
+
+  private:
+
+    void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
+                          const LowMap& low_map, ChildLists& child_lists) {
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        Node source = n;
+
+        std::vector<Node> targets;
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          Node target = _graph.target(e);
+
+          if (order_map[source] < order_map[target] && tree_map[e]) {
+            targets.push_back(target);
+          }
+        }
+
+        if (targets.size() == 0) {
+          child_lists[source].first = INVALID;
+        } else if (targets.size() == 1) {
+          child_lists[source].first = targets[0];
+          child_lists[targets[0]].prev = INVALID;
+          child_lists[targets[0]].next = INVALID;
+        } else {
+          radixSort(targets.begin(), targets.end(), mapToFunctor(low_map));
+          for (int i = 1; i < int(targets.size()); ++i) {
+            child_lists[targets[i]].prev = targets[i - 1];
+            child_lists[targets[i - 1]].next = targets[i];
+          }
+          child_lists[targets.back()].next = INVALID;
+          child_lists[targets.front()].prev = INVALID;
+          child_lists[source].first = targets.front();
+        }
+      }
+    }
+
+    void walkUp(const Node& node, Node root, int rorder,
+                const PredMap& pred_map, const LowMap& low_map,
+                const OrderMap& order_map, const OrderList& order_list,
+                NodeData& node_data, MergeRoots& merge_roots) {
+
+      int na, nb;
+      bool da, db;
+
+      na = nb = order_map[node];
+      da = true; db = false;
+
+      while (true) {
+
+        if (node_data[na].visited == rorder) break;
+        if (node_data[nb].visited == rorder) break;
+
+        node_data[na].visited = rorder;
+        node_data[nb].visited = rorder;
+
+        int rn = -1;
+
+        if (na >= int(order_list.size())) {
+          rn = na;
+        } else if (nb >= int(order_list.size())) {
+          rn = nb;
+        }
+
+        if (rn == -1) {
+          int nn;
+
+          nn = da ? node_data[na].prev : node_data[na].next;
+          da = node_data[nn].prev != na;
+          na = nn;
+
+          nn = db ? node_data[nb].prev : node_data[nb].next;
+          db = node_data[nn].prev != nb;
+          nb = nn;
+
+        } else {
+
+          Node rep = order_list[rn - order_list.size()];
+          Node parent = _graph.source(pred_map[rep]);
+
+          if (low_map[rep] < rorder) {
+            merge_roots[parent].push_back(rn);
+          } else {
+            merge_roots[parent].push_front(rn);
+          }
+
+          if (parent != root) {
+            na = nb = order_map[parent];
+            da = true; db = false;
+          } else {
+            break;
+          }
+        }
+      }
+    }
+
+    void walkDown(int rn, int rorder, NodeData& node_data,
+                  ArcLists& arc_lists, FlipMap& flip_map,
+                  OrderList& order_list, ChildLists& child_lists,
+                  AncestorMap& ancestor_map, LowMap& low_map,
+                  EmbedArc& embed_arc, MergeRoots& merge_roots) {
+
+      std::vector<std::pair<int, bool> > merge_stack;
+
+      for (int di = 0; di < 2; ++di) {
+        bool rd = di == 0;
+        int pn = rn;
+        int n = rd ? node_data[rn].next : node_data[rn].prev;
+
+        while (n != rn) {
+
+          Node node = order_list[n];
+
+          if (embed_arc[node] != INVALID) {
+
+            // Merging components on the critical path
+            while (!merge_stack.empty()) {
+
+              // Component root
+              int cn = merge_stack.back().first;
+              bool cd = merge_stack.back().second;
+              merge_stack.pop_back();
+
+              // Parent of component
+              int dn = merge_stack.back().first;
+              bool dd = merge_stack.back().second;
+              merge_stack.pop_back();
+
+              Node parent = order_list[dn];
+
+              // Erasing from merge_roots
+              merge_roots[parent].pop_front();
+
+              Node child = order_list[cn - order_list.size()];
+
+              // Erasing from child_lists
+              if (child_lists[child].prev != INVALID) {
+                child_lists[child_lists[child].prev].next =
+                  child_lists[child].next;
+              } else {
+                child_lists[parent].first = child_lists[child].next;
+              }
+
+              if (child_lists[child].next != INVALID) {
+                child_lists[child_lists[child].next].prev =
+                  child_lists[child].prev;
+              }
+
+              // Merging arcs + flipping
+              Arc de = node_data[dn].first;
+              Arc ce = node_data[cn].first;
+
+              flip_map[order_list[cn - order_list.size()]] = cd != dd;
+              if (cd != dd) {
+                std::swap(arc_lists[ce].prev, arc_lists[ce].next);
+                ce = arc_lists[ce].prev;
+                std::swap(arc_lists[ce].prev, arc_lists[ce].next);
+              }
+
+              {
+                Arc dne = arc_lists[de].next;
+                Arc cne = arc_lists[ce].next;
+
+                arc_lists[de].next = cne;
+                arc_lists[ce].next = dne;
+
+                arc_lists[dne].prev = ce;
+                arc_lists[cne].prev = de;
+              }
+
+              if (dd) {
+                node_data[dn].first = ce;
+              }
+
+              // Merging external faces
+              {
+                int en = cn;
+                cn = cd ? node_data[cn].prev : node_data[cn].next;
+                cd = node_data[cn].next == en;
+
+                 if (node_data[cn].prev == node_data[cn].next &&
+                    node_data[cn].inverted) {
+                   cd = !cd;
+                 }
+              }
+
+              if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
+              if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
+
+            }
+
+            bool d = pn == node_data[n].prev;
+
+            if (node_data[n].prev == node_data[n].next &&
+                node_data[n].inverted) {
+              d = !d;
+            }
+
+            // Add new arc
+            {
+              Arc arc = embed_arc[node];
+              Arc re = node_data[rn].first;
+
+              arc_lists[arc_lists[re].next].prev = arc;
+              arc_lists[arc].next = arc_lists[re].next;
+              arc_lists[arc].prev = re;
+              arc_lists[re].next = arc;
+
+              if (!rd) {
+                node_data[rn].first = arc;
+              }
+
+              Arc rev = _graph.oppositeArc(arc);
+              Arc e = node_data[n].first;
+
+              arc_lists[arc_lists[e].next].prev = rev;
+              arc_lists[rev].next = arc_lists[e].next;
+              arc_lists[rev].prev = e;
+              arc_lists[e].next = rev;
+
+              if (d) {
+                node_data[n].first = rev;
+              }
+
+            }
+
+            // Embedding arc into external face
+            if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
+            if (d) node_data[n].prev = rn; else node_data[n].next = rn;
+            pn = rn;
+
+            embed_arc[order_list[n]] = INVALID;
+          }
+
+          if (!merge_roots[node].empty()) {
+
+            bool d = pn == node_data[n].prev;
+            if (node_data[n].prev == node_data[n].next &&
+                node_data[n].inverted) {
+              d = !d;
+            }
+
+            merge_stack.push_back(std::make_pair(n, d));
+
+            int rn = merge_roots[node].front();
+
+            int xn = node_data[rn].next;
+            Node xnode = order_list[xn];
+
+            int yn = node_data[rn].prev;
+            Node ynode = order_list[yn];
+
+            bool rd;
+            if (!external(xnode, rorder, child_lists, ancestor_map, low_map)) {
+              rd = true;
+            } else if (!external(ynode, rorder, child_lists,
+                                 ancestor_map, low_map)) {
+              rd = false;
+            } else if (pertinent(xnode, embed_arc, merge_roots)) {
+              rd = true;
+            } else {
+              rd = false;
+            }
+
+            merge_stack.push_back(std::make_pair(rn, rd));
+
+            pn = rn;
+            n = rd ? xn : yn;
+
+          } else if (!external(node, rorder, child_lists,
+                               ancestor_map, low_map)) {
+            int nn = (node_data[n].next != pn ?
+                      node_data[n].next : node_data[n].prev);
+
+            bool nd = n == node_data[nn].prev;
+
+            if (nd) node_data[nn].prev = pn;
+            else node_data[nn].next = pn;
+
+            if (n == node_data[pn].prev) node_data[pn].prev = nn;
+            else node_data[pn].next = nn;
+
+            node_data[nn].inverted =
+              (node_data[nn].prev == node_data[nn].next && nd != rd);
+
+            n = nn;
+          }
+          else break;
+
+        }
+
+        if (!merge_stack.empty() || n == rn) {
+          break;
+        }
+      }
+    }
+
+    void initFace(const Node& node, ArcLists& arc_lists,
+                  NodeData& node_data, const PredMap& pred_map,
+                  const OrderMap& order_map, const OrderList& order_list) {
+      int n = order_map[node];
+      int rn = n + order_list.size();
+
+      node_data[n].next = node_data[n].prev = rn;
+      node_data[rn].next = node_data[rn].prev = n;
+
+      node_data[n].visited = order_list.size();
+      node_data[rn].visited = order_list.size();
+
+      node_data[n].inverted = false;
+      node_data[rn].inverted = false;
+
+      Arc arc = pred_map[node];
+      Arc rev = _graph.oppositeArc(arc);
+
+      node_data[rn].first = arc;
+      node_data[n].first = rev;
+
+      arc_lists[arc].prev = arc;
+      arc_lists[arc].next = arc;
+
+      arc_lists[rev].prev = rev;
+      arc_lists[rev].next = rev;
+
+    }
+
+    void mergeRemainingFaces(const Node& node, NodeData& node_data,
+                             OrderList& order_list, OrderMap& order_map,
+                             ChildLists& child_lists, ArcLists& arc_lists) {
+      while (child_lists[node].first != INVALID) {
+        int dd = order_map[node];
+        Node child = child_lists[node].first;
+        int cd = order_map[child] + order_list.size();
+        child_lists[node].first = child_lists[child].next;
+
+        Arc de = node_data[dd].first;
+        Arc ce = node_data[cd].first;
+
+        if (de != INVALID) {
+          Arc dne = arc_lists[de].next;
+          Arc cne = arc_lists[ce].next;
+
+          arc_lists[de].next = cne;
+          arc_lists[ce].next = dne;
+
+          arc_lists[dne].prev = ce;
+          arc_lists[cne].prev = de;
+        }
+
+        node_data[dd].first = ce;
+
+      }
+    }
+
+    void storeEmbedding(const Node& node, NodeData& node_data,
+                        OrderMap& order_map, PredMap& pred_map,
+                        ArcLists& arc_lists, FlipMap& flip_map) {
+
+      if (node_data[order_map[node]].first == INVALID) return;
+
+      if (pred_map[node] != INVALID) {
+        Node source = _graph.source(pred_map[node]);
+        flip_map[node] = flip_map[node] != flip_map[source];
+      }
+
+      Arc first = node_data[order_map[node]].first;
+      Arc prev = first;
+
+      Arc arc = flip_map[node] ?
+        arc_lists[prev].prev : arc_lists[prev].next;
+
+      _embedding[prev] = arc;
+
+      while (arc != first) {
+        Arc next = arc_lists[arc].prev == prev ?
+          arc_lists[arc].next : arc_lists[arc].prev;
+        prev = arc; arc = next;
+        _embedding[prev] = arc;
+      }
+    }
+
+
+    bool external(const Node& node, int rorder,
+                  ChildLists& child_lists, AncestorMap& ancestor_map,
+                  LowMap& low_map) {
+      Node child = child_lists[node].first;
+
+      if (child != INVALID) {
+        if (low_map[child] < rorder) return true;
+      }
+
+      if (ancestor_map[node] < rorder) return true;
+
+      return false;
+    }
+
+    bool pertinent(const Node& node, const EmbedArc& embed_arc,
+                   const MergeRoots& merge_roots) {
+      return !merge_roots[node].empty() || embed_arc[node] != INVALID;
+    }
+
+    int lowPoint(const Node& node, OrderMap& order_map, ChildLists& child_lists,
+                 AncestorMap& ancestor_map, LowMap& low_map) {
+      int low_point;
+
+      Node child = child_lists[node].first;
+
+      if (child != INVALID) {
+        low_point = low_map[child];
+      } else {
+        low_point = order_map[node];
+      }
+
+      if (low_point > ancestor_map[node]) {
+        low_point = ancestor_map[node];
+      }
+
+      return low_point;
+    }
+
+    int findComponentRoot(Node root, Node node, ChildLists& child_lists,
+                          OrderMap& order_map, OrderList& order_list) {
+
+      int order = order_map[root];
+      int norder = order_map[node];
+
+      Node child = child_lists[root].first;
+      while (child != INVALID) {
+        int corder = order_map[child];
+        if (corder > order && corder < norder) {
+          order = corder;
+        }
+        child = child_lists[child].next;
+      }
+      return order + order_list.size();
+    }
+
+    Node findPertinent(Node node, OrderMap& order_map, NodeData& node_data,
+                       EmbedArc& embed_arc, MergeRoots& merge_roots) {
+      Node wnode =_graph.target(node_data[order_map[node]].first);
+      while (!pertinent(wnode, embed_arc, merge_roots)) {
+        wnode = _graph.target(node_data[order_map[wnode]].first);
+      }
+      return wnode;
+    }
+
+
+    Node findExternal(Node node, int rorder, OrderMap& order_map,
+                      ChildLists& child_lists, AncestorMap& ancestor_map,
+                      LowMap& low_map, NodeData& node_data) {
+      Node wnode =_graph.target(node_data[order_map[node]].first);
+      while (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
+        wnode = _graph.target(node_data[order_map[wnode]].first);
+      }
+      return wnode;
+    }
+
+    void markCommonPath(Node node, int rorder, Node& wnode, Node& znode,
+                        OrderList& order_list, OrderMap& order_map,
+                        NodeData& node_data, ArcLists& arc_lists,
+                        EmbedArc& embed_arc, MergeRoots& merge_roots,
+                        ChildLists& child_lists, AncestorMap& ancestor_map,
+                        LowMap& low_map) {
+
+      Node cnode = node;
+      Node pred = INVALID;
+
+      while (true) {
+
+        bool pert = pertinent(cnode, embed_arc, merge_roots);
+        bool ext = external(cnode, rorder, child_lists, ancestor_map, low_map);
+
+        if (pert && ext) {
+          if (!merge_roots[cnode].empty()) {
+            int cn = merge_roots[cnode].back();
+
+            if (low_map[order_list[cn - order_list.size()]] < rorder) {
+              Arc arc = node_data[cn].first;
+              _kuratowski.set(arc, true);
+
+              pred = cnode;
+              cnode = _graph.target(arc);
+
+              continue;
+            }
+          }
+          wnode = znode = cnode;
+          return;
+
+        } else if (pert) {
+          wnode = cnode;
+
+          while (!external(cnode, rorder, child_lists, ancestor_map, low_map)) {
+            Arc arc = node_data[order_map[cnode]].first;
+
+            if (_graph.target(arc) == pred) {
+              arc = arc_lists[arc].next;
+            }
+            _kuratowski.set(arc, true);
+
+            Node next = _graph.target(arc);
+            pred = cnode; cnode = next;
+          }
+
+          znode = cnode;
+          return;
+
+        } else if (ext) {
+          znode = cnode;
+
+          while (!pertinent(cnode, embed_arc, merge_roots)) {
+            Arc arc = node_data[order_map[cnode]].first;
+
+            if (_graph.target(arc) == pred) {
+              arc = arc_lists[arc].next;
+            }
+            _kuratowski.set(arc, true);
+
+            Node next = _graph.target(arc);
+            pred = cnode; cnode = next;
+          }
+
+          wnode = cnode;
+          return;
+
+        } else {
+          Arc arc = node_data[order_map[cnode]].first;
+
+          if (_graph.target(arc) == pred) {
+            arc = arc_lists[arc].next;
+          }
+          _kuratowski.set(arc, true);
+
+          Node next = _graph.target(arc);
+          pred = cnode; cnode = next;
+        }
+
+      }
+
+    }
+
+    void orientComponent(Node root, int rn, OrderMap& order_map,
+                         PredMap& pred_map, NodeData& node_data,
+                         ArcLists& arc_lists, FlipMap& flip_map,
+                         TypeMap& type_map) {
+      node_data[order_map[root]].first = node_data[rn].first;
+      type_map[root] = 1;
+
+      std::vector<Node> st, qu;
+
+      st.push_back(root);
+      while (!st.empty()) {
+        Node node = st.back();
+        st.pop_back();
+        qu.push_back(node);
+
+        Arc arc = node_data[order_map[node]].first;
+
+        if (type_map[_graph.target(arc)] == 0) {
+          st.push_back(_graph.target(arc));
+          type_map[_graph.target(arc)] = 1;
+        }
+
+        Arc last = arc, pred = arc;
+        arc = arc_lists[arc].next;
+        while (arc != last) {
+
+          if (type_map[_graph.target(arc)] == 0) {
+            st.push_back(_graph.target(arc));
+            type_map[_graph.target(arc)] = 1;
+          }
+
+          Arc next = arc_lists[arc].next != pred ?
+            arc_lists[arc].next : arc_lists[arc].prev;
+          pred = arc; arc = next;
+        }
+
+      }
+
+      type_map[root] = 2;
+      flip_map[root] = false;
+
+      for (int i = 1; i < int(qu.size()); ++i) {
+
+        Node node = qu[i];
+
+        while (type_map[node] != 2) {
+          st.push_back(node);
+          type_map[node] = 2;
+          node = _graph.source(pred_map[node]);
+        }
+
+        bool flip = flip_map[node];
+
+        while (!st.empty()) {
+          node = st.back();
+          st.pop_back();
+
+          flip_map[node] = flip != flip_map[node];
+          flip = flip_map[node];
+
+          if (flip) {
+            Arc arc = node_data[order_map[node]].first;
+            std::swap(arc_lists[arc].prev, arc_lists[arc].next);
+            arc = arc_lists[arc].prev;
+            std::swap(arc_lists[arc].prev, arc_lists[arc].next);
+            node_data[order_map[node]].first = arc;
+          }
+        }
+      }
+
+      for (int i = 0; i < int(qu.size()); ++i) {
+
+        Arc arc = node_data[order_map[qu[i]]].first;
+        Arc last = arc, pred = arc;
+
+        arc = arc_lists[arc].next;
+        while (arc != last) {
+
+          if (arc_lists[arc].next == pred) {
+            std::swap(arc_lists[arc].next, arc_lists[arc].prev);
+          }
+          pred = arc; arc = arc_lists[arc].next;
+        }
+
+      }
+    }
+
+    void setFaceFlags(Node root, Node wnode, Node ynode, Node xnode,
+                      OrderMap& order_map, NodeData& node_data,
+                      TypeMap& type_map) {
+      Node node = _graph.target(node_data[order_map[root]].first);
+
+      while (node != ynode) {
+        type_map[node] = HIGHY;
+        node = _graph.target(node_data[order_map[node]].first);
+      }
+
+      while (node != wnode) {
+        type_map[node] = LOWY;
+        node = _graph.target(node_data[order_map[node]].first);
+      }
+
+      node = _graph.target(node_data[order_map[wnode]].first);
+
+      while (node != xnode) {
+        type_map[node] = LOWX;
+        node = _graph.target(node_data[order_map[node]].first);
+      }
+      type_map[node] = LOWX;
+
+      node = _graph.target(node_data[order_map[xnode]].first);
+      while (node != root) {
+        type_map[node] = HIGHX;
+        node = _graph.target(node_data[order_map[node]].first);
+      }
+
+      type_map[wnode] = PERTINENT;
+      type_map[root] = ROOT;
+    }
+
+    void findInternalPath(std::vector<Arc>& ipath,
+                          Node wnode, Node root, TypeMap& type_map,
+                          OrderMap& order_map, NodeData& node_data,
+                          ArcLists& arc_lists) {
+      std::vector<Arc> st;
+
+      Node node = wnode;
+
+      while (node != root) {
+        Arc arc = arc_lists[node_data[order_map[node]].first].next;
+        st.push_back(arc);
+        node = _graph.target(arc);
+      }
+
+      while (true) {
+        Arc arc = st.back();
+        if (type_map[_graph.target(arc)] == LOWX ||
+            type_map[_graph.target(arc)] == HIGHX) {
+          break;
+        }
+        if (type_map[_graph.target(arc)] == 2) {
+          type_map[_graph.target(arc)] = 3;
+
+          arc = arc_lists[_graph.oppositeArc(arc)].next;
+          st.push_back(arc);
+        } else {
+          st.pop_back();
+          arc = arc_lists[arc].next;
+
+          while (_graph.oppositeArc(arc) == st.back()) {
+            arc = st.back();
+            st.pop_back();
+            arc = arc_lists[arc].next;
+          }
+          st.push_back(arc);
+        }
+      }
+
+      for (int i = 0; i < int(st.size()); ++i) {
+        if (type_map[_graph.target(st[i])] != LOWY &&
+            type_map[_graph.target(st[i])] != HIGHY) {
+          for (; i < int(st.size()); ++i) {
+            ipath.push_back(st[i]);
+          }
+        }
+      }
+    }
+
+    void setInternalFlags(std::vector<Arc>& ipath, TypeMap& type_map) {
+      for (int i = 1; i < int(ipath.size()); ++i) {
+        type_map[_graph.source(ipath[i])] = INTERNAL;
+      }
+    }
+
+    void findPilePath(std::vector<Arc>& ppath,
+                      Node root, TypeMap& type_map, OrderMap& order_map,
+                      NodeData& node_data, ArcLists& arc_lists) {
+      std::vector<Arc> st;
+
+      st.push_back(_graph.oppositeArc(node_data[order_map[root]].first));
+      st.push_back(node_data[order_map[root]].first);
+
+      while (st.size() > 1) {
+        Arc arc = st.back();
+        if (type_map[_graph.target(arc)] == INTERNAL) {
+          break;
+        }
+        if (type_map[_graph.target(arc)] == 3) {
+          type_map[_graph.target(arc)] = 4;
+
+          arc = arc_lists[_graph.oppositeArc(arc)].next;
+          st.push_back(arc);
+        } else {
+          st.pop_back();
+          arc = arc_lists[arc].next;
+
+          while (!st.empty() && _graph.oppositeArc(arc) == st.back()) {
+            arc = st.back();
+            st.pop_back();
+            arc = arc_lists[arc].next;
+          }
+          st.push_back(arc);
+        }
+      }
+
+      for (int i = 1; i < int(st.size()); ++i) {
+        ppath.push_back(st[i]);
+      }
+    }
+
+
+    int markExternalPath(Node node, OrderMap& order_map,
+                         ChildLists& child_lists, PredMap& pred_map,
+                         AncestorMap& ancestor_map, LowMap& low_map) {
+      int lp = lowPoint(node, order_map, child_lists,
+                        ancestor_map, low_map);
+
+      if (ancestor_map[node] != lp) {
+        node = child_lists[node].first;
+        _kuratowski[pred_map[node]] = true;
+
+        while (ancestor_map[node] != lp) {
+          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
+            Node tnode = _graph.target(e);
+            if (order_map[tnode] > order_map[node] && low_map[tnode] == lp) {
+              node = tnode;
+              _kuratowski[e] = true;
+              break;
+            }
+          }
+        }
+      }
+
+      for (OutArcIt e(_graph, node); e != INVALID; ++e) {
+        if (order_map[_graph.target(e)] == lp) {
+          _kuratowski[e] = true;
+          break;
+        }
+      }
+
+      return lp;
+    }
+
+    void markPertinentPath(Node node, OrderMap& order_map,
+                           NodeData& node_data, ArcLists& arc_lists,
+                           EmbedArc& embed_arc, MergeRoots& merge_roots) {
+      while (embed_arc[node] == INVALID) {
+        int n = merge_roots[node].front();
+        Arc arc = node_data[n].first;
+
+        _kuratowski.set(arc, true);
+
+        Node pred = node;
+        node = _graph.target(arc);
+        while (!pertinent(node, embed_arc, merge_roots)) {
+          arc = node_data[order_map[node]].first;
+          if (_graph.target(arc) == pred) {
+            arc = arc_lists[arc].next;
+          }
+          _kuratowski.set(arc, true);
+          pred = node;
+          node = _graph.target(arc);
+        }
+      }
+      _kuratowski.set(embed_arc[node], true);
+    }
+
+    void markPredPath(Node node, Node snode, PredMap& pred_map) {
+      while (node != snode) {
+        _kuratowski.set(pred_map[node], true);
+        node = _graph.source(pred_map[node]);
+      }
+    }
+
+    void markFacePath(Node ynode, Node xnode,
+                      OrderMap& order_map, NodeData& node_data) {
+      Arc arc = node_data[order_map[ynode]].first;
+      Node node = _graph.target(arc);
+      _kuratowski.set(arc, true);
+
+      while (node != xnode) {
+        arc = node_data[order_map[node]].first;
+        _kuratowski.set(arc, true);
+        node = _graph.target(arc);
+      }
+    }
+
+    void markInternalPath(std::vector<Arc>& path) {
+      for (int i = 0; i < int(path.size()); ++i) {
+        _kuratowski.set(path[i], true);
+      }
+    }
+
+    void markPilePath(std::vector<Arc>& path) {
+      for (int i = 0; i < int(path.size()); ++i) {
+        _kuratowski.set(path[i], true);
+      }
+    }
+
+    void isolateKuratowski(Arc arc, NodeData& node_data,
+                           ArcLists& arc_lists, FlipMap& flip_map,
+                           OrderMap& order_map, OrderList& order_list,
+                           PredMap& pred_map, ChildLists& child_lists,
+                           AncestorMap& ancestor_map, LowMap& low_map,
+                           EmbedArc& embed_arc, MergeRoots& merge_roots) {
+
+      Node root = _graph.source(arc);
+      Node enode = _graph.target(arc);
+
+      int rorder = order_map[root];
+
+      TypeMap type_map(_graph, 0);
+
+      int rn = findComponentRoot(root, enode, child_lists,
+                                 order_map, order_list);
+
+      Node xnode = order_list[node_data[rn].next];
+      Node ynode = order_list[node_data[rn].prev];
+
+      // Minor-A
+      {
+        while (!merge_roots[xnode].empty() || !merge_roots[ynode].empty()) {
+
+          if (!merge_roots[xnode].empty()) {
+            root = xnode;
+            rn = merge_roots[xnode].front();
+          } else {
+            root = ynode;
+            rn = merge_roots[ynode].front();
+          }
+
+          xnode = order_list[node_data[rn].next];
+          ynode = order_list[node_data[rn].prev];
+        }
+
+        if (root != _graph.source(arc)) {
+          orientComponent(root, rn, order_map, pred_map,
+                          node_data, arc_lists, flip_map, type_map);
+          markFacePath(root, root, order_map, node_data);
+          int xlp = markExternalPath(xnode, order_map, child_lists,
+                                     pred_map, ancestor_map, low_map);
+          int ylp = markExternalPath(ynode, order_map, child_lists,
+                                     pred_map, ancestor_map, low_map);
+          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
+          Node lwnode = findPertinent(ynode, order_map, node_data,
+                                      embed_arc, merge_roots);
+
+          markPertinentPath(lwnode, order_map, node_data, arc_lists,
+                            embed_arc, merge_roots);
+
+          return;
+        }
+      }
+
+      orientComponent(root, rn, order_map, pred_map,
+                      node_data, arc_lists, flip_map, type_map);
+
+      Node wnode = findPertinent(ynode, order_map, node_data,
+                                 embed_arc, merge_roots);
+      setFaceFlags(root, wnode, ynode, xnode, order_map, node_data, type_map);
+
+
+      //Minor-B
+      if (!merge_roots[wnode].empty()) {
+        int cn = merge_roots[wnode].back();
+        Node rep = order_list[cn - order_list.size()];
+        if (low_map[rep] < rorder) {
+          markFacePath(root, root, order_map, node_data);
+          int xlp = markExternalPath(xnode, order_map, child_lists,
+                                     pred_map, ancestor_map, low_map);
+          int ylp = markExternalPath(ynode, order_map, child_lists,
+                                     pred_map, ancestor_map, low_map);
+
+          Node lwnode, lznode;
+          markCommonPath(wnode, rorder, lwnode, lznode, order_list,
+                         order_map, node_data, arc_lists, embed_arc,
+                         merge_roots, child_lists, ancestor_map, low_map);
+
+          markPertinentPath(lwnode, order_map, node_data, arc_lists,
+                            embed_arc, merge_roots);
+          int zlp = markExternalPath(lznode, order_map, child_lists,
+                                     pred_map, ancestor_map, low_map);
+
+          int minlp = xlp < ylp ? xlp : ylp;
+          if (zlp < minlp) minlp = zlp;
+
+          int maxlp = xlp > ylp ? xlp : ylp;
+          if (zlp > maxlp) maxlp = zlp;
+
+          markPredPath(order_list[maxlp], order_list[minlp], pred_map);
+
+          return;
+        }
+      }
+
+      Node pxnode, pynode;
+      std::vector<Arc> ipath;
+      findInternalPath(ipath, wnode, root, type_map, order_map,
+                       node_data, arc_lists);
+      setInternalFlags(ipath, type_map);
+      pynode = _graph.source(ipath.front());
+      pxnode = _graph.target(ipath.back());
+
+      wnode = findPertinent(pynode, order_map, node_data,
+                            embed_arc, merge_roots);
+
+      // Minor-C
+      {
+        if (type_map[_graph.source(ipath.front())] == HIGHY) {
+          if (type_map[_graph.target(ipath.back())] == HIGHX) {
+            markFacePath(xnode, pxnode, order_map, node_data);
+          }
+          markFacePath(root, xnode, order_map, node_data);
+          markPertinentPath(wnode, order_map, node_data, arc_lists,
+                            embed_arc, merge_roots);
+          markInternalPath(ipath);
+          int xlp = markExternalPath(xnode, order_map, child_lists,
+                                     pred_map, ancestor_map, low_map);
+          int ylp = markExternalPath(ynode, order_map, child_lists,
+                                     pred_map, ancestor_map, low_map);
+          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
+          return;
+        }
+
+        if (type_map[_graph.target(ipath.back())] == HIGHX) {
+          markFacePath(ynode, root, order_map, node_data);
+          markPertinentPath(wnode, order_map, node_data, arc_lists,
+                            embed_arc, merge_roots);
+          markInternalPath(ipath);
+          int xlp = markExternalPath(xnode, order_map, child_lists,
+                                     pred_map, ancestor_map, low_map);
+          int ylp = markExternalPath(ynode, order_map, child_lists,
+                                     pred_map, ancestor_map, low_map);
+          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
+          return;
+        }
+      }
+
+      std::vector<Arc> ppath;
+      findPilePath(ppath, root, type_map, order_map, node_data, arc_lists);
+
+      // Minor-D
+      if (!ppath.empty()) {
+        markFacePath(ynode, xnode, order_map, node_data);
+        markPertinentPath(wnode, order_map, node_data, arc_lists,
+                          embed_arc, merge_roots);
+        markPilePath(ppath);
+        markInternalPath(ipath);
+        int xlp = markExternalPath(xnode, order_map, child_lists,
+                                   pred_map, ancestor_map, low_map);
+        int ylp = markExternalPath(ynode, order_map, child_lists,
+                                   pred_map, ancestor_map, low_map);
+        markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
+        return;
+      }
+
+      // Minor-E*
+      {
+
+        if (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
+          Node znode = findExternal(pynode, rorder, order_map,
+                                    child_lists, ancestor_map,
+                                    low_map, node_data);
+
+          if (type_map[znode] == LOWY) {
+            markFacePath(root, xnode, order_map, node_data);
+            markPertinentPath(wnode, order_map, node_data, arc_lists,
+                              embed_arc, merge_roots);
+            markInternalPath(ipath);
+            int xlp = markExternalPath(xnode, order_map, child_lists,
+                                       pred_map, ancestor_map, low_map);
+            int zlp = markExternalPath(znode, order_map, child_lists,
+                                       pred_map, ancestor_map, low_map);
+            markPredPath(root, order_list[xlp < zlp ? xlp : zlp], pred_map);
+          } else {
+            markFacePath(ynode, root, order_map, node_data);
+            markPertinentPath(wnode, order_map, node_data, arc_lists,
+                              embed_arc, merge_roots);
+            markInternalPath(ipath);
+            int ylp = markExternalPath(ynode, order_map, child_lists,
+                                       pred_map, ancestor_map, low_map);
+            int zlp = markExternalPath(znode, order_map, child_lists,
+                                       pred_map, ancestor_map, low_map);
+            markPredPath(root, order_list[ylp < zlp ? ylp : zlp], pred_map);
+          }
+          return;
+        }
+
+        int xlp = markExternalPath(xnode, order_map, child_lists,
+                                   pred_map, ancestor_map, low_map);
+        int ylp = markExternalPath(ynode, order_map, child_lists,
+                                   pred_map, ancestor_map, low_map);
+        int wlp = markExternalPath(wnode, order_map, child_lists,
+                                   pred_map, ancestor_map, low_map);
+
+        if (wlp > xlp && wlp > ylp) {
+          markFacePath(root, root, order_map, node_data);
+          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
+          return;
+        }
+
+        markInternalPath(ipath);
+        markPertinentPath(wnode, order_map, node_data, arc_lists,
+                          embed_arc, merge_roots);
+
+        if (xlp > ylp && xlp > wlp) {
+          markFacePath(root, pynode, order_map, node_data);
+          markFacePath(wnode, xnode, order_map, node_data);
+          markPredPath(root, order_list[ylp < wlp ? ylp : wlp], pred_map);
+          return;
+        }
+
+        if (ylp > xlp && ylp > wlp) {
+          markFacePath(pxnode, root, order_map, node_data);
+          markFacePath(ynode, wnode, order_map, node_data);
+          markPredPath(root, order_list[xlp < wlp ? xlp : wlp], pred_map);
+          return;
+        }
+
+        if (pynode != ynode) {
+          markFacePath(pxnode, wnode, order_map, node_data);
+
+          int minlp = xlp < ylp ? xlp : ylp;
+          if (wlp < minlp) minlp = wlp;
+
+          int maxlp = xlp > ylp ? xlp : ylp;
+          if (wlp > maxlp) maxlp = wlp;
+
+          markPredPath(order_list[maxlp], order_list[minlp], pred_map);
+          return;
+        }
+
+        if (pxnode != xnode) {
+          markFacePath(wnode, pynode, order_map, node_data);
+
+          int minlp = xlp < ylp ? xlp : ylp;
+          if (wlp < minlp) minlp = wlp;
+
+          int maxlp = xlp > ylp ? xlp : ylp;
+          if (wlp > maxlp) maxlp = wlp;
+
+          markPredPath(order_list[maxlp], order_list[minlp], pred_map);
+          return;
+        }
+
+        markFacePath(root, root, order_map, node_data);
+        int minlp = xlp < ylp ? xlp : ylp;
+        if (wlp < minlp) minlp = wlp;
+        markPredPath(root, order_list[minlp], pred_map);
+        return;
+      }
+
+    }
+
+  };
+
+  namespace _planarity_bits {
+
+    template <typename Graph, typename EmbeddingMap>
+    void makeConnected(Graph& graph, EmbeddingMap& embedding) {
+      DfsVisitor<Graph> null_visitor;
+      DfsVisit<Graph, DfsVisitor<Graph> > dfs(graph, null_visitor);
+      dfs.init();
+
+      typename Graph::Node u = INVALID;
+      for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
+        if (!dfs.reached(n)) {
+          dfs.addSource(n);
+          dfs.start();
+          if (u == INVALID) {
+            u = n;
+          } else {
+            typename Graph::Node v = n;
+
+            typename Graph::Arc ue = typename Graph::OutArcIt(graph, u);
+            typename Graph::Arc ve = typename Graph::OutArcIt(graph, v);
+
+            typename Graph::Arc e = graph.direct(graph.addEdge(u, v), true);
+
+            if (ue != INVALID) {
+              embedding[e] = embedding[ue];
+              embedding[ue] = e;
+            } else {
+              embedding[e] = e;
+            }
+
+            if (ve != INVALID) {
+              embedding[graph.oppositeArc(e)] = embedding[ve];
+              embedding[ve] = graph.oppositeArc(e);
+            } else {
+              embedding[graph.oppositeArc(e)] = graph.oppositeArc(e);
+            }
+          }
+        }
+      }
+    }
+
+    template <typename Graph, typename EmbeddingMap>
+    void makeBiNodeConnected(Graph& graph, EmbeddingMap& embedding) {
+      typename Graph::template ArcMap<bool> processed(graph);
+
+      std::vector<typename Graph::Arc> arcs;
+      for (typename Graph::ArcIt e(graph); e != INVALID; ++e) {
+        arcs.push_back(e);
+      }
+
+      IterableBoolMap<Graph, typename Graph::Node> visited(graph, false);
+
+      for (int i = 0; i < int(arcs.size()); ++i) {
+        typename Graph::Arc pp = arcs[i];
+        if (processed[pp]) continue;
+
+        typename Graph::Arc e = embedding[graph.oppositeArc(pp)];
+        processed[e] = true;
+        visited.set(graph.source(e), true);
+
+        typename Graph::Arc p = e, l = e;
+        e = embedding[graph.oppositeArc(e)];
+
+        while (e != l) {
+          processed[e] = true;
+
+          if (visited[graph.source(e)]) {
+
+            typename Graph::Arc n =
+              graph.direct(graph.addEdge(graph.source(p),
+                                           graph.target(e)), true);
+            embedding[n] = p;
+            embedding[graph.oppositeArc(pp)] = n;
+
+            embedding[graph.oppositeArc(n)] =
+              embedding[graph.oppositeArc(e)];
+            embedding[graph.oppositeArc(e)] =
+              graph.oppositeArc(n);
+
+            p = n;
+            e = embedding[graph.oppositeArc(n)];
+          } else {
+            visited.set(graph.source(e), true);
+            pp = p;
+            p = e;
+            e = embedding[graph.oppositeArc(e)];
+          }
+        }
+        visited.setAll(false);
+      }
+    }
+
+
+    template <typename Graph, typename EmbeddingMap>
+    void makeMaxPlanar(Graph& graph, EmbeddingMap& embedding) {
+
+      typename Graph::template NodeMap<int> degree(graph);
+
+      for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
+        degree[n] = countIncEdges(graph, n);
+      }
+
+      typename Graph::template ArcMap<bool> processed(graph);
+      IterableBoolMap<Graph, typename Graph::Node> visited(graph, false);
+
+      std::vector<typename Graph::Arc> arcs;
+      for (typename Graph::ArcIt e(graph); e != INVALID; ++e) {
+        arcs.push_back(e);
+      }
+
+      for (int i = 0; i < int(arcs.size()); ++i) {
+        typename Graph::Arc e = arcs[i];
+
+        if (processed[e]) continue;
+        processed[e] = true;
+
+        typename Graph::Arc mine = e;
+        int mind = degree[graph.source(e)];
+
+        int face_size = 1;
+
+        typename Graph::Arc l = e;
+        e = embedding[graph.oppositeArc(e)];
+        while (l != e) {
+          processed[e] = true;
+
+          ++face_size;
+
+          if (degree[graph.source(e)] < mind) {
+            mine = e;
+            mind = degree[graph.source(e)];
+          }
+
+          e = embedding[graph.oppositeArc(e)];
+        }
+
+        if (face_size < 4) {
+          continue;
+        }
+
+        typename Graph::Node s = graph.source(mine);
+        for (typename Graph::OutArcIt e(graph, s); e != INVALID; ++e) {
+          visited.set(graph.target(e), true);
+        }
+
+        typename Graph::Arc oppe = INVALID;
+
+        e = embedding[graph.oppositeArc(mine)];
+        e = embedding[graph.oppositeArc(e)];
+        while (graph.target(e) != s) {
+          if (visited[graph.source(e)]) {
+            oppe = e;
+            break;
+          }
+          e = embedding[graph.oppositeArc(e)];
+        }
+        visited.setAll(false);
+
+        if (oppe == INVALID) {
+
+          e = embedding[graph.oppositeArc(mine)];
+          typename Graph::Arc pn = mine, p = e;
+
+          e = embedding[graph.oppositeArc(e)];
+          while (graph.target(e) != s) {
+            typename Graph::Arc n =
+              graph.direct(graph.addEdge(s, graph.source(e)), true);
+
+            embedding[n] = pn;
+            embedding[graph.oppositeArc(n)] = e;
+            embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
+
+            pn = n;
+
+            p = e;
+            e = embedding[graph.oppositeArc(e)];
+          }
+
+          embedding[graph.oppositeArc(e)] = pn;
+
+        } else {
+
+          mine = embedding[graph.oppositeArc(mine)];
+          s = graph.source(mine);
+          oppe = embedding[graph.oppositeArc(oppe)];
+          typename Graph::Node t = graph.source(oppe);
+
+          typename Graph::Arc ce = graph.direct(graph.addEdge(s, t), true);
+          embedding[ce] = mine;
+          embedding[graph.oppositeArc(ce)] = oppe;
+
+          typename Graph::Arc pn = ce, p = oppe;
+          e = embedding[graph.oppositeArc(oppe)];
+          while (graph.target(e) != s) {
+            typename Graph::Arc n =
+              graph.direct(graph.addEdge(s, graph.source(e)), true);
+
+            embedding[n] = pn;
+            embedding[graph.oppositeArc(n)] = e;
+            embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
+
+            pn = n;
+
+            p = e;
+            e = embedding[graph.oppositeArc(e)];
+
+          }
+          embedding[graph.oppositeArc(e)] = pn;
+
+          pn = graph.oppositeArc(ce), p = mine;
+          e = embedding[graph.oppositeArc(mine)];
+          while (graph.target(e) != t) {
+            typename Graph::Arc n =
+              graph.direct(graph.addEdge(t, graph.source(e)), true);
+
+            embedding[n] = pn;
+            embedding[graph.oppositeArc(n)] = e;
+            embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
+
+            pn = n;
+
+            p = e;
+            e = embedding[graph.oppositeArc(e)];
+
+          }
+          embedding[graph.oppositeArc(e)] = pn;
+        }
+      }
+    }
+
+  }
+
+  /// \ingroup planar
+  ///
+  /// \brief Schnyder's planar drawing algorithm
+  ///
+  /// The planar drawing algorithm calculates positions for the nodes
+  /// in the plane. These coordinates satisfy that if the edges are
+  /// represented with straight lines, then they will not intersect
+  /// each other.
+  ///
+  /// Scnyder's algorithm embeds the graph on an \c (n-2)x(n-2) size grid,
+  /// i.e. each node will be located in the \c [0..n-2]x[0..n-2] square.
+  /// The time complexity of the algorithm is O(n).
+  ///
+  /// \see PlanarEmbedding
+  template <typename Graph>
+  class PlanarDrawing {
+  public:
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    /// \brief The point type for storing coordinates
+    typedef dim2::Point<int> Point;
+    /// \brief The map type for storing the coordinates of the nodes
+    typedef typename Graph::template NodeMap<Point> PointMap;
+
+
+    /// \brief Constructor
+    ///
+    /// Constructor
+    /// \pre The graph must be simple, i.e. it should not
+    /// contain parallel or loop arcs.
+    PlanarDrawing(const Graph& graph)
+      : _graph(graph), _point_map(graph) {}
+
+  private:
+
+    template <typename AuxGraph, typename AuxEmbeddingMap>
+    void drawing(const AuxGraph& graph,
+                 const AuxEmbeddingMap& next,
+                 PointMap& point_map) {
+      TEMPLATE_GRAPH_TYPEDEFS(AuxGraph);
+
+      typename AuxGraph::template ArcMap<Arc> prev(graph);
+
+      for (NodeIt n(graph); n != INVALID; ++n) {
+        Arc e = OutArcIt(graph, n);
+
+        Arc p = e, l = e;
+
+        e = next[e];
+        while (e != l) {
+          prev[e] = p;
+          p = e;
+          e = next[e];
+        }
+        prev[e] = p;
+      }
+
+      Node anode, bnode, cnode;
+
+      {
+        Arc e = ArcIt(graph);
+        anode = graph.source(e);
+        bnode = graph.target(e);
+        cnode = graph.target(next[graph.oppositeArc(e)]);
+      }
+
+      IterableBoolMap<AuxGraph, Node> proper(graph, false);
+      typename AuxGraph::template NodeMap<int> conn(graph, -1);
+
+      conn[anode] = conn[bnode] = -2;
+      {
+        for (OutArcIt e(graph, anode); e != INVALID; ++e) {
+          Node m = graph.target(e);
+          if (conn[m] == -1) {
+            conn[m] = 1;
+          }
+        }
+        conn[cnode] = 2;
+
+        for (OutArcIt e(graph, bnode); e != INVALID; ++e) {
+          Node m = graph.target(e);
+          if (conn[m] == -1) {
+            conn[m] = 1;
+          } else if (conn[m] != -2) {
+            conn[m] += 1;
+            Arc pe = graph.oppositeArc(e);
+            if (conn[graph.target(next[pe])] == -2) {
+              conn[m] -= 1;
+            }
+            if (conn[graph.target(prev[pe])] == -2) {
+              conn[m] -= 1;
+            }
+
+            proper.set(m, conn[m] == 1);
+          }
+        }
+      }
+
+
+      typename AuxGraph::template ArcMap<int> angle(graph, -1);
+
+      while (proper.trueNum() != 0) {
+        Node n = typename IterableBoolMap<AuxGraph, Node>::TrueIt(proper);
+        proper.set(n, false);
+        conn[n] = -2;
+
+        for (OutArcIt e(graph, n); e != INVALID; ++e) {
+          Node m = graph.target(e);
+          if (conn[m] == -1) {
+            conn[m] = 1;
+          } else if (conn[m] != -2) {
+            conn[m] += 1;
+            Arc pe = graph.oppositeArc(e);
+            if (conn[graph.target(next[pe])] == -2) {
+              conn[m] -= 1;
+            }
+            if (conn[graph.target(prev[pe])] == -2) {
+              conn[m] -= 1;
+            }
+
+            proper.set(m, conn[m] == 1);
+          }
+        }
+
+        {
+          Arc e = OutArcIt(graph, n);
+          Arc p = e, l = e;
+
+          e = next[e];
+          while (e != l) {
+
+            if (conn[graph.target(e)] == -2 && conn[graph.target(p)] == -2) {
+              Arc f = e;
+              angle[f] = 0;
+              f = next[graph.oppositeArc(f)];
+              angle[f] = 1;
+              f = next[graph.oppositeArc(f)];
+              angle[f] = 2;
+            }
+
+            p = e;
+            e = next[e];
+          }
+
+          if (conn[graph.target(e)] == -2 && conn[graph.target(p)] == -2) {
+            Arc f = e;
+            angle[f] = 0;
+            f = next[graph.oppositeArc(f)];
+            angle[f] = 1;
+            f = next[graph.oppositeArc(f)];
+            angle[f] = 2;
+          }
+        }
+      }
+
+      typename AuxGraph::template NodeMap<Node> apred(graph, INVALID);
+      typename AuxGraph::template NodeMap<Node> bpred(graph, INVALID);
+      typename AuxGraph::template NodeMap<Node> cpred(graph, INVALID);
+
+      typename AuxGraph::template NodeMap<int> apredid(graph, -1);
+      typename AuxGraph::template NodeMap<int> bpredid(graph, -1);
+      typename AuxGraph::template NodeMap<int> cpredid(graph, -1);
+
+      for (ArcIt e(graph); e != INVALID; ++e) {
+        if (angle[e] == angle[next[e]]) {
+          switch (angle[e]) {
+          case 2:
+            apred[graph.target(e)] = graph.source(e);
+            apredid[graph.target(e)] = graph.id(graph.source(e));
+            break;
+          case 1:
+            bpred[graph.target(e)] = graph.source(e);
+            bpredid[graph.target(e)] = graph.id(graph.source(e));
+            break;
+          case 0:
+            cpred[graph.target(e)] = graph.source(e);
+            cpredid[graph.target(e)] = graph.id(graph.source(e));
+            break;
+          }
+        }
+      }
+
+      cpred[anode] = INVALID;
+      cpred[bnode] = INVALID;
+
+      std::vector<Node> aorder, border, corder;
+
+      {
+        typename AuxGraph::template NodeMap<bool> processed(graph, false);
+        std::vector<Node> st;
+        for (NodeIt n(graph); n != INVALID; ++n) {
+          if (!processed[n] && n != bnode && n != cnode) {
+            st.push_back(n);
+            processed[n] = true;
+            Node m = apred[n];
+            while (m != INVALID && !processed[m]) {
+              st.push_back(m);
+              processed[m] = true;
+              m = apred[m];
+            }
+            while (!st.empty()) {
+              aorder.push_back(st.back());
+              st.pop_back();
+            }
+          }
+        }
+      }
+
+      {
+        typename AuxGraph::template NodeMap<bool> processed(graph, false);
+        std::vector<Node> st;
+        for (NodeIt n(graph); n != INVALID; ++n) {
+          if (!processed[n] && n != cnode && n != anode) {
+            st.push_back(n);
+            processed[n] = true;
+            Node m = bpred[n];
+            while (m != INVALID && !processed[m]) {
+              st.push_back(m);
+              processed[m] = true;
+              m = bpred[m];
+            }
+            while (!st.empty()) {
+              border.push_back(st.back());
+              st.pop_back();
+            }
+          }
+        }
+      }
+
+      {
+        typename AuxGraph::template NodeMap<bool> processed(graph, false);
+        std::vector<Node> st;
+        for (NodeIt n(graph); n != INVALID; ++n) {
+          if (!processed[n] && n != anode && n != bnode) {
+            st.push_back(n);
+            processed[n] = true;
+            Node m = cpred[n];
+            while (m != INVALID && !processed[m]) {
+              st.push_back(m);
+              processed[m] = true;
+              m = cpred[m];
+            }
+            while (!st.empty()) {
+              corder.push_back(st.back());
+              st.pop_back();
+            }
+          }
+        }
+      }
+
+      typename AuxGraph::template NodeMap<int> atree(graph, 0);
+      for (int i = aorder.size() - 1; i >= 0; --i) {
+        Node n = aorder[i];
+        atree[n] = 1;
+        for (OutArcIt e(graph, n); e != INVALID; ++e) {
+          if (apred[graph.target(e)] == n) {
+            atree[n] += atree[graph.target(e)];
+          }
+        }
+      }
+
+      typename AuxGraph::template NodeMap<int> btree(graph, 0);
+      for (int i = border.size() - 1; i >= 0; --i) {
+        Node n = border[i];
+        btree[n] = 1;
+        for (OutArcIt e(graph, n); e != INVALID; ++e) {
+          if (bpred[graph.target(e)] == n) {
+            btree[n] += btree[graph.target(e)];
+          }
+        }
+      }
+
+      typename AuxGraph::template NodeMap<int> apath(graph, 0);
+      apath[bnode] = apath[cnode] = 1;
+      typename AuxGraph::template NodeMap<int> apath_btree(graph, 0);
+      apath_btree[bnode] = btree[bnode];
+      for (int i = 1; i < int(aorder.size()); ++i) {
+        Node n = aorder[i];
+        apath[n] = apath[apred[n]] + 1;
+        apath_btree[n] = btree[n] + apath_btree[apred[n]];
+      }
+
+      typename AuxGraph::template NodeMap<int> bpath_atree(graph, 0);
+      bpath_atree[anode] = atree[anode];
+      for (int i = 1; i < int(border.size()); ++i) {
+        Node n = border[i];
+        bpath_atree[n] = atree[n] + bpath_atree[bpred[n]];
+      }
+
+      typename AuxGraph::template NodeMap<int> cpath(graph, 0);
+      cpath[anode] = cpath[bnode] = 1;
+      typename AuxGraph::template NodeMap<int> cpath_atree(graph, 0);
+      cpath_atree[anode] = atree[anode];
+      typename AuxGraph::template NodeMap<int> cpath_btree(graph, 0);
+      cpath_btree[bnode] = btree[bnode];
+      for (int i = 1; i < int(corder.size()); ++i) {
+        Node n = corder[i];
+        cpath[n] = cpath[cpred[n]] + 1;
+        cpath_atree[n] = atree[n] + cpath_atree[cpred[n]];
+        cpath_btree[n] = btree[n] + cpath_btree[cpred[n]];
+      }
+
+      typename AuxGraph::template NodeMap<int> third(graph);
+      for (NodeIt n(graph); n != INVALID; ++n) {
+        point_map[n].x =
+          bpath_atree[n] + cpath_atree[n] - atree[n] - cpath[n] + 1;
+        point_map[n].y =
+          cpath_btree[n] + apath_btree[n] - btree[n] - apath[n] + 1;
+      }
+
+    }
+
+  public:
+
+    /// \brief Calculate the node positions
+    ///
+    /// This function calculates the node positions on the plane.
+    /// \return \c true if the graph is planar.
+    bool run() {
+      PlanarEmbedding<Graph> pe(_graph);
+      if (!pe.run()) return false;
+
+      run(pe);
+      return true;
+    }
+
+    /// \brief Calculate the node positions according to a
+    /// combinatorical embedding
+    ///
+    /// This function calculates the node positions on the plane.
+    /// The given \c embedding map should contain a valid combinatorical
+    /// embedding, i.e. a valid cyclic order of the arcs.
+    /// It can be computed using PlanarEmbedding.
+    template <typename EmbeddingMap>
+    void run(const EmbeddingMap& embedding) {
+      typedef SmartEdgeSet<Graph> AuxGraph;
+
+      if (3 * countNodes(_graph) - 6 == countEdges(_graph)) {
+        drawing(_graph, embedding, _point_map);
+        return;
+      }
+
+      AuxGraph aux_graph(_graph);
+      typename AuxGraph::template ArcMap<typename AuxGraph::Arc>
+        aux_embedding(aux_graph);
+
+      {
+
+        typename Graph::template EdgeMap<typename AuxGraph::Edge>
+          ref(_graph);
+
+        for (EdgeIt e(_graph); e != INVALID; ++e) {
+          ref[e] = aux_graph.addEdge(_graph.u(e), _graph.v(e));
+        }
+
+        for (EdgeIt e(_graph); e != INVALID; ++e) {
+          Arc ee = embedding[_graph.direct(e, true)];
+          aux_embedding[aux_graph.direct(ref[e], true)] =
+            aux_graph.direct(ref[ee], _graph.direction(ee));
+          ee = embedding[_graph.direct(e, false)];
+          aux_embedding[aux_graph.direct(ref[e], false)] =
+            aux_graph.direct(ref[ee], _graph.direction(ee));
+        }
+      }
+      _planarity_bits::makeConnected(aux_graph, aux_embedding);
+      _planarity_bits::makeBiNodeConnected(aux_graph, aux_embedding);
+      _planarity_bits::makeMaxPlanar(aux_graph, aux_embedding);
+      drawing(aux_graph, aux_embedding, _point_map);
+    }
+
+    /// \brief The coordinate of the given node
+    ///
+    /// This function returns the coordinate of the given node.
+    Point operator[](const Node& node) const {
+      return _point_map[node];
+    }
+
+    /// \brief Return the grid embedding in a node map
+    ///
+    /// This function returns the grid embedding in a node map of
+    /// \c dim2::Point<int> coordinates.
+    const PointMap& coords() const {
+      return _point_map;
+    }
+
+  private:
+
+    const Graph& _graph;
+    PointMap _point_map;
+
+  };
+
+  namespace _planarity_bits {
+
+    template <typename ColorMap>
+    class KempeFilter {
+    public:
+      typedef typename ColorMap::Key Key;
+      typedef bool Value;
+
+      KempeFilter(const ColorMap& color_map,
+                  const typename ColorMap::Value& first,
+                  const typename ColorMap::Value& second)
+        : _color_map(color_map), _first(first), _second(second) {}
+
+      Value operator[](const Key& key) const {
+        return _color_map[key] == _first || _color_map[key] == _second;
+      }
+
+    private:
+      const ColorMap& _color_map;
+      typename ColorMap::Value _first, _second;
+    };
+  }
+
+  /// \ingroup planar
+  ///
+  /// \brief Coloring planar graphs
+  ///
+  /// The graph coloring problem is the coloring of the graph nodes
+  /// so that there are no adjacent nodes with the same color. The
+  /// planar graphs can always be colored with four colors, which is
+  /// proved by Appel and Haken. Their proofs provide a quadratic
+  /// time algorithm for four coloring, but it could not be used to
+  /// implement an efficient algorithm. The five and six coloring can be
+  /// made in linear time, but in this class, the five coloring has
+  /// quadratic worst case time complexity. The two coloring (if
+  /// possible) is solvable with a graph search algorithm and it is
+  /// implemented in \ref bipartitePartitions() function in LEMON. To
+  /// decide whether a planar graph is three colorable is NP-complete.
+  ///
+  /// This class contains member functions for calculate colorings
+  /// with five and six colors. The six coloring algorithm is a simple
+  /// greedy coloring on the backward minimum outgoing order of nodes.
+  /// This order can be computed by selecting the node with least
+  /// outgoing arcs to unprocessed nodes in each phase. This order
+  /// guarantees that when a node is chosen for coloring it has at
+  /// most five already colored adjacents. The five coloring algorithm
+  /// use the same method, but if the greedy approach fails to color
+  /// with five colors, i.e. the node has five already different
+  /// colored neighbours, it swaps the colors in one of the connected
+  /// two colored sets with the Kempe recoloring method.
+  template <typename Graph>
+  class PlanarColoring {
+  public:
+
+    TEMPLATE_GRAPH_TYPEDEFS(Graph);
+
+    /// \brief The map type for storing color indices
+    typedef typename Graph::template NodeMap<int> IndexMap;
+    /// \brief The map type for storing colors
+    ///
+    /// The map type for storing colors.
+    /// \see Palette, Color
+    typedef ComposeMap<Palette, IndexMap> ColorMap;
+
+    /// \brief Constructor
+    ///
+    /// Constructor.
+    /// \pre The graph must be simple, i.e. it should not
+    /// contain parallel or loop arcs.
+    PlanarColoring(const Graph& graph)
+      : _graph(graph), _color_map(graph), _palette(0) {
+      _palette.add(Color(1,0,0));
+      _palette.add(Color(0,1,0));
+      _palette.add(Color(0,0,1));
+      _palette.add(Color(1,1,0));
+      _palette.add(Color(1,0,1));
+      _palette.add(Color(0,1,1));
+    }
+
+    /// \brief Return the node map of color indices
+    ///
+    /// This function returns the node map of color indices. The values are
+    /// in the range \c [0..4] or \c [0..5] according to the coloring method.
+    IndexMap colorIndexMap() const {
+      return _color_map;
+    }
+
+    /// \brief Return the node map of colors
+    ///
+    /// This function returns the node map of colors. The values are among
+    /// five or six distinct \ref lemon::Color "colors".
+    ColorMap colorMap() const {
+      return composeMap(_palette, _color_map);
+    }
+
+    /// \brief Return the color index of the node
+    ///
+    /// This function returns the color index of the given node. The value is
+    /// in the range \c [0..4] or \c [0..5] according to the coloring method.
+    int colorIndex(const Node& node) const {
+      return _color_map[node];
+    }
+
+    /// \brief Return the color of the node
+    ///
+    /// This function returns the color of the given node. The value is among
+    /// five or six distinct \ref lemon::Color "colors".
+    Color color(const Node& node) const {
+      return _palette[_color_map[node]];
+    }
+
+
+    /// \brief Calculate a coloring with at most six colors
+    ///
+    /// This function calculates a coloring with at most six colors. The time
+    /// complexity of this variant is linear in the size of the graph.
+    /// \return \c true if the algorithm could color the graph with six colors.
+    /// If the algorithm fails, then the graph is not planar.
+    /// \note This function can return \c true if the graph is not
+    /// planar, but it can be colored with at most six colors.
+    bool runSixColoring() {
+
+      typename Graph::template NodeMap<int> heap_index(_graph, -1);
+      BucketHeap<typename Graph::template NodeMap<int> > heap(heap_index);
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _color_map[n] = -2;
+        heap.push(n, countOutArcs(_graph, n));
+      }
+
+      std::vector<Node> order;
+
+      while (!heap.empty()) {
+        Node n = heap.top();
+        heap.pop();
+        _color_map[n] = -1;
+        order.push_back(n);
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          Node t = _graph.runningNode(e);
+          if (_color_map[t] == -2) {
+            heap.decrease(t, heap[t] - 1);
+          }
+        }
+      }
+
+      for (int i = order.size() - 1; i >= 0; --i) {
+        std::vector<bool> forbidden(6, false);
+        for (OutArcIt e(_graph, order[i]); e != INVALID; ++e) {
+          Node t = _graph.runningNode(e);
+          if (_color_map[t] != -1) {
+            forbidden[_color_map[t]] = true;
+          }
+        }
+               for (int k = 0; k < 6; ++k) {
+          if (!forbidden[k]) {
+            _color_map[order[i]] = k;
+            break;
+          }
+        }
+        if (_color_map[order[i]] == -1) {
+          return false;
+        }
+      }
+      return true;
+    }
+
+  private:
+
+    bool recolor(const Node& u, const Node& v) {
+      int ucolor = _color_map[u];
+      int vcolor = _color_map[v];
+      typedef _planarity_bits::KempeFilter<IndexMap> KempeFilter;
+      KempeFilter filter(_color_map, ucolor, vcolor);
+
+      typedef FilterNodes<const Graph, const KempeFilter> KempeGraph;
+      KempeGraph kempe_graph(_graph, filter);
+
+      std::vector<Node> comp;
+      Bfs<KempeGraph> bfs(kempe_graph);
+      bfs.init();
+      bfs.addSource(u);
+      while (!bfs.emptyQueue()) {
+        Node n = bfs.nextNode();
+        if (n == v) return false;
+        comp.push_back(n);
+        bfs.processNextNode();
+      }
+
+      int scolor = ucolor + vcolor;
+      for (int i = 0; i < static_cast<int>(comp.size()); ++i) {
+        _color_map[comp[i]] = scolor - _color_map[comp[i]];
+      }
+
+      return true;
+    }
+
+    template <typename EmbeddingMap>
+    void kempeRecoloring(const Node& node, const EmbeddingMap& embedding) {
+      std::vector<Node> nodes;
+      nodes.reserve(4);
+
+      for (Arc e = OutArcIt(_graph, node); e != INVALID; e = embedding[e]) {
+        Node t = _graph.target(e);
+        if (_color_map[t] != -1) {
+          nodes.push_back(t);
+          if (nodes.size() == 4) break;
+        }
+      }
+
+      int color = _color_map[nodes[0]];
+      if (recolor(nodes[0], nodes[2])) {
+        _color_map[node] = color;
+      } else {
+        color = _color_map[nodes[1]];
+        recolor(nodes[1], nodes[3]);
+        _color_map[node] = color;
+      }
+    }
+
+  public:
+
+    /// \brief Calculate a coloring with at most five colors
+    ///
+    /// This function calculates a coloring with at most five
+    /// colors. The worst case time complexity of this variant is
+    /// quadratic in the size of the graph.
+    /// \param embedding This map should contain a valid combinatorical
+    /// embedding, i.e. a valid cyclic order of the arcs.
+    /// It can be computed using PlanarEmbedding.
+    template <typename EmbeddingMap>
+    void runFiveColoring(const EmbeddingMap& embedding) {
+
+      typename Graph::template NodeMap<int> heap_index(_graph, -1);
+      BucketHeap<typename Graph::template NodeMap<int> > heap(heap_index);
+
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        _color_map[n] = -2;
+        heap.push(n, countOutArcs(_graph, n));
+      }
+
+      std::vector<Node> order;
+
+      while (!heap.empty()) {
+        Node n = heap.top();
+        heap.pop();
+        _color_map[n] = -1;
+        order.push_back(n);
+        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
+          Node t = _graph.runningNode(e);
+          if (_color_map[t] == -2) {
+            heap.decrease(t, heap[t] - 1);
+          }
+        }
+      }
+
+      for (int i = order.size() - 1; i >= 0; --i) {
+        std::vector<bool> forbidden(5, false);
+        for (OutArcIt e(_graph, order[i]); e != INVALID; ++e) {
+          Node t = _graph.runningNode(e);
+          if (_color_map[t] != -1) {
+            forbidden[_color_map[t]] = true;
+          }
+        }
+        for (int k = 0; k < 5; ++k) {
+          if (!forbidden[k]) {
+            _color_map[order[i]] = k;
+            break;
+          }
+        }
+        if (_color_map[order[i]] == -1) {
+          kempeRecoloring(order[i], embedding);
+        }
+      }
+    }
+
+    /// \brief Calculate a coloring with at most five colors
+    ///
+    /// This function calculates a coloring with at most five
+    /// colors. The worst case time complexity of this variant is
+    /// quadratic in the size of the graph.
+    /// \return \c true if the graph is planar.
+    bool runFiveColoring() {
+      PlanarEmbedding<Graph> pe(_graph);
+      if (!pe.run()) return false;
+
+      runFiveColoring(pe.embeddingMap());
+      return true;
+    }
+
+  private:
+
+    const Graph& _graph;
+    IndexMap _color_map;
+    Palette _palette;
+  };
+
+}
+
+#endif
Index: lemon/preflow.h
===================================================================
--- lemon/preflow.h	(revision 559)
+++ lemon/preflow.h	(revision 944)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2011
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -53,10 +53,14 @@
     /// The type of the map that stores the flow values.
     /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+#ifdef DOXYGEN
+    typedef GR::ArcMap<Value> FlowMap;
+#else
     typedef typename Digraph::template ArcMap<Value> FlowMap;
+#endif
 
     /// \brief Instantiates a FlowMap.
     ///
     /// This function instantiates a \ref FlowMap.
-    /// \param digraph The digraph, to which we would like to define
+    /// \param digraph The digraph for which we would like to define
     /// the flow map.
     static FlowMap* createFlowMap(const Digraph& digraph) {
@@ -68,12 +72,15 @@
     /// The elevator type used by Preflow algorithm.
     ///
-    /// \sa Elevator
-    /// \sa LinkedElevator
-    typedef LinkedElevator<Digraph, typename Digraph::Node> Elevator;
+    /// \sa Elevator, LinkedElevator
+#ifdef DOXYGEN
+    typedef lemon::Elevator<GR, GR::Node> Elevator;
+#else
+    typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
+#endif
 
     /// \brief Instantiates an Elevator.
     ///
     /// This function instantiates an \ref Elevator.
-    /// \param digraph The digraph, to which we would like to define
+    /// \param digraph The digraph for which we would like to define
     /// the elevator.
     /// \param max_level The maximum level of the elevator.
@@ -96,7 +103,8 @@
   /// This class provides an implementation of Goldberg-Tarjan's \e preflow
   /// \e push-relabel algorithm producing a \ref max_flow
-  /// "flow of maximum value" in a digraph.
+  /// "flow of maximum value" in a digraph \ref clrs01algorithms,
+  /// \ref amo93networkflows, \ref goldberg88newapproach.
   /// The preflow algorithms are the fastest known maximum
-  /// flow algorithms. The current implementation use a mixture of the
+  /// flow algorithms. The current implementation uses 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$.
@@ -106,7 +114,15 @@
   /// second phase constructs a feasible maximum flow on each arc.
   ///
+  /// \warning This implementation cannot handle infinite or very large
+  /// capacities (e.g. the maximum value of \c CAP::Value).
+  ///
   /// \tparam GR The type of the digraph the algorithm runs on.
   /// \tparam CAP The type of the capacity map. The default map
   /// type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
+  /// \tparam TR The traits class that defines various types used by the
+  /// algorithm. By default, it is \ref PreflowDefaultTraits
+  /// "PreflowDefaultTraits<GR, CAP>".
+  /// In most cases, this parameter should not be set directly,
+  /// consider to use the named template parameters instead.
 #ifdef DOXYGEN
   template <typename GR, typename CAP, typename TR>
@@ -258,5 +274,5 @@
     /// 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
+    /// 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().
@@ -372,8 +388,9 @@
     }
 
-    /// \brief Sets the tolerance used by algorithm.
-    ///
-    /// Sets the tolerance used by algorithm.
-    Preflow& tolerance(const Tolerance& tolerance) const {
+    /// \brief Sets the tolerance used by the algorithm.
+    ///
+    /// Sets the tolerance object used by the algorithm.
+    /// \return <tt>(*this)</tt>
+    Preflow& tolerance(const Tolerance& tolerance) {
       _tolerance = tolerance;
       return *this;
@@ -382,7 +399,8 @@
     /// \brief Returns a const reference to the tolerance.
     ///
-    /// Returns a const reference to the tolerance.
+    /// Returns a const reference to the tolerance object used by
+    /// the algorithm.
     const Tolerance& tolerance() const {
-      return tolerance;
+      return _tolerance;
     }
 
@@ -390,6 +408,6 @@
     /// 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
+    /// If you need better control on the initial solution or the execution,
+    /// you have to call one of the \ref init() functions first, then
     /// \ref startFirstPhase() and if you need it \ref startSecondPhase().
 
@@ -405,5 +423,5 @@
       _phase = true;
       for (NodeIt n(_graph); n != INVALID; ++n) {
-        _excess->set(n, 0);
+        (*_excess)[n] = 0;
       }
 
@@ -418,8 +436,8 @@
 
       std::vector<Node> queue;
-      reached.set(_source, true);
+      reached[_source] = true;
 
       queue.push_back(_target);
-      reached.set(_target, true);
+      reached[_target] = true;
       while (!queue.empty()) {
         _level->initNewLevel();
@@ -430,5 +448,5 @@
             Node u = _graph.source(e);
             if (!reached[u] && _tolerance.positive((*_capacity)[e])) {
-              reached.set(u, true);
+              reached[u] = true;
               _level->initAddItem(u);
               nqueue.push_back(u);
@@ -445,5 +463,5 @@
           if ((*_level)[u] == _level->maxLevel()) continue;
           _flow->set(e, (*_capacity)[e]);
-          _excess->set(u, (*_excess)[u] + (*_capacity)[e]);
+          (*_excess)[u] += (*_capacity)[e];
           if (u != _target && !_level->active(u)) {
             _level->activate(u);
@@ -479,5 +497,5 @@
         }
         if (excess < 0 && n != _source) return false;
-        _excess->set(n, excess);
+        (*_excess)[n] = excess;
       }
 
@@ -488,8 +506,8 @@
 
       std::vector<Node> queue;
-      reached.set(_source, true);
+      reached[_source] = true;
 
       queue.push_back(_target);
-      reached.set(_target, true);
+      reached[_target] = true;
       while (!queue.empty()) {
         _level->initNewLevel();
@@ -501,5 +519,5 @@
             if (!reached[u] &&
                 _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
-              reached.set(u, true);
+              reached[u] = true;
               _level->initAddItem(u);
               nqueue.push_back(u);
@@ -509,5 +527,5 @@
             Node v = _graph.target(e);
             if (!reached[v] && _tolerance.positive((*_flow)[e])) {
-              reached.set(v, true);
+              reached[v] = true;
               _level->initAddItem(v);
               nqueue.push_back(v);
@@ -525,8 +543,5 @@
           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);
-          }
+          (*_excess)[u] += rem;
         }
       }
@@ -537,10 +552,11 @@
           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);
-          }
-        }
-      }
+          (*_excess)[v] += rem;
+        }
+      }
+      for (NodeIt n(_graph); n != INVALID; ++n)
+        if(n!=_source && n!=_target && _tolerance.positive((*_excess)[n]))
+          _level->activate(n);
+
       return true;
     }
@@ -559,10 +575,16 @@
       _phase = true;
 
-      Node n = _level->highestActive();
-      int level = _level->highestActiveLevel();
-      while (n != INVALID) {
+      while (true) {
         int num = _node_num;
 
-        while (num > 0 && n != INVALID) {
+        Node n = INVALID;
+        int level = -1;
+
+        while (num > 0) {
+          n = _level->highestActive();
+          if (n == INVALID) goto first_phase_done;
+          level = _level->highestActiveLevel();
+          --num;
+
           Value excess = (*_excess)[n];
           int new_level = _level->maxLevel();
@@ -578,10 +600,10 @@
               if (!_tolerance.less(rem, excess)) {
                 _flow->set(e, (*_flow)[e] + excess);
-                _excess->set(v, (*_excess)[v] + excess);
+                (*_excess)[v] += excess;
                 excess = 0;
                 goto no_more_push_1;
               } else {
                 excess -= rem;
-                _excess->set(v, (*_excess)[v] + rem);
+                (*_excess)[v] += rem;
                 _flow->set(e, (*_capacity)[e]);
               }
@@ -601,10 +623,10 @@
               if (!_tolerance.less(rem, excess)) {
                 _flow->set(e, (*_flow)[e] - excess);
-                _excess->set(v, (*_excess)[v] + excess);
+                (*_excess)[v] += excess;
                 excess = 0;
                 goto no_more_push_1;
               } else {
                 excess -= rem;
-                _excess->set(v, (*_excess)[v] + rem);
+                (*_excess)[v] += rem;
                 _flow->set(e, 0);
               }
@@ -616,5 +638,5 @@
         no_more_push_1:
 
-          _excess->set(n, excess);
+          (*_excess)[n] = excess;
 
           if (excess != 0) {
@@ -630,12 +652,20 @@
             _level->deactivate(n);
           }
-
-          n = _level->highestActive();
-          level = _level->highestActiveLevel();
+        }
+
+        num = _node_num * 20;
+        while (num > 0) {
+          while (level >= 0 && _level->activeFree(level)) {
+            --level;
+          }
+          if (level == -1) {
+            n = _level->highestActive();
+            level = _level->highestActiveLevel();
+            if (n == INVALID) goto first_phase_done;
+          } else {
+            n = _level->activeOn(level);
+          }
           --num;
-        }
-
-        num = _node_num * 20;
-        while (num > 0 && n != INVALID) {
+
           Value excess = (*_excess)[n];
           int new_level = _level->maxLevel();
@@ -651,10 +681,10 @@
               if (!_tolerance.less(rem, excess)) {
                 _flow->set(e, (*_flow)[e] + excess);
-                _excess->set(v, (*_excess)[v] + excess);
+                (*_excess)[v] += excess;
                 excess = 0;
                 goto no_more_push_2;
               } else {
                 excess -= rem;
-                _excess->set(v, (*_excess)[v] + rem);
+                (*_excess)[v] += rem;
                 _flow->set(e, (*_capacity)[e]);
               }
@@ -674,10 +704,10 @@
               if (!_tolerance.less(rem, excess)) {
                 _flow->set(e, (*_flow)[e] - excess);
-                _excess->set(v, (*_excess)[v] + excess);
+                (*_excess)[v] += excess;
                 excess = 0;
                 goto no_more_push_2;
               } else {
                 excess -= rem;
-                _excess->set(v, (*_excess)[v] + rem);
+                (*_excess)[v] += rem;
                 _flow->set(e, 0);
               }
@@ -689,5 +719,5 @@
         no_more_push_2:
 
-          _excess->set(n, excess);
+          (*_excess)[n] = excess;
 
           if (excess != 0) {
@@ -703,17 +733,7 @@
             _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;
-        }
-      }
+        }
+      }
+    first_phase_done:;
     }
 
@@ -732,5 +752,5 @@
       typename Digraph::template NodeMap<bool> reached(_graph);
       for (NodeIt n(_graph); n != INVALID; ++n) {
-        reached.set(n, (*_level)[n] < _level->maxLevel());
+        reached[n] = (*_level)[n] < _level->maxLevel();
       }
 
@@ -740,5 +760,5 @@
       std::vector<Node> queue;
       queue.push_back(_source);
-      reached.set(_source, true);
+      reached[_source] = true;
 
       while (!queue.empty()) {
@@ -750,5 +770,5 @@
             Node v = _graph.target(e);
             if (!reached[v] && _tolerance.positive((*_flow)[e])) {
-              reached.set(v, true);
+              reached[v] = true;
               _level->initAddItem(v);
               nqueue.push_back(v);
@@ -759,5 +779,5 @@
             if (!reached[u] &&
                 _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
-              reached.set(u, true);
+              reached[u] = true;
               _level->initAddItem(u);
               nqueue.push_back(u);
@@ -793,10 +813,10 @@
             if (!_tolerance.less(rem, excess)) {
               _flow->set(e, (*_flow)[e] + excess);
-              _excess->set(v, (*_excess)[v] + excess);
+              (*_excess)[v] += excess;
               excess = 0;
               goto no_more_push;
             } else {
               excess -= rem;
-              _excess->set(v, (*_excess)[v] + rem);
+              (*_excess)[v] += rem;
               _flow->set(e, (*_capacity)[e]);
             }
@@ -816,10 +836,10 @@
             if (!_tolerance.less(rem, excess)) {
               _flow->set(e, (*_flow)[e] - excess);
-              _excess->set(v, (*_excess)[v] + excess);
+              (*_excess)[v] += excess;
               excess = 0;
               goto no_more_push;
             } else {
               excess -= rem;
-              _excess->set(v, (*_excess)[v] + rem);
+              (*_excess)[v] += rem;
               _flow->set(e, 0);
             }
@@ -831,5 +851,5 @@
       no_more_push:
 
-        _excess->set(n, excess);
+        (*_excess)[n] = excess;
 
         if (excess != 0) {
@@ -902,7 +922,7 @@
     }
 
-    /// \brief Returns the flow on the given arc.
-    ///
-    /// Returns the flow on the given arc. This method can
+    /// \brief Returns the flow value on the given arc.
+    ///
+    /// Returns the flow value on the given arc. This method can
     /// be called after the second phase of the algorithm.
     ///
Index: lemon/quad_heap.h
===================================================================
--- lemon/quad_heap.h	(revision 855)
+++ lemon/quad_heap.h	(revision 855)
@@ -0,0 +1,343 @@
+/* -*- 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_QUAD_HEAP_H
+#define LEMON_QUAD_HEAP_H
+
+///\ingroup heaps
+///\file
+///\brief Fourary (quaternary) heap implementation.
+
+#include <vector>
+#include <utility>
+#include <functional>
+
+namespace lemon {
+
+  /// \ingroup heaps
+  ///
+  ///\brief Fourary (quaternary) heap data structure.
+  ///
+  /// This class implements the \e Fourary (\e quaternary) \e heap
+  /// data structure.
+  /// It fully conforms to the \ref concepts::Heap "heap concept".
+  ///
+  /// The fourary heap is a specialization of the \ref DHeap "D-ary heap"
+  /// for <tt>D=4</tt>. It is similar to the \ref BinHeap "binary heap",
+  /// but its nodes have at most four children, instead of two.
+  ///
+  /// \tparam PR Type of the priorities of the items.
+  /// \tparam IM A read-writable item map with \c int values, used
+  /// internally to handle the cross references.
+  /// \tparam CMP A functor class for comparing the priorities.
+  /// The default is \c std::less<PR>.
+  ///
+  ///\sa BinHeap
+  ///\sa DHeap
+#ifdef DOXYGEN
+  template <typename PR, typename IM, typename CMP>
+#else
+  template <typename PR, typename IM, typename CMP = std::less<PR> >
+#endif
+  class QuadHeap {
+  public:
+    /// Type of the item-int map.
+    typedef IM ItemIntMap;
+    /// Type of the priorities.
+    typedef PR Prio;
+    /// Type of the items stored in the heap.
+    typedef typename ItemIntMap::Key Item;
+    /// Type of the item-priority pairs.
+    typedef std::pair<Item,Prio> Pair;
+    /// Functor type for comparing the priorities.
+    typedef CMP Compare;
+
+    /// \brief Type to represent the states of the items.
+    ///
+    /// Each item has a state associated to it. It can be "in heap",
+    /// "pre-heap" or "post-heap". The latter two are indifferent from the
+    /// heap's point of view, but may be useful to the user.
+    ///
+    /// The item-int map must be initialized in such way that it assigns
+    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
+    enum State {
+      IN_HEAP = 0,    ///< = 0.
+      PRE_HEAP = -1,  ///< = -1.
+      POST_HEAP = -2  ///< = -2.
+    };
+
+  private:
+    std::vector<Pair> _data;
+    Compare _comp;
+    ItemIntMap &_iim;
+
+  public:
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    explicit QuadHeap(ItemIntMap &map) : _iim(map) {}
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    /// \param comp The function object used for comparing the priorities.
+    QuadHeap(ItemIntMap &map, const Compare &comp)
+      : _iim(map), _comp(comp) {}
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// This function returns the number of items stored in the heap.
+    int size() const { return _data.size(); }
+
+    /// \brief Check if the heap is empty.
+    ///
+    /// This function returns \c true if the heap is empty.
+    bool empty() const { return _data.empty(); }
+
+    /// \brief Make the heap empty.
+    ///
+    /// This functon makes the heap empty.
+    /// It does not change the cross reference map. If you want to reuse
+    /// a heap that is not surely empty, you should first clear it and
+    /// then you should set the cross reference map to \c PRE_HEAP
+    /// for each item.
+    void clear() { _data.clear(); }
+
+  private:
+    static int parent(int i) { return (i-1)/4; }
+    static int firstChild(int i) { return 4*i+1; }
+
+    bool less(const Pair &p1, const Pair &p2) const {
+      return _comp(p1.second, p2.second);
+    }
+
+    void bubbleUp(int hole, Pair p) {
+      int par = parent(hole);
+      while( hole>0 && less(p,_data[par]) ) {
+        move(_data[par],hole);
+        hole = par;
+        par = parent(hole);
+      }
+      move(p, hole);
+    }
+
+    void bubbleDown(int hole, Pair p, int length) {
+      if( length>1 ) {
+        int child = firstChild(hole);
+        while( child+3<length ) {
+          int min=child;
+          if( less(_data[++child], _data[min]) ) min=child;
+          if( less(_data[++child], _data[min]) ) min=child;
+          if( less(_data[++child], _data[min]) ) min=child;
+          if( !less(_data[min], p) )
+            goto ok;
+          move(_data[min], hole);
+          hole = min;
+          child = firstChild(hole);
+        }
+        if ( child<length ) {
+          int min = child;
+          if( ++child<length && less(_data[child], _data[min]) ) min=child;
+          if( ++child<length && less(_data[child], _data[min]) ) min=child;
+          if( less(_data[min], p) ) {
+            move(_data[min], hole);
+            hole = min;
+          }
+        }
+      }
+    ok:
+      move(p, hole);
+    }
+
+    void move(const Pair &p, int i) {
+      _data[i] = p;
+      _iim.set(p.first, i);
+    }
+
+  public:
+    /// \brief Insert a pair of item and priority into the heap.
+    ///
+    /// This function inserts \c p.first to the heap with priority
+    /// \c p.second.
+    /// \param p The pair to insert.
+    /// \pre \c p.first must not be stored in the heap.
+    void push(const Pair &p) {
+      int n = _data.size();
+      _data.resize(n+1);
+      bubbleUp(n, p);
+    }
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// This function inserts the given item into the heap with the
+    /// given priority.
+    /// \param i The item to insert.
+    /// \param p The priority of the item.
+    /// \pre \e i must not be stored in the heap.
+    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
+
+    /// \brief Return the item having minimum priority.
+    ///
+    /// This function returns the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    Item top() const { return _data[0].first; }
+
+    /// \brief The minimum priority.
+    ///
+    /// This function returns the minimum priority.
+    /// \pre The heap must be non-empty.
+    Prio prio() const { return _data[0].second; }
+
+    /// \brief Remove the item having minimum priority.
+    ///
+    /// This function removes the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      int n = _data.size()-1;
+      _iim.set(_data[0].first, POST_HEAP);
+      if (n>0) bubbleDown(0, _data[n], n);
+      _data.pop_back();
+    }
+
+    /// \brief Remove the given item from the heap.
+    ///
+    /// This function removes the given item from the heap if it is
+    /// already stored.
+    /// \param i The item to delete.
+    /// \pre \e i must be in the heap.
+    void erase(const Item &i) {
+      int h = _iim[i];
+      int n = _data.size()-1;
+      _iim.set(_data[h].first, POST_HEAP);
+      if( h<n ) {
+        if( less(_data[parent(h)], _data[n]) )
+          bubbleDown(h, _data[n], n);
+        else
+          bubbleUp(h, _data[n]);
+      }
+      _data.pop_back();
+    }
+
+    /// \brief The priority of the given item.
+    ///
+    /// This function returns the priority of the given item.
+    /// \param i The item.
+    /// \pre \e i must be in the heap.
+    Prio operator[](const Item &i) const {
+      int idx = _iim[i];
+      return _data[idx].second;
+    }
+
+    /// \brief Set the priority of an item or insert it, if it is
+    /// not stored in the heap.
+    ///
+    /// This method sets the priority of the given item if it is
+    /// already stored in the heap. Otherwise it inserts the given
+    /// item into the heap with the given priority.
+    /// \param i The item.
+    /// \param p The priority.
+    void set(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      if( idx < 0 )
+        push(i,p);
+      else if( _comp(p, _data[idx].second) )
+        bubbleUp(idx, Pair(i,p));
+      else
+        bubbleDown(idx, Pair(i,p), _data.size());
+    }
+
+    /// \brief Decrease the priority of an item to the given value.
+    ///
+    /// This function decreases the priority of an item to the given value.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be stored in the heap with priority at least \e p.
+    void decrease(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      bubbleUp(idx, Pair(i,p));
+    }
+
+    /// \brief Increase the priority of an item to the given value.
+    ///
+    /// This function increases the priority of an item to the given value.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be stored in the heap with priority at most \e p.
+    void increase(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      bubbleDown(idx, Pair(i,p), _data.size());
+    }
+
+    /// \brief Return the state of an item.
+    ///
+    /// This method returns \c PRE_HEAP if the given item has never
+    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
+    /// and \c POST_HEAP otherwise.
+    /// In the latter case it is possible that the item will get back
+    /// to the heap again.
+    /// \param i The item.
+    State state(const Item &i) const {
+      int s = _iim[i];
+      if (s>=0) s=0;
+      return State(s);
+    }
+
+    /// \brief Set the state of an item in the heap.
+    ///
+    /// This function sets the state of the given item in the heap.
+    /// It can be used to manually clear the heap when it is important
+    /// to achive better time complexity.
+    /// \param i The item.
+    /// \param st The state. It should not be \c IN_HEAP.
+    void state(const Item& i, State st) {
+      switch (st) {
+        case POST_HEAP:
+        case PRE_HEAP:
+          if (state(i) == IN_HEAP) erase(i);
+          _iim[i] = st;
+          break;
+        case IN_HEAP:
+          break;
+      }
+    }
+
+    /// \brief Replace an item in the heap.
+    ///
+    /// This function replaces item \c i with item \c j.
+    /// Item \c i must be in the heap, while \c j must be out of the heap.
+    /// After calling this method, item \c i will be out of the
+    /// heap and \c j will be in the heap with the same prioriority
+    /// as item \c i had before.
+    void replace(const Item& i, const Item& j) {
+      int idx = _iim[i];
+      _iim.set(i, _iim[j]);
+      _iim.set(j, idx);
+      _data[idx].first = j;
+    }
+
+  }; // class QuadHeap
+
+} // namespace lemon
+
+#endif // LEMON_FOURARY_HEAP_H
Index: lemon/radix_heap.h
===================================================================
--- lemon/radix_heap.h	(revision 711)
+++ lemon/radix_heap.h	(revision 711)
@@ -0,0 +1,438 @@
+/* -*- 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_RADIX_HEAP_H
+#define LEMON_RADIX_HEAP_H
+
+///\ingroup heaps
+///\file
+///\brief Radix heap implementation.
+
+#include <vector>
+#include <lemon/error.h>
+
+namespace lemon {
+
+
+  /// \ingroup heaps
+  ///
+  /// \brief Radix heap data structure.
+  ///
+  /// This class implements the \e radix \e heap data structure.
+  /// It practically conforms to the \ref concepts::Heap "heap concept",
+  /// but it has some limitations due its special implementation.
+  /// The type of the priorities must be \c int and the priority of an
+  /// item cannot be decreased under the priority of the last removed item.
+  ///
+  /// \tparam IM A read-writable item map with \c int values, used
+  /// internally to handle the cross references.
+  template <typename IM>
+  class RadixHeap {
+
+  public:
+
+    /// Type of the item-int map.
+    typedef IM ItemIntMap;
+    /// Type of the priorities.
+    typedef int Prio;
+    /// Type of the items stored in the heap.
+    typedef typename ItemIntMap::Key Item;
+
+    /// \brief Exception thrown by RadixHeap.
+    ///
+    /// This exception is thrown when an item is inserted into a
+    /// RadixHeap with a priority smaller than the last erased one.
+    /// \see RadixHeap
+    class PriorityUnderflowError : public Exception {
+    public:
+      virtual const char* what() const throw() {
+        return "lemon::RadixHeap::PriorityUnderflowError";
+      }
+    };
+
+    /// \brief Type to represent the states of the items.
+    ///
+    /// Each item has a state associated to it. It can be "in heap",
+    /// "pre-heap" or "post-heap". The latter two are indifferent from the
+    /// heap's point of view, but may be useful to the user.
+    ///
+    /// The item-int map must be initialized in such way that it assigns
+    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
+    enum State {
+      IN_HEAP = 0,    ///< = 0.
+      PRE_HEAP = -1,  ///< = -1.
+      POST_HEAP = -2  ///< = -2.
+    };
+
+  private:
+
+    struct RadixItem {
+      int prev, next, box;
+      Item item;
+      int prio;
+      RadixItem(Item _item, int _prio) : item(_item), prio(_prio) {}
+    };
+
+    struct RadixBox {
+      int first;
+      int min, size;
+      RadixBox(int _min, int _size) : first(-1), min(_min), size(_size) {}
+    };
+
+    std::vector<RadixItem> _data;
+    std::vector<RadixBox> _boxes;
+
+    ItemIntMap &_iim;
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// Constructor.
+    /// \param map A map that assigns \c int values to the items.
+    /// It is used internally to handle the cross references.
+    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
+    /// \param minimum The initial minimum value of the heap.
+    /// \param capacity The initial capacity of the heap.
+    RadixHeap(ItemIntMap &map, int minimum = 0, int capacity = 0)
+      : _iim(map)
+    {
+      _boxes.push_back(RadixBox(minimum, 1));
+      _boxes.push_back(RadixBox(minimum + 1, 1));
+      while (lower(_boxes.size() - 1, capacity + minimum - 1)) {
+        extend();
+      }
+    }
+
+    /// \brief The number of items stored in the heap.
+    ///
+    /// This function returns the number of items stored in the heap.
+    int size() const { return _data.size(); }
+
+    /// \brief Check if the heap is empty.
+    ///
+    /// This function returns \c true if the heap is empty.
+    bool empty() const { return _data.empty(); }
+
+    /// \brief Make the heap empty.
+    ///
+    /// This functon makes the heap empty.
+    /// It does not change the cross reference map. If you want to reuse
+    /// a heap that is not surely empty, you should first clear it and
+    /// then you should set the cross reference map to \c PRE_HEAP
+    /// for each item.
+    /// \param minimum The minimum value of the heap.
+    /// \param capacity The capacity of the heap.
+    void clear(int minimum = 0, int capacity = 0) {
+      _data.clear(); _boxes.clear();
+      _boxes.push_back(RadixBox(minimum, 1));
+      _boxes.push_back(RadixBox(minimum + 1, 1));
+      while (lower(_boxes.size() - 1, capacity + minimum - 1)) {
+        extend();
+      }
+    }
+
+  private:
+
+    bool upper(int box, Prio pr) {
+      return pr < _boxes[box].min;
+    }
+
+    bool lower(int box, Prio pr) {
+      return pr >= _boxes[box].min + _boxes[box].size;
+    }
+
+    // Remove item from the box list
+    void remove(int index) {
+      if (_data[index].prev >= 0) {
+        _data[_data[index].prev].next = _data[index].next;
+      } else {
+        _boxes[_data[index].box].first = _data[index].next;
+      }
+      if (_data[index].next >= 0) {
+        _data[_data[index].next].prev = _data[index].prev;
+      }
+    }
+
+    // Insert item into the box list
+    void insert(int box, int index) {
+      if (_boxes[box].first == -1) {
+        _boxes[box].first = index;
+        _data[index].next = _data[index].prev = -1;
+      } else {
+        _data[index].next = _boxes[box].first;
+        _data[_boxes[box].first].prev = index;
+        _data[index].prev = -1;
+        _boxes[box].first = index;
+      }
+      _data[index].box = box;
+    }
+
+    // Add a new box to the box list
+    void extend() {
+      int min = _boxes.back().min + _boxes.back().size;
+      int bs = 2 * _boxes.back().size;
+      _boxes.push_back(RadixBox(min, bs));
+    }
+
+    // Move an item up into the proper box.
+    void bubbleUp(int index) {
+      if (!lower(_data[index].box, _data[index].prio)) return;
+      remove(index);
+      int box = findUp(_data[index].box, _data[index].prio);
+      insert(box, index);
+    }
+
+    // Find up the proper box for the item with the given priority
+    int findUp(int start, int pr) {
+      while (lower(start, pr)) {
+        if (++start == int(_boxes.size())) {
+          extend();
+        }
+      }
+      return start;
+    }
+
+    // Move an item down into the proper box
+    void bubbleDown(int index) {
+      if (!upper(_data[index].box, _data[index].prio)) return;
+      remove(index);
+      int box = findDown(_data[index].box, _data[index].prio);
+      insert(box, index);
+    }
+
+    // Find down the proper box for the item with the given priority
+    int findDown(int start, int pr) {
+      while (upper(start, pr)) {
+        if (--start < 0) throw PriorityUnderflowError();
+      }
+      return start;
+    }
+
+    // Find the first non-empty box
+    int findFirst() {
+      int first = 0;
+      while (_boxes[first].first == -1) ++first;
+      return first;
+    }
+
+    // Gives back the minimum priority of the given box
+    int minValue(int box) {
+      int min = _data[_boxes[box].first].prio;
+      for (int k = _boxes[box].first; k != -1; k = _data[k].next) {
+        if (_data[k].prio < min) min = _data[k].prio;
+      }
+      return min;
+    }
+
+    // Rearrange the items of the heap and make the first box non-empty
+    void moveDown() {
+      int box = findFirst();
+      if (box == 0) return;
+      int min = minValue(box);
+      for (int i = 0; i <= box; ++i) {
+        _boxes[i].min = min;
+        min += _boxes[i].size;
+      }
+      int curr = _boxes[box].first, next;
+      while (curr != -1) {
+        next = _data[curr].next;
+        bubbleDown(curr);
+        curr = next;
+      }
+    }
+
+    void relocateLast(int index) {
+      if (index != int(_data.size()) - 1) {
+        _data[index] = _data.back();
+        if (_data[index].prev != -1) {
+          _data[_data[index].prev].next = index;
+        } else {
+          _boxes[_data[index].box].first = index;
+        }
+        if (_data[index].next != -1) {
+          _data[_data[index].next].prev = index;
+        }
+        _iim[_data[index].item] = index;
+      }
+      _data.pop_back();
+    }
+
+  public:
+
+    /// \brief Insert an item into the heap with the given priority.
+    ///
+    /// This function inserts the given item into the heap with the
+    /// given priority.
+    /// \param i The item to insert.
+    /// \param p The priority of the item.
+    /// \pre \e i must not be stored in the heap.
+    /// \warning This method may throw an \c UnderFlowPriorityException.
+    void push(const Item &i, const Prio &p) {
+      int n = _data.size();
+      _iim.set(i, n);
+      _data.push_back(RadixItem(i, p));
+      while (lower(_boxes.size() - 1, p)) {
+        extend();
+      }
+      int box = findDown(_boxes.size() - 1, p);
+      insert(box, n);
+    }
+
+    /// \brief Return the item having minimum priority.
+    ///
+    /// This function returns the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    Item top() const {
+      const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
+      return _data[_boxes[0].first].item;
+    }
+
+    /// \brief The minimum priority.
+    ///
+    /// This function returns the minimum priority.
+    /// \pre The heap must be non-empty.
+    Prio prio() const {
+      const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
+      return _data[_boxes[0].first].prio;
+     }
+
+    /// \brief Remove the item having minimum priority.
+    ///
+    /// This function removes the item having minimum priority.
+    /// \pre The heap must be non-empty.
+    void pop() {
+      moveDown();
+      int index = _boxes[0].first;
+      _iim[_data[index].item] = POST_HEAP;
+      remove(index);
+      relocateLast(index);
+    }
+
+    /// \brief Remove the given item from the heap.
+    ///
+    /// This function removes the given item from the heap if it is
+    /// already stored.
+    /// \param i The item to delete.
+    /// \pre \e i must be in the heap.
+    void erase(const Item &i) {
+      int index = _iim[i];
+      _iim[i] = POST_HEAP;
+      remove(index);
+      relocateLast(index);
+   }
+
+    /// \brief The priority of the given item.
+    ///
+    /// This function returns the priority of the given item.
+    /// \param i The item.
+    /// \pre \e i must be in the heap.
+    Prio operator[](const Item &i) const {
+      int idx = _iim[i];
+      return _data[idx].prio;
+    }
+
+    /// \brief Set the priority of an item or insert it, if it is
+    /// not stored in the heap.
+    ///
+    /// This method sets the priority of the given item if it is
+    /// already stored in the heap. Otherwise it inserts the given
+    /// item into the heap with the given priority.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be in the heap.
+    /// \warning This method may throw an \c UnderFlowPriorityException.
+    void set(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      if( idx < 0 ) {
+        push(i, p);
+      }
+      else if( p >= _data[idx].prio ) {
+        _data[idx].prio = p;
+        bubbleUp(idx);
+      } else {
+        _data[idx].prio = p;
+        bubbleDown(idx);
+      }
+    }
+
+    /// \brief Decrease the priority of an item to the given value.
+    ///
+    /// This function decreases the priority of an item to the given value.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be stored in the heap with priority at least \e p.
+    /// \warning This method may throw an \c UnderFlowPriorityException.
+    void decrease(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      _data[idx].prio = p;
+      bubbleDown(idx);
+    }
+
+    /// \brief Increase the priority of an item to the given value.
+    ///
+    /// This function increases the priority of an item to the given value.
+    /// \param i The item.
+    /// \param p The priority.
+    /// \pre \e i must be stored in the heap with priority at most \e p.
+    void increase(const Item &i, const Prio &p) {
+      int idx = _iim[i];
+      _data[idx].prio = p;
+      bubbleUp(idx);
+    }
+
+    /// \brief Return the state of an item.
+    ///
+    /// This method returns \c PRE_HEAP if the given item has never
+    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
+    /// and \c POST_HEAP otherwise.
+    /// In the latter case it is possible that the item will get back
+    /// to the heap again.
+    /// \param i The item.
+    State state(const Item &i) const {
+      int s = _iim[i];
+      if( s >= 0 ) s = 0;
+      return State(s);
+    }
+
+    /// \brief Set the state of an item in the heap.
+    ///
+    /// This function sets the state of the given item in the heap.
+    /// It can be used to manually clear the heap when it is important
+    /// to achive better time complexity.
+    /// \param i The item.
+    /// \param st The state. It should not be \c IN_HEAP.
+    void state(const Item& i, State st) {
+      switch (st) {
+      case POST_HEAP:
+      case PRE_HEAP:
+        if (state(i) == IN_HEAP) {
+          erase(i);
+        }
+        _iim[i] = st;
+        break;
+      case IN_HEAP:
+        break;
+      }
+    }
+
+  }; // class RadixHeap
+
+} // namespace lemon
+
+#endif // LEMON_RADIX_HEAP_H
Index: lemon/random.h
===================================================================
--- lemon/random.h	(revision 559)
+++ lemon/random.h	(revision 584)
@@ -660,5 +660,5 @@
     /// @}
 
-    ///\name Uniform distributions
+    ///\name Uniform Distributions
     ///
     /// @{
@@ -763,5 +763,5 @@
     /// @}
 
-    ///\name Non-uniform distributions
+    ///\name Non-uniform Distributions
     ///
     ///@{
@@ -939,5 +939,5 @@
     ///@}
 
-    ///\name Two dimensional distributions
+    ///\name Two Dimensional Distributions
     ///
     ///@{
Index: lemon/smart_graph.h
===================================================================
--- lemon/smart_graph.h	(revision 559)
+++ lemon/smart_graph.h	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -33,8 +33,5 @@
 
   class SmartDigraph;
-  ///Base of SmartDigraph
-
-  ///Base of SmartDigraph
-  ///
+
   class SmartDigraphBase {
   protected:
@@ -56,5 +53,5 @@
   public:
 
-    typedef SmartDigraphBase Graph;
+    typedef SmartDigraphBase Digraph;
 
     class Node;
@@ -188,34 +185,30 @@
   ///\brief A smart directed graph class.
   ///
-  ///This is a simple and fast digraph implementation.
-  ///It is also quite memory efficient, but at the price
-  ///that <b> it does support only limited (only stack-like)
-  ///node and arc deletions</b>.
-  ///It conforms to the \ref concepts::Digraph "Digraph concept" with
-  ///an important extra feature that its maps are real \ref
-  ///concepts::ReferenceMap "reference map"s.
-  ///
-  ///\sa concepts::Digraph.
+  ///\ref SmartDigraph is a simple and fast digraph implementation.
+  ///It is also quite memory efficient but at the price
+  ///that it does not support node and arc deletion
+  ///(except for the Snapshot feature).
+  ///
+  ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
+  ///and it also provides some additional functionalities.
+  ///Most of its member functions and nested classes are documented
+  ///only in the concept class.
+  ///
+  ///This class provides constant time counting for nodes and arcs.
+  ///
+  ///\sa concepts::Digraph
+  ///\sa SmartGraph
   class SmartDigraph : public ExtendedSmartDigraphBase {
+    typedef ExtendedSmartDigraphBase Parent;
+
+  private:
+    /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
+    SmartDigraph(const SmartDigraph &) : ExtendedSmartDigraphBase() {};
+    /// \brief Assignment of a digraph to another one is \e not allowed.
+    /// Use DigraphCopy instead.
+    void operator=(const SmartDigraph &) {}
+
   public:
 
-    typedef ExtendedSmartDigraphBase Parent;
-
-  private:
-
-    ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
-
-    ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
-    ///
-    SmartDigraph(const SmartDigraph &) : ExtendedSmartDigraphBase() {};
-    ///\brief Assignment of SmartDigraph to another one is \e not allowed.
-    ///Use DigraphCopy() instead.
-
-    ///Assignment of SmartDigraph to another one is \e not allowed.
-    ///Use DigraphCopy() instead.
-    void operator=(const SmartDigraph &) {}
-
-  public:
-
     /// Constructor
 
@@ -226,77 +219,47 @@
     ///Add a new node to the digraph.
 
-    /// Add a new node to the digraph.
-    /// \return The new node.
+    ///This function adds a new node to the digraph.
+    ///\return The new node.
     Node addNode() { return Parent::addNode(); }
 
     ///Add a new arc to the digraph.
 
-    ///Add a new arc to the digraph with source node \c s
+    ///This function adds a new arc to the digraph with source node \c s
     ///and target node \c t.
     ///\return The new arc.
-    Arc addArc(const Node& s, const Node& t) {
+    Arc addArc(Node s, Node t) {
       return Parent::addArc(s, t);
     }
 
-    /// \brief Using this it is possible to avoid the superfluous memory
-    /// allocation.
-
-    /// Using this it is possible to avoid the superfluous memory
-    /// allocation: if you know that the digraph you want to build will
-    /// be very large (e.g. it will contain millions of nodes and/or arcs)
-    /// then it is worth reserving space for this amount before starting
-    /// to build the digraph.
-    /// \sa reserveArc
-    void reserveNode(int n) { nodes.reserve(n); };
-
-    /// \brief Using this it is possible to avoid the superfluous memory
-    /// allocation.
-
-    /// Using this it is possible to avoid the superfluous memory
-    /// allocation: if you know that the digraph you want to build will
-    /// be very large (e.g. it will contain millions of nodes and/or arcs)
-    /// then it is worth reserving space for this amount before starting
-    /// to build the digraph.
-    /// \sa reserveNode
-    void reserveArc(int m) { arcs.reserve(m); };
-
     /// \brief Node validity check
     ///
-    /// This function gives back true if the given node is valid,
-    /// ie. it is a real node of the graph.
+    /// This function gives back \c true if the given node is valid,
+    /// i.e. it is a real node of the digraph.
     ///
     /// \warning A removed node (using Snapshot) could become valid again
-    /// when new nodes are added to the graph.
+    /// if new nodes are added to the digraph.
     bool valid(Node n) const { return Parent::valid(n); }
 
     /// \brief Arc validity check
     ///
-    /// This function gives back true if the given arc is valid,
-    /// ie. it is a real arc of the graph.
+    /// This function gives back \c true if the given arc is valid,
+    /// i.e. it is a real arc of the digraph.
     ///
     /// \warning A removed arc (using Snapshot) could become valid again
-    /// when new arcs are added to the graph.
+    /// if new arcs are added to the graph.
     bool valid(Arc a) const { return Parent::valid(a); }
 
-    ///Clear the digraph.
-
-    ///Erase all the nodes and arcs from the digraph.
-    ///
-    void clear() {
-      Parent::clear();
-    }
-
     ///Split a node.
 
-    ///This function splits a node. First a new node is added to the digraph,
-    ///then the source of each outgoing arc of \c n is moved to this new node.
-    ///If \c connect is \c true (this is the default value), then a new arc
-    ///from \c n to the newly created node is also added.
+    ///This function splits the given node. First, a new node is added
+    ///to the digraph, then the source of each outgoing arc of node \c n
+    ///is moved to this new node.
+    ///If the second parameter \c connect is \c true (this is the default
+    ///value), then a new arc from node \c n to the newly created node
+    ///is also added.
     ///\return The newly created node.
     ///
-    ///\note The <tt>Arc</tt>s
-    ///referencing a moved arc remain
-    ///valid. However <tt>InArc</tt>'s and <tt>OutArc</tt>'s
-    ///may be invalidated.
+    ///\note All iterators remain valid.
+    ///
     ///\warning This functionality cannot be used together with the Snapshot
     ///feature.
@@ -313,4 +276,32 @@
     }
 
+    ///Clear the digraph.
+
+    ///This function erases all nodes and arcs from the digraph.
+    ///
+    void clear() {
+      Parent::clear();
+    }
+
+    /// Reserve memory for nodes.
+
+    /// Using this function, it is possible to avoid superfluous memory
+    /// allocation: if you know that the digraph you want to build will
+    /// be large (e.g. it will contain millions of nodes and/or arcs),
+    /// then it is worth reserving space for this amount before starting
+    /// to build the digraph.
+    /// \sa reserveArc()
+    void reserveNode(int n) { nodes.reserve(n); };
+
+    /// Reserve memory for arcs.
+
+    /// Using this function, it is possible to avoid superfluous memory
+    /// allocation: if you know that the digraph you want to build will
+    /// be large (e.g. it will contain millions of nodes and/or arcs),
+    /// then it is worth reserving space for this amount before starting
+    /// to build the digraph.
+    /// \sa reserveNode()
+    void reserveArc(int m) { arcs.reserve(m); };
+
   public:
 
@@ -337,18 +328,21 @@
   public:
 
-    ///Class to make a snapshot of the digraph and to restrore to it later.
-
-    ///Class to make a snapshot of the digraph and to restrore to it later.
+    ///Class to make a snapshot of the digraph and to restore it later.
+
+    ///Class to make a snapshot of the digraph and to restore it later.
     ///
     ///The newly added nodes and arcs can be removed using the
-    ///restore() function.
-    ///\note After you restore a state, you cannot restore
-    ///a later state, in other word you cannot add again the arcs deleted
-    ///by restore() using another one Snapshot instance.
-    ///
-    ///\warning If you do not use correctly the snapshot that can cause
-    ///either broken program, invalid state of the digraph, valid but
-    ///not the restored digraph or no change. Because the runtime performance
-    ///the validity of the snapshot is not stored.
+    ///restore() function. This is the only way for deleting nodes and/or
+    ///arcs from a SmartDigraph structure.
+    ///
+    ///\note After a state is restored, you cannot restore a later state,
+    ///i.e. you cannot add the removed nodes and arcs again using
+    ///another Snapshot instance.
+    ///
+    ///\warning Node splitting cannot be restored.
+    ///\warning The validity of the snapshot is not stored due to
+    ///performance reasons. If you do not use the snapshot correctly,
+    ///it can cause broken program, invalid or not restored state of
+    ///the digraph or no change.
     class Snapshot
     {
@@ -362,12 +356,11 @@
 
       ///Default constructor.
-      ///To actually make a snapshot you must call save().
-      ///
+      ///You have to call save() to actually make a snapshot.
       Snapshot() : _graph(0) {}
       ///Constructor that immediately makes a snapshot
 
-      ///This constructor immediately makes a snapshot of the digraph.
-      ///\param graph The digraph we make a snapshot of.
-      Snapshot(SmartDigraph &graph) : _graph(&graph) {
+      ///This constructor immediately makes a snapshot of the given digraph.
+      ///
+      Snapshot(SmartDigraph &gr) : _graph(&gr) {
         node_num=_graph->nodes.size();
         arc_num=_graph->arcs.size();
@@ -376,12 +369,9 @@
       ///Make a snapshot.
 
-      ///Make a snapshot of the digraph.
-      ///
-      ///This function can be called more than once. In case of a repeated
+      ///This function makes a snapshot of the given digraph.
+      ///It can be called more than once. In case of a repeated
       ///call, the previous snapshot gets lost.
-      ///\param graph The digraph we make the snapshot of.
-      void save(SmartDigraph &graph)
-      {
-        _graph=&graph;
+      void save(SmartDigraph &gr) {
+        _graph=&gr;
         node_num=_graph->nodes.size();
         arc_num=_graph->arcs.size();
@@ -390,9 +380,6 @@
       ///Undo the changes until a snapshot.
 
-      ///Undo the changes until a snapshot created by save().
-      ///
-      ///\note After you restored a state, you cannot restore
-      ///a later state, in other word you cannot add again the arcs deleted
-      ///by restore().
+      ///This function undos the changes until the last snapshot
+      ///created by save() or Snapshot(SmartDigraph&).
       void restore()
       {
@@ -423,5 +410,5 @@
   public:
 
-    typedef SmartGraphBase Digraph;
+    typedef SmartGraphBase Graph;
 
     class Node;
@@ -513,5 +500,5 @@
     }
 
-    void next(Node& node) const {
+    static void next(Node& node) {
       --node._id;
     }
@@ -521,5 +508,5 @@
     }
 
-    void next(Arc& arc) const {
+    static void next(Arc& arc) {
       --arc._id;
     }
@@ -529,5 +516,5 @@
     }
 
-    void next(Edge& arc) const {
+    static void next(Edge& arc) {
       --arc._id;
     }
@@ -626,37 +613,30 @@
   /// \brief A smart undirected graph class.
   ///
-  /// This is a simple and fast graph implementation.
-  /// It is also quite memory efficient, but at the price
-  /// that <b> it does support only limited (only stack-like)
-  /// node and arc deletions</b>.
-  /// Except from this it conforms to
-  /// the \ref concepts::Graph "Graph concept".
-  ///
-  /// It also has an
-  /// important extra feature that
-  /// its maps are real \ref concepts::ReferenceMap "reference map"s.
-  ///
-  /// \sa concepts::Graph.
-  ///
+  /// \ref SmartGraph is a simple and fast graph implementation.
+  /// It is also quite memory efficient but at the price
+  /// that it does not support node and edge deletion
+  /// (except for the Snapshot feature).
+  ///
+  /// This type fully conforms to the \ref concepts::Graph "Graph concept"
+  /// and it also provides some additional functionalities.
+  /// Most of its member functions and nested classes are documented
+  /// only in the concept class.
+  ///
+  /// This class provides constant time counting for nodes, edges and arcs.
+  ///
+  /// \sa concepts::Graph
+  /// \sa SmartDigraph
   class SmartGraph : public ExtendedSmartGraphBase {
+    typedef ExtendedSmartGraphBase Parent;
+
   private:
-
-    ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
-
-    ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
-    ///
+    /// Graphs are \e not copy constructible. Use GraphCopy instead.
     SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {};
-
-    ///\brief Assignment of SmartGraph to another one is \e not allowed.
-    ///Use GraphCopy() instead.
-
-    ///Assignment of SmartGraph to another one is \e not allowed.
-    ///Use GraphCopy() instead.
+    /// \brief Assignment of a graph to another one is \e not allowed.
+    /// Use GraphCopy instead.
     void operator=(const SmartGraph &) {}
 
   public:
 
-    typedef ExtendedSmartGraphBase Parent;
-
     /// Constructor
 
@@ -665,53 +645,74 @@
     SmartGraph() {}
 
-    ///Add a new node to the graph.
-
-    /// Add a new node to the graph.
+    /// \brief Add a new node to the graph.
+    ///
+    /// This function adds a new node to the graph.
     /// \return The new node.
     Node addNode() { return Parent::addNode(); }
 
-    ///Add a new edge to the graph.
-
-    ///Add a new edge to the graph with node \c s
-    ///and \c t.
-    ///\return The new edge.
-    Edge addEdge(const Node& s, const Node& t) {
-      return Parent::addEdge(s, t);
+    /// \brief Add a new edge to the graph.
+    ///
+    /// This function adds a new edge to the graph between nodes
+    /// \c u and \c v with inherent orientation from node \c u to
+    /// node \c v.
+    /// \return The new edge.
+    Edge addEdge(Node u, Node v) {
+      return Parent::addEdge(u, v);
     }
 
     /// \brief Node validity check
     ///
-    /// This function gives back true if the given node is valid,
-    /// ie. it is a real node of the graph.
+    /// This function gives back \c true if the given node is valid,
+    /// i.e. it is a real node of the graph.
     ///
     /// \warning A removed node (using Snapshot) could become valid again
-    /// when new nodes are added to the graph.
+    /// if new nodes are added to the graph.
     bool valid(Node n) const { return Parent::valid(n); }
 
+    /// \brief Edge validity check
+    ///
+    /// This function gives back \c true if the given edge is valid,
+    /// i.e. it is a real edge of the graph.
+    ///
+    /// \warning A removed edge (using Snapshot) could become valid again
+    /// if new edges are added to the graph.
+    bool valid(Edge e) const { return Parent::valid(e); }
+
     /// \brief Arc validity check
     ///
-    /// This function gives back true if the given arc is valid,
-    /// ie. it is a real arc of the graph.
+    /// This function gives back \c true if the given arc is valid,
+    /// i.e. it is a real arc of the graph.
     ///
     /// \warning A removed arc (using Snapshot) could become valid again
-    /// when new edges are added to the graph.
+    /// if new edges are added to the graph.
     bool valid(Arc a) const { return Parent::valid(a); }
 
-    /// \brief Edge validity check
-    ///
-    /// This function gives back true if the given edge is valid,
-    /// ie. it is a real edge of the graph.
-    ///
-    /// \warning A removed edge (using Snapshot) could become valid again
-    /// when new edges are added to the graph.
-    bool valid(Edge e) const { return Parent::valid(e); }
-
     ///Clear the graph.
 
-    ///Erase all the nodes and edges from the graph.
+    ///This function erases all nodes and arcs from the graph.
     ///
     void clear() {
       Parent::clear();
     }
+
+    /// Reserve memory for nodes.
+
+    /// Using this function, it is possible to avoid superfluous memory
+    /// allocation: if you know that the graph you want to build will
+    /// be large (e.g. it will contain millions of nodes and/or edges),
+    /// then it is worth reserving space for this amount before starting
+    /// to build the graph.
+    /// \sa reserveEdge()
+    void reserveNode(int n) { nodes.reserve(n); };
+
+    /// Reserve memory for edges.
+
+    /// Using this function, it is possible to avoid superfluous memory
+    /// allocation: if you know that the graph you want to build will
+    /// be large (e.g. it will contain millions of nodes and/or edges),
+    /// then it is worth reserving space for this amount before starting
+    /// to build the graph.
+    /// \sa reserveNode()
+    void reserveEdge(int m) { arcs.reserve(2 * m); };
 
   public:
@@ -753,19 +754,20 @@
   public:
 
-    ///Class to make a snapshot of the digraph and to restrore to it later.
-
-    ///Class to make a snapshot of the digraph and to restrore to it later.
-    ///
-    ///The newly added nodes and arcs can be removed using the
-    ///restore() function.
-    ///
-    ///\note After you restore a state, you cannot restore
-    ///a later state, in other word you cannot add again the arcs deleted
-    ///by restore() using another one Snapshot instance.
-    ///
-    ///\warning If you do not use correctly the snapshot that can cause
-    ///either broken program, invalid state of the digraph, valid but
-    ///not the restored digraph or no change. Because the runtime performance
-    ///the validity of the snapshot is not stored.
+    ///Class to make a snapshot of the graph and to restore it later.
+
+    ///Class to make a snapshot of the graph and to restore it later.
+    ///
+    ///The newly added nodes and edges can be removed using the
+    ///restore() function. This is the only way for deleting nodes and/or
+    ///edges from a SmartGraph structure.
+    ///
+    ///\note After a state is restored, you cannot restore a later state,
+    ///i.e. you cannot add the removed nodes and edges again using
+    ///another Snapshot instance.
+    ///
+    ///\warning The validity of the snapshot is not stored due to
+    ///performance reasons. If you do not use the snapshot correctly,
+    ///it can cause broken program, invalid or not restored state of
+    ///the graph or no change.
     class Snapshot
     {
@@ -779,34 +781,28 @@
 
       ///Default constructor.
-      ///To actually make a snapshot you must call save().
-      ///
+      ///You have to call save() to actually make a snapshot.
       Snapshot() : _graph(0) {}
       ///Constructor that immediately makes a snapshot
 
-      ///This constructor immediately makes a snapshot of the digraph.
-      ///\param graph The digraph we make a snapshot of.
-      Snapshot(SmartGraph &graph) {
-        graph.saveSnapshot(*this);
+      /// This constructor immediately makes a snapshot of the given graph.
+      ///
+      Snapshot(SmartGraph &gr) {
+        gr.saveSnapshot(*this);
       }
 
       ///Make a snapshot.
 
-      ///Make a snapshot of the graph.
-      ///
-      ///This function can be called more than once. In case of a repeated
+      ///This function makes a snapshot of the given graph.
+      ///It can be called more than once. In case of a repeated
       ///call, the previous snapshot gets lost.
-      ///\param graph The digraph we make the snapshot of.
-      void save(SmartGraph &graph)
+      void save(SmartGraph &gr)
       {
-        graph.saveSnapshot(*this);
-      }
-
-      ///Undo the changes until a snapshot.
-
-      ///Undo the changes until a snapshot created by save().
-      ///
-      ///\note After you restored a state, you cannot restore
-      ///a later state, in other word you cannot add again the arcs deleted
-      ///by restore().
+        gr.saveSnapshot(*this);
+      }
+
+      ///Undo the changes until the last snapshot.
+
+      ///This function undos the changes until the last snapshot
+      ///created by save() or Snapshot(SmartGraph&).
       void restore()
       {
Index: lemon/soplex.cc
===================================================================
--- lemon/soplex.cc	(revision 540)
+++ lemon/soplex.cc	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -21,4 +21,5 @@
 
 #include <soplex.h>
+#include <spxout.h>
 
 
@@ -29,4 +30,5 @@
   SoplexLp::SoplexLp() {
     soplex = new soplex::SoPlex;
+    messageLevel(MESSAGE_NOTHING);
   }
 
@@ -48,4 +50,5 @@
     _row_names_ref = lp._row_names_ref;
 
+    messageLevel(MESSAGE_NOTHING);
   }
 
@@ -82,4 +85,17 @@
     r.setLhs(-soplex::infinity);
     r.setRhs(soplex::infinity);
+    soplex->addRow(r);
+
+    _row_names.push_back(std::string());
+
+    return soplex->nRows() - 1;
+  }
+
+  int SoplexLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
+    soplex::DSVector v;
+    for (ExprIterator it = b; it != e; ++it) {
+      v.add(it->first, it->second);
+    }
+    soplex::LPRow r(l, v, u);
     soplex->addRow(r);
 
@@ -272,4 +288,6 @@
 
     _clear_temporals();
+
+    _applyMessageLevel();
 
     soplex::SPxSolver::Status status = soplex->solve();
@@ -420,4 +438,28 @@
   }
 
+  void SoplexLp::_messageLevel(MessageLevel level) {
+    switch (level) {
+    case MESSAGE_NOTHING:
+      _message_level = -1;
+      break;
+    case MESSAGE_ERROR:
+      _message_level = soplex::SPxOut::ERROR;
+      break;
+    case MESSAGE_WARNING:
+      _message_level = soplex::SPxOut::WARNING;
+      break;
+    case MESSAGE_NORMAL:
+      _message_level = soplex::SPxOut::INFO2;
+      break;
+    case MESSAGE_VERBOSE:
+      _message_level = soplex::SPxOut::DEBUG;
+      break;
+    }
+  }
+
+  void SoplexLp::_applyMessageLevel() {
+    soplex::Param::setVerbose(_message_level);
+  }
+
 } //namespace lemon
 
Index: lemon/soplex.h
===================================================================
--- lemon/soplex.h	(revision 540)
+++ lemon/soplex.h	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -85,4 +85,5 @@
     virtual int _addCol();
     virtual int _addRow();
+    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
 
     virtual void _eraseCol(int i);
@@ -145,4 +146,9 @@
     virtual void _clear();
 
+    void _messageLevel(MessageLevel m);
+    void _applyMessageLevel();
+
+    int _message_level;
+
   };
 
Index: lemon/static_graph.h
===================================================================
--- lemon/static_graph.h	(revision 877)
+++ lemon/static_graph.h	(revision 877)
@@ -0,0 +1,476 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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_STATIC_GRAPH_H
+#define LEMON_STATIC_GRAPH_H
+
+///\ingroup graphs
+///\file
+///\brief StaticDigraph class.
+
+#include <lemon/core.h>
+#include <lemon/bits/graph_extender.h>
+
+namespace lemon {
+
+  class StaticDigraphBase {
+  public:
+
+    StaticDigraphBase()
+      : built(false), node_num(0), arc_num(0),
+        node_first_out(NULL), node_first_in(NULL),
+        arc_source(NULL), arc_target(NULL),
+        arc_next_in(NULL), arc_next_out(NULL) {}
+
+    ~StaticDigraphBase() {
+      if (built) {
+        delete[] node_first_out;
+        delete[] node_first_in;
+        delete[] arc_source;
+        delete[] arc_target;
+        delete[] arc_next_out;
+        delete[] arc_next_in;
+      }
+    }
+
+    class Node {
+      friend class StaticDigraphBase;
+    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 StaticDigraphBase;
+    protected:
+      int id;
+      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; }
+    };
+
+    Node source(const Arc& e) const { return Node(arc_source[e.id]); }
+    Node target(const Arc& e) const { return Node(arc_target[e.id]); }
+
+    void first(Node& n) const { n.id = node_num - 1; }
+    static void next(Node& n) { --n.id; }
+
+    void first(Arc& e) const { e.id = arc_num - 1; }
+    static void next(Arc& e) { --e.id; }
+
+    void firstOut(Arc& e, const Node& n) const {
+      e.id = node_first_out[n.id] != node_first_out[n.id + 1] ?
+        node_first_out[n.id] : -1;
+    }
+    void nextOut(Arc& e) const { e.id = arc_next_out[e.id]; }
+
+    void firstIn(Arc& e, const Node& n) const { e.id = node_first_in[n.id]; }
+    void nextIn(Arc& e) const { e.id = arc_next_in[e.id]; }
+
+    static int id(const Node& n) { return n.id; }
+    static Node nodeFromId(int id) { return Node(id); }
+    int maxNodeId() const { return node_num - 1; }
+
+    static int id(const Arc& e) { return e.id; }
+    static Arc arcFromId(int id) { return Arc(id); }
+    int maxArcId() const { return arc_num - 1; }
+
+    typedef True NodeNumTag;
+    typedef True ArcNumTag;
+
+    int nodeNum() const { return node_num; }
+    int arcNum() const { return arc_num; }
+
+  private:
+
+    template <typename Digraph, typename NodeRefMap>
+    class ArcLess {
+    public:
+      typedef typename Digraph::Arc Arc;
+
+      ArcLess(const Digraph &_graph, const NodeRefMap& _nodeRef)
+        : digraph(_graph), nodeRef(_nodeRef) {}
+
+      bool operator()(const Arc& left, const Arc& right) const {
+        return nodeRef[digraph.target(left)] < nodeRef[digraph.target(right)];
+      }
+    private:
+      const Digraph& digraph;
+      const NodeRefMap& nodeRef;
+    };
+
+  public:
+
+    typedef True BuildTag;
+
+    void clear() {
+      if (built) {
+        delete[] node_first_out;
+        delete[] node_first_in;
+        delete[] arc_source;
+        delete[] arc_target;
+        delete[] arc_next_out;
+        delete[] arc_next_in;
+      }
+      built = false;
+      node_num = 0;
+      arc_num = 0;
+    }
+
+    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
+    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
+      typedef typename Digraph::Node GNode;
+      typedef typename Digraph::Arc GArc;
+
+      built = true;
+
+      node_num = countNodes(digraph);
+      arc_num = countArcs(digraph);
+
+      node_first_out = new int[node_num + 1];
+      node_first_in = new int[node_num];
+
+      arc_source = new int[arc_num];
+      arc_target = new int[arc_num];
+      arc_next_out = new int[arc_num];
+      arc_next_in = new int[arc_num];
+
+      int node_index = 0;
+      for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
+        nodeRef[n] = Node(node_index);
+        node_first_in[node_index] = -1;
+        ++node_index;
+      }
+
+      ArcLess<Digraph, NodeRefMap> arcLess(digraph, nodeRef);
+
+      int arc_index = 0;
+      for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
+        int source = nodeRef[n].id;
+        std::vector<GArc> arcs;
+        for (typename Digraph::OutArcIt e(digraph, n); e != INVALID; ++e) {
+          arcs.push_back(e);
+        }
+        if (!arcs.empty()) {
+          node_first_out[source] = arc_index;
+          std::sort(arcs.begin(), arcs.end(), arcLess);
+          for (typename std::vector<GArc>::iterator it = arcs.begin();
+               it != arcs.end(); ++it) {
+            int target = nodeRef[digraph.target(*it)].id;
+            arcRef[*it] = Arc(arc_index);
+            arc_source[arc_index] = source;
+            arc_target[arc_index] = target;
+            arc_next_in[arc_index] = node_first_in[target];
+            node_first_in[target] = arc_index;
+            arc_next_out[arc_index] = arc_index + 1;
+            ++arc_index;
+          }
+          arc_next_out[arc_index - 1] = -1;
+        } else {
+          node_first_out[source] = arc_index;
+        }
+      }
+      node_first_out[node_num] = arc_num;
+    }
+
+    template <typename ArcListIterator>
+    void build(int n, ArcListIterator first, ArcListIterator last) {
+      built = true;
+
+      node_num = n;
+      arc_num = std::distance(first, last);
+
+      node_first_out = new int[node_num + 1];
+      node_first_in = new int[node_num];
+
+      arc_source = new int[arc_num];
+      arc_target = new int[arc_num];
+      arc_next_out = new int[arc_num];
+      arc_next_in = new int[arc_num];
+
+      for (int i = 0; i != node_num; ++i) {
+        node_first_in[i] = -1;
+      }
+
+      int arc_index = 0;
+      for (int i = 0; i != node_num; ++i) {
+        node_first_out[i] = arc_index;
+        for ( ; first != last && (*first).first == i; ++first) {
+          int j = (*first).second;
+          LEMON_ASSERT(j >= 0 && j < node_num,
+            "Wrong arc list for StaticDigraph::build()");
+          arc_source[arc_index] = i;
+          arc_target[arc_index] = j;
+          arc_next_in[arc_index] = node_first_in[j];
+          node_first_in[j] = arc_index;
+          arc_next_out[arc_index] = arc_index + 1;
+          ++arc_index;
+        }
+        if (arc_index > node_first_out[i])
+          arc_next_out[arc_index - 1] = -1;
+      }
+      LEMON_ASSERT(first == last,
+        "Wrong arc list for StaticDigraph::build()");
+      node_first_out[node_num] = arc_num;
+    }
+
+  protected:
+
+    void fastFirstOut(Arc& e, const Node& n) const {
+      e.id = node_first_out[n.id];
+    }
+
+    static void fastNextOut(Arc& e) {
+      ++e.id;
+    }
+    void fastLastOut(Arc& e, const Node& n) const {
+      e.id = node_first_out[n.id + 1];
+    }
+
+  protected:
+    bool built;
+    int node_num;
+    int arc_num;
+    int *node_first_out;
+    int *node_first_in;
+    int *arc_source;
+    int *arc_target;
+    int *arc_next_in;
+    int *arc_next_out;
+  };
+
+  typedef DigraphExtender<StaticDigraphBase> ExtendedStaticDigraphBase;
+
+
+  /// \ingroup graphs
+  ///
+  /// \brief A static directed graph class.
+  ///
+  /// \ref StaticDigraph is a highly efficient digraph implementation,
+  /// but it is fully static.
+  /// It stores only two \c int values for each node and only four \c int
+  /// values for each arc. Moreover it provides faster item iteration than
+  /// \ref ListDigraph and \ref SmartDigraph, especially using \c OutArcIt
+  /// iterators, since its arcs are stored in an appropriate order.
+  /// However it only provides build() and clear() functions and does not
+  /// support any other modification of the digraph.
+  ///
+  /// Since this digraph structure is completely static, its nodes and arcs
+  /// can be indexed with integers from the ranges <tt>[0..nodeNum()-1]</tt>
+  /// and <tt>[0..arcNum()-1]</tt>, respectively.
+  /// The index of an item is the same as its ID, it can be obtained
+  /// using the corresponding \ref index() or \ref concepts::Digraph::id()
+  /// "id()" function. A node or arc with a certain index can be obtained
+  /// using node() or arc().
+  ///
+  /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
+  /// Most of its member functions and nested classes are documented
+  /// only in the concept class.
+  ///
+  /// This class provides constant time counting for nodes and arcs.
+  ///
+  /// \sa concepts::Digraph
+  class StaticDigraph : public ExtendedStaticDigraphBase {
+  public:
+
+    typedef ExtendedStaticDigraphBase Parent;
+
+  public:
+
+    /// \brief Constructor
+    ///
+    /// Default constructor.
+    StaticDigraph() : Parent() {}
+
+    /// \brief The node with the given index.
+    ///
+    /// This function returns the node with the given index.
+    /// \sa index()
+    static Node node(int ix) { return Parent::nodeFromId(ix); }
+
+    /// \brief The arc with the given index.
+    ///
+    /// This function returns the arc with the given index.
+    /// \sa index()
+    static Arc arc(int ix) { return Parent::arcFromId(ix); }
+
+    /// \brief The index of the given node.
+    ///
+    /// This function returns the index of the the given node.
+    /// \sa node()
+    static int index(Node node) { return Parent::id(node); }
+
+    /// \brief The index of the given arc.
+    ///
+    /// This function returns the index of the the given arc.
+    /// \sa arc()
+    static int index(Arc arc) { return Parent::id(arc); }
+
+    /// \brief Number of nodes.
+    ///
+    /// This function returns the number of nodes.
+    int nodeNum() const { return node_num; }
+
+    /// \brief Number of arcs.
+    ///
+    /// This function returns the number of arcs.
+    int arcNum() const { return arc_num; }
+
+    /// \brief Build the digraph copying another digraph.
+    ///
+    /// This function builds the digraph copying another digraph of any
+    /// kind. It can be called more than once, but in such case, the whole
+    /// structure and all maps will be cleared and rebuilt.
+    ///
+    /// This method also makes possible to copy a digraph to a StaticDigraph
+    /// structure using \ref DigraphCopy.
+    ///
+    /// \param digraph An existing digraph to be copied.
+    /// \param nodeRef The node references will be copied into this map.
+    /// Its key type must be \c Digraph::Node and its value type must be
+    /// \c StaticDigraph::Node.
+    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
+    /// concept.
+    /// \param arcRef The arc references will be copied into this map.
+    /// Its key type must be \c Digraph::Arc and its value type must be
+    /// \c StaticDigraph::Arc.
+    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+    ///
+    /// \note If you do not need the arc references, then you could use
+    /// \ref NullMap for the last parameter. However the node references
+    /// are required by the function itself, thus they must be readable
+    /// from the map.
+    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
+    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
+      if (built) Parent::clear();
+      Parent::build(digraph, nodeRef, arcRef);
+    }
+
+    /// \brief Build the digraph from an arc list.
+    ///
+    /// This function builds the digraph from the given arc list.
+    /// It can be called more than once, but in such case, the whole
+    /// structure and all maps will be cleared and rebuilt.
+    ///
+    /// The list of the arcs must be given in the range <tt>[begin, end)</tt>
+    /// specified by STL compatible itartors whose \c value_type must be
+    /// <tt>std::pair<int,int></tt>.
+    /// Each arc must be specified by a pair of integer indices
+    /// from the range <tt>[0..n-1]</tt>. <i>The pairs must be in a
+    /// non-decreasing order with respect to their first values.</i>
+    /// If the k-th pair in the list is <tt>(i,j)</tt>, then
+    /// <tt>arc(k-1)</tt> will connect <tt>node(i)</tt> to <tt>node(j)</tt>.
+    ///
+    /// \param n The number of nodes.
+    /// \param begin An iterator pointing to the beginning of the arc list.
+    /// \param end An iterator pointing to the end of the arc list.
+    ///
+    /// For example, a simple digraph can be constructed like this.
+    /// \code
+    ///   std::vector<std::pair<int,int> > arcs;
+    ///   arcs.push_back(std::make_pair(0,1));
+    ///   arcs.push_back(std::make_pair(0,2));
+    ///   arcs.push_back(std::make_pair(1,3));
+    ///   arcs.push_back(std::make_pair(1,2));
+    ///   arcs.push_back(std::make_pair(3,0));
+    ///   StaticDigraph gr;
+    ///   gr.build(4, arcs.begin(), arcs.end());
+    /// \endcode
+    template <typename ArcListIterator>
+    void build(int n, ArcListIterator begin, ArcListIterator end) {
+      if (built) Parent::clear();
+      StaticDigraphBase::build(n, begin, end);
+      notifier(Node()).build();
+      notifier(Arc()).build();
+    }
+
+    /// \brief Clear the digraph.
+    ///
+    /// This function erases all nodes and arcs from the digraph.
+    void clear() {
+      Parent::clear();
+    }
+
+  protected:
+
+    using Parent::fastFirstOut;
+    using Parent::fastNextOut;
+    using Parent::fastLastOut;
+
+  public:
+
+    class OutArcIt : public Arc {
+    public:
+
+      OutArcIt() { }
+
+      OutArcIt(Invalid i) : Arc(i) { }
+
+      OutArcIt(const StaticDigraph& digraph, const Node& node) {
+        digraph.fastFirstOut(*this, node);
+        digraph.fastLastOut(last, node);
+        if (last == *this) *this = INVALID;
+      }
+
+      OutArcIt(const StaticDigraph& digraph, const Arc& arc) : Arc(arc) {
+        if (arc != INVALID) {
+          digraph.fastLastOut(last, digraph.source(arc));
+        }
+      }
+
+      OutArcIt& operator++() {
+        StaticDigraph::fastNextOut(*this);
+        if (last == *this) *this = INVALID;
+        return *this;
+      }
+
+    private:
+      Arc last;
+    };
+
+    Node baseNode(const OutArcIt &arc) const {
+      return Parent::source(static_cast<const Arc&>(arc));
+    }
+
+    Node runningNode(const OutArcIt &arc) const {
+      return Parent::target(static_cast<const Arc&>(arc));
+    }
+
+    Node baseNode(const InArcIt &arc) const {
+      return Parent::target(static_cast<const Arc&>(arc));
+    }
+
+    Node runningNode(const InArcIt &arc) const {
+      return Parent::source(static_cast<const Arc&>(arc));
+    }
+
+  };
+
+}
+
+#endif
Index: lemon/suurballe.h
===================================================================
--- lemon/suurballe.h	(revision 559)
+++ lemon/suurballe.h	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -26,10 +26,55 @@
 
 #include <vector>
+#include <limits>
 #include <lemon/bin_heap.h>
 #include <lemon/path.h>
 #include <lemon/list_graph.h>
+#include <lemon/dijkstra.h>
 #include <lemon/maps.h>
 
 namespace lemon {
+
+  /// \brief Default traits class of Suurballe algorithm.
+  ///
+  /// Default traits class of Suurballe algorithm.
+  /// \tparam GR The digraph type the algorithm runs on.
+  /// \tparam LEN The type of the length map.
+  /// The default value is <tt>GR::ArcMap<int></tt>.
+#ifdef DOXYGEN
+  template <typename GR, typename LEN>
+#else
+  template < typename GR,
+             typename LEN = typename GR::template ArcMap<int> >
+#endif
+  struct SuurballeDefaultTraits
+  {
+    /// The type of the digraph.
+    typedef GR Digraph;
+    /// The type of the length map.
+    typedef LEN LengthMap;
+    /// The type of the lengths.
+    typedef typename LEN::Value Length;
+    /// The type of the flow map.
+    typedef typename GR::template ArcMap<int> FlowMap;
+    /// The type of the potential map.
+    typedef typename GR::template NodeMap<Length> PotentialMap;
+
+    /// \brief The path type
+    ///
+    /// The type used for storing the found arc-disjoint paths.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addBack() function.
+    typedef lemon::Path<Digraph> Path;
+
+    /// The cross reference type used for the heap.
+    typedef typename GR::template NodeMap<int> HeapCrossRef;
+
+    /// \brief The heap type used for internal Dijkstra computations.
+    ///
+    /// The type of the heap used for internal Dijkstra computations.
+    /// It must conform to the \ref lemon::concepts::Heap "Heap" concept
+    /// and its priority type must be \c Length.
+    typedef BinHeap<Length, HeapCrossRef> Heap;
+  };
 
   /// \addtogroup shortest_path
@@ -43,21 +88,26 @@
   /// 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.
+  /// Note that this problem is a special case of the \ref min_cost_flow
+  /// "minimum cost flow problem". This implementation is actually an
+  /// efficient specialized version of the \ref CapacityScaling
+  /// "successive shortest path" algorithm directly for this problem.
+  /// Therefore this class provides query functions for flow values and
+  /// node potentials (the dual solution) just like the minimum cost flow
+  /// algorithms.
   ///
   /// \tparam GR The digraph type the algorithm runs on.
-  /// The default value is \c ListDigraph.
-  /// \tparam LEN The type of the length (cost) map.
-  /// The default value is <tt>Digraph::ArcMap<int></tt>.
+  /// \tparam LEN The type of the length map.
+  /// The default value is <tt>GR::ArcMap<int></tt>.
   ///
-  /// \warning Length values should be \e non-negative \e integers.
+  /// \warning Length values should be \e non-negative.
   ///
-  /// \note For finding node-disjoint paths this algorithm can be used
-  /// with \ref SplitNodes.
+  /// \note For finding \e node-disjoint paths, this algorithm can be used
+  /// along with the \ref SplitNodes adaptor.
 #ifdef DOXYGEN
-  template <typename GR, typename LEN>
+  template <typename GR, typename LEN, typename TR>
 #else
-  template < typename GR = ListDigraph,
-             typename LEN = typename GR::template ArcMap<int> >
+  template < typename GR,
+             typename LEN = typename GR::template ArcMap<int>,
+             typename TR = SuurballeDefaultTraits<GR, LEN> >
 #endif
   class Suurballe
@@ -70,67 +120,66 @@
   public:
 
-    /// The type of the digraph the algorithm runs on.
-    typedef GR Digraph;
+    /// The type of the digraph.
+    typedef typename TR::Digraph Digraph;
     /// The type of the length map.
-    typedef LEN LengthMap;
+    typedef typename TR::LengthMap LengthMap;
     /// The type of the lengths.
-    typedef typename LengthMap::Value Length;
+    typedef typename TR::Length Length;
+
     /// The type of the flow map.
-    typedef typename Digraph::template ArcMap<int> FlowMap;
+    typedef typename TR::FlowMap FlowMap;
     /// The type of the potential map.
-    typedef typename Digraph::template NodeMap<Length> PotentialMap;
+    typedef typename TR::PotentialMap PotentialMap;
     /// The type of the path structures.
-    typedef SimplePath<Digraph> Path;
+    typedef typename TR::Path Path;
+    /// The cross reference type used for the heap.
+    typedef typename TR::HeapCrossRef HeapCrossRef;
+    /// The heap type used for internal Dijkstra computations.
+    typedef typename TR::Heap Heap;
+
+    /// The \ref SuurballeDefaultTraits "traits class" of the algorithm.
+    typedef TR Traits;
 
   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.
+    // ResidualDijkstra is a special implementation of the
+    // Dijkstra algorithm for finding shortest paths in the
+    // residual network 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 LengthMap &_length;
       const FlowMap &_flow;
-      const LengthMap &_length;
-      PotentialMap &_potential;
-
-      // The distance map
-      PotentialMap _dist;
-      // The pred arc map
+      PotentialMap &_pi;
       PredMap &_pred;
-      // The processed (i.e. permanently labeled) nodes
-      std::vector<Node> _proc_nodes;
-
       Node _s;
       Node _t;
 
+      PotentialMap _dist;
+      std::vector<Node> _proc_nodes;
+
     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() {
+      // Constructor
+      ResidualDijkstra(Suurballe &srb) :
+        _graph(srb._graph), _length(srb._length),
+        _flow(*srb._flow), _pi(*srb._potential), _pred(srb._pred),
+        _s(srb._s), _t(srb._t), _dist(_graph) {}
+
+      // Run the algorithm and return true if a path is found
+      // from the source node to the target node.
+      bool run(int cnt) {
+        return cnt == 0 ? startFirst() : start();
+      }
+
+    private:
+
+      // Execute the algorithm for the first time (the flow and potential
+      // functions have to be identically zero).
+      bool startFirst() {
         HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
         Heap heap(heap_cross_ref);
@@ -142,8 +191,53 @@
         while (!heap.empty() && heap.top() != _t) {
           Node u = heap.top(), v;
-          Length d = heap.prio() + _potential[u], nd;
+          Length d = heap.prio(), dn;
           _dist[u] = heap.prio();
+          _proc_nodes.push_back(u);
           heap.pop();
+
+          // Traverse outgoing arcs
+          for (OutArcIt e(_graph, u); e != INVALID; ++e) {
+            v = _graph.target(e);
+            switch(heap.state(v)) {
+              case Heap::PRE_HEAP:
+                heap.push(v, d + _length[e]);
+                _pred[v] = e;
+                break;
+              case Heap::IN_HEAP:
+                dn = d + _length[e];
+                if (dn < heap[v]) {
+                  heap.decrease(v, dn);
+                  _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)
+          _pi[_proc_nodes[i]] = _dist[_proc_nodes[i]] - t_dist;
+        return true;
+      }
+
+      // Execute the algorithm.
+      bool start() {
+        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() + _pi[u], dn;
+          _dist[u] = heap.prio();
           _proc_nodes.push_back(u);
+          heap.pop();
 
           // Traverse outgoing arcs
@@ -152,17 +246,17 @@
               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);
+                case Heap::PRE_HEAP:
+                  heap.push(v, d + _length[e] - _pi[v]);
                   _pred[v] = e;
-                }
-                break;
-              case Heap::POST_HEAP:
-                break;
+                  break;
+                case Heap::IN_HEAP:
+                  dn = d + _length[e] - _pi[v];
+                  if (dn < heap[v]) {
+                    heap.decrease(v, dn);
+                    _pred[v] = e;
+                  }
+                  break;
+                case Heap::POST_HEAP:
+                  break;
               }
             }
@@ -174,17 +268,17 @@
               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);
+                case Heap::PRE_HEAP:
+                  heap.push(v, d - _length[e] - _pi[v]);
                   _pred[v] = e;
-                }
-                break;
-              case Heap::POST_HEAP:
-                break;
+                  break;
+                case Heap::IN_HEAP:
+                  dn = d - _length[e] - _pi[v];
+                  if (dn < heap[v]) {
+                    heap.decrease(v, dn);
+                    _pred[v] = e;
+                  }
+                  break;
+                case Heap::POST_HEAP:
+                  break;
               }
             }
@@ -196,9 +290,86 @@
         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;
+          _pi[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
         return true;
       }
 
     }; //class ResidualDijkstra
+
+  public:
+
+    /// \name Named Template Parameters
+    /// @{
+
+    template <typename T>
+    struct SetFlowMapTraits : public Traits {
+      typedef T FlowMap;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c FlowMap type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting
+    /// \c FlowMap type.
+    template <typename T>
+    struct SetFlowMap
+      : public Suurballe<GR, LEN, SetFlowMapTraits<T> > {
+      typedef Suurballe<GR, LEN, SetFlowMapTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetPotentialMapTraits : public Traits {
+      typedef T PotentialMap;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c PotentialMap type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting
+    /// \c PotentialMap type.
+    template <typename T>
+    struct SetPotentialMap
+      : public Suurballe<GR, LEN, SetPotentialMapTraits<T> > {
+      typedef Suurballe<GR, LEN, SetPotentialMapTraits<T> > Create;
+    };
+
+    template <typename T>
+    struct SetPathTraits : public Traits {
+      typedef T Path;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c %Path type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c %Path type.
+    /// It must conform to the \ref lemon::concepts::Path "Path" concept
+    /// and it must have an \c addBack() function.
+    template <typename T>
+    struct SetPath
+      : public Suurballe<GR, LEN, SetPathTraits<T> > {
+      typedef Suurballe<GR, LEN, SetPathTraits<T> > Create;
+    };
+
+    template <typename H, typename CR>
+    struct SetHeapTraits : public Traits {
+      typedef H Heap;
+      typedef CR HeapCrossRef;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c Heap and \c HeapCrossRef types.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c Heap
+    /// and \c HeapCrossRef types with automatic allocation.
+    /// They will be used for internal Dijkstra computations.
+    /// The heap type must conform to the \ref lemon::concepts::Heap "Heap"
+    /// concept and its priority type must be \c Length.
+    template <typename H,
+              typename CR = typename Digraph::template NodeMap<int> >
+    struct SetHeap
+      : public Suurballe<GR, LEN, SetHeapTraits<H, CR> > {
+      typedef Suurballe<GR, LEN, SetHeapTraits<H, CR> > Create;
+    };
+
+    /// @}
 
   private:
@@ -217,17 +388,23 @@
 
     // The source node
-    Node _source;
+    Node _s;
     // The target node
-    Node _target;
+    Node _t;
 
     // Container to store the found paths
-    std::vector< SimplePath<Digraph> > paths;
+    std::vector<Path> _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;
+
+    // Data for full init
+    PotentialMap *_init_dist;
+    PredMap *_init_pred;
+    bool _full_init;
+
+  protected:
+
+    Suurballe() {}
 
   public:
@@ -237,14 +414,12 @@
     /// Constructor.
     ///
-    /// \param digraph The digraph the algorithm runs on.
+    /// \param graph 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) {}
+    Suurballe( const Digraph &graph,
+               const LengthMap &length ) :
+      _graph(graph), _length(length), _flow(0), _local_flow(false),
+      _potential(0), _local_potential(false), _pred(graph),
+      _init_dist(0), _init_pred(0)
+    {}
 
     /// Destructor.
@@ -252,5 +427,6 @@
       if (_local_flow) delete _flow;
       if (_local_potential) delete _potential;
-      delete _dijkstra;
+      delete _init_dist;
+      delete _init_pred;
     }
 
@@ -258,7 +434,10 @@
     ///
     /// 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.
+    /// If it is not used before calling \ref run() or \ref init(),
+    /// an instance will be allocated automatically. The destructor
+    /// deallocates this automatically allocated map, of course.
+    ///
+    /// The found flow contains only 0 and 1 values, since it is the
+    /// union of the found arc-disjoint paths.
     ///
     /// \return <tt>(*this)</tt>
@@ -275,7 +454,10 @@
     ///
     /// This function sets the potential map.
-    ///
-    /// The potentials provide the dual solution of the underlying
-    /// minimum cost flow problem.
+    /// If it is not used before calling \ref run() or \ref init(),
+    /// an instance will be allocated automatically. The destructor
+    /// deallocates this automatically allocated map, of course.
+    ///
+    /// The node potentials provide the dual solution of the underlying
+    /// \ref min_cost_flow "minimum cost flow problem".
     ///
     /// \return <tt>(*this)</tt>
@@ -289,10 +471,13 @@
     }
 
-    /// \name Execution control
+    /// \name Execution Control
     /// The simplest way to execute the algorithm is to call the run()
-    /// function.
-    /// \n
+    /// function.\n
+    /// If you need to execute the algorithm many times using the same
+    /// source node, then you may call fullInit() once and start()
+    /// for each target node.\n
     /// If you only need the flow that is the union of the found
-    /// arc-disjoint paths, you may call init() and findFlow().
+    /// arc-disjoint paths, then you may call findFlow() instead of
+    /// start().
 
     /// @{
@@ -302,4 +487,6 @@
     /// This function runs the algorithm.
     ///
+    /// \param s The source node.
+    /// \param t The target node.
     /// \param k The number of paths to be found.
     ///
@@ -308,15 +495,13 @@
     /// arc-disjoint paths found.
     ///
-    /// \note Apart from the return value, <tt>s.run(k)</tt> is just a
-    /// shortcut of the following code.
+    /// \note Apart from the return value, <tt>s.run(s, t, k)</tt> is
+    /// just a shortcut of the following code.
     /// \code
-    ///   s.init();
-    ///   s.findFlow(k);
-    ///   s.findPaths();
+    ///   s.init(s);
+    ///   s.start(t, k);
     /// \endcode
-    int run(int k = 2) {
-      init();
-      findFlow(k);
-      findPaths();
+    int run(const Node& s, const Node& t, int k = 2) {
+      init(s);
+      start(t, k);
       return _path_num;
     }
@@ -324,6 +509,10 @@
     /// \brief Initialize the algorithm.
     ///
-    /// This function initializes the algorithm.
-    void init() {
+    /// This function initializes the algorithm with the given source node.
+    ///
+    /// \param s The source node.
+    void init(const Node& s) {
+      _s = s;
+
       // Initialize maps
       if (!_flow) {
@@ -335,18 +524,46 @@
         _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.
+      _full_init = false;
+    }
+
+    /// \brief Initialize the algorithm and perform Dijkstra.
+    ///
+    /// This function initializes the algorithm and performs a full
+    /// Dijkstra search from the given source node. It makes consecutive
+    /// executions of \ref start() "start(t, k)" faster, since they
+    /// have to perform %Dijkstra only k-1 times.
+    ///
+    /// This initialization is usually worth using instead of \ref init()
+    /// if the algorithm is executed many times using the same source node.
+    ///
+    /// \param s The source node.
+    void fullInit(const Node& s) {
+      // Initialize maps
+      init(s);
+      if (!_init_dist) {
+        _init_dist = new PotentialMap(_graph);
+      }
+      if (!_init_pred) {
+        _init_pred = new PredMap(_graph);
+      }
+
+      // Run a full Dijkstra
+      typename Dijkstra<Digraph, LengthMap>
+        ::template SetStandardHeap<Heap>
+        ::template SetDistMap<PotentialMap>
+        ::template SetPredMap<PredMap>
+        ::Create dijk(_graph, _length);
+      dijk.distMap(*_init_dist).predMap(*_init_pred);
+      dijk.run(s);
+
+      _full_init = true;
+    }
+
+    /// \brief Execute the algorithm.
+    ///
+    /// This function executes the algorithm.
+    ///
+    /// \param t The target node.
+    /// \param k The number of paths to be found.
     ///
     /// \return \c k if there are at least \c k arc-disjoint paths from
@@ -354,15 +571,64 @@
     /// arc-disjoint paths found.
     ///
+    /// \note Apart from the return value, <tt>s.start(t, k)</tt> is
+    /// just a shortcut of the following code.
+    /// \code
+    ///   s.findFlow(t, k);
+    ///   s.findPaths();
+    /// \endcode
+    int start(const Node& t, int k = 2) {
+      findFlow(t, k);
+      findPaths();
+      return _path_num;
+    }
+
+    /// \brief Execute the 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.
+    ///
+    /// \param t The target node.
+    /// \param k The number of paths to be found.
+    ///
+    /// \return \c k if there are at least \c k arc-disjoint paths from
+    /// the source node to the given node \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) {
+    int findFlow(const Node& t, int k = 2) {
+      _t = t;
+      ResidualDijkstra dijkstra(*this);
+
+      // Initialization
+      for (ArcIt e(_graph); e != INVALID; ++e) {
+        (*_flow)[e] = 0;
+      }
+      if (_full_init) {
+        for (NodeIt n(_graph); n != INVALID; ++n) {
+          (*_potential)[n] = (*_init_dist)[n];
+        }
+        Node u = _t;
+        Arc e;
+        while ((e = (*_init_pred)[u]) != INVALID) {
+          (*_flow)[e] = 1;
+          u = _graph.source(e);
+        }
+        _path_num = 1;
+      } else {
+        for (NodeIt n(_graph); n != INVALID; ++n) {
+          (*_potential)[n] = 0;
+        }
+        _path_num = 0;
+      }
+
       // Find shortest paths
-      _path_num = 0;
       while (_path_num < k) {
         // Run Dijkstra
-        if (!_dijkstra->run()) break;
+        if (!dijkstra.run(_path_num)) break;
         ++_path_num;
 
         // Set the flow along the found shortest path
-        Node u = _target;
+        Node u = _t;
         Arc e;
         while ((e = _pred[u]) != INVALID) {
@@ -381,23 +647,22 @@
     /// \brief Compute the paths from the flow.
     ///
-    /// This function computes the paths from the flow.
+    /// This function computes arc-disjoint paths from the found minimum
+    /// cost flow, which is the union of them.
     ///
     /// \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);
+      _paths.clear();
+      _paths.resize(_path_num);
       for (int i = 0; i < _path_num; ++i) {
-        Node n = _source;
-        while (n != _target) {
+        Node n = _s;
+        while (n != _t) {
           OutArcIt e(_graph, n);
           for ( ; res_flow[e] == 0; ++e) ;
           n = _graph.target(e);
-          paths[i].addBack(e);
+          _paths[i].addBack(e);
           res_flow[e] = 0;
         }
@@ -414,55 +679,9 @@
     /// @{
 
-    /// \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 O(e).
+    /// \brief Return the total length of the found paths.
+    ///
+    /// This function returns the total length of the found paths, i.e.
+    /// the total cost of the found flow.
+    /// The complexity of the function is O(e).
     ///
     /// \pre \ref run() or \ref findFlow() must be called before using
@@ -475,4 +694,53 @@
     }
 
+    /// \brief Return the flow value on the given arc.
+    ///
+    /// This function returns the flow value on the given arc.
+    /// It is \c 1 if the arc is involved in one of the found arc-disjoint
+    /// 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 a const reference to an arc map storing the
+    /// found flow.
+    ///
+    /// This function returns a const reference to an 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 the potential of the given node.
+    ///
+    /// This function returns the potential of the given node.
+    /// The node potentials provide the dual solution of the
+    /// underlying \ref min_cost_flow "minimum cost flow problem".
+    ///
+    /// \pre \ref run() or \ref findFlow() must be called before using
+    /// this function.
+    Length potential(const Node& node) const {
+      return (*_potential)[node];
+    }
+
+    /// \brief Return a const reference to a node map storing the
+    /// found potentials (the dual solution).
+    ///
+    /// This function returns a const reference to a node map storing
+    /// the found potentials that provide the dual solution of the
+    /// underlying \ref min_cost_flow "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 number of the found paths.
     ///
@@ -489,11 +757,11 @@
     /// This function returns a const reference to the specified path.
     ///
-    /// \param i The function returns the \c i-th path.
+    /// \param i The function returns the <tt>i</tt>-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];
+    const Path& path(int i) const {
+      return _paths[i];
     }
 
Index: lemon/time_measure.h
===================================================================
--- lemon/time_measure.h	(revision 548)
+++ lemon/time_measure.h	(revision 786)
@@ -288,5 +288,5 @@
     Timer(bool run=true) :_running(run) {_reset();}
 
-    ///\name Control the state of the timer
+    ///\name Control the State of the Timer
     ///Basically a Timer can be either running or stopped,
     ///but it provides a bit finer control on the execution.
@@ -376,5 +376,5 @@
     ///This function returns the number of stop() exections that is
     ///necessary to really stop the timer.
-    ///For example the timer
+    ///For example, the timer
     ///is running if and only if the return value is \c true
     ///(i.e. greater than
@@ -396,5 +396,5 @@
     ///@}
 
-    ///\name Query Functions for the ellapsed time
+    ///\name Query Functions for the Ellapsed Time
 
     ///@{
Index: lemon/unionfind.h
===================================================================
--- lemon/unionfind.h	(revision 559)
+++ lemon/unionfind.h	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -44,5 +44,5 @@
   /// This is a very simple but efficient implementation, providing
   /// only four methods: join (union), find, insert and size.
-  /// For more features see the \ref UnionFindEnum class.
+  /// For more features, see the \ref UnionFindEnum class.
   ///
   /// It is primarily used in Kruskal algorithm for finding minimal
@@ -740,5 +740,5 @@
     void clear() {
       items.clear();
-      classes.clear;
+      classes.clear();
       firstClass = firstFreeClass = firstFreeItem = -1;
     }
@@ -1289,4 +1289,13 @@
         first_free_class(-1), first_free_node(-1) {}
 
+    /// \brief Clears the union-find data structure
+    ///
+    /// Erase each item from the data structure.
+    void clear() {
+      nodes.clear();
+      classes.clear();
+      first_free_node = first_free_class = first_class = -1;
+    }
+
     /// \brief Insert a new node into a new component.
     ///
Index: lx_check_clp.m4
===================================================================
--- m4/lx_check_clp.m4	(revision 459)
+++ 	(revision )
@@ -1,73 +1,0 @@
-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_coin.m4
===================================================================
--- m4/lx_check_coin.m4	(revision 749)
+++ m4/lx_check_coin.m4	(revision 749)
@@ -0,0 +1,136 @@
+AC_DEFUN([LX_CHECK_COIN],
+[
+  AC_ARG_WITH([coin],
+AS_HELP_STRING([--with-coin@<:@=PREFIX@:>@], [search for CLP under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@])
+AS_HELP_STRING([--without-coin], [disable checking for CLP]),
+              [], [with_coin=yes])
+
+  AC_ARG_WITH([coin-includedir],
+AS_HELP_STRING([--with-coin-includedir=DIR], [search for CLP headers in DIR]),
+              [], [with_coin_includedir=no])
+
+  AC_ARG_WITH([coin-libdir],
+AS_HELP_STRING([--with-coin-libdir=DIR], [search for CLP libraries in DIR]),
+              [], [with_coin_libdir=no])
+
+  lx_clp_found=no
+  if test x"$with_coin" != x"no"; then
+    AC_MSG_CHECKING([for CLP])
+
+    if test x"$with_coin_includedir" != x"no"; then
+      CLP_CXXFLAGS="-I$with_coin_includedir"
+    elif test x"$with_coin" != x"yes"; then
+      CLP_CXXFLAGS="-I$with_coin/include"
+    fi
+
+    if test x"$with_coin_libdir" != x"no"; then
+      CLP_LDFLAGS="-L$with_coin_libdir"
+    elif test x"$with_coin" != x"yes"; then
+      CLP_LDFLAGS="-L$with_coin/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([LEMON_HAVE_CLP], [1], [Define to 1 if you have CLP.])
+      lx_lp_found=yes
+      AC_DEFINE([LEMON_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"])
+
+
+  lx_cbc_found=no
+  if test x"$lx_clp_found" = x"yes"; then
+    if test x"$with_coin" != x"no"; then
+      AC_MSG_CHECKING([for CBC])
+
+      if test x"$with_coin_includedir" != x"no"; then
+        CBC_CXXFLAGS="-I$with_coin_includedir"
+      elif test x"$with_coin" != x"yes"; then
+        CBC_CXXFLAGS="-I$with_coin/include"
+      fi
+
+      if test x"$with_coin_libdir" != x"no"; then
+        CBC_LDFLAGS="-L$with_coin_libdir"
+      elif test x"$with_coin" != x"yes"; then
+        CBC_LDFLAGS="-L$with_coin/lib"
+      fi
+      CBC_LIBS="-lOsi -lCbc -lCbcSolver -lClp -lOsiClp -lCoinUtils -lVol -lOsiVol -lCgl -lm -llapack -lblas"
+
+      lx_save_cxxflags="$CXXFLAGS"
+      lx_save_ldflags="$LDFLAGS"
+      lx_save_libs="$LIBS"
+      CXXFLAGS="$CBC_CXXFLAGS"
+      LDFLAGS="$CBC_LDFLAGS"
+      LIBS="$CBC_LIBS"
+
+      lx_cbc_test_prog='
+        #include <coin/CbcModel.hpp>
+
+        int main(int argc, char** argv)
+        {
+          CbcModel cbc;
+          return 0;
+        }'
+
+      AC_LANG_PUSH(C++)
+      AC_LINK_IFELSE([$lx_cbc_test_prog], [lx_cbc_found=yes], [lx_cbc_found=no])
+      AC_LANG_POP(C++)
+
+      CXXFLAGS="$lx_save_cxxflags"
+      LDFLAGS="$lx_save_ldflags"
+      LIBS="$lx_save_libs"
+
+      if test x"$lx_cbc_found" = x"yes"; then
+        AC_DEFINE([LEMON_HAVE_CBC], [1], [Define to 1 if you have CBC.])
+        lx_lp_found=yes
+        AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
+        lx_mip_found=yes
+        AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
+        AC_MSG_RESULT([yes])
+      else
+        CBC_CXXFLAGS=""
+        CBC_LDFLAGS=""
+        CBC_LIBS=""
+        AC_MSG_RESULT([no])
+      fi
+    fi
+  fi
+  CBC_LIBS="$CBC_LDFLAGS $CBC_LIBS"
+  AC_SUBST(CBC_CXXFLAGS)
+  AC_SUBST(CBC_LIBS)
+  AM_CONDITIONAL([HAVE_CBC], [test x"$lx_cbc_found" = x"yes"])
+])
Index: m4/lx_check_cplex.m4
===================================================================
--- m4/lx_check_cplex.m4	(revision 457)
+++ m4/lx_check_cplex.m4	(revision 627)
@@ -62,9 +62,9 @@
 
     if test x"$lx_cplex_found" = x"yes"; then
-      AC_DEFINE([HAVE_CPLEX], [1], [Define to 1 if you have CPLEX.])
+      AC_DEFINE([LEMON_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.])
+      AC_DEFINE([LEMON_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_DEFINE([LEMON_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 459)
+++ m4/lx_check_glpk.m4	(revision 627)
@@ -65,9 +65,9 @@
 
     if test x"$lx_glpk_found" = x"yes"; then
-      AC_DEFINE([HAVE_GLPK], [1], [Define to 1 if you have GLPK.])
+      AC_DEFINE([LEMON_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.])
+      AC_DEFINE([LEMON_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_DEFINE([LEMON_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 539)
+++ m4/lx_check_soplex.m4	(revision 627)
@@ -56,7 +56,7 @@
 
     if test x"$lx_soplex_found" = x"yes"; then
-      AC_DEFINE([HAVE_SOPLEX], [1], [Define to 1 if you have SOPLEX.])
+      AC_DEFINE([LEMON_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_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
       AC_MSG_RESULT([yes])
     else
Index: scripts/Makefile.am
===================================================================
--- scripts/Makefile.am	(revision 793)
+++ scripts/Makefile.am	(revision 793)
@@ -0,0 +1,7 @@
+EXTRA_DIST += \
+	scripts/bib2dox.py \
+	scripts/bootstrap.sh \
+	scripts/chg-len.py \
+	scripts/mk-release.sh \
+	scripts/unify-sources.sh \
+	scripts/valgrind-wrapper.sh
Index: scripts/bib2dox.py
===================================================================
--- scripts/bib2dox.py	(revision 836)
+++ scripts/bib2dox.py	(revision 836)
@@ -0,0 +1,816 @@
+#! /usr/bin/env python
+"""
+  BibTeX to Doxygen converter
+  Usage: python bib2dox.py bibfile.bib > bibfile.dox
+
+  This file is a part of LEMON, a generic C++ optimization library.
+
+  **********************************************************************
+
+  This code is the modification of the BibTeX to XML converter
+  by Vidar Bronken Gundersen et al.
+  See the original copyright notices below. 
+
+  **********************************************************************
+
+  Decoder for bibliographic data, BibTeX
+  Usage: python bibtex2xml.py bibfile.bib > bibfile.xml
+
+  v.8
+  (c)2002-06-23 Vidar Bronken Gundersen
+  http://bibtexml.sf.net/
+  Reuse approved as long as this notification is kept.
+  Licence: GPL.
+
+  Contributions/thanks to:
+  Egon Willighagen, http://sf.net/projects/jreferences/
+  Richard Mahoney (for providing a test case)
+
+  Editted by Sara Sprenkle to be more robust and handle more bibtex features.
+  (c) 2003-01-15
+
+  1.  Changed bibtex: tags to bibxml: tags.
+  2.  Use xmlns:bibxml="http://bibtexml.sf.net/"
+  3.  Allow spaces between @type and first {
+  4.  "author" fields with multiple authors split by " and "
+      are put in separate xml "bibxml:author" tags.
+  5.  Option for Titles: words are capitalized
+      only if first letter in title or capitalized inside braces
+  6.  Removes braces from within field values
+  7.  Ignores comments in bibtex file (including @comment{ or % )
+  8.  Replaces some special latex tags, e.g., replaces ~ with '&#160;'
+  9.  Handles bibtex @string abbreviations
+        --> includes bibtex's default abbreviations for months
+        --> does concatenation of abbr # " more " and " more " # abbr
+  10. Handles @type( ... ) or @type{ ... }
+  11. The keywords field is split on , or ; and put into separate xml
+      "bibxml:keywords" tags
+  12. Ignores @preamble
+
+  Known Limitations
+  1.  Does not transform Latex encoding like math mode and special
+      latex symbols.
+  2.  Does not parse author fields into first and last names.
+      E.g., It does not do anything special to an author whose name is
+      in the form LAST_NAME, FIRST_NAME
+      In "author" tag, will show up as
+      <bibxml:author>LAST_NAME, FIRST_NAME</bibxml:author>
+  3.  Does not handle "crossref" fields other than to print
+      <bibxml:crossref>...</bibxml:crossref>
+  4.  Does not inform user of the input's format errors.  You just won't
+      be able to transform the file later with XSL
+
+  You will have to manually edit the XML output if you need to handle
+  these (and unknown) limitations.
+
+"""
+
+import string, re
+
+# set of valid name characters
+valid_name_chars = '[\w\-:]'
+
+#
+# define global regular expression variables
+#
+author_rex = re.compile('\s+and\s+')
+rembraces_rex = re.compile('[{}]')
+capitalize_rex = re.compile('({[^}]*})')
+
+# used by bibtexkeywords(data)
+keywords_rex = re.compile('[,;]')
+
+# used by concat_line(line)
+concatsplit_rex = re.compile('\s*#\s*')
+
+# split on {, }, or " in verify_out_of_braces
+delimiter_rex = re.compile('([{}"])',re.I)
+
+field_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
+data_rex = re.compile('\s*(\w*)\s*=\s*([^,]*),?')
+
+url_rex = re.compile('\\\url\{([^}]*)\}')
+
+#
+# styles for html formatting
+#
+divstyle = 'margin-top: -4ex; margin-left: 8em;'
+
+#
+# return the string parameter without braces
+#
+def transformurls(str):
+    return url_rex.sub(r'<a href="\1">\1</a>', str)
+
+#
+# return the string parameter without braces
+#
+def removebraces(str):
+    return rembraces_rex.sub('', str)
+
+#
+# latex-specific replacements
+# (do this after braces were removed)
+#
+def latexreplacements(line):
+    line = string.replace(line, '~', '&nbsp;')
+    line = string.replace(line, '\\\'a', '&aacute;')
+    line = string.replace(line, '\\"a', '&auml;')
+    line = string.replace(line, '\\\'e', '&eacute;')
+    line = string.replace(line, '\\"e', '&euml;')
+    line = string.replace(line, '\\\'i', '&iacute;')
+    line = string.replace(line, '\\"i', '&iuml;')
+    line = string.replace(line, '\\\'o', '&oacute;')
+    line = string.replace(line, '\\"o', '&ouml;')
+    line = string.replace(line, '\\\'u', '&uacute;')
+    line = string.replace(line, '\\"u', '&uuml;')
+    line = string.replace(line, '\\H o', '&otilde;')
+    line = string.replace(line, '\\H u', '&uuml;')   # &utilde; does not exist
+    line = string.replace(line, '\\\'A', '&Aacute;')
+    line = string.replace(line, '\\"A', '&Auml;')
+    line = string.replace(line, '\\\'E', '&Eacute;')
+    line = string.replace(line, '\\"E', '&Euml;')
+    line = string.replace(line, '\\\'I', '&Iacute;')
+    line = string.replace(line, '\\"I', '&Iuml;')
+    line = string.replace(line, '\\\'O', '&Oacute;')
+    line = string.replace(line, '\\"O', '&Ouml;')
+    line = string.replace(line, '\\\'U', '&Uacute;')
+    line = string.replace(line, '\\"U', '&Uuml;')
+    line = string.replace(line, '\\H O', '&Otilde;')
+    line = string.replace(line, '\\H U', '&Uuml;')   # &Utilde; does not exist
+
+    return line
+
+#
+# copy characters form a string decoding html expressions (&xyz;)
+#
+def copychars(str, ifrom, count):
+    result = ''
+    i = ifrom
+    c = 0
+    html_spec = False
+    while (i < len(str)) and (c < count):
+        if str[i] == '&':
+            html_spec = True;
+            if i+1 < len(str):
+                result += str[i+1]
+            c += 1
+            i += 2
+        else:
+            if not html_spec:
+                if ((str[i] >= 'A') and (str[i] <= 'Z')) or \
+                   ((str[i] >= 'a') and (str[i] <= 'z')):
+                    result += str[i]
+                    c += 1
+            elif str[i] == ';':
+                html_spec = False;
+            i += 1
+    
+    return result
+
+
+# 
+# Handle a list of authors (separated by 'and').
+# It gives back an array of the follwing values:
+#  - num: the number of authors,
+#  - list: the list of the author names,
+#  - text: the bibtex text (separated by commas and/or 'and')
+#  - abbrev: abbreviation that can be used for indicate the
+#    bibliography entries
+#
+def bibtexauthor(data):
+    result = {}
+    bibtex = ''
+    result['list'] = author_rex.split(data)
+    result['num'] = len(result['list'])
+    for i, author in enumerate(result['list']):
+        # general transformations
+        author = latexreplacements(removebraces(author.strip()))
+        # transform "Xyz, A. B." to "A. B. Xyz"
+        pos = author.find(',')
+        if pos != -1:
+            author = author[pos+1:].strip() + ' ' + author[:pos].strip()
+        result['list'][i] = author
+        bibtex += author + '#'
+    bibtex = bibtex[:-1]
+    if result['num'] > 1:
+        ix = bibtex.rfind('#')
+        if result['num'] == 2:
+            bibtex = bibtex[:ix] + ' and ' + bibtex[ix+1:]
+        else:
+            bibtex = bibtex[:ix] + ', and ' + bibtex[ix+1:]
+    bibtex = bibtex.replace('#', ', ')
+    result['text'] = bibtex
+    
+    result['abbrev'] = ''
+    for author in result['list']:
+        pos = author.rfind(' ') + 1
+        count = 1
+        if result['num'] == 1:
+            count = 3
+        result['abbrev'] += copychars(author, pos, count)
+
+    return result
+
+
+#
+# data = title string
+# @return the capitalized title (first letter is capitalized), rest are capitalized
+# only if capitalized inside braces
+#
+def capitalizetitle(data):
+    title_list = capitalize_rex.split(data)
+    title = ''
+    count = 0
+    for phrase in title_list:
+         check = string.lstrip(phrase)
+
+         # keep phrase's capitalization the same
+         if check.find('{') == 0:
+              title += removebraces(phrase)
+         else:
+         # first word --> capitalize first letter (after spaces)
+              if count == 0:
+                  title += check.capitalize()
+              else:
+                  title += phrase.lower()
+         count = count + 1
+
+    return title
+
+
+#
+# @return the bibtex for the title
+# @param data --> title string
+# braces are removed from title
+#
+def bibtextitle(data, entrytype):
+    if entrytype in ('book', 'inbook'):
+        title = removebraces(data.strip())
+    else:
+        title = removebraces(capitalizetitle(data.strip()))
+    bibtex = title
+    return bibtex
+
+
+#
+# function to compare entry lists
+#
+def entry_cmp(x, y):
+    return cmp(x[0], y[0])
+
+
+#
+# print the XML for the transformed "filecont_source"
+#
+def bibtexdecoder(filecont_source):
+    filecont = []
+    file = []
+    
+    # want @<alphanumeric chars><spaces>{<spaces><any chars>,
+    pubtype_rex = re.compile('@(\w*)\s*{\s*(.*),')
+    endtype_rex = re.compile('}\s*$')
+    endtag_rex = re.compile('^\s*}\s*$')
+
+    bracefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
+    bracedata_rex = re.compile('\s*(\w*)\s*=\s*{(.*)},?')
+
+    quotefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
+    quotedata_rex = re.compile('\s*(\w*)\s*=\s*"(.*)",?')
+
+    for line in filecont_source:
+        line = line[:-1]
+
+        # encode character entities
+        line = string.replace(line, '&', '&amp;')
+        line = string.replace(line, '<', '&lt;')
+        line = string.replace(line, '>', '&gt;')
+
+        # start entry: publication type (store for later use)
+        if pubtype_rex.match(line):
+        # want @<alphanumeric chars><spaces>{<spaces><any chars>,
+            entrycont = {}
+            entry = []
+            entrytype = pubtype_rex.sub('\g<1>',line)
+            entrytype = string.lower(entrytype)
+            entryid   = pubtype_rex.sub('\g<2>', line)
+
+        # end entry if just a }
+        elif endtype_rex.match(line):
+            # generate doxygen code for the entry
+
+            # enty type related formattings
+            if entrytype in ('book', 'inbook'):
+                entrycont['title'] = '<em>' + entrycont['title'] + '</em>'
+                if not entrycont.has_key('author'):
+                    entrycont['author'] = entrycont['editor']
+                    entrycont['author']['text'] += ', editors'
+            elif entrytype == 'article':
+                entrycont['journal'] = '<em>' + entrycont['journal'] + '</em>'
+            elif entrytype in ('inproceedings', 'incollection', 'conference'):
+                entrycont['booktitle'] = '<em>' + entrycont['booktitle'] + '</em>'
+            elif entrytype == 'techreport':
+                if not entrycont.has_key('type'):
+                    entrycont['type'] = 'Technical report'
+            elif entrytype == 'mastersthesis':
+                entrycont['type'] = 'Master\'s thesis'
+            elif entrytype == 'phdthesis':
+                entrycont['type'] = 'PhD thesis'
+
+            for eline in entrycont:
+                if eline != '':
+                    eline = latexreplacements(eline)
+
+            if entrycont.has_key('pages') and (entrycont['pages'] != ''):
+                entrycont['pages'] = string.replace(entrycont['pages'], '--', '-')
+
+            if entrycont.has_key('author') and (entrycont['author'] != ''):
+                entry.append(entrycont['author']['text'] + '.')
+            if entrycont.has_key('title') and (entrycont['title'] != ''):
+                entry.append(entrycont['title'] + '.')
+            if entrycont.has_key('journal') and (entrycont['journal'] != ''):
+                entry.append(entrycont['journal'] + ',')
+            if entrycont.has_key('booktitle') and (entrycont['booktitle'] != ''):
+                entry.append('In ' + entrycont['booktitle'] + ',')
+            if entrycont.has_key('type') and (entrycont['type'] != ''):
+                eline = entrycont['type']
+                if entrycont.has_key('number') and (entrycont['number'] != ''):
+                    eline += ' ' + entrycont['number']
+                eline += ','
+                entry.append(eline)
+            if entrycont.has_key('institution') and (entrycont['institution'] != ''):
+                entry.append(entrycont['institution'] + ',')
+            if entrycont.has_key('publisher') and (entrycont['publisher'] != ''):
+                entry.append(entrycont['publisher'] + ',')
+            if entrycont.has_key('school') and (entrycont['school'] != ''):
+                entry.append(entrycont['school'] + ',')
+            if entrycont.has_key('address') and (entrycont['address'] != ''):
+                entry.append(entrycont['address'] + ',')
+            if entrycont.has_key('edition') and (entrycont['edition'] != ''):
+                entry.append(entrycont['edition'] + ' edition,')
+            if entrycont.has_key('howpublished') and (entrycont['howpublished'] != ''):
+                entry.append(entrycont['howpublished'] + ',')
+            if entrycont.has_key('volume') and (entrycont['volume'] != ''):
+                eline = entrycont['volume'];
+                if entrycont.has_key('number') and (entrycont['number'] != ''):
+                    eline += '(' + entrycont['number'] + ')'
+                if entrycont.has_key('pages') and (entrycont['pages'] != ''):
+                    eline += ':' + entrycont['pages']
+                eline += ','
+                entry.append(eline)
+            else:
+                if entrycont.has_key('pages') and (entrycont['pages'] != ''):
+                    entry.append('pages ' + entrycont['pages'] + ',')
+            if entrycont.has_key('year') and (entrycont['year'] != ''):
+                if entrycont.has_key('month') and (entrycont['month'] != ''):
+                    entry.append(entrycont['month'] + ' ' + entrycont['year'] + '.')
+                else:
+                    entry.append(entrycont['year'] + '.')
+            if entrycont.has_key('note') and (entrycont['note'] != ''):
+                entry.append(entrycont['note'] + '.')
+            if entrycont.has_key('url') and (entrycont['url'] != ''):
+                entry.append(entrycont['url'] + '.')
+
+            # generate keys for sorting and for the output
+            sortkey = ''
+            bibkey = ''
+            if entrycont.has_key('author'):
+                for author in entrycont['author']['list']:
+                    sortkey += copychars(author, author.rfind(' ')+1, len(author))
+                bibkey = entrycont['author']['abbrev']
+            else:
+                bibkey = 'x'
+            if entrycont.has_key('year'):
+                sortkey += entrycont['year']
+                bibkey += entrycont['year'][-2:]
+            if entrycont.has_key('title'):
+                sortkey += entrycont['title']
+            if entrycont.has_key('key'):
+                sortkey = entrycont['key'] + sortkey
+                bibkey = entrycont['key']
+            entry.insert(0, sortkey)
+            entry.insert(1, bibkey)
+            entry.insert(2, entryid)
+           
+            # add the entry to the file contents
+            filecont.append(entry)
+
+        else:
+            # field, publication info
+            field = ''
+            data = ''
+            
+            # field = {data} entries
+            if bracedata_rex.match(line):
+                field = bracefield_rex.sub('\g<1>', line)
+                field = string.lower(field)
+                data =  bracedata_rex.sub('\g<2>', line)
+
+            # field = "data" entries
+            elif quotedata_rex.match(line):
+                field = quotefield_rex.sub('\g<1>', line)
+                field = string.lower(field)
+                data =  quotedata_rex.sub('\g<2>', line)
+
+            # field = data entries
+            elif data_rex.match(line):
+                field = field_rex.sub('\g<1>', line)
+                field = string.lower(field)
+                data =  data_rex.sub('\g<2>', line)
+
+            if field == 'url':
+                data = '\\url{' + data.strip() + '}'
+            
+            if field in ('author', 'editor'):
+                entrycont[field] = bibtexauthor(data)
+                line = ''
+            elif field == 'title':
+                line = bibtextitle(data, entrytype)
+            elif field != '':
+                line = removebraces(transformurls(data.strip()))
+
+            if line != '':
+                line = latexreplacements(line)
+                entrycont[field] = line
+
+
+    # sort entries
+    filecont.sort(entry_cmp)
+    
+    # count the bibtex keys
+    keytable = {}
+    counttable = {}
+    for entry in filecont:
+        bibkey = entry[1]
+        if not keytable.has_key(bibkey):
+            keytable[bibkey] = 1
+        else:
+            keytable[bibkey] += 1
+
+    for bibkey in keytable.keys():
+        counttable[bibkey] = 0
+    
+    # generate output
+    for entry in filecont:
+        # generate output key form the bibtex key
+        bibkey = entry[1]
+        entryid = entry[2]
+        if keytable[bibkey] == 1:
+            outkey = bibkey
+        else:
+            outkey = bibkey + chr(97 + counttable[bibkey])
+        counttable[bibkey] += 1
+        
+        # append the entry code to the output
+        file.append('\\section ' + entryid + ' [' + outkey + ']')
+        file.append('<div style="' + divstyle + '">')
+        for line in entry[3:]:
+            file.append(line)
+        file.append('</div>')
+        file.append('')
+
+    return file
+
+
+#
+# return 1 iff abbr is in line but not inside braces or quotes
+# assumes that abbr appears only once on the line (out of braces and quotes)
+#
+def verify_out_of_braces(line, abbr):
+
+    phrase_split = delimiter_rex.split(line)
+
+    abbr_rex = re.compile( '\\b' + abbr + '\\b', re.I)
+
+    open_brace = 0
+    open_quote = 0
+
+    for phrase in phrase_split:
+        if phrase == "{":
+            open_brace = open_brace + 1
+        elif phrase == "}":
+            open_brace = open_brace - 1
+        elif phrase == '"':
+            if open_quote == 1:
+                open_quote = 0
+            else:
+                open_quote = 1
+        elif abbr_rex.search(phrase):
+            if open_brace == 0 and open_quote == 0:
+                return 1
+
+    return 0
+
+
+#
+# a line in the form phrase1 # phrase2 # ... # phrasen
+# is returned as phrase1 phrase2 ... phrasen
+# with the correct punctuation
+# Bug: Doesn't always work with multiple abbreviations plugged in
+#
+def concat_line(line):
+    # only look at part after equals
+    field = field_rex.sub('\g<1>',line)
+    rest = field_rex.sub('\g<2>',line)
+
+    concat_line = field + ' ='
+
+    pound_split = concatsplit_rex.split(rest)
+
+    phrase_count = 0
+    length = len(pound_split)
+
+    for phrase in pound_split:
+        phrase = phrase.strip()
+        if phrase_count != 0:
+            if phrase.startswith('"') or phrase.startswith('{'):
+                phrase = phrase[1:]
+        elif phrase.startswith('"'):
+            phrase = phrase.replace('"','{',1)
+
+        if phrase_count != length-1:
+            if phrase.endswith('"') or phrase.endswith('}'):
+                phrase = phrase[:-1]
+        else:
+            if phrase.endswith('"'):
+                phrase = phrase[:-1]
+                phrase = phrase + "}"
+            elif phrase.endswith('",'):
+                phrase = phrase[:-2]
+                phrase = phrase + "},"
+
+        # if phrase did have \#, add the \# back
+        if phrase.endswith('\\'):
+            phrase = phrase + "#"
+        concat_line = concat_line + ' ' + phrase
+
+        phrase_count = phrase_count + 1
+
+    return concat_line
+
+
+#
+# substitute abbreviations into filecont
+# @param filecont_source - string of data from file
+#
+def bibtex_replace_abbreviations(filecont_source):
+    filecont = filecont_source.splitlines()
+
+    #  These are defined in bibtex, so we'll define them too
+    abbr_list = ['jan','feb','mar','apr','may','jun',
+                 'jul','aug','sep','oct','nov','dec']
+    value_list = ['January','February','March','April',
+                  'May','June','July','August','September',
+                  'October','November','December']
+
+    abbr_rex = []
+    total_abbr_count = 0
+
+    front = '\\b'
+    back = '(,?)\\b'
+
+    for x in abbr_list:
+        abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
+        total_abbr_count = total_abbr_count + 1
+
+
+    abbrdef_rex = re.compile('\s*@string\s*{\s*('+ valid_name_chars +'*)\s*=(.*)',
+                             re.I)
+
+    comment_rex = re.compile('@comment\s*{',re.I)
+    preamble_rex = re.compile('@preamble\s*{',re.I)
+
+    waiting_for_end_string = 0
+    i = 0
+    filecont2 = ''
+
+    for line in filecont:
+        if line == ' ' or line == '':
+            continue
+
+        if waiting_for_end_string:
+            if re.search('}',line):
+                waiting_for_end_string = 0
+                continue
+
+        if abbrdef_rex.search(line):
+            abbr = abbrdef_rex.sub('\g<1>', line)
+
+            if abbr_list.count(abbr) == 0:
+                val = abbrdef_rex.sub('\g<2>', line)
+                abbr_list.append(abbr)
+                value_list.append(string.strip(val))
+                abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
+                total_abbr_count = total_abbr_count + 1
+            waiting_for_end_string = 1
+            continue
+
+        if comment_rex.search(line):
+            waiting_for_end_string = 1
+            continue
+
+        if preamble_rex.search(line):
+            waiting_for_end_string = 1
+            continue
+
+
+        # replace subsequent abbreviations with the value
+        abbr_count = 0
+
+        for x in abbr_list:
+
+            if abbr_rex[abbr_count].search(line):
+                if verify_out_of_braces(line,abbr_list[abbr_count]) == 1:
+                    line = abbr_rex[abbr_count].sub( value_list[abbr_count] + '\g<1>', line)
+                # Check for # concatenations
+                if concatsplit_rex.search(line):
+                    line = concat_line(line)
+            abbr_count = abbr_count + 1
+
+
+        filecont2 = filecont2 + line + '\n'
+        i = i+1
+
+
+    # Do one final pass over file
+
+    # make sure that didn't end up with {" or }" after the substitution
+    filecont2 = filecont2.replace('{"','{{')
+    filecont2 = filecont2.replace('"}','}}')
+
+    afterquotevalue_rex = re.compile('"\s*,\s*')
+    afterbrace_rex = re.compile('"\s*}')
+    afterbracevalue_rex = re.compile('(=\s*{[^=]*)},\s*')
+
+    # add new lines to data that changed because of abbreviation substitutions
+    filecont2 = afterquotevalue_rex.sub('",\n', filecont2)
+    filecont2 = afterbrace_rex.sub('"\n}', filecont2)
+    filecont2 = afterbracevalue_rex.sub('\g<1>},\n', filecont2)
+
+    return filecont2
+
+#
+# convert @type( ... ) to @type{ ... }
+#
+def no_outer_parens(filecont):
+
+    # do checking for open parens
+    # will convert to braces
+    paren_split = re.split('([(){}])',filecont)
+
+    open_paren_count = 0
+    open_type = 0
+    look_next = 0
+
+    # rebuild filecont
+    filecont = ''
+
+    at_rex = re.compile('@\w*')
+
+    for phrase in paren_split:
+        if look_next == 1:
+            if phrase == '(':
+                phrase = '{'
+                open_paren_count = open_paren_count + 1
+            else:
+                open_type = 0
+            look_next = 0
+
+        if phrase == '(':
+            open_paren_count = open_paren_count + 1
+
+        elif phrase == ')':
+            open_paren_count = open_paren_count - 1
+            if open_type == 1 and open_paren_count == 0:
+                phrase = '}'
+                open_type = 0
+
+        elif at_rex.search( phrase ):
+            open_type = 1
+            look_next = 1
+
+        filecont = filecont + phrase
+
+    return filecont
+
+
+#
+# make all whitespace into just one space
+# format the bibtex file into a usable form.
+#
+def bibtexwasher(filecont_source):
+
+    space_rex = re.compile('\s+')
+    comment_rex = re.compile('\s*%')
+
+    filecont = []
+
+    # remove trailing and excessive whitespace
+    # ignore comments
+    for line in filecont_source:
+        line = string.strip(line)
+        line = space_rex.sub(' ', line)
+        # ignore comments
+        if not comment_rex.match(line) and line != '':
+            filecont.append(' '+ line)
+
+    filecont = string.join(filecont, '')
+
+    # the file is in one long string
+
+    filecont = no_outer_parens(filecont)
+
+    #
+    # split lines according to preferred syntax scheme
+    #
+    filecont = re.sub('(=\s*{[^=]*)},', '\g<1>},\n', filecont)
+
+    # add new lines after commas that are after values
+    filecont = re.sub('"\s*,', '",\n', filecont)
+    filecont = re.sub('=\s*([\w\d]+)\s*,', '= \g<1>,\n', filecont)
+    filecont = re.sub('(@\w*)\s*({(\s*)[^,\s]*)\s*,',
+                          '\n\n\g<1>\g<2>,\n', filecont)
+
+    # add new lines after }
+    filecont = re.sub('"\s*}','"\n}\n', filecont)
+    filecont = re.sub('}\s*,','},\n', filecont)
+
+
+    filecont = re.sub('@(\w*)', '\n@\g<1>', filecont)
+
+    # character encoding, reserved latex characters
+    filecont = re.sub('{\\\&}', '&', filecont)
+    filecont = re.sub('\\\&', '&', filecont)
+
+    # do checking for open braces to get format correct
+    open_brace_count = 0
+    brace_split = re.split('([{}])',filecont)
+
+    # rebuild filecont
+    filecont = ''
+
+    for phrase in brace_split:
+        if phrase == '{':
+            open_brace_count = open_brace_count + 1
+        elif phrase == '}':
+            open_brace_count = open_brace_count - 1
+            if open_brace_count == 0:
+                filecont = filecont + '\n'
+
+        filecont = filecont + phrase
+
+    filecont2 = bibtex_replace_abbreviations(filecont)
+
+    # gather
+    filecont = filecont2.splitlines()
+    i=0
+    j=0         # count the number of blank lines
+    for line in filecont:
+        # ignore blank lines
+        if line == '' or line == ' ':
+            j = j+1
+            continue
+        filecont[i] = line + '\n'
+        i = i+1
+
+    # get rid of the extra stuff at the end of the array
+    # (The extra stuff are duplicates that are in the array because
+    # blank lines were removed.)
+    length = len( filecont)
+    filecont[length-j:length] = []
+
+    return filecont
+
+
+def filehandler(filepath):
+    try:
+        fd = open(filepath, 'r')
+        filecont_source = fd.readlines()
+        fd.close()
+    except:
+        print 'Could not open file:', filepath
+    washeddata = bibtexwasher(filecont_source)
+    outdata = bibtexdecoder(washeddata)
+    print '/**'
+    print '\page references References'
+    print
+    for line in outdata:
+        print line
+    print '*/'
+
+
+# main program
+
+def main():
+    import sys
+    if sys.argv[1:]:
+        filepath = sys.argv[1]
+    else:
+        print "No input file"
+        sys.exit()
+    filehandler(filepath)
+
+if __name__ == "__main__": main()
+
+
+# end python script
Index: scripts/bootstrap.sh
===================================================================
--- scripts/bootstrap.sh	(revision 850)
+++ scripts/bootstrap.sh	(revision 850)
@@ -0,0 +1,157 @@
+#!/bin/bash
+#
+# 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.
+
+
+if [ ! -f ~/.lemon-bootstrap ]; then
+    echo 'Create ~/.lemon-bootstrap'.
+    cat >~/.lemon-bootstrap <<EOF
+#
+# Default settings for bootstraping the LEMON source code repository
+#
+EOF
+fi
+
+source ~/.lemon-bootstrap
+if [ -f ../../../.lemon-bootstrap ]; then source ../../../.lemon-bootstrap; fi
+if [ -f ../../.lemon-bootstrap ]; then source ../../.lemon-bootstrap; fi
+if [ -f ../.lemon-bootstrap ]; then source ../.lemon-bootstrap; fi
+if [ -f ./.lemon-bootstrap ]; then source ./.lemon-bootstrap; fi
+
+
+function augment_config() { 
+    if [ "x${!1}" == "x" ]; then
+        eval $1=$2
+        echo Add "'$1'" to '~/.lemon-bootstrap'.
+        echo >>~/.lemon-bootstrap
+        echo $3 >>~/.lemon-bootstrap
+        echo $1=$2 >>~/.lemon-bootstrap
+    fi
+}
+
+augment_config LEMON_INSTALL_PREFIX /usr/local \
+    "# LEMON installation prefix"
+
+augment_config GLPK_PREFIX /usr/local/ \
+    "# GLPK installation root prefix"
+
+augment_config COIN_OR_PREFIX /usr/local/coin-or \
+    "# COIN-OR installation root prefix (used for CLP/CBC)"
+
+augment_config SOPLEX_PREFIX /usr/local/soplex \
+    "# Soplex build prefix"
+
+
+function ask() {
+echo -n "$1 [$2]? "
+read _an
+if [ "x$_an" == "x" ]; then
+    ret="$2"
+else
+    ret=$_an
+fi
+}
+
+function yesorno() {
+    ret='rossz'
+    while [ "$ret" != "y" -a "$ret" != "n" -a "$ret" != "yes" -a "$ret" != "no" ]; do
+        ask "$1" "$2"
+    done
+    if [ "$ret" != "y" -a "$ret" != "yes" ]; then
+        return 1
+    else
+        return 0
+    fi
+}
+
+if yesorno "External build" "n"
+then
+    CONFIGURE_PATH=".."
+else
+    CONFIGURE_PATH="."
+    if yesorno "Autoreconf" "y"
+    then
+        AUTORE=yes
+    else
+        AUTORE=no
+    fi
+fi
+
+if yesorno "Optimize" "n" 
+then
+    opt_flags=' -O2'
+else
+    opt_flags=''
+fi
+
+if yesorno "Stop on warning" "y" 
+then
+    werror_flags=' -Werror'
+else
+    werror_flags=''
+fi
+
+cxx_flags="CXXFLAGS=-ggdb$opt_flags$werror_flags"
+
+if yesorno "Check with valgrind" "n" 
+then
+    valgrind_flags=' --enable-valgrind'
+else
+    valgrind_flags=''
+fi
+
+if [ -f ${GLPK_PREFIX}/include/glpk.h ]; then
+    if yesorno "Use GLPK" "y"
+    then
+        glpk_flag="--with-glpk=$GLPK_PREFIX"
+    else
+        glpk_flag="--without-glpk"
+    fi
+else
+    glpk_flag="--without-glpk"        
+fi
+
+if [ -f ${COIN_OR_PREFIX}/include/coin/config_coinutils.h ]; then
+    if yesorno "Use COIN-OR (CBC/CLP)" "n"
+    then
+        coin_flag="--with-coin=$COIN_OR_PREFIX"
+    else
+        coin_flag="--without-coin"
+    fi
+else
+    coin_flag="--without-coin"        
+fi
+
+if [ -f ${SOPLEX_PREFIX}/src/soplex.h ]; then
+    if yesorno "Use Soplex" "n"
+    then
+        soplex_flag="--with-soplex=$SOPLEX_PREFIX"
+    else
+        soplex_flag="--without-soplex"
+    fi
+else
+    soplex_flag="--without-soplex"
+fi
+
+if [ "x$AUTORE" == "xyes" ]; then
+    autoreconf -vif;
+fi
+${CONFIGURE_PATH}/configure --prefix=$LEMON_INSTALL_PREFIX \
+$valgrind_flags \
+"$cxx_flags" \
+$glpk_flag \
+$coin_flag \
+$soplex_flag \
+$*
Index: scripts/chg-len.py
===================================================================
--- scripts/chg-len.py	(revision 422)
+++ scripts/chg-len.py	(revision 733)
@@ -1,3 +1,17 @@
 #! /usr/bin/env python
+#
+# 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.
 
 import sys
Index: scripts/mk-release.sh
===================================================================
--- scripts/mk-release.sh	(revision 733)
+++ scripts/mk-release.sh	(revision 733)
@@ -0,0 +1,49 @@
+#!/bin/bash
+#
+# 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.
+
+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
+
+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 554)
+++ scripts/unify-sources.sh	(revision 733)
@@ -1,6 +1,29 @@
 #!/bin/bash
-
-YEAR=`date +2003-%Y`
+#
+# 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.
+
+YEAR=`date +%Y`
 HGROOT=`hg root`
+
+function hg_year() {
+    if [ -n "$(hg st $1)" ]; then
+        echo $YEAR
+    else
+        hg log -l 1 --template='{date|isodate}\n' $1 |
+        cut -d '-' -f 1
+    fi
+}
 
 # file enumaration modes
@@ -192,5 +215,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) "$YEAR"
+ * Copyright (C) 2003-"$(hg_year $1)"
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
Index: scripts/valgrind-wrapper.sh
===================================================================
--- scripts/valgrind-wrapper.sh	(revision 793)
+++ scripts/valgrind-wrapper.sh	(revision 793)
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# Run in valgrind, with leak checking enabled
+
+valgrind -q --leak-check=full "$@" 2> .valgrind-log
+
+# Save the test result
+
+result="$?"
+
+# Valgrind should generate no error messages
+
+log_contents="`cat .valgrind-log`"
+
+if [ "$log_contents" != "" ]; then
+        cat .valgrind-log >&2
+        result=1
+fi
+
+rm -f .valgrind-log
+
+exit $result
Index: test/CMakeLists.txt
===================================================================
--- test/CMakeLists.txt	(revision 549)
+++ test/CMakeLists.txt	(revision 966)
@@ -4,14 +4,19 @@
 )
 
-IF(HAVE_GLPK)
-  INCLUDE_DIRECTORIES(${GLPK_INCLUDE_DIR})
-ENDIF(HAVE_GLPK)
+LINK_DIRECTORIES(
+  ${PROJECT_BINARY_DIR}/lemon
+)
 
-LINK_DIRECTORIES(${PROJECT_BINARY_DIR}/lemon)
+SET(TEST_WITH_VALGRIND "NO" CACHE STRING
+  "Run the test with valgrind (YES/NO).")
+SET(VALGRIND_FLAGS "" CACHE STRING "Valgrind flags used by the tests.")
 
 SET(TESTS
   adaptors_test
+  arc_look_up_test
+  bellman_ford_test
   bfs_test
   circulation_test
+  connectivity_test
   counter_test
   dfs_test
@@ -22,4 +27,5 @@
   error_test
   euler_test
+  fractional_matching_test
   gomory_hu_test
   graph_copy_test
@@ -29,8 +35,12 @@
   heap_test
   kruskal_test
+  lgf_test
   maps_test
-  max_matching_test
+  matching_test
   min_cost_arborescence_test
+  min_cost_flow_test
+  min_mean_cycle_test
   path_test
+  planarity_test
   preflow_test
   radix_sort_test
@@ -38,45 +48,105 @@
   suurballe_test
   time_measure_test
-  unionfind_test)
+  unionfind_test
+)
 
-IF(HAVE_LP)
-  ADD_EXECUTABLE(lp_test lp_test.cc)
-  IF(HAVE_GLPK)
-    TARGET_LINK_LIBRARIES(lp_test lemon ${GLPK_LIBRARIES})
-  ENDIF(HAVE_GLPK)
+IF(LEMON_HAVE_LP)
+  IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
+    ADD_EXECUTABLE(lp_test lp_test.cc)
+  ELSE()
+    ADD_EXECUTABLE(lp_test EXCLUDE_FROM_ALL lp_test.cc)
+  ENDIF()
+
+  SET(LP_TEST_LIBS lemon)
+
+  IF(LEMON_HAVE_GLPK)
+    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${GLPK_LIBRARIES})
+  ENDIF()
+  IF(LEMON_HAVE_CPLEX)
+    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${CPLEX_LIBRARIES})
+  ENDIF()
+  IF(LEMON_HAVE_CLP)
+    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${COIN_CLP_LIBRARIES})
+  ENDIF()
+
+  TARGET_LINK_LIBRARIES(lp_test ${LP_TEST_LIBS})
   ADD_TEST(lp_test lp_test)
+  ADD_DEPENDENCIES(check lp_test)
 
-  IF(WIN32 AND HAVE_GLPK)
+  IF(WIN32 AND LEMON_HAVE_GLPK)
     GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
     GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
     ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
-      COMMAND cmake -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
-      COMMAND cmake -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
-      COMMAND cmake -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
+      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
+      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
+      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
     )
-  ENDIF(WIN32 AND HAVE_GLPK)
-ENDIF(HAVE_LP)
+  ENDIF()
 
-IF(HAVE_MIP)
-  ADD_EXECUTABLE(mip_test mip_test.cc)
-  IF(HAVE_GLPK)
-    TARGET_LINK_LIBRARIES(mip_test lemon ${GLPK_LIBRARIES})
-  ENDIF(HAVE_GLPK)
+  IF(WIN32 AND LEMON_HAVE_CPLEX)
+    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
+    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
+    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
+      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex.dll ${TARGET_PATH}
+    )
+  ENDIF()
+ENDIF()
+
+IF(LEMON_HAVE_MIP)
+  IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
+    ADD_EXECUTABLE(mip_test mip_test.cc)
+  ELSE()
+    ADD_EXECUTABLE(mip_test EXCLUDE_FROM_ALL mip_test.cc)
+  ENDIF()
+
+  SET(MIP_TEST_LIBS lemon)
+
+  IF(LEMON_HAVE_GLPK)
+    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${GLPK_LIBRARIES})
+  ENDIF()
+  IF(LEMON_HAVE_CPLEX)
+    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${CPLEX_LIBRARIES})
+  ENDIF()
+  IF(LEMON_HAVE_CBC)
+    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${COIN_CBC_LIBRARIES})
+  ENDIF()
+
+  TARGET_LINK_LIBRARIES(mip_test ${MIP_TEST_LIBS})
   ADD_TEST(mip_test mip_test)
+  ADD_DEPENDENCIES(check mip_test)
 
-  IF(WIN32 AND HAVE_GLPK)
+  IF(WIN32 AND LEMON_HAVE_GLPK)
     GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
     GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
     ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
-      COMMAND cmake -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
-      COMMAND cmake -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
-      COMMAND cmake -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
+      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
+      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
+      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
     )
-  ENDIF(WIN32 AND HAVE_GLPK)
-ENDIF(HAVE_MIP)
+  ENDIF()
+
+  IF(WIN32 AND LEMON_HAVE_CPLEX)
+    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
+    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
+    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
+      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex.dll ${TARGET_PATH}
+    )
+  ENDIF()
+ENDIF()
 
 FOREACH(TEST_NAME ${TESTS})
-  ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc)
+  IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
+    ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc)
+  ELSE()
+    ADD_EXECUTABLE(${TEST_NAME} EXCLUDE_FROM_ALL ${TEST_NAME}.cc)
+  ENDIF()
   TARGET_LINK_LIBRARIES(${TEST_NAME} lemon)
-  ADD_TEST(${TEST_NAME} ${TEST_NAME})
-ENDFOREACH(TEST_NAME)
+    IF(TEST_WITH_VALGRIND)
+      ADD_TEST(${TEST_NAME}
+        valgrind --error-exitcode=1 ${VALGRIND_FLAGS}
+        ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME} )
+    ELSE()
+      ADD_TEST(${TEST_NAME} ${TEST_NAME})
+    ENDIF()
+  ADD_DEPENDENCIES(check ${TEST_NAME})
+ENDFOREACH()
Index: test/Makefile.am
===================================================================
--- test/Makefile.am	(revision 543)
+++ test/Makefile.am	(revision 998)
@@ -1,2 +1,6 @@
+if USE_VALGRIND
+TESTS_ENVIRONMENT=$(top_srcdir)/scripts/valgrind-wrapper.sh
+endif
+
 EXTRA_DIST += \
 	test/CMakeLists.txt
@@ -8,6 +12,9 @@
 check_PROGRAMS += \
 	test/adaptors_test \
+	test/arc_lookup_test \
+	test/bellman_ford_test \
 	test/bfs_test \
 	test/circulation_test \
+	test/connectivity_test \
 	test/counter_test \
 	test/dfs_test \
@@ -18,4 +25,5 @@
 	test/error_test \
 	test/euler_test \
+	test/fractional_matching_test \
 	test/gomory_hu_test \
 	test/graph_copy_test \
@@ -25,8 +33,12 @@
 	test/heap_test \
 	test/kruskal_test \
+	test/lgf_test \
 	test/maps_test \
-	test/max_matching_test \
+	test/matching_test \
 	test/min_cost_arborescence_test \
+	test/min_cost_flow_test \
+	test/min_mean_cycle_test \
 	test/path_test \
+	test/planarity_test \
 	test/preflow_test \
 	test/radix_sort_test \
@@ -37,4 +49,6 @@
 	test/time_measure_test \
 	test/unionfind_test
+
+test_test_tools_pass_DEPENDENCIES = demo
 
 if HAVE_LP
@@ -49,7 +63,10 @@
 
 test_adaptors_test_SOURCES = test/adaptors_test.cc
+test_adaptors_test_SOURCES = test/arc_lookup_test.cc
+test_bellman_ford_test_SOURCES = test/bellman_ford_test.cc
 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_connectivity_test_SOURCES = test/connectivity_test.cc
 test_dfs_test_SOURCES = test/dfs_test.cc
 test_digraph_test_SOURCES = test/digraph_test.cc
@@ -59,17 +76,22 @@
 test_error_test_SOURCES = test/error_test.cc
 test_euler_test_SOURCES = test/euler_test.cc
+test_fractional_matching_test_SOURCES = test/fractional_matching_test.cc
 test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc
 test_graph_copy_test_SOURCES = test/graph_copy_test.cc
 test_graph_test_SOURCES = test/graph_test.cc
 test_graph_utils_test_SOURCES = test/graph_utils_test.cc
+test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc
 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_lgf_test_SOURCES = test/lgf_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_matching_test_SOURCES = test/matching_test.cc
 test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
+test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
+test_min_mean_cycle_test_SOURCES = test/min_mean_cycle_test.cc
 test_path_test_SOURCES = test/path_test.cc
+test_planarity_test_SOURCES = test/planarity_test.cc
 test_preflow_test_SOURCES = test/preflow_test.cc
 test_radix_sort_test_SOURCES = test/radix_sort_test.cc
Index: test/adaptors_test.cc
===================================================================
--- test/adaptors_test.cc	(revision 465)
+++ test/adaptors_test.cc	(revision 983)
@@ -66,4 +66,5 @@
   Digraph::Arc a2 = digraph.addArc(n1, n3);
   Digraph::Arc a3 = digraph.addArc(n2, n3);
+  ::lemon::ignore_unused_variable_warning(a3);
 
   // Check the adaptor
@@ -100,4 +101,5 @@
   Adaptor::Arc a7 = adaptor.addArc(n1, n4);
   Adaptor::Arc a8 = adaptor.addArc(n1, n2);
+  ::lemon::ignore_unused_variable_warning(a6,a7,a8);
 
   adaptor.erase(a1);
@@ -759,4 +761,5 @@
   Digraph::Arc a2 = digraph.addArc(n1, n3);
   Digraph::Arc a3 = digraph.addArc(n2, n3);
+  ::lemon::ignore_unused_variable_warning(a1,a2,a3);
 
   checkGraphNodeList(adaptor, 6);
@@ -1372,26 +1375,20 @@
 
   GridGraph::EdgeMap<bool> dir_map(graph);
-  dir_map[graph.right(n1)] = graph.u(graph.right(n1)) == n1;
-  dir_map[graph.up(n1)] = graph.u(graph.up(n1)) != n1;
-  dir_map[graph.left(n4)] = graph.u(graph.left(n4)) != n4;
-  dir_map[graph.down(n4)] = graph.u(graph.down(n4)) != n4;
+  dir_map[graph.right(n1)] = graph.u(graph.right(n1)) != n1;
+  dir_map[graph.up(n1)] = graph.u(graph.up(n1)) == n1;
+  dir_map[graph.left(n4)] = graph.u(graph.left(n4)) == n4;
+  dir_map[graph.down(n4)] = graph.u(graph.down(n4)) == n4;
 
   // Apply several adaptors on the grid graph
-  typedef SplitNodes< ReverseDigraph< const Orienter<
-            const GridGraph, GridGraph::EdgeMap<bool> > > >
-    RevSplitGridGraph;
-  typedef ReverseDigraph<const RevSplitGridGraph> SplitGridGraph;
+  typedef Orienter< const GridGraph, GridGraph::EdgeMap<bool> >
+    OrientedGridGraph;
+  typedef SplitNodes<OrientedGridGraph> SplitGridGraph;
   typedef Undirector<const SplitGridGraph> USplitGridGraph;
-  typedef Undirector<const USplitGridGraph> UUSplitGridGraph;
-  checkConcept<concepts::Digraph, RevSplitGridGraph>();
   checkConcept<concepts::Digraph, SplitGridGraph>();
   checkConcept<concepts::Graph, USplitGridGraph>();
-  checkConcept<concepts::Graph, UUSplitGridGraph>();
-
-  RevSplitGridGraph rev_adaptor =
-    splitNodes(reverseDigraph(orienter(graph, dir_map)));
-  SplitGridGraph adaptor = reverseDigraph(rev_adaptor);
+
+  OrientedGridGraph oadaptor = orienter(graph, dir_map);
+  SplitGridGraph adaptor = splitNodes(oadaptor);
   USplitGridGraph uadaptor = undirector(adaptor);
-  UUSplitGridGraph uuadaptor = undirector(uadaptor);
 
   // Check adaptor
@@ -1400,21 +1397,21 @@
   checkGraphConArcList(adaptor, 8);
 
-  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n1), 1);
-  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n1), 1);
-  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n2), 2);
-  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n2), 1);
-  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n3), 1);
-  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n3), 1);
-  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n4), 0);
-  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n4), 1);
-
-  checkGraphInArcList(adaptor, rev_adaptor.inNode(n1), 1);
-  checkGraphInArcList(adaptor, rev_adaptor.outNode(n1), 1);
-  checkGraphInArcList(adaptor, rev_adaptor.inNode(n2), 1);
-  checkGraphInArcList(adaptor, rev_adaptor.outNode(n2), 0);
-  checkGraphInArcList(adaptor, rev_adaptor.inNode(n3), 1);
-  checkGraphInArcList(adaptor, rev_adaptor.outNode(n3), 1);
-  checkGraphInArcList(adaptor, rev_adaptor.inNode(n4), 1);
-  checkGraphInArcList(adaptor, rev_adaptor.outNode(n4), 2);
+  checkGraphOutArcList(adaptor, adaptor.inNode(n1), 1);
+  checkGraphOutArcList(adaptor, adaptor.outNode(n1), 1);
+  checkGraphOutArcList(adaptor, adaptor.inNode(n2), 1);
+  checkGraphOutArcList(adaptor, adaptor.outNode(n2), 0);
+  checkGraphOutArcList(adaptor, adaptor.inNode(n3), 1);
+  checkGraphOutArcList(adaptor, adaptor.outNode(n3), 1);
+  checkGraphOutArcList(adaptor, adaptor.inNode(n4), 1);
+  checkGraphOutArcList(adaptor, adaptor.outNode(n4), 2);
+
+  checkGraphInArcList(adaptor, adaptor.inNode(n1), 1);
+  checkGraphInArcList(adaptor, adaptor.outNode(n1), 1);
+  checkGraphInArcList(adaptor, adaptor.inNode(n2), 2);
+  checkGraphInArcList(adaptor, adaptor.outNode(n2), 1);
+  checkGraphInArcList(adaptor, adaptor.inNode(n3), 1);
+  checkGraphInArcList(adaptor, adaptor.outNode(n3), 1);
+  checkGraphInArcList(adaptor, adaptor.inNode(n4), 0);
+  checkGraphInArcList(adaptor, adaptor.outNode(n4), 1);
 
   checkNodeIds(adaptor);
@@ -1439,27 +1436,12 @@
   checkGraphArcMap(uadaptor);
 
-  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n1), 2);
-  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n1), 2);
-  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n2), 3);
-  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n2), 1);
-  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n3), 2);
-  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n3), 2);
-  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n4), 1);
-  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n4), 3);
-
-  // Check uuadaptor
-  checkGraphNodeList(uuadaptor, 8);
-  checkGraphEdgeList(uuadaptor, 16);
-  checkGraphArcList(uuadaptor, 32);
-  checkGraphConEdgeList(uuadaptor, 16);
-  checkGraphConArcList(uuadaptor, 32);
-
-  checkNodeIds(uuadaptor);
-  checkEdgeIds(uuadaptor);
-  checkArcIds(uuadaptor);
-
-  checkGraphNodeMap(uuadaptor);
-  checkGraphEdgeMap(uuadaptor);
-  checkGraphArcMap(uuadaptor);
+  checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n1), 2);
+  checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n1), 2);
+  checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n2), 3);
+  checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n2), 1);
+  checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n3), 2);
+  checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n3), 2);
+  checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n4), 1);
+  checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n4), 3);
 }
 
Index: test/arc_look_up_test.cc
===================================================================
--- test/arc_look_up_test.cc	(revision 959)
+++ test/arc_look_up_test.cc	(revision 959)
@@ -0,0 +1,85 @@
+/* -*- 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 "test_tools.h"
+
+using namespace lemon;
+
+const int lgfn = 4;
+const std::string lgf =
+  "@nodes\n"
+"label\n"
+"0\n"
+"1\n"
+"2\n"
+"3\n"
+"4\n"
+"5\n"
+"6\n"
+"@arcs\n"
+"label\n"
+"5 6 0\n"
+"5 4 1\n"
+"4 6 2\n"
+"3 4 3\n"
+"3 4 4\n"
+"3 2 5\n"
+"3 5 6\n"
+"3 5 7\n"
+"3 5 8\n"
+"3 5 9\n"
+"2 4 10\n"
+"2 4 11\n"
+"2 4 12\n"
+"2 4 13\n"
+"1 2 14\n"
+"1 2 15\n"
+"1 0 16\n"
+"1 3 17\n"
+"1 3 18\n"
+"1 3 19\n"
+"1 3 20\n"
+"0 2 21\n"
+"0 2 22\n"
+"0 2 23\n"
+"0 2 24\n";
+
+
+int main() {
+  ListDigraph graph;
+  std::istringstream lgfs(lgf);
+  DigraphReader<ListDigraph>(graph, lgfs).run();
+  
+  AllArcLookUp<ListDigraph> lookup(graph);
+	
+  int numArcs = countArcs(graph);
+	
+  int arcCnt = 0;
+  for(ListDigraph::NodeIt n1(graph); n1 != INVALID; ++n1)
+    for(ListDigraph::NodeIt n2(graph); n2 != INVALID; ++n2)
+      for(ListDigraph::Arc a = lookup(n1, n2); a != INVALID;
+	  a = lookup(n1, n2, a))
+	++arcCnt;
+  check(arcCnt==numArcs, "Wrong total number of arcs");
+
+  return 0;
+}
Index: test/bellman_ford_test.cc
===================================================================
--- test/bellman_ford_test.cc	(revision 984)
+++ test/bellman_ford_test.cc	(revision 984)
@@ -0,0 +1,289 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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/concepts/digraph.h>
+#include <lemon/smart_graph.h>
+#include <lemon/list_graph.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/bellman_ford.h>
+#include <lemon/path.h>
+
+#include "graph_test.h"
+#include "test_tools.h"
+
+using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "@arcs\n"
+  "    length\n"
+  "0 1 3\n"
+  "1 2 -3\n"
+  "1 2 -5\n"
+  "1 3 -2\n"
+  "0 2 -1\n"
+  "1 2 -4\n"
+  "0 3 2\n"
+  "4 2 -5\n"
+  "2 3 1\n"
+  "@attributes\n"
+  "source 0\n"
+  "target 3\n";
+
+
+void checkBellmanFordCompile()
+{
+  typedef int Value;
+  typedef concepts::Digraph Digraph;
+  typedef concepts::ReadMap<Digraph::Arc,Value> LengthMap;
+  typedef BellmanFord<Digraph, LengthMap> BF;
+  typedef Digraph::Node Node;
+  typedef Digraph::Arc Arc;
+
+  Digraph gr;
+  Node s, t, n;
+  Arc e;
+  Value l;
+  ::lemon::ignore_unused_variable_warning(l);
+  int k=3;
+  bool b;
+  ::lemon::ignore_unused_variable_warning(b);
+  BF::DistMap d(gr);
+  BF::PredMap p(gr);
+  LengthMap length;
+  concepts::Path<Digraph> pp;
+
+  {
+    BF bf_test(gr,length);
+    const BF& const_bf_test = bf_test;
+
+    bf_test.run(s);
+    bf_test.run(s,k);
+
+    bf_test.init();
+    bf_test.addSource(s);
+    bf_test.addSource(s, 1);
+    b = bf_test.processNextRound();
+    b = bf_test.processNextWeakRound();
+
+    bf_test.start();
+    bf_test.checkedStart();
+    bf_test.limitedStart(k);
+
+    l  = const_bf_test.dist(t);
+    e  = const_bf_test.predArc(t);
+    s  = const_bf_test.predNode(t);
+    b  = const_bf_test.reached(t);
+    d  = const_bf_test.distMap();
+    p  = const_bf_test.predMap();
+    pp = const_bf_test.path(t);
+    pp = const_bf_test.negativeCycle();
+
+    for (BF::ActiveIt it(const_bf_test); it != INVALID; ++it) {}
+  }
+  {
+    BF::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
+      ::SetDistMap<concepts::ReadWriteMap<Node,Value> >
+      ::SetOperationTraits<BellmanFordDefaultOperationTraits<Value> >
+      ::Create bf_test(gr,length);
+
+    LengthMap length_map;
+    concepts::ReadWriteMap<Node,Arc> pred_map;
+    concepts::ReadWriteMap<Node,Value> dist_map;
+
+    bf_test
+      .lengthMap(length_map)
+      .predMap(pred_map)
+      .distMap(dist_map);
+
+    bf_test.run(s);
+    bf_test.run(s,k);
+
+    bf_test.init();
+    bf_test.addSource(s);
+    bf_test.addSource(s, 1);
+    b = bf_test.processNextRound();
+    b = bf_test.processNextWeakRound();
+
+    bf_test.start();
+    bf_test.checkedStart();
+    bf_test.limitedStart(k);
+
+    l  = bf_test.dist(t);
+    e  = bf_test.predArc(t);
+    s  = bf_test.predNode(t);
+    b  = bf_test.reached(t);
+    pp = bf_test.path(t);
+    pp = bf_test.negativeCycle();
+  }
+}
+
+void checkBellmanFordFunctionCompile()
+{
+  typedef int Value;
+  typedef concepts::Digraph Digraph;
+  typedef Digraph::Arc Arc;
+  typedef Digraph::Node Node;
+  typedef concepts::ReadMap<Digraph::Arc,Value> LengthMap;
+
+  Digraph g;
+  bool b;
+  ::lemon::ignore_unused_variable_warning(b);
+
+  bellmanFord(g,LengthMap()).run(Node());
+  b = bellmanFord(g,LengthMap()).run(Node(),Node());
+  bellmanFord(g,LengthMap())
+    .predMap(concepts::ReadWriteMap<Node,Arc>())
+    .distMap(concepts::ReadWriteMap<Node,Value>())
+    .run(Node());
+  b=bellmanFord(g,LengthMap())
+    .predMap(concepts::ReadWriteMap<Node,Arc>())
+    .distMap(concepts::ReadWriteMap<Node,Value>())
+    .path(concepts::Path<Digraph>())
+    .dist(Value())
+    .run(Node(),Node());
+}
+
+
+template <typename Digraph, typename Value>
+void checkBellmanFord() {
+  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+  typedef typename Digraph::template ArcMap<Value> LengthMap;
+
+  Digraph gr;
+  Node s, t;
+  LengthMap length(gr);
+
+  std::istringstream input(test_lgf);
+  digraphReader(gr, input).
+    arcMap("length", length).
+    node("source", s).
+    node("target", t).
+    run();
+
+  BellmanFord<Digraph, LengthMap>
+    bf(gr, length);
+  bf.run(s);
+  Path<Digraph> p = bf.path(t);
+
+  check(bf.reached(t) && bf.dist(t) == -1, "Bellman-Ford found a wrong path.");
+  check(p.length() == 3, "path() found a wrong path.");
+  check(checkPath(gr, p), "path() found a wrong path.");
+  check(pathSource(gr, p) == s, "path() found a wrong path.");
+  check(pathTarget(gr, p) == t, "path() found a wrong path.");
+
+  ListPath<Digraph> path;
+  Value dist = 0;
+  bool reached = bellmanFord(gr,length).path(path).dist(dist).run(s,t);
+
+  check(reached && dist == -1, "Bellman-Ford found a wrong path.");
+  check(path.length() == 3, "path() found a wrong path.");
+  check(checkPath(gr, path), "path() found a wrong path.");
+  check(pathSource(gr, path) == s, "path() found a wrong path.");
+  check(pathTarget(gr, path) == t, "path() found a wrong path.");
+
+  for(ArcIt e(gr); e!=INVALID; ++e) {
+    Node u=gr.source(e);
+    Node v=gr.target(e);
+    check(!bf.reached(u) || (bf.dist(v) - bf.dist(u) <= length[e]),
+          "Wrong output. dist(target)-dist(source)-arc_length=" <<
+          bf.dist(v) - bf.dist(u) - length[e]);
+  }
+
+  for(NodeIt v(gr); v!=INVALID; ++v) {
+    if (bf.reached(v)) {
+      check(v==s || bf.predArc(v)!=INVALID, "Wrong tree.");
+      if (bf.predArc(v)!=INVALID ) {
+        Arc e=bf.predArc(v);
+        Node u=gr.source(e);
+        check(u==bf.predNode(v),"Wrong tree.");
+        check(bf.dist(v) - bf.dist(u) == length[e],
+              "Wrong distance! Difference: " <<
+              bf.dist(v) - bf.dist(u) - length[e]);
+      }
+    }
+  }
+}
+
+void checkBellmanFordNegativeCycle() {
+  DIGRAPH_TYPEDEFS(SmartDigraph);
+
+  SmartDigraph gr;
+  IntArcMap length(gr);
+
+  Node n1 = gr.addNode();
+  Node n2 = gr.addNode();
+  Node n3 = gr.addNode();
+  Node n4 = gr.addNode();
+
+  Arc a1 = gr.addArc(n1, n2);
+  Arc a2 = gr.addArc(n2, n2);
+
+  length[a1] = 2;
+  length[a2] = -1;
+
+  {
+    BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
+    bf.run(n1);
+    StaticPath<SmartDigraph> p = bf.negativeCycle();
+    check(p.length() == 1 && p.front() == p.back() && p.front() == a2,
+          "Wrong negative cycle.");
+  }
+
+  length[a2] = 0;
+
+  {
+    BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
+    bf.run(n1);
+    check(bf.negativeCycle().empty(),
+          "Negative cycle should not be found.");
+  }
+
+  length[gr.addArc(n1, n3)] = 5;
+  length[gr.addArc(n4, n3)] = 1;
+  length[gr.addArc(n2, n4)] = 2;
+  length[gr.addArc(n3, n2)] = -4;
+
+  {
+    BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
+    bf.init();
+    bf.addSource(n1);
+    for (int i = 0; i < 4; ++i) {
+      check(bf.negativeCycle().empty(),
+            "Negative cycle should not be found.");
+      bf.processNextRound();
+    }
+    StaticPath<SmartDigraph> p = bf.negativeCycle();
+    check(p.length() == 3, "Wrong negative cycle.");
+    check(length[p.nth(0)] + length[p.nth(1)] + length[p.nth(2)] == -1,
+          "Wrong negative cycle.");
+  }
+}
+
+int main() {
+  checkBellmanFord<ListDigraph, int>();
+  checkBellmanFord<SmartDigraph, double>();
+  checkBellmanFordNegativeCycle();
+  return 0;
+}
Index: test/bfs_test.cc
===================================================================
--- test/bfs_test.cc	(revision 440)
+++ test/bfs_test.cc	(revision 983)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -59,14 +59,17 @@
 
   Digraph G;
-  Node s, t;
+  Node s, t, n;
   Arc e;
-  int l;
+  int l, i;
+  ::lemon::ignore_unused_variable_warning(l,i);
   bool b;
   BType::DistMap d(G);
   BType::PredMap p(G);
   Path<Digraph> pp;
+  concepts::ReadMap<Node,bool> nm;
 
   {
     BType bfs_test(G);
+    const BType& const_bfs_test = bfs_test;
 
     bfs_test.run(s);
@@ -74,11 +77,24 @@
     bfs_test.run();
 
-    l  = bfs_test.dist(t);
-    e  = bfs_test.predArc(t);
-    s  = bfs_test.predNode(t);
-    b  = bfs_test.reached(t);
-    d  = bfs_test.distMap();
-    p  = bfs_test.predMap();
-    pp = bfs_test.path(t);
+    bfs_test.init();
+    bfs_test.addSource(s);
+    n = bfs_test.processNextNode();
+    n = bfs_test.processNextNode(t, b);
+    n = bfs_test.processNextNode(nm, n);
+    n = const_bfs_test.nextNode();
+    b = const_bfs_test.emptyQueue();
+    i = const_bfs_test.queueSize();
+
+    bfs_test.start();
+    bfs_test.start(t);
+    bfs_test.start(nm);
+
+    l  = const_bfs_test.dist(t);
+    e  = const_bfs_test.predArc(t);
+    s  = const_bfs_test.predNode(t);
+    b  = const_bfs_test.reached(t);
+    d  = const_bfs_test.distMap();
+    p  = const_bfs_test.predMap();
+    pp = const_bfs_test.path(t);
   }
   {
@@ -87,11 +103,35 @@
       ::SetDistMap<concepts::ReadWriteMap<Node,int> >
       ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
+      ::SetStandardProcessedMap
       ::SetProcessedMap<concepts::WriteMap<Node,bool> >
-      ::SetStandardProcessedMap
       ::Create bfs_test(G);
+
+    concepts::ReadWriteMap<Node,Arc> pred_map;
+    concepts::ReadWriteMap<Node,int> dist_map;
+    concepts::ReadWriteMap<Node,bool> reached_map;
+    concepts::WriteMap<Node,bool> processed_map;
+
+    bfs_test
+      .predMap(pred_map)
+      .distMap(dist_map)
+      .reachedMap(reached_map)
+      .processedMap(processed_map);
 
     bfs_test.run(s);
     bfs_test.run(s,t);
     bfs_test.run();
+
+    bfs_test.init();
+    bfs_test.addSource(s);
+    n = bfs_test.processNextNode();
+    n = bfs_test.processNextNode(t, b);
+    n = bfs_test.processNextNode(nm, n);
+    n = bfs_test.nextNode();
+    b = bfs_test.emptyQueue();
+    i = bfs_test.queueSize();
+
+    bfs_test.start();
+    bfs_test.start(t);
+    bfs_test.start(nm);
 
     l  = bfs_test.dist(t);
@@ -112,4 +152,6 @@
   Digraph g;
   bool b;
+  ::lemon::ignore_unused_variable_warning(b);
+
   bfs(g).run(Node());
   b=bfs(g).run(Node(),Node());
Index: test/circulation_test.cc
===================================================================
--- test/circulation_test.cc	(revision 440)
+++ test/circulation_test.cc	(revision 983)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -58,5 +58,5 @@
   typedef Digraph::Arc Arc;
   typedef concepts::ReadMap<Arc,VType> CapMap;
-  typedef concepts::ReadMap<Node,VType> DeltaMap;
+  typedef concepts::ReadMap<Node,VType> SupplyMap;
   typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
   typedef concepts::WriteMap<Node,bool> BarrierMap;
@@ -69,19 +69,29 @@
   Arc a;
   CapMap lcap, ucap;
-  DeltaMap delta;
+  SupplyMap supply;
   FlowMap flow;
   BarrierMap bar;
+  VType v;
+  bool b;
+  ::lemon::ignore_unused_variable_warning(v,b);
 
-  Circulation<Digraph, CapMap, CapMap, DeltaMap>
-    ::SetFlowMap<FlowMap>
-    ::SetElevator<Elev>
-    ::SetStandardElevator<LinkedElev>
-    ::Create circ_test(g,lcap,ucap,delta);
+  typedef Circulation<Digraph, CapMap, CapMap, SupplyMap>
+            ::SetFlowMap<FlowMap>
+            ::SetElevator<Elev>
+            ::SetStandardElevator<LinkedElev>
+            ::Create CirculationType;
+  CirculationType circ_test(g, lcap, ucap, supply);
+  const CirculationType& const_circ_test = circ_test;
 
-  circ_test.lowerCapMap(lcap);
-  circ_test.upperCapMap(ucap);
-  circ_test.deltaMap(delta);
-  flow = circ_test.flowMap();
-  circ_test.flowMap(flow);
+  circ_test
+    .lowerMap(lcap)
+    .upperMap(ucap)
+    .supplyMap(supply)
+    .flowMap(flow);
+
+  const CirculationType::Elevator& elev = const_circ_test.elevator();
+  circ_test.elevator(const_cast<CirculationType::Elevator&>(elev));
+  CirculationType::Tolerance tol = const_circ_test.tolerance();
+  circ_test.tolerance(tol);
 
   circ_test.init();
@@ -90,7 +100,10 @@
   circ_test.run();
 
-  circ_test.barrier(n);
-  circ_test.barrierMap(bar);
-  circ_test.flow(a);
+  v = const_circ_test.flow(a);
+  const FlowMap& fm = const_circ_test.flowMap();
+  b = const_circ_test.barrier(n);
+  const_circ_test.barrierMap(bar);
+
+  ::lemon::ignore_unused_variable_warning(fm);
 }
 
Index: test/connectivity_test.cc
===================================================================
--- test/connectivity_test.cc	(revision 988)
+++ test/connectivity_test.cc	(revision 988)
@@ -0,0 +1,316 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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/connectivity.h>
+#include <lemon/list_graph.h>
+#include <lemon/adaptors.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+
+
+int main()
+{
+  typedef ListDigraph Digraph;
+  typedef Undirector<Digraph> Graph;
+
+  {
+    Digraph d;
+    Digraph::NodeMap<int> order(d);
+    Graph g(d);
+
+    check(stronglyConnected(d), "The empty digraph is strongly connected");
+    check(countStronglyConnectedComponents(d) == 0,
+          "The empty digraph has 0 strongly connected component");
+    check(connected(g), "The empty graph is connected");
+    check(countConnectedComponents(g) == 0,
+          "The empty graph has 0 connected component");
+
+    check(biNodeConnected(g), "The empty graph is bi-node-connected");
+    check(countBiNodeConnectedComponents(g) == 0,
+          "The empty graph has 0 bi-node-connected component");
+    check(biEdgeConnected(g), "The empty graph is bi-edge-connected");
+    check(countBiEdgeConnectedComponents(g) == 0,
+          "The empty graph has 0 bi-edge-connected component");
+
+    check(dag(d), "The empty digraph is DAG.");
+    check(checkedTopologicalSort(d, order), "The empty digraph is DAG.");
+    check(loopFree(d), "The empty digraph is loop-free.");
+    check(parallelFree(d), "The empty digraph is parallel-free.");
+    check(simpleGraph(d), "The empty digraph is simple.");
+
+    check(acyclic(g), "The empty graph is acyclic.");
+    check(tree(g), "The empty graph is tree.");
+    check(bipartite(g), "The empty graph is bipartite.");
+    check(loopFree(g), "The empty graph is loop-free.");
+    check(parallelFree(g), "The empty graph is parallel-free.");
+    check(simpleGraph(g), "The empty graph is simple.");
+  }
+
+  {
+    Digraph d;
+    Digraph::NodeMap<int> order(d);
+    Graph g(d);
+    Digraph::Node n = d.addNode();
+    ::lemon::ignore_unused_variable_warning(n);
+
+    check(stronglyConnected(d), "This digraph is strongly connected");
+    check(countStronglyConnectedComponents(d) == 1,
+          "This digraph has 1 strongly connected component");
+    check(connected(g), "This graph is connected");
+    check(countConnectedComponents(g) == 1,
+          "This graph has 1 connected component");
+
+    check(biNodeConnected(g), "This graph is bi-node-connected");
+    check(countBiNodeConnectedComponents(g) == 0,
+          "This graph has 0 bi-node-connected component");
+    check(biEdgeConnected(g), "This graph is bi-edge-connected");
+    check(countBiEdgeConnectedComponents(g) == 1,
+          "This graph has 1 bi-edge-connected component");
+
+    check(dag(d), "This digraph is DAG.");
+    check(checkedTopologicalSort(d, order), "This digraph is DAG.");
+    check(loopFree(d), "This digraph is loop-free.");
+    check(parallelFree(d), "This digraph is parallel-free.");
+    check(simpleGraph(d), "This digraph is simple.");
+
+    check(acyclic(g), "This graph is acyclic.");
+    check(tree(g), "This graph is tree.");
+    check(bipartite(g), "This graph is bipartite.");
+    check(loopFree(g), "This graph is loop-free.");
+    check(parallelFree(g), "This graph is parallel-free.");
+    check(simpleGraph(g), "This graph is simple.");
+  }
+
+  {
+    ListGraph g;
+    ListGraph::NodeMap<bool> map(g);
+
+    ListGraph::Node n1 = g.addNode();
+    ListGraph::Node n2 = g.addNode();
+
+    ListGraph::Edge e1 = g.addEdge(n1, n2);
+    ::lemon::ignore_unused_variable_warning(e1);
+    check(biNodeConnected(g), "Graph is bi-node-connected");
+
+    ListGraph::Node n3 = g.addNode();
+    ::lemon::ignore_unused_variable_warning(n3);
+    check(!biNodeConnected(g), "Graph is not bi-node-connected");
+  }
+
+
+  {
+    Digraph d;
+    Digraph::NodeMap<int> order(d);
+    Graph g(d);
+
+    Digraph::Node n1 = d.addNode();
+    Digraph::Node n2 = d.addNode();
+    Digraph::Node n3 = d.addNode();
+    Digraph::Node n4 = d.addNode();
+    Digraph::Node n5 = d.addNode();
+    Digraph::Node n6 = d.addNode();
+
+    d.addArc(n1, n3);
+    d.addArc(n3, n2);
+    d.addArc(n2, n1);
+    d.addArc(n4, n2);
+    d.addArc(n4, n3);
+    d.addArc(n5, n6);
+    d.addArc(n6, n5);
+
+    check(!stronglyConnected(d), "This digraph is not strongly connected");
+    check(countStronglyConnectedComponents(d) == 3,
+          "This digraph has 3 strongly connected components");
+    check(!connected(g), "This graph is not connected");
+    check(countConnectedComponents(g) == 2,
+          "This graph has 2 connected components");
+
+    check(!dag(d), "This digraph is not DAG.");
+    check(!checkedTopologicalSort(d, order), "This digraph is not DAG.");
+    check(loopFree(d), "This digraph is loop-free.");
+    check(parallelFree(d), "This digraph is parallel-free.");
+    check(simpleGraph(d), "This digraph is simple.");
+
+    check(!acyclic(g), "This graph is not acyclic.");
+    check(!tree(g), "This graph is not tree.");
+    check(!bipartite(g), "This graph is not bipartite.");
+    check(loopFree(g), "This graph is loop-free.");
+    check(!parallelFree(g), "This graph is not parallel-free.");
+    check(!simpleGraph(g), "This graph is not simple.");
+
+    d.addArc(n3, n3);
+
+    check(!loopFree(d), "This digraph is not loop-free.");
+    check(!loopFree(g), "This graph is not loop-free.");
+    check(!simpleGraph(d), "This digraph is not simple.");
+
+    d.addArc(n3, n2);
+
+    check(!parallelFree(d), "This digraph is not parallel-free.");
+  }
+
+  {
+    Digraph d;
+    Digraph::ArcMap<bool> cutarcs(d, false);
+    Graph g(d);
+
+    Digraph::Node n1 = d.addNode();
+    Digraph::Node n2 = d.addNode();
+    Digraph::Node n3 = d.addNode();
+    Digraph::Node n4 = d.addNode();
+    Digraph::Node n5 = d.addNode();
+    Digraph::Node n6 = d.addNode();
+    Digraph::Node n7 = d.addNode();
+    Digraph::Node n8 = d.addNode();
+
+    d.addArc(n1, n2);
+    d.addArc(n5, n1);
+    d.addArc(n2, n8);
+    d.addArc(n8, n5);
+    d.addArc(n6, n4);
+    d.addArc(n4, n6);
+    d.addArc(n2, n5);
+    d.addArc(n1, n8);
+    d.addArc(n6, n7);
+    d.addArc(n7, n6);
+
+    check(!stronglyConnected(d), "This digraph is not strongly connected");
+    check(countStronglyConnectedComponents(d) == 3,
+          "This digraph has 3 strongly connected components");
+    Digraph::NodeMap<int> scomp1(d);
+    check(stronglyConnectedComponents(d, scomp1) == 3,
+          "This digraph has 3 strongly connected components");
+    check(scomp1[n1] != scomp1[n3] && scomp1[n1] != scomp1[n4] &&
+          scomp1[n3] != scomp1[n4], "Wrong stronglyConnectedComponents()");
+    check(scomp1[n1] == scomp1[n2] && scomp1[n1] == scomp1[n5] &&
+          scomp1[n1] == scomp1[n8], "Wrong stronglyConnectedComponents()");
+    check(scomp1[n4] == scomp1[n6] && scomp1[n4] == scomp1[n7],
+          "Wrong stronglyConnectedComponents()");
+    Digraph::ArcMap<bool> scut1(d, false);
+    check(stronglyConnectedCutArcs(d, scut1) == 0,
+          "This digraph has 0 strongly connected cut arc.");
+    for (Digraph::ArcIt a(d); a != INVALID; ++a) {
+      check(!scut1[a], "Wrong stronglyConnectedCutArcs()");
+    }
+
+    check(!connected(g), "This graph is not connected");
+    check(countConnectedComponents(g) == 3,
+          "This graph has 3 connected components");
+    Graph::NodeMap<int> comp(g);
+    check(connectedComponents(g, comp) == 3,
+          "This graph has 3 connected components");
+    check(comp[n1] != comp[n3] && comp[n1] != comp[n4] &&
+          comp[n3] != comp[n4], "Wrong connectedComponents()");
+    check(comp[n1] == comp[n2] && comp[n1] == comp[n5] &&
+          comp[n1] == comp[n8], "Wrong connectedComponents()");
+    check(comp[n4] == comp[n6] && comp[n4] == comp[n7],
+          "Wrong connectedComponents()");
+
+    cutarcs[d.addArc(n3, n1)] = true;
+    cutarcs[d.addArc(n3, n5)] = true;
+    cutarcs[d.addArc(n3, n8)] = true;
+    cutarcs[d.addArc(n8, n6)] = true;
+    cutarcs[d.addArc(n8, n7)] = true;
+
+    check(!stronglyConnected(d), "This digraph is not strongly connected");
+    check(countStronglyConnectedComponents(d) == 3,
+          "This digraph has 3 strongly connected components");
+    Digraph::NodeMap<int> scomp2(d);
+    check(stronglyConnectedComponents(d, scomp2) == 3,
+          "This digraph has 3 strongly connected components");
+    check(scomp2[n3] == 0, "Wrong stronglyConnectedComponents()");
+    check(scomp2[n1] == 1 && scomp2[n2] == 1 && scomp2[n5] == 1 &&
+          scomp2[n8] == 1, "Wrong stronglyConnectedComponents()");
+    check(scomp2[n4] == 2 && scomp2[n6] == 2 && scomp2[n7] == 2,
+          "Wrong stronglyConnectedComponents()");
+    Digraph::ArcMap<bool> scut2(d, false);
+    check(stronglyConnectedCutArcs(d, scut2) == 5,
+          "This digraph has 5 strongly connected cut arcs.");
+    for (Digraph::ArcIt a(d); a != INVALID; ++a) {
+      check(scut2[a] == cutarcs[a], "Wrong stronglyConnectedCutArcs()");
+    }
+  }
+
+  {
+    // DAG example for topological sort from the book New Algorithms
+    // (T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein)
+    Digraph d;
+    Digraph::NodeMap<int> order(d);
+
+    Digraph::Node belt = d.addNode();
+    Digraph::Node trousers = d.addNode();
+    Digraph::Node necktie = d.addNode();
+    Digraph::Node coat = d.addNode();
+    Digraph::Node socks = d.addNode();
+    Digraph::Node shirt = d.addNode();
+    Digraph::Node shoe = d.addNode();
+    Digraph::Node watch = d.addNode();
+    Digraph::Node pants = d.addNode();
+    ::lemon::ignore_unused_variable_warning(watch);
+
+    d.addArc(socks, shoe);
+    d.addArc(pants, shoe);
+    d.addArc(pants, trousers);
+    d.addArc(trousers, shoe);
+    d.addArc(trousers, belt);
+    d.addArc(belt, coat);
+    d.addArc(shirt, belt);
+    d.addArc(shirt, necktie);
+    d.addArc(necktie, coat);
+
+    check(dag(d), "This digraph is DAG.");
+    topologicalSort(d, order);
+    for (Digraph::ArcIt a(d); a != INVALID; ++a) {
+      check(order[d.source(a)] < order[d.target(a)],
+            "Wrong topologicalSort()");
+    }
+  }
+
+  {
+    ListGraph g;
+    ListGraph::NodeMap<bool> map(g);
+
+    ListGraph::Node n1 = g.addNode();
+    ListGraph::Node n2 = g.addNode();
+    ListGraph::Node n3 = g.addNode();
+    ListGraph::Node n4 = g.addNode();
+    ListGraph::Node n5 = g.addNode();
+    ListGraph::Node n6 = g.addNode();
+    ListGraph::Node n7 = g.addNode();
+
+    g.addEdge(n1, n3);
+    g.addEdge(n1, n4);
+    g.addEdge(n2, n5);
+    g.addEdge(n3, n6);
+    g.addEdge(n4, n6);
+    g.addEdge(n4, n7);
+    g.addEdge(n5, n7);
+
+    check(bipartite(g), "This graph is bipartite");
+    check(bipartitePartitions(g, map), "This graph is bipartite");
+
+    check(map[n1] == map[n2] && map[n1] == map[n6] && map[n1] == map[n7],
+          "Wrong bipartitePartitions()");
+    check(map[n3] == map[n4] && map[n3] == map[n5],
+          "Wrong bipartitePartitions()");
+  }
+
+  return 0;
+}
Index: test/dfs_test.cc
===================================================================
--- test/dfs_test.cc	(revision 440)
+++ test/dfs_test.cc	(revision 985)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2011
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -51,5 +51,8 @@
   "@attributes\n"
   "source 0\n"
-  "target 5\n";
+  "target 5\n"
+  "source1 6\n"
+  "target1 3\n";
+
 
 void checkDfsCompile()
@@ -63,12 +66,16 @@
   Node s, t;
   Arc e;
-  int l;
+  int l, i;
   bool b;
+  ::lemon::ignore_unused_variable_warning(l,i,b);
+
   DType::DistMap d(G);
   DType::PredMap p(G);
   Path<Digraph> pp;
+  concepts::ReadMap<Arc,bool> am;
 
   {
     DType dfs_test(G);
+    const DType& const_dfs_test = dfs_test;
 
     dfs_test.run(s);
@@ -76,11 +83,22 @@
     dfs_test.run();
 
-    l  = dfs_test.dist(t);
-    e  = dfs_test.predArc(t);
-    s  = dfs_test.predNode(t);
-    b  = dfs_test.reached(t);
-    d  = dfs_test.distMap();
-    p  = dfs_test.predMap();
-    pp = dfs_test.path(t);
+    dfs_test.init();
+    dfs_test.addSource(s);
+    e = dfs_test.processNextArc();
+    e = const_dfs_test.nextArc();
+    b = const_dfs_test.emptyQueue();
+    i = const_dfs_test.queueSize();
+
+    dfs_test.start();
+    dfs_test.start(t);
+    dfs_test.start(am);
+
+    l  = const_dfs_test.dist(t);
+    e  = const_dfs_test.predArc(t);
+    s  = const_dfs_test.predNode(t);
+    b  = const_dfs_test.reached(t);
+    d  = const_dfs_test.distMap();
+    p  = const_dfs_test.predMap();
+    pp = const_dfs_test.path(t);
   }
   {
@@ -89,11 +107,33 @@
       ::SetDistMap<concepts::ReadWriteMap<Node,int> >
       ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
+      ::SetStandardProcessedMap
       ::SetProcessedMap<concepts::WriteMap<Node,bool> >
-      ::SetStandardProcessedMap
       ::Create dfs_test(G);
+
+    concepts::ReadWriteMap<Node,Arc> pred_map;
+    concepts::ReadWriteMap<Node,int> dist_map;
+    concepts::ReadWriteMap<Node,bool> reached_map;
+    concepts::WriteMap<Node,bool> processed_map;
+
+    dfs_test
+      .predMap(pred_map)
+      .distMap(dist_map)
+      .reachedMap(reached_map)
+      .processedMap(processed_map);
 
     dfs_test.run(s);
     dfs_test.run(s,t);
     dfs_test.run();
+    dfs_test.init();
+
+    dfs_test.addSource(s);
+    e = dfs_test.processNextArc();
+    e = dfs_test.nextArc();
+    b = dfs_test.emptyQueue();
+    i = dfs_test.queueSize();
+
+    dfs_test.start();
+    dfs_test.start(t);
+    dfs_test.start(am);
 
     l  = dfs_test.dist(t);
@@ -114,4 +154,6 @@
   Digraph g;
   bool b;
+  ::lemon::ignore_unused_variable_warning(b);
+
   dfs(g).run(Node());
   b=dfs(g).run(Node(),Node());
@@ -145,4 +187,5 @@
   Digraph G;
   Node s, t;
+  Node s1, t1;
 
   std::istringstream input(test_lgf);
@@ -150,4 +193,6 @@
     node("source", s).
     node("target", t).
+    node("source1", s1).
+    node("target1", t1).
     run();
 
@@ -176,4 +221,9 @@
 
   {
+  Dfs<Digraph> dfs(G);
+  check(dfs.run(s1,t1) && dfs.reached(t1),"Node 3 is reachable from Node 6.");
+  }
+
+  {
     NullMap<Node,Arc> myPredMap;
     dfs(G).predMap(myPredMap).run(s);
Index: test/digraph_test.cc
===================================================================
--- test/digraph_test.cc	(revision 440)
+++ test/digraph_test.cc	(revision 984)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -20,4 +20,5 @@
 #include <lemon/list_graph.h>
 #include <lemon/smart_graph.h>
+#include <lemon/static_graph.h>
 #include <lemon/full_graph.h>
 
@@ -35,4 +36,7 @@
   checkGraphNodeList(G, 0);
   checkGraphArcList(G, 0);
+
+  G.reserveNode(3);
+  G.reserveArc(4);
 
   Node
@@ -61,4 +65,5 @@
       a3 = G.addArc(n2, n3),
       a4 = G.addArc(n2, n3);
+  ::lemon::ignore_unused_variable_warning(a2,a3,a4);
 
   checkGraphNodeList(G, 3);
@@ -89,4 +94,5 @@
   Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
       a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
+  ::lemon::ignore_unused_variable_warning(a1,a2,a3,a4);
 
   Node n4 = G.split(n2);
@@ -122,4 +128,5 @@
       a3 = G.addArc(n4, n3), a4 = G.addArc(n4, n3),
       a5 = G.addArc(n2, n4);
+  ::lemon::ignore_unused_variable_warning(a1,a2,a3,a5);
 
   checkGraphNodeList(G, 4);
@@ -201,4 +208,5 @@
       a3 = G.addArc(n4, n3), a4 = G.addArc(n3, n1),
       a5 = G.addArc(n2, n4);
+  ::lemon::ignore_unused_variable_warning(a2,a3,a4,a5);
 
   // Check arc deletion
@@ -248,4 +256,5 @@
   Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
       a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
+  ::lemon::ignore_unused_variable_warning(a1,a2,a3,a4);
 
   typename Digraph::Snapshot snapshot(G);
@@ -280,4 +289,12 @@
   G.addNode();
   snapshot.save(G);
+
+  G.addArc(G.addNode(), G.addNode());
+
+  snapshot.restore();
+  snapshot.save(G);
+
+  checkGraphNodeList(G, 4);
+  checkGraphArcList(G, 4);
 
   G.addArc(G.addNode(), G.addNode());
@@ -318,4 +335,8 @@
     checkConcept<ClearableDigraphComponent<>, SmartDigraph>();
   }
+  { // Checking StaticDigraph
+    checkConcept<Digraph, StaticDigraph>();
+    checkConcept<ClearableDigraphComponent<>, StaticDigraph>();
+  }
   { // Checking FullDigraph
     checkConcept<Digraph, FullDigraph>();
@@ -336,4 +357,5 @@
     e1 = g.addArc(n1, n2),
     e2 = g.addArc(n2, n3);
+  ::lemon::ignore_unused_variable_warning(e2);
 
   check(g.valid(n1), "Wrong validity check");
@@ -373,8 +395,121 @@
 }
 
+void checkStaticDigraph() {
+  SmartDigraph g;
+  SmartDigraph::NodeMap<StaticDigraph::Node> nref(g);
+  SmartDigraph::ArcMap<StaticDigraph::Arc> aref(g);
+
+  StaticDigraph G;
+
+  checkGraphNodeList(G, 0);
+  checkGraphArcList(G, 0);
+
+  G.build(g, nref, aref);
+
+  checkGraphNodeList(G, 0);
+  checkGraphArcList(G, 0);
+
+  SmartDigraph::Node
+    n1 = g.addNode(),
+    n2 = g.addNode(),
+    n3 = g.addNode();
+
+  G.build(g, nref, aref);
+
+  checkGraphNodeList(G, 3);
+  checkGraphArcList(G, 0);
+
+  SmartDigraph::Arc a1 = g.addArc(n1, n2);
+
+  G.build(g, nref, aref);
+
+  check(G.source(aref[a1]) == nref[n1] && G.target(aref[a1]) == nref[n2],
+        "Wrong arc or wrong references");
+  checkGraphNodeList(G, 3);
+  checkGraphArcList(G, 1);
+
+  checkGraphOutArcList(G, nref[n1], 1);
+  checkGraphOutArcList(G, nref[n2], 0);
+  checkGraphOutArcList(G, nref[n3], 0);
+
+  checkGraphInArcList(G, nref[n1], 0);
+  checkGraphInArcList(G, nref[n2], 1);
+  checkGraphInArcList(G, nref[n3], 0);
+
+  checkGraphConArcList(G, 1);
+
+  SmartDigraph::Arc
+    a2 = g.addArc(n2, n1),
+    a3 = g.addArc(n2, n3),
+    a4 = g.addArc(n2, n3);
+  ::lemon::ignore_unused_variable_warning(a2,a3,a4);
+
+  digraphCopy(g, G).nodeRef(nref).run();
+
+  checkGraphNodeList(G, 3);
+  checkGraphArcList(G, 4);
+
+  checkGraphOutArcList(G, nref[n1], 1);
+  checkGraphOutArcList(G, nref[n2], 3);
+  checkGraphOutArcList(G, nref[n3], 0);
+
+  checkGraphInArcList(G, nref[n1], 1);
+  checkGraphInArcList(G, nref[n2], 1);
+  checkGraphInArcList(G, nref[n3], 2);
+
+  checkGraphConArcList(G, 4);
+
+  std::vector<std::pair<int,int> > arcs;
+  arcs.push_back(std::make_pair(0,1));
+  arcs.push_back(std::make_pair(0,2));
+  arcs.push_back(std::make_pair(1,3));
+  arcs.push_back(std::make_pair(1,2));
+  arcs.push_back(std::make_pair(3,0));
+  arcs.push_back(std::make_pair(3,3));
+  arcs.push_back(std::make_pair(4,2));
+  arcs.push_back(std::make_pair(4,3));
+  arcs.push_back(std::make_pair(4,1));
+
+  G.build(6, arcs.begin(), arcs.end());
+
+  checkGraphNodeList(G, 6);
+  checkGraphArcList(G, 9);
+
+  checkGraphOutArcList(G, G.node(0), 2);
+  checkGraphOutArcList(G, G.node(1), 2);
+  checkGraphOutArcList(G, G.node(2), 0);
+  checkGraphOutArcList(G, G.node(3), 2);
+  checkGraphOutArcList(G, G.node(4), 3);
+  checkGraphOutArcList(G, G.node(5), 0);
+
+  checkGraphInArcList(G, G.node(0), 1);
+  checkGraphInArcList(G, G.node(1), 2);
+  checkGraphInArcList(G, G.node(2), 3);
+  checkGraphInArcList(G, G.node(3), 3);
+  checkGraphInArcList(G, G.node(4), 0);
+  checkGraphInArcList(G, G.node(5), 0);
+
+  checkGraphConArcList(G, 9);
+
+  checkNodeIds(G);
+  checkArcIds(G);
+  checkGraphNodeMap(G);
+  checkGraphArcMap(G);
+
+  int n = G.nodeNum();
+  int m = G.arcNum();
+  check(G.index(G.node(n-1)) == n-1, "Wrong index.");
+  check(G.index(G.arc(m-1)) == m-1, "Wrong index.");
+}
+
 void checkFullDigraph(int num) {
   typedef FullDigraph Digraph;
   DIGRAPH_TYPEDEFS(Digraph);
+
   Digraph G(num);
+  check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
+
+  G.resize(num);
+  check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
 
   checkGraphNodeList(G, num);
@@ -420,4 +555,7 @@
     checkDigraphValidity<SmartDigraph>();
   }
+  { // Checking StaticDigraph
+    checkStaticDigraph();
+  }
   { // Checking FullDigraph
     checkFullDigraph(8);
Index: test/dijkstra_test.cc
===================================================================
--- test/dijkstra_test.cc	(revision 440)
+++ test/dijkstra_test.cc	(revision 983)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -61,18 +61,86 @@
 
   Digraph G;
-  Node s, t;
+  Node s, t, n;
   Arc e;
   VType l;
+  int i;
   bool b;
+  ::lemon::ignore_unused_variable_warning(l,i,b);
+
   DType::DistMap d(G);
   DType::PredMap p(G);
   LengthMap length;
   Path<Digraph> pp;
+  concepts::ReadMap<Node,bool> nm;
 
   {
     DType dijkstra_test(G,length);
+    const DType& const_dijkstra_test = dijkstra_test;
 
     dijkstra_test.run(s);
     dijkstra_test.run(s,t);
+
+    dijkstra_test.init();
+    dijkstra_test.addSource(s);
+    dijkstra_test.addSource(s, 1);
+    n = dijkstra_test.processNextNode();
+    n = const_dijkstra_test.nextNode();
+    b = const_dijkstra_test.emptyQueue();
+    i = const_dijkstra_test.queueSize();
+
+    dijkstra_test.start();
+    dijkstra_test.start(t);
+    dijkstra_test.start(nm);
+
+    l  = const_dijkstra_test.dist(t);
+    e  = const_dijkstra_test.predArc(t);
+    s  = const_dijkstra_test.predNode(t);
+    b  = const_dijkstra_test.reached(t);
+    b  = const_dijkstra_test.processed(t);
+    d  = const_dijkstra_test.distMap();
+    p  = const_dijkstra_test.predMap();
+    pp = const_dijkstra_test.path(t);
+    l  = const_dijkstra_test.currentDist(t);
+  }
+  {
+    DType
+      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
+      ::SetDistMap<concepts::ReadWriteMap<Node,VType> >
+      ::SetStandardProcessedMap
+      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
+      ::SetOperationTraits<DijkstraDefaultOperationTraits<VType> >
+      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
+      ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
+      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> >,
+                concepts::ReadWriteMap<Node,int> >
+      ::Create dijkstra_test(G,length);
+
+    LengthMap length_map;
+    concepts::ReadWriteMap<Node,Arc> pred_map;
+    concepts::ReadWriteMap<Node,VType> dist_map;
+    concepts::WriteMap<Node,bool> processed_map;
+    concepts::ReadWriteMap<Node,int> heap_cross_ref;
+    BinHeap<VType, concepts::ReadWriteMap<Node,int> > heap(heap_cross_ref);
+
+    dijkstra_test
+      .lengthMap(length_map)
+      .predMap(pred_map)
+      .distMap(dist_map)
+      .processedMap(processed_map)
+      .heap(heap, heap_cross_ref);
+
+    dijkstra_test.run(s);
+    dijkstra_test.run(s,t);
+
+    dijkstra_test.addSource(s);
+    dijkstra_test.addSource(s, 1);
+    n = dijkstra_test.processNextNode();
+    n = dijkstra_test.nextNode();
+    b = dijkstra_test.emptyQueue();
+    i = dijkstra_test.queueSize();
+
+    dijkstra_test.start();
+    dijkstra_test.start(t);
+    dijkstra_test.start(nm);
 
     l  = dijkstra_test.dist(t);
@@ -80,27 +148,7 @@
     s  = dijkstra_test.predNode(t);
     b  = dijkstra_test.reached(t);
-    d  = dijkstra_test.distMap();
-    p  = dijkstra_test.predMap();
+    b  = dijkstra_test.processed(t);
     pp = dijkstra_test.path(t);
-  }
-  {
-    DType
-      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
-      ::SetDistMap<concepts::ReadWriteMap<Node,VType> >
-      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
-      ::SetStandardProcessedMap
-      ::SetOperationTraits<DijkstraDefaultOperationTraits<VType> >
-      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
-      ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
-      ::Create dijkstra_test(G,length);
-
-    dijkstra_test.run(s);
-    dijkstra_test.run(s,t);
-
-    l  = dijkstra_test.dist(t);
-    e  = dijkstra_test.predArc(t);
-    s  = dijkstra_test.predNode(t);
-    b  = dijkstra_test.reached(t);
-    pp = dijkstra_test.path(t);
+    l  = dijkstra_test.currentDist(t);
   }
 
@@ -117,4 +165,6 @@
   Digraph g;
   bool b;
+  ::lemon::ignore_unused_variable_warning(b);
+
   dijkstra(g,LengthMap()).run(Node());
   b=dijkstra(g,LengthMap()).run(Node(),Node());
Index: test/edge_set_test.cc
===================================================================
--- test/edge_set_test.cc	(revision 512)
+++ test/edge_set_test.cc	(revision 983)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -45,8 +45,10 @@
 
   Digraph::Arc ga1 = digraph.addArc(n1, n2);
+  ::lemon::ignore_unused_variable_warning(ga1);
 
   ArcSet arc_set(digraph);
 
   Digraph::Arc ga2 = digraph.addArc(n2, n1);
+  ::lemon::ignore_unused_variable_warning(ga2);
 
   checkGraphNodeList(arc_set, 2);
@@ -76,4 +78,6 @@
     a3 = arc_set.addArc(n2, n3),
     a4 = arc_set.addArc(n2, n3);
+  ::lemon::ignore_unused_variable_warning(a2,a3,a4);
+
   checkGraphNodeList(arc_set, 3);
   checkGraphArcList(arc_set, 4);
@@ -111,8 +115,10 @@
 
   Digraph::Arc ga1 = digraph.addArc(n1, n2);
+  ::lemon::ignore_unused_variable_warning(ga1);
 
   ArcSet arc_set(digraph);
 
   Digraph::Arc ga2 = digraph.addArc(n2, n1);
+  ::lemon::ignore_unused_variable_warning(ga2);
 
   checkGraphNodeList(arc_set, 2);
@@ -142,4 +148,6 @@
     a3 = arc_set.addArc(n2, n3),
     a4 = arc_set.addArc(n2, n3);
+  ::lemon::ignore_unused_variable_warning(a2,a3,a4);
+
   checkGraphNodeList(arc_set, 3);
   checkGraphArcList(arc_set, 4);
@@ -191,8 +199,10 @@
 
   Digraph::Arc ga1 = digraph.addArc(n1, n2);
+  ::lemon::ignore_unused_variable_warning(ga1);
 
   EdgeSet edge_set(digraph);
 
   Digraph::Arc ga2 = digraph.addArc(n2, n1);
+  ::lemon::ignore_unused_variable_warning(ga2);
 
   checkGraphNodeList(edge_set, 2);
@@ -231,4 +241,6 @@
     e3 = edge_set.addEdge(n2, n3),
     e4 = edge_set.addEdge(n2, n3);
+  ::lemon::ignore_unused_variable_warning(e2,e3,e4);
+
   checkGraphNodeList(edge_set, 3);
   checkGraphEdgeList(edge_set, 4);
@@ -275,8 +287,10 @@
 
   Digraph::Arc ga1 = digraph.addArc(n1, n2);
+  ::lemon::ignore_unused_variable_warning(ga1);
 
   EdgeSet edge_set(digraph);
 
   Digraph::Arc ga2 = digraph.addArc(n2, n1);
+  ::lemon::ignore_unused_variable_warning(ga2);
 
   checkGraphNodeList(edge_set, 2);
@@ -315,4 +329,6 @@
     e3 = edge_set.addEdge(n2, n3),
     e4 = edge_set.addEdge(n2, n3);
+  ::lemon::ignore_unused_variable_warning(e2,e3,e4);
+
   checkGraphNodeList(edge_set, 3);
   checkGraphEdgeList(edge_set, 4);
Index: test/euler_test.cc
===================================================================
--- test/euler_test.cc	(revision 531)
+++ test/euler_test.cc	(revision 983)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -19,61 +19,64 @@
 #include <lemon/euler.h>
 #include <lemon/list_graph.h>
-#include <test/test_tools.h>
+#include <lemon/adaptors.h>
+#include "test_tools.h"
 
 using namespace lemon;
 
 template <typename Digraph>
-void checkDiEulerIt(const Digraph& g)
+void checkDiEulerIt(const Digraph& g,
+                    const typename Digraph::Node& start = INVALID)
 {
   typename Digraph::template ArcMap<int> visitationNumber(g, 0);
 
-  DiEulerIt<Digraph> e(g);
+  DiEulerIt<Digraph> e(g, start);
+  if (e == INVALID) return;
   typename Digraph::Node firstNode = g.source(e);
   typename Digraph::Node lastNode = g.target(e);
-
-  for (; e != INVALID; ++e)
-  {
-    if (e != INVALID)
-    {
-      lastNode = g.target(e);
-    }
+  if (start != INVALID) {
+    check(firstNode == start, "checkDiEulerIt: Wrong first node");
+  }
+
+  for (; e != INVALID; ++e) {
+    if (e != INVALID) lastNode = g.target(e);
     ++visitationNumber[e];
   }
 
   check(firstNode == lastNode,
-      "checkDiEulerIt: first and last node are not the same");
+      "checkDiEulerIt: First and last nodes are not the same");
 
   for (typename Digraph::ArcIt a(g); a != INVALID; ++a)
   {
     check(visitationNumber[a] == 1,
-        "checkDiEulerIt: not visited or multiple times visited arc found");
+        "checkDiEulerIt: Not visited or multiple times visited arc found");
   }
 }
 
 template <typename Graph>
-void checkEulerIt(const Graph& g)
+void checkEulerIt(const Graph& g,
+                  const typename Graph::Node& start = INVALID)
 {
   typename Graph::template EdgeMap<int> visitationNumber(g, 0);
 
-  EulerIt<Graph> e(g);
-  typename Graph::Node firstNode = g.u(e);
-  typename Graph::Node lastNode = g.v(e);
-
-  for (; e != INVALID; ++e)
-  {
-    if (e != INVALID)
-    {
-      lastNode = g.v(e);
-    }
+  EulerIt<Graph> e(g, start);
+  if (e == INVALID) return;
+  typename Graph::Node firstNode = g.source(typename Graph::Arc(e));
+  typename Graph::Node lastNode = g.target(typename Graph::Arc(e));
+  if (start != INVALID) {
+    check(firstNode == start, "checkEulerIt: Wrong first node");
+  }
+
+  for (; e != INVALID; ++e) {
+    if (e != INVALID) lastNode = g.target(typename Graph::Arc(e));
     ++visitationNumber[e];
   }
 
   check(firstNode == lastNode,
-      "checkEulerIt: first and last node are not the same");
+      "checkEulerIt: First and last nodes are not the same");
 
   for (typename Graph::EdgeIt e(g); e != INVALID; ++e)
   {
     check(visitationNumber[e] == 1,
-        "checkEulerIt: not visited or multiple times visited edge found");
+        "checkEulerIt: Not visited or multiple times visited edge found");
   }
 }
@@ -82,71 +85,140 @@
 {
   typedef ListDigraph Digraph;
-  typedef ListGraph Graph;
-
-  Digraph digraphWithEulerianCircuit;
-  {
-    Digraph& g = digraphWithEulerianCircuit;
-
-    Digraph::Node n0 = g.addNode();
-    Digraph::Node n1 = g.addNode();
-    Digraph::Node n2 = g.addNode();
-
-    g.addArc(n0, n1);
-    g.addArc(n1, n0);
-    g.addArc(n1, n2);
-    g.addArc(n2, n1);
-  }
-
-  Digraph digraphWithoutEulerianCircuit;
-  {
-    Digraph& g = digraphWithoutEulerianCircuit;
-
-    Digraph::Node n0 = g.addNode();
-    Digraph::Node n1 = g.addNode();
-    Digraph::Node n2 = g.addNode();
-
-    g.addArc(n0, n1);
-    g.addArc(n1, n0);
-    g.addArc(n1, n2);
-  }
-
-  Graph graphWithEulerianCircuit;
-  {
-    Graph& g = graphWithEulerianCircuit;
-
-    Graph::Node n0 = g.addNode();
-    Graph::Node n1 = g.addNode();
-    Graph::Node n2 = g.addNode();
-
-    g.addEdge(n0, n1);
-    g.addEdge(n1, n2);
-    g.addEdge(n2, n0);
-  }
-
-  Graph graphWithoutEulerianCircuit;
-  {
-    Graph& g = graphWithoutEulerianCircuit;
-
-    Graph::Node n0 = g.addNode();
-    Graph::Node n1 = g.addNode();
-    Graph::Node n2 = g.addNode();
-
-    g.addEdge(n0, n1);
-    g.addEdge(n1, n2);
-  }
-
-  checkDiEulerIt(digraphWithEulerianCircuit);
-
-  checkEulerIt(graphWithEulerianCircuit);
-
-  check(eulerian(digraphWithEulerianCircuit),
-      "this graph should have an Eulerian circuit");
-  check(!eulerian(digraphWithoutEulerianCircuit),
-      "this graph should not have an Eulerian circuit");
-
-  check(eulerian(graphWithEulerianCircuit),
-      "this graph should have an Eulerian circuit");
-  check(!eulerian(graphWithoutEulerianCircuit),
-      "this graph should have an Eulerian circuit");
+  typedef Undirector<Digraph> Graph;
+
+  {
+    Digraph d;
+    Graph g(d);
+
+    checkDiEulerIt(d);
+    checkDiEulerIt(g);
+    checkEulerIt(g);
+
+    check(eulerian(d), "This graph is Eulerian");
+    check(eulerian(g), "This graph is Eulerian");
+  }
+  {
+    Digraph d;
+    Graph g(d);
+    Digraph::Node n = d.addNode();
+    ::lemon::ignore_unused_variable_warning(n);
+  
+    checkDiEulerIt(d);
+    checkDiEulerIt(g);
+    checkEulerIt(g);
+
+    check(eulerian(d), "This graph is Eulerian");
+    check(eulerian(g), "This graph is Eulerian");
+  }
+  {
+    Digraph d;
+    Graph g(d);
+    Digraph::Node n = d.addNode();
+    d.addArc(n, n);
+
+    checkDiEulerIt(d);
+    checkDiEulerIt(g);
+    checkEulerIt(g);
+
+    check(eulerian(d), "This graph is Eulerian");
+    check(eulerian(g), "This graph is Eulerian");
+  }
+  {
+    Digraph d;
+    Graph g(d);
+    Digraph::Node n1 = d.addNode();
+    Digraph::Node n2 = d.addNode();
+    Digraph::Node n3 = d.addNode();
+
+    d.addArc(n1, n2);
+    d.addArc(n2, n1);
+    d.addArc(n2, n3);
+    d.addArc(n3, n2);
+
+    checkDiEulerIt(d);
+    checkDiEulerIt(d, n2);
+    checkDiEulerIt(g);
+    checkDiEulerIt(g, n2);
+    checkEulerIt(g);
+    checkEulerIt(g, n2);
+
+    check(eulerian(d), "This graph is Eulerian");
+    check(eulerian(g), "This graph is Eulerian");
+  }
+  {
+    Digraph d;
+    Graph g(d);
+    Digraph::Node n1 = d.addNode();
+    Digraph::Node n2 = d.addNode();
+    Digraph::Node n3 = d.addNode();
+    Digraph::Node n4 = d.addNode();
+    Digraph::Node n5 = d.addNode();
+    Digraph::Node n6 = d.addNode();
+
+    d.addArc(n1, n2);
+    d.addArc(n2, n4);
+    d.addArc(n1, n3);
+    d.addArc(n3, n4);
+    d.addArc(n4, n1);
+    d.addArc(n3, n5);
+    d.addArc(n5, n2);
+    d.addArc(n4, n6);
+    d.addArc(n2, n6);
+    d.addArc(n6, n1);
+    d.addArc(n6, n3);
+
+    checkDiEulerIt(d);
+    checkDiEulerIt(d, n1);
+    checkDiEulerIt(d, n5);
+
+    checkDiEulerIt(g);
+    checkDiEulerIt(g, n1);
+    checkDiEulerIt(g, n5);
+    checkEulerIt(g);
+    checkEulerIt(g, n1);
+    checkEulerIt(g, n5);
+
+    check(eulerian(d), "This graph is Eulerian");
+    check(eulerian(g), "This graph is Eulerian");
+  }
+  {
+    Digraph d;
+    Graph g(d);
+    Digraph::Node n0 = d.addNode();
+    Digraph::Node n1 = d.addNode();
+    Digraph::Node n2 = d.addNode();
+    Digraph::Node n3 = d.addNode();
+    Digraph::Node n4 = d.addNode();
+    Digraph::Node n5 = d.addNode();
+    ::lemon::ignore_unused_variable_warning(n0,n4,n5);
+
+    d.addArc(n1, n2);
+    d.addArc(n2, n3);
+    d.addArc(n3, n1);
+
+    checkDiEulerIt(d);
+    checkDiEulerIt(d, n2);
+
+    checkDiEulerIt(g);
+    checkDiEulerIt(g, n2);
+    checkEulerIt(g);
+    checkEulerIt(g, n2);
+
+    check(!eulerian(d), "This graph is not Eulerian");
+    check(!eulerian(g), "This graph is not Eulerian");
+  }
+  {
+    Digraph d;
+    Graph g(d);
+    Digraph::Node n1 = d.addNode();
+    Digraph::Node n2 = d.addNode();
+    Digraph::Node n3 = d.addNode();
+
+    d.addArc(n1, n2);
+    d.addArc(n2, n3);
+
+    check(!eulerian(d), "This graph is not Eulerian");
+    check(!eulerian(g), "This graph is not Eulerian");
+  }
 
   return 0;
Index: test/fractional_matching_test.cc
===================================================================
--- test/fractional_matching_test.cc	(revision 984)
+++ test/fractional_matching_test.cc	(revision 984)
@@ -0,0 +1,527 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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 <cstdlib>
+
+#include <lemon/fractional_matching.h>
+#include <lemon/smart_graph.h>
+#include <lemon/concepts/graph.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/math.h>
+
+#include "test_tools.h"
+
+using namespace std;
+using namespace lemon;
+
+GRAPH_TYPEDEFS(SmartGraph);
+
+
+const int lgfn = 4;
+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",
+
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "@edges\n"
+  "     label  weight\n"
+  "0 0  0      100\n"
+};
+
+void checkMaxFractionalMatchingCompile()
+{
+  typedef concepts::Graph Graph;
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+
+  Graph g;
+  Node n;
+  Edge e;
+
+  MaxFractionalMatching<Graph> mat_test(g);
+  const MaxFractionalMatching<Graph>&
+    const_mat_test = mat_test;
+
+  mat_test.init();
+  mat_test.start();
+  mat_test.start(true);
+  mat_test.startPerfect();
+  mat_test.startPerfect(true);
+  mat_test.run();
+  mat_test.run(true);
+  mat_test.runPerfect();
+  mat_test.runPerfect(true);
+
+  const_mat_test.matchingSize();
+  const_mat_test.matching(e);
+  const_mat_test.matching(n);
+  const MaxFractionalMatching<Graph>::MatchingMap& mmap =
+    const_mat_test.matchingMap();
+  e = mmap[n];
+
+  const_mat_test.barrier(n);
+}
+
+void checkMaxWeightedFractionalMatchingCompile()
+{
+  typedef concepts::Graph Graph;
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+  typedef Graph::EdgeMap<int> WeightMap;
+
+  Graph g;
+  Node n;
+  Edge e;
+  WeightMap w(g);
+
+  MaxWeightedFractionalMatching<Graph> mat_test(g, w);
+  const MaxWeightedFractionalMatching<Graph>&
+    const_mat_test = mat_test;
+
+  mat_test.init();
+  mat_test.start();
+  mat_test.run();
+
+  const_mat_test.matchingWeight();
+  const_mat_test.matchingSize();
+  const_mat_test.matching(e);
+  const_mat_test.matching(n);
+  const MaxWeightedFractionalMatching<Graph>::MatchingMap& mmap =
+    const_mat_test.matchingMap();
+  e = mmap[n];
+
+  const_mat_test.dualValue();
+  const_mat_test.nodeValue(n);
+}
+
+void checkMaxWeightedPerfectFractionalMatchingCompile()
+{
+  typedef concepts::Graph Graph;
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+  typedef Graph::EdgeMap<int> WeightMap;
+
+  Graph g;
+  Node n;
+  Edge e;
+  WeightMap w(g);
+
+  MaxWeightedPerfectFractionalMatching<Graph> mat_test(g, w);
+  const MaxWeightedPerfectFractionalMatching<Graph>&
+    const_mat_test = mat_test;
+
+  mat_test.init();
+  mat_test.start();
+  mat_test.run();
+
+  const_mat_test.matchingWeight();
+  const_mat_test.matching(e);
+  const_mat_test.matching(n);
+  const MaxWeightedPerfectFractionalMatching<Graph>::MatchingMap& mmap =
+    const_mat_test.matchingMap();
+  e = mmap[n];
+
+  const_mat_test.dualValue();
+  const_mat_test.nodeValue(n);
+}
+
+void checkFractionalMatching(const SmartGraph& graph,
+                             const MaxFractionalMatching<SmartGraph>& mfm,
+                             bool allow_loops = true) {
+  int pv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    int indeg = 0;
+    for (InArcIt a(graph, n); a != INVALID; ++a) {
+      if (mfm.matching(graph.source(a)) == a) {
+        ++indeg;
+      }
+    }
+    if (mfm.matching(n) != INVALID) {
+      check(indeg == 1, "Invalid matching");
+      ++pv;
+    } else {
+      check(indeg == 0, "Invalid matching");
+    }
+  }
+  check(pv == mfm.matchingSize(), "Wrong matching size");
+
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    check((e == mfm.matching(graph.u(e)) ? 1 : 0) +
+          (e == mfm.matching(graph.v(e)) ? 1 : 0) ==
+          mfm.matching(e), "Invalid matching");
+  }
+
+  SmartGraph::NodeMap<bool> processed(graph, false);
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    if (processed[n]) continue;
+    processed[n] = true;
+    if (mfm.matching(n) == INVALID) continue;
+    int num = 1;
+    Node v = graph.target(mfm.matching(n));
+    while (v != n) {
+      processed[v] = true;
+      ++num;
+      v = graph.target(mfm.matching(v));
+    }
+    check(num == 2 || num % 2 == 1, "Wrong cycle size");
+    check(allow_loops || num != 1, "Wrong cycle size");
+  }
+
+  int anum = 0, bnum = 0;
+  SmartGraph::NodeMap<bool> neighbours(graph, false);
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    if (!mfm.barrier(n)) continue;
+    ++anum;
+    for (SmartGraph::InArcIt a(graph, n); a != INVALID; ++a) {
+      Node u = graph.source(a);
+      if (!allow_loops && u == n) continue;
+      if (!neighbours[u]) {
+        neighbours[u] = true;
+        ++bnum;
+      }
+    }
+  }
+  check(anum - bnum + mfm.matchingSize() == countNodes(graph),
+        "Wrong barrier");
+}
+
+void checkPerfectFractionalMatching(const SmartGraph& graph,
+                             const MaxFractionalMatching<SmartGraph>& mfm,
+                             bool perfect, bool allow_loops = true) {
+  if (perfect) {
+    for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+      int indeg = 0;
+      for (InArcIt a(graph, n); a != INVALID; ++a) {
+        if (mfm.matching(graph.source(a)) == a) {
+          ++indeg;
+        }
+      }
+      check(mfm.matching(n) != INVALID, "Invalid matching");
+      check(indeg == 1, "Invalid matching");
+    }
+    for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+      check((e == mfm.matching(graph.u(e)) ? 1 : 0) +
+            (e == mfm.matching(graph.v(e)) ? 1 : 0) ==
+            mfm.matching(e), "Invalid matching");
+    }
+  } else {
+    int anum = 0, bnum = 0;
+    SmartGraph::NodeMap<bool> neighbours(graph, false);
+    for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+      if (!mfm.barrier(n)) continue;
+      ++anum;
+      for (SmartGraph::InArcIt a(graph, n); a != INVALID; ++a) {
+        Node u = graph.source(a);
+        if (!allow_loops && u == n) continue;
+        if (!neighbours[u]) {
+          neighbours[u] = true;
+          ++bnum;
+        }
+      }
+    }
+    check(anum - bnum > 0, "Wrong barrier");
+  }
+}
+
+void checkWeightedFractionalMatching(const SmartGraph& graph,
+                   const SmartGraph::EdgeMap<int>& weight,
+                   const MaxWeightedFractionalMatching<SmartGraph>& mwfm,
+                   bool allow_loops = true) {
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    if (graph.u(e) == graph.v(e) && !allow_loops) continue;
+    int rw = mwfm.nodeValue(graph.u(e)) + mwfm.nodeValue(graph.v(e))
+      - weight[e] * mwfm.dualScale;
+
+    check(rw >= 0, "Negative reduced weight");
+    check(rw == 0 || !mwfm.matching(e),
+          "Non-zero reduced weight on matching edge");
+  }
+
+  int pv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    int indeg = 0;
+    for (InArcIt a(graph, n); a != INVALID; ++a) {
+      if (mwfm.matching(graph.source(a)) == a) {
+        ++indeg;
+      }
+    }
+    check(indeg <= 1, "Invalid matching");
+    if (mwfm.matching(n) != INVALID) {
+      check(mwfm.nodeValue(n) >= 0, "Invalid node value");
+      check(indeg == 1, "Invalid matching");
+      pv += weight[mwfm.matching(n)];
+      SmartGraph::Node o = graph.target(mwfm.matching(n));
+      ::lemon::ignore_unused_variable_warning(o);
+    } else {
+      check(mwfm.nodeValue(n) == 0, "Invalid matching");
+      check(indeg == 0, "Invalid matching");
+    }
+  }
+
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    check((e == mwfm.matching(graph.u(e)) ? 1 : 0) +
+          (e == mwfm.matching(graph.v(e)) ? 1 : 0) ==
+          mwfm.matching(e), "Invalid matching");
+  }
+
+  int dv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    dv += mwfm.nodeValue(n);
+  }
+
+  check(pv * mwfm.dualScale == dv * 2, "Wrong duality");
+
+  SmartGraph::NodeMap<bool> processed(graph, false);
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    if (processed[n]) continue;
+    processed[n] = true;
+    if (mwfm.matching(n) == INVALID) continue;
+    int num = 1;
+    Node v = graph.target(mwfm.matching(n));
+    while (v != n) {
+      processed[v] = true;
+      ++num;
+      v = graph.target(mwfm.matching(v));
+    }
+    check(num == 2 || num % 2 == 1, "Wrong cycle size");
+    check(allow_loops || num != 1, "Wrong cycle size");
+  }
+
+  return;
+}
+
+void checkWeightedPerfectFractionalMatching(const SmartGraph& graph,
+                const SmartGraph::EdgeMap<int>& weight,
+                const MaxWeightedPerfectFractionalMatching<SmartGraph>& mwpfm,
+                bool allow_loops = true) {
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    if (graph.u(e) == graph.v(e) && !allow_loops) continue;
+    int rw = mwpfm.nodeValue(graph.u(e)) + mwpfm.nodeValue(graph.v(e))
+      - weight[e] * mwpfm.dualScale;
+
+    check(rw >= 0, "Negative reduced weight");
+    check(rw == 0 || !mwpfm.matching(e),
+          "Non-zero reduced weight on matching edge");
+  }
+
+  int pv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    int indeg = 0;
+    for (InArcIt a(graph, n); a != INVALID; ++a) {
+      if (mwpfm.matching(graph.source(a)) == a) {
+        ++indeg;
+      }
+    }
+    check(mwpfm.matching(n) != INVALID, "Invalid perfect matching");
+    check(indeg == 1, "Invalid perfect matching");
+    pv += weight[mwpfm.matching(n)];
+    SmartGraph::Node o = graph.target(mwpfm.matching(n));
+    ::lemon::ignore_unused_variable_warning(o);
+  }
+
+  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
+    check((e == mwpfm.matching(graph.u(e)) ? 1 : 0) +
+          (e == mwpfm.matching(graph.v(e)) ? 1 : 0) ==
+          mwpfm.matching(e), "Invalid matching");
+  }
+
+  int dv = 0;
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    dv += mwpfm.nodeValue(n);
+  }
+
+  check(pv * mwpfm.dualScale == dv * 2, "Wrong duality");
+
+  SmartGraph::NodeMap<bool> processed(graph, false);
+  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
+    if (processed[n]) continue;
+    processed[n] = true;
+    if (mwpfm.matching(n) == INVALID) continue;
+    int num = 1;
+    Node v = graph.target(mwpfm.matching(n));
+    while (v != n) {
+      processed[v] = true;
+      ++num;
+      v = graph.target(mwpfm.matching(v));
+    }
+    check(num == 2 || num % 2 == 1, "Wrong cycle size");
+    check(allow_loops || num != 1, "Wrong cycle size");
+  }
+
+  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();
+
+    bool perfect_with_loops;
+    {
+      MaxFractionalMatching<SmartGraph> mfm(graph, true);
+      mfm.run();
+      checkFractionalMatching(graph, mfm, true);
+      perfect_with_loops = mfm.matchingSize() == countNodes(graph);
+    }
+
+    bool perfect_without_loops;
+    {
+      MaxFractionalMatching<SmartGraph> mfm(graph, false);
+      mfm.run();
+      checkFractionalMatching(graph, mfm, false);
+      perfect_without_loops = mfm.matchingSize() == countNodes(graph);
+    }
+
+    {
+      MaxFractionalMatching<SmartGraph> mfm(graph, true);
+      bool result = mfm.runPerfect();
+      checkPerfectFractionalMatching(graph, mfm, result, true);
+      check(result == perfect_with_loops, "Wrong perfect matching");
+    }
+
+    {
+      MaxFractionalMatching<SmartGraph> mfm(graph, false);
+      bool result = mfm.runPerfect();
+      checkPerfectFractionalMatching(graph, mfm, result, false);
+      check(result == perfect_without_loops, "Wrong perfect matching");
+    }
+
+    {
+      MaxWeightedFractionalMatching<SmartGraph> mwfm(graph, weight, true);
+      mwfm.run();
+      checkWeightedFractionalMatching(graph, weight, mwfm, true);
+    }
+
+    {
+      MaxWeightedFractionalMatching<SmartGraph> mwfm(graph, weight, false);
+      mwfm.run();
+      checkWeightedFractionalMatching(graph, weight, mwfm, false);
+    }
+
+    {
+      MaxWeightedPerfectFractionalMatching<SmartGraph> mwpfm(graph, weight,
+                                                             true);
+      bool perfect = mwpfm.run();
+      check(perfect == (mwpfm.matchingSize() == countNodes(graph)),
+            "Perfect matching found");
+      check(perfect == perfect_with_loops, "Wrong perfect matching");
+
+      if (perfect) {
+        checkWeightedPerfectFractionalMatching(graph, weight, mwpfm, true);
+      }
+    }
+
+    {
+      MaxWeightedPerfectFractionalMatching<SmartGraph> mwpfm(graph, weight,
+                                                             false);
+      bool perfect = mwpfm.run();
+      check(perfect == (mwpfm.matchingSize() == countNodes(graph)),
+            "Perfect matching found");
+      check(perfect == perfect_without_loops, "Wrong perfect matching");
+
+      if (perfect) {
+        checkWeightedPerfectFractionalMatching(graph, weight, mwpfm, false);
+      }
+    }
+
+  }
+
+  return 0;
+}
Index: test/gomory_hu_test.cc
===================================================================
--- test/gomory_hu_test.cc	(revision 546)
+++ test/gomory_hu_test.cc	(revision 983)
@@ -1,6 +1,26 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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/concepts/graph.h>
+#include <lemon/concepts/maps.h>
 #include <lemon/lgf_reader.h>
 #include <lemon/gomory_hu.h>
@@ -32,5 +52,36 @@
   "source 0\n"
   "target 3\n";
-  
+
+void checkGomoryHuCompile()
+{
+  typedef int Value;
+  typedef concepts::Graph Graph;
+
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+  typedef concepts::ReadMap<Edge, Value> CapMap;
+  typedef concepts::ReadWriteMap<Node, bool> CutMap;
+
+  Graph g;
+  Node n;
+  CapMap cap;
+  CutMap cut;
+  Value v;
+  int d;
+  ::lemon::ignore_unused_variable_warning(v,d);
+
+  GomoryHu<Graph, CapMap> gh_test(g, cap);
+  const GomoryHu<Graph, CapMap>&
+    const_gh_test = gh_test;
+
+  gh_test.run();
+
+  n = const_gh_test.predNode(n);
+  v = const_gh_test.predValue(n);
+  d = const_gh_test.rootDist(n);
+  v = const_gh_test.minCutValue(n, n);
+  v = const_gh_test.minCutMap(n, n, cut);
+}
+
 GRAPH_TYPEDEFS(Graph);
 typedef Graph::EdgeMap<int> IntEdgeMap;
@@ -38,5 +89,5 @@
 
 int cutValue(const Graph& graph, const BoolNodeMap& cut,
-	     const IntEdgeMap& capacity) {
+             const IntEdgeMap& capacity) {
 
   int sum = 0;
@@ -71,10 +122,10 @@
       ght.minCutMap(u, v, cm);
       check(pf.flowValue() == ght.minCutValue(u, v), "Wrong cut 1");
-      check(cm[u] != cm[v], "Wrong cut 3");
-      check(pf.flowValue() == cutValue(graph, cm, capacity), "Wrong cut 2");
+      check(cm[u] != cm[v], "Wrong cut 2");
+      check(pf.flowValue() == cutValue(graph, cm, capacity), "Wrong cut 3");
 
       int sum=0;
       for(GomoryHu<Graph>::MinCutEdgeIt a(ght, u, v);a!=INVALID;++a)
-        sum+=capacity[a]; 
+        sum+=capacity[a];
       check(sum == ght.minCutValue(u, v), "Problem with MinCutEdgeIt");
 
@@ -85,8 +136,7 @@
         sum++;
       check(sum == countNodes(graph), "Problem with MinCutNodeIt");
-      
     }
   }
-  
+
   return 0;
 }
Index: test/graph_copy_test.cc
===================================================================
--- test/graph_copy_test.cc	(revision 440)
+++ test/graph_copy_test.cc	(revision 927)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2011
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -30,4 +30,5 @@
   const int nn = 10;
 
+  // Build a digraph
   SmartDigraph from;
   SmartDigraph::NodeMap<int> fnm(from);
@@ -52,4 +53,5 @@
   }
 
+  // Test digraph copy
   ListDigraph to;
   ListDigraph::NodeMap<int> tnm(to);
@@ -70,4 +72,7 @@
     node(fn, tn).arc(fa, ta).run();
 
+  check(countNodes(from) == countNodes(to), "Wrong copy.");
+  check(countArcs(from) == countArcs(to), "Wrong copy.");
+
   for (SmartDigraph::NodeIt it(from); it != INVALID; ++it) {
     check(ncr[nr[it]] == it, "Wrong copy.");
@@ -91,4 +96,10 @@
   check(tn == nr[fn], "Wrong copy.");
   check(ta == er[fa], "Wrong copy.");
+
+  // Test repeated copy
+  digraphCopy(from, to).run();
+
+  check(countNodes(from) == countNodes(to), "Wrong copy.");
+  check(countArcs(from) == countArcs(to), "Wrong copy.");
 }
 
@@ -96,4 +107,5 @@
   const int nn = 10;
 
+  // Build a graph
   SmartGraph from;
   SmartGraph::NodeMap<int> fnm(from);
@@ -123,4 +135,5 @@
   }
 
+  // Test graph copy
   ListGraph to;
   ListGraph::NodeMap<int> tnm(to);
@@ -144,4 +157,8 @@
     nodeCrossRef(ncr).arcCrossRef(acr).edgeCrossRef(ecr).
     node(fn, tn).arc(fa, ta).edge(fe, te).run();
+
+  check(countNodes(from) == countNodes(to), "Wrong copy.");
+  check(countEdges(from) == countEdges(to), "Wrong copy.");
+  check(countArcs(from) == countArcs(to), "Wrong copy.");
 
   for (SmartGraph::NodeIt it(from); it != INVALID; ++it) {
@@ -181,4 +198,11 @@
   check(ta == ar[fa], "Wrong copy.");
   check(te == er[fe], "Wrong copy.");
+
+  // Test repeated copy
+  graphCopy(from, to).run();
+
+  check(countNodes(from) == countNodes(to), "Wrong copy.");
+  check(countEdges(from) == countEdges(to), "Wrong copy.");
+  check(countArcs(from) == countArcs(to), "Wrong copy.");
 }
 
Index: test/graph_test.cc
===================================================================
--- test/graph_test.cc	(revision 440)
+++ test/graph_test.cc	(revision 983)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -39,4 +39,7 @@
   checkGraphArcList(G, 0);
 
+  G.reserveNode(3);
+  G.reserveEdge(3);
+
   Node
     n1 = G.addNode(),
@@ -64,4 +67,5 @@
   Edge e2 = G.addEdge(n2, n1),
        e3 = G.addEdge(n2, n3);
+  ::lemon::ignore_unused_variable_warning(e2,e3);
 
   checkGraphNodeList(G, 3);
@@ -96,4 +100,5 @@
        e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
        e5 = G.addEdge(n4, n3);
+  ::lemon::ignore_unused_variable_warning(e1,e3,e4,e5);
 
   checkGraphNodeList(G, 4);
@@ -175,4 +180,5 @@
        e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
        e5 = G.addEdge(n4, n3);
+  ::lemon::ignore_unused_variable_warning(e1,e3,e4,e5);
 
   // Check edge deletion
@@ -215,4 +221,5 @@
   Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
        e3 = G.addEdge(n2, n3);
+  ::lemon::ignore_unused_variable_warning(e1,e2,e3);
 
   checkGraphNodeList(G, 3);
@@ -257,8 +264,17 @@
 
   snapshot.restore();
+  snapshot.save(G);
 
   checkGraphNodeList(G, 4);
   checkGraphEdgeList(G, 3);
   checkGraphArcList(G, 6);
+
+  G.addEdge(G.addNode(), G.addNode());
+
+  snapshot.restore();
+
+  checkGraphNodeList(G, 4);
+  checkGraphEdgeList(G, 3);
+  checkGraphArcList(G, 6);
 }
 
@@ -268,4 +284,11 @@
 
   Graph G(num);
+  check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
+        "Wrong size");
+
+  G.resize(num);
+  check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
+        "Wrong size");
+
   checkGraphNodeList(G, num);
   checkGraphEdgeList(G, num * (num - 1) / 2);
@@ -363,4 +386,5 @@
     e1 = g.addEdge(n1, n2),
     e2 = g.addEdge(n2, n3);
+  ::lemon::ignore_unused_variable_warning(e2);
 
   check(g.valid(n1), "Wrong validity check");
@@ -409,4 +433,8 @@
   Graph G(width, height);
 
+  check(G.width() == width, "Wrong column number");
+  check(G.height() == height, "Wrong row number");
+
+  G.resize(width, height);
   check(G.width() == width, "Wrong column number");
   check(G.height() == height, "Wrong row number");
@@ -487,4 +515,9 @@
 
   HypercubeGraph G(dim);
+  check(G.dimension() == dim, "Wrong dimension");
+
+  G.resize(dim);
+  check(G.dimension() == dim, "Wrong dimension");
+
   checkGraphNodeList(G, 1 << dim);
   checkGraphEdgeList(G, dim * (1 << (dim-1)));
@@ -492,4 +525,5 @@
 
   Node n = G.nodeFromId(dim);
+  ::lemon::ignore_unused_variable_warning(n);
 
   for (NodeIt n(G); n != INVALID; ++n) {
Index: test/graph_utils_test.cc
===================================================================
--- test/graph_utils_test.cc	(revision 440)
+++ test/graph_utils_test.cc	(revision 572)
@@ -39,6 +39,6 @@
       digraph.addNode();
     }
-    DescriptorMap<Digraph, Node> nodes(digraph);
-    typename DescriptorMap<Digraph, Node>::InverseMap invNodes(nodes);
+    RangeIdMap<Digraph, Node> nodes(digraph);
+    typename RangeIdMap<Digraph, Node>::InverseMap invNodes(nodes);
     for (int i = 0; i < 100; ++i) {
       int src = rnd[invNodes.size()];
@@ -47,5 +47,5 @@
     }
     typename Digraph::template ArcMap<bool> found(digraph, false);
-    DescriptorMap<Digraph, Arc> arcs(digraph);
+    RangeIdMap<Digraph, Arc> arcs(digraph);
     for (NodeIt src(digraph); src != INVALID; ++src) {
       for (NodeIt trg(digraph); trg != INVALID; ++trg) {
@@ -114,6 +114,6 @@
     graph.addNode();
   }
-  DescriptorMap<Graph, Node> nodes(graph);
-  typename DescriptorMap<Graph, Node>::InverseMap invNodes(nodes);
+  RangeIdMap<Graph, Node> nodes(graph);
+  typename RangeIdMap<Graph, Node>::InverseMap invNodes(nodes);
   for (int i = 0; i < 100; ++i) {
     int src = rnd[invNodes.size()];
@@ -122,5 +122,5 @@
   }
   typename Graph::template EdgeMap<int> found(graph, 0);
-  DescriptorMap<Graph, Edge> edges(graph);
+  RangeIdMap<Graph, Edge> edges(graph);
   for (NodeIt src(graph); src != INVALID; ++src) {
     for (NodeIt trg(graph); trg != INVALID; ++trg) {
Index: test/hao_orlin_test.cc
===================================================================
--- test/hao_orlin_test.cc	(revision 440)
+++ test/hao_orlin_test.cc	(revision 983)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -20,7 +20,10 @@
 
 #include <lemon/smart_graph.h>
+#include <lemon/adaptors.h>
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/lgf_reader.h>
 #include <lemon/hao_orlin.h>
 
-#include <lemon/lgf_reader.h>
 #include "test_tools.h"
 
@@ -38,25 +41,123 @@
   "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";
+  "     cap1 cap2 cap3\n"
+  "0 1  1    1    1   \n"
+  "0 2  2    2    4   \n"
+  "1 2  4    4    4   \n"
+  "3 4  1    1    1   \n"
+  "3 5  2    2    4   \n"
+  "4 5  4    4    4   \n"
+  "5 4  4    4    4   \n"
+  "2 3  1    6    6   \n"
+  "4 0  1    6    6   \n";
+
+void checkHaoOrlinCompile()
+{
+  typedef int Value;
+  typedef concepts::Digraph Digraph;
+
+  typedef Digraph::Node Node;
+  typedef Digraph::Arc Arc;
+  typedef concepts::ReadMap<Arc, Value> CapMap;
+  typedef concepts::WriteMap<Node, bool> CutMap;
+
+  Digraph g;
+  Node n;
+  CapMap cap;
+  CutMap cut;
+  Value v;
+  ::lemon::ignore_unused_variable_warning(v);
+
+  HaoOrlin<Digraph, CapMap> ho_test(g, cap);
+  const HaoOrlin<Digraph, CapMap>&
+    const_ho_test = ho_test;
+
+  ho_test.init();
+  ho_test.init(n);
+  ho_test.calculateOut();
+  ho_test.calculateIn();
+  ho_test.run();
+  ho_test.run(n);
+
+  v = const_ho_test.minCutValue();
+  v = const_ho_test.minCutMap(cut);
+}
+
+template <typename Graph, typename CapMap, typename CutMap>
+typename CapMap::Value
+  cutValue(const Graph& graph, const CapMap& cap, const CutMap& cut)
+{
+  typename CapMap::Value sum = 0;
+  for (typename Graph::ArcIt a(graph); a != INVALID; ++a) {
+    if (cut[graph.source(a)] && !cut[graph.target(a)])
+      sum += cap[a];
+  }
+  return sum;
+}
 
 int main() {
-  SmartGraph graph;
-  SmartGraph::EdgeMap<int> capacity(graph);
+  SmartDigraph graph;
+  SmartDigraph::ArcMap<int> cap1(graph), cap2(graph), cap3(graph);
+  SmartDigraph::NodeMap<bool> cut(graph);
 
-  istringstream lgfs(lgf);
-  graphReader(graph, lgfs).
-    edgeMap("capacity", capacity).run();
+  istringstream input(lgf);
+  digraphReader(graph, input)
+    .arcMap("cap1", cap1)
+    .arcMap("cap2", cap2)
+    .arcMap("cap3", cap3)
+    .run();
 
-  HaoOrlin<SmartGraph, SmartGraph::EdgeMap<int> > ho(graph, capacity);
-  ho.run();
+  {
+    HaoOrlin<SmartDigraph> ho(graph, cap1);
+    ho.run();
+    ho.minCutMap(cut);
 
-  check(ho.minCutValue() == 3, "Wrong cut value");
+    check(ho.minCutValue() == 1, "Wrong cut value");
+    check(ho.minCutValue() == cutValue(graph, cap1, cut), "Wrong cut value");
+  }
+  {
+    HaoOrlin<SmartDigraph> ho(graph, cap2);
+    ho.run();
+    ho.minCutMap(cut);
+
+    check(ho.minCutValue() == 1, "Wrong cut value");
+    check(ho.minCutValue() == cutValue(graph, cap2, cut), "Wrong cut value");
+  }
+  {
+    HaoOrlin<SmartDigraph> ho(graph, cap3);
+    ho.run();
+    ho.minCutMap(cut);
+
+    check(ho.minCutValue() == 1, "Wrong cut value");
+    check(ho.minCutValue() == cutValue(graph, cap3, cut), "Wrong cut value");
+  }
+
+  typedef Undirector<SmartDigraph> UGraph;
+  UGraph ugraph(graph);
+
+  {
+    HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap1);
+    ho.run();
+    ho.minCutMap(cut);
+
+    check(ho.minCutValue() == 2, "Wrong cut value");
+    check(ho.minCutValue() == cutValue(ugraph, cap1, cut), "Wrong cut value");
+  }
+  {
+    HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap2);
+    ho.run();
+    ho.minCutMap(cut);
+
+    check(ho.minCutValue() == 5, "Wrong cut value");
+    check(ho.minCutValue() == cutValue(ugraph, cap2, cut), "Wrong cut value");
+  }
+  {
+    HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap3);
+    ho.run();
+    ho.minCutMap(cut);
+
+    check(ho.minCutValue() == 5, "Wrong cut value");
+    check(ho.minCutValue() == cutValue(ugraph, cap3, cut), "Wrong cut value");
+  }
 
   return 0;
Index: test/heap_test.cc
===================================================================
--- test/heap_test.cc	(revision 440)
+++ test/heap_test.cc	(revision 927)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2011
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -26,5 +26,4 @@
 
 #include <lemon/smart_graph.h>
-
 #include <lemon/lgf_reader.h>
 #include <lemon/dijkstra.h>
@@ -32,4 +31,11 @@
 
 #include <lemon/bin_heap.h>
+#include <lemon/quad_heap.h>
+#include <lemon/dheap.h>
+#include <lemon/fib_heap.h>
+#include <lemon/pairing_heap.h>
+#include <lemon/radix_heap.h>
+#include <lemon/binomial_heap.h>
+#include <lemon/bucket_heap.h>
 
 #include "test_tools.h"
@@ -87,9 +93,7 @@
 void heapSortTest() {
   RangeMap<int> map(test_len, -1);
-
   Heap heap(map);
 
   std::vector<int> v(test_len);
-
   for (int i = 0; i < test_len; ++i) {
     v[i] = test_seq[i];
@@ -98,5 +102,5 @@
   std::sort(v.begin(), v.end());
   for (int i = 0; i < test_len; ++i) {
-    check(v[i] == heap.prio() ,"Wrong order in heap sort.");
+    check(v[i] == heap.prio(), "Wrong order in heap sort.");
     heap.pop();
   }
@@ -110,5 +114,4 @@
 
   std::vector<int> v(test_len);
-
   for (int i = 0; i < test_len; ++i) {
     v[i] = test_seq[i];
@@ -121,10 +124,8 @@
   std::sort(v.begin(), v.end());
   for (int i = 0; i < test_len; ++i) {
-    check(v[i] == heap.prio() ,"Wrong order in heap increase test.");
+    check(v[i] == heap.prio(), "Wrong order in heap increase test.");
     heap.pop();
   }
 }
-
-
 
 template <typename Heap>
@@ -142,5 +143,5 @@
     if (dijkstra.reached(s)) {
       check( dijkstra.dist(t) - dijkstra.dist(s) <= length[a],
-             "Error in a shortest path tree!");
+             "Error in shortest path tree.");
     }
   }
@@ -151,5 +152,5 @@
       Node s = digraph.source(a);
       check( dijkstra.dist(n) - dijkstra.dist(s) == length[a],
-             "Error in a shortest path tree!");
+             "Error in shortest path tree.");
     }
   }
@@ -173,4 +174,5 @@
     run();
 
+  // BinHeap
   {
     typedef BinHeap<Prio, ItemIntMap> IntHeap;
@@ -183,4 +185,125 @@
     dijkstraHeapTest<NodeHeap>(digraph, length, source);
   }
+
+  // QuadHeap
+  {
+    typedef QuadHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef QuadHeap<Prio, IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  // DHeap
+  {
+    typedef DHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef DHeap<Prio, IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  // FibHeap
+  {
+    typedef FibHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef FibHeap<Prio, IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  // PairingHeap
+  {
+    typedef PairingHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef PairingHeap<Prio, IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  // RadixHeap
+  {
+    typedef RadixHeap<ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef RadixHeap<IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  // BinomialHeap
+  {
+    typedef BinomialHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef BinomialHeap<Prio, IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  // BucketHeap, SimpleBucketHeap
+  {
+    typedef BucketHeap<ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef BucketHeap<IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+
+    typedef SimpleBucketHeap<ItemIntMap> SimpleIntHeap;
+    heapSortTest<SimpleIntHeap>();
+  }
+
+  {
+    typedef FibHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef FibHeap<Prio, IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  {
+    typedef RadixHeap<ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef RadixHeap<IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  {
+    typedef BucketHeap<ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef BucketHeap<IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
 
   return 0;
Index: test/kruskal_test.cc
===================================================================
--- test/kruskal_test.cc	(revision 440)
+++ test/kruskal_test.cc	(revision 581)
@@ -100,14 +100,14 @@
         "Total cost should be 10");
 
-  edge_cost_map.set(e1, -10);
-  edge_cost_map.set(e2, -9);
-  edge_cost_map.set(e3, -8);
-  edge_cost_map.set(e4, -7);
-  edge_cost_map.set(e5, -6);
-  edge_cost_map.set(e6, -5);
-  edge_cost_map.set(e7, -4);
-  edge_cost_map.set(e8, -3);
-  edge_cost_map.set(e9, -2);
-  edge_cost_map.set(e10, -1);
+  edge_cost_map[e1] = -10;
+  edge_cost_map[e2] = -9;
+  edge_cost_map[e3] = -8;
+  edge_cost_map[e4] = -7;
+  edge_cost_map[e5] = -6;
+  edge_cost_map[e6] = -5;
+  edge_cost_map[e7] = -4;
+  edge_cost_map[e8] = -3;
+  edge_cost_map[e9] = -2;
+  edge_cost_map[e10] = -1;
 
   vector<Edge> tree_edge_vec(5);
Index: test/lgf_test.cc
===================================================================
--- test/lgf_test.cc	(revision 935)
+++ test/lgf_test.cc	(revision 935)
@@ -0,0 +1,169 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2011
+ * 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/list_graph.h>
+#include <lemon/lgf_reader.h>
+#include "test_tools.h"
+
+using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "@arcs\n"
+  "     label\n"
+  "0 1  0\n"
+  "1 0  1\n"
+  "@attributes\n"
+  "source 0\n"
+  "target 1\n";
+
+char test_lgf_nomap[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "@arcs\n"
+  "     -\n"
+  "0 1\n";
+
+char test_lgf_bad1[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "@arcs\n"
+  "     - another\n"
+  "0 1\n";
+
+char test_lgf_bad2[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "@arcs\n"
+  "     label -\n"
+  "0 1\n";
+
+
+int main()
+{
+  {
+    ListDigraph d;
+    ListDigraph::Node s,t;
+    ListDigraph::ArcMap<int> label(d);
+    std::istringstream input(test_lgf);
+    digraphReader(d, input).
+      node("source", s).
+      node("target", t).
+      arcMap("label", label).
+      run();
+    check(countNodes(d) == 2,"There should be 2 nodes");
+    check(countArcs(d) == 2,"There should be 2 arcs");
+  }
+  {
+    ListGraph g;
+    ListGraph::Node s,t;
+    ListGraph::EdgeMap<int> label(g);
+    std::istringstream input(test_lgf);
+    graphReader(g, input).
+      node("source", s).
+      node("target", t).
+      edgeMap("label", label).
+      run();
+    check(countNodes(g) == 2,"There should be 2 nodes");
+    check(countEdges(g) == 2,"There should be 2 arcs");
+  }
+
+  {
+    ListDigraph d;
+    std::istringstream input(test_lgf_nomap);
+    digraphReader(d, input).
+      run();
+    check(countNodes(d) == 2,"There should be 2 nodes");
+    check(countArcs(d) == 1,"There should be 1 arc");
+  }
+  {
+    ListGraph g;
+    std::istringstream input(test_lgf_nomap);
+    graphReader(g, input).
+      run();
+    check(countNodes(g) == 2,"There should be 2 nodes");
+    check(countEdges(g) == 1,"There should be 1 edge");
+  }
+
+  {
+    ListDigraph d;
+    std::istringstream input(test_lgf_bad1);
+    bool ok=false;
+    try {
+      digraphReader(d, input).
+        run();
+    }
+    catch (FormatError&)
+      {
+        ok = true;
+      }
+    check(ok,"FormatError exception should have occured");
+  }
+  {
+    ListGraph g;
+    std::istringstream input(test_lgf_bad1);
+    bool ok=false;
+    try {
+      graphReader(g, input).
+        run();
+    }
+    catch (FormatError&)
+      {
+        ok = true;
+      }
+    check(ok,"FormatError exception should have occured");
+  }
+
+  {
+    ListDigraph d;
+    std::istringstream input(test_lgf_bad2);
+    bool ok=false;
+    try {
+      digraphReader(d, input).
+        run();
+    }
+    catch (FormatError&)
+      {
+        ok = true;
+      }
+    check(ok,"FormatError exception should have occured");
+  }
+  {
+    ListGraph g;
+    std::istringstream input(test_lgf_bad2);
+    bool ok=false;
+    try {
+      graphReader(g, input).
+        run();
+    }
+    catch (FormatError&)
+      {
+        ok = true;
+      }
+    check(ok,"FormatError exception should have occured");
+  }
+}
Index: test/lp_test.cc
===================================================================
--- test/lp_test.cc	(revision 551)
+++ test/lp_test.cc	(revision 981)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2011
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -22,25 +22,36 @@
 #include <lemon/tolerance.h>
 
-#ifdef HAVE_CONFIG_H
 #include <lemon/config.h>
-#endif
-
-#ifdef HAVE_GLPK
+
+#ifdef LEMON_HAVE_GLPK
 #include <lemon/glpk.h>
 #endif
 
-#ifdef HAVE_CPLEX
+#ifdef LEMON_HAVE_CPLEX
 #include <lemon/cplex.h>
 #endif
 
-#ifdef HAVE_SOPLEX
+#ifdef LEMON_HAVE_SOPLEX
 #include <lemon/soplex.h>
 #endif
 
-#ifdef HAVE_CLP
+#ifdef LEMON_HAVE_CLP
 #include <lemon/clp.h>
 #endif
 
 using namespace lemon;
+
+int countCols(LpBase & lp) {
+  int count=0;
+  for (LpBase::ColIt c(lp); c!=INVALID; ++c) ++count;
+  return count;
+}
+
+int countRows(LpBase & lp) {
+  int count=0;
+  for (LpBase::RowIt r(lp); r!=INVALID; ++r) ++count;
+  return count;
+}
+
 
 void lpTest(LpSolver& lp)
@@ -48,4 +59,18 @@
 
   typedef LpSolver LP;
+
+  // Test LpBase::clear()
+  check(countRows(lp)==0, "Wrong number of rows");
+  check(countCols(lp)==0, "Wrong number of cols");
+  lp.addCol(); lp.addRow(); lp.addRow();
+  check(countRows(lp)==2, "Wrong number of rows");
+  check(countCols(lp)==1, "Wrong number of cols");
+  lp.clear();
+  check(countRows(lp)==0, "Wrong number of rows");
+  check(countCols(lp)==0, "Wrong number of cols");
+  lp.addCol(); lp.addCol(); lp.addCol(); lp.addRow();
+  check(countRows(lp)==1, "Wrong number of rows");
+  check(countCols(lp)==3, "Wrong number of cols");
+  lp.clear();
 
   std::vector<LP::Col> x(10);
@@ -169,4 +194,17 @@
     c = ((2 >= p1) >= 3);
 
+    { //Tests for #430
+      LP::Col v=lp.addCol();
+      LP::Constr c = v >= -3;
+      c = c <= 4;
+      LP::Constr c2;
+#if ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ == 3 )
+      c2 = ( -3 <= v ) <= 4;
+#else
+      c2 = -3 <= v <= 4;
+#endif
+
+    }
+
     e[x[3]]=2;
     e[x[3]]=4;
@@ -208,6 +246,5 @@
   {
     LP::DualExpr e,f,g;
-    LP::Row p1 = INVALID, p2 = INVALID, p3 = INVALID,
-      p4 = INVALID, p5 = INVALID;
+    LP::Row p1 = INVALID, p2 = INVALID;
 
     e[p1]=2;
@@ -380,5 +417,5 @@
   lpTest(lp_skel);
 
-#ifdef HAVE_GLPK
+#ifdef LEMON_HAVE_GLPK
   {
     GlpkLp lp_glpk1,lp_glpk2;
@@ -389,5 +426,5 @@
 #endif
 
-#ifdef HAVE_CPLEX
+#ifdef LEMON_HAVE_CPLEX
   try {
     CplexLp lp_cplex1,lp_cplex2;
@@ -396,14 +433,9 @@
     cloneTest<CplexLp>();
   } 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
+  }
+#endif
+
+#ifdef LEMON_HAVE_SOPLEX
   {
     SoplexLp lp_soplex1,lp_soplex2;
@@ -414,5 +446,5 @@
 #endif
 
-#ifdef HAVE_CLP
+#ifdef LEMON_HAVE_CLP
   {
     ClpLp lp_clp1,lp_clp2;
Index: test/maps_test.cc
===================================================================
--- test/maps_test.cc	(revision 507)
+++ test/maps_test.cc	(revision 991)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2011
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -23,4 +23,9 @@
 #include <lemon/concepts/maps.h>
 #include <lemon/maps.h>
+#include <lemon/list_graph.h>
+#include <lemon/smart_graph.h>
+#include <lemon/adaptors.h>
+#include <lemon/dfs.h>
+#include <algorithm>
 
 #include "test_tools.h"
@@ -34,7 +39,20 @@
 
 class C {
-  int x;
+  int _x;
 public:
-  C(int _x) : x(_x) {}
+  C(int x) : _x(x) {}
+  int get() const { return _x; }
+};
+inline bool operator<(C c1, C c2) { return c1.get() < c2.get(); }
+inline bool operator==(C c1, C c2) { return c1.get() == c2.get(); }
+
+C createC(int x) { return C(x); }
+
+template <typename T>
+class Less {
+  T _t;
+public:
+  Less(T t): _t(t) {}
+  bool operator()(const T& t) const { return t < _t; }
 };
 
@@ -52,4 +70,12 @@
 
 int binc(int a, B) { return a+1; }
+
+template <typename T>
+class Sum {
+  T& _sum;
+public:
+  Sum(T& sum) : _sum(sum) {}
+  void operator()(const T& t) { _sum += t; }
+};
 
 typedef ReadMap<A, double> DoubleMap;
@@ -78,4 +104,5 @@
     NullMap<A,B> map1;
     NullMap<A,B> map2 = map1;
+    ::lemon::ignore_unused_variable_warning(map2);
     map1 = nullMap<A,B>();
   }
@@ -88,4 +115,6 @@
     ConstMap<A,B> map2 = B();
     ConstMap<A,B> map3 = map1;
+    ::lemon::ignore_unused_variable_warning(map2,map3);
+
     map1 = constMap<A>(B());
     map1 = constMap<A,B>();
@@ -93,4 +122,6 @@
     ConstMap<A,C> map4(C(1));
     ConstMap<A,C> map5 = map4;
+    ::lemon::ignore_unused_variable_warning(map5);
+
     map4 = constMap<A>(C(2));
     map4.setAll(C(3));
@@ -113,4 +144,6 @@
     IdentityMap<A> map1;
     IdentityMap<A> map2 = map1;
+    ::lemon::ignore_unused_variable_warning(map2);
+
     map1 = identityMap<A>();
 
@@ -172,5 +205,7 @@
     checkConcept<ReadMap<B,double>, CompMap>();
     CompMap map1 = CompMap(DoubleMap(),ReadMap<B,A>());
+    ::lemon::ignore_unused_variable_warning(map1);
     CompMap map2 = composeMap(DoubleMap(), ReadMap<B,A>());
+    ::lemon::ignore_unused_variable_warning(map2);
 
     SparseMap<double, bool> m1(false); m1[3.14] = true;
@@ -185,5 +220,7 @@
     checkConcept<ReadMap<A,double>, CombMap>();
     CombMap map1 = CombMap(DoubleMap(), DoubleMap());
+    ::lemon::ignore_unused_variable_warning(map1);
     CombMap map2 = combineMap(DoubleMap(), DoubleMap(), std::plus<double>());
+    ::lemon::ignore_unused_variable_warning(map2);
 
     check(combineMap(constMap<B,int,2>(), identityMap<B>(), &binc)[B()] == 3,
@@ -197,8 +234,13 @@
     FunctorToMap<F> map1;
     FunctorToMap<F> map2 = FunctorToMap<F>(F());
+    ::lemon::ignore_unused_variable_warning(map2);
+
     B b = functorToMap(F())[A()];
+    ::lemon::ignore_unused_variable_warning(b);
 
     checkConcept<ReadMap<A,B>, MapToFunctor<ReadMap<A,B> > >();
-    MapToFunctor<ReadMap<A,B> > map = MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>());
+    MapToFunctor<ReadMap<A,B> > map =
+      MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>());
+    ::lemon::ignore_unused_variable_warning(map);
 
     check(functorToMap(&func)[A()] == 3,
@@ -218,5 +260,8 @@
       ConvertMap<ReadMap<double, int>, double> >();
     ConvertMap<RangeMap<bool>, int> map1(rangeMap(1, true));
+    ::lemon::ignore_unused_variable_warning(map1);
     ConvertMap<RangeMap<bool>, int> map2 = convertMap<int>(rangeMap(2, false));
+    ::lemon::ignore_unused_variable_warning(map2);
+
   }
 
@@ -329,4 +374,8 @@
   {
     typedef std::vector<int> vec;
+    checkConcept<WriteMap<int, bool>, LoggerBoolMap<vec::iterator> >();
+    checkConcept<WriteMap<int, bool>,
+                 LoggerBoolMap<std::back_insert_iterator<vec> > >();
+
     vec v1;
     vec v2(10);
@@ -348,4 +397,624 @@
           it != map2.end(); ++it )
       check(v1[i++] == *it, "Something is wrong with LoggerBoolMap");
+
+    typedef ListDigraph Graph;
+    DIGRAPH_TYPEDEFS(Graph);
+    Graph gr;
+
+    Node n0 = gr.addNode();
+    Node n1 = gr.addNode();
+    Node n2 = gr.addNode();
+    Node n3 = gr.addNode();
+
+    gr.addArc(n3, n0);
+    gr.addArc(n3, n2);
+    gr.addArc(n0, n2);
+    gr.addArc(n2, n1);
+    gr.addArc(n0, n1);
+
+    {
+      std::vector<Node> v;
+      dfs(gr).processedMap(loggerBoolMap(std::back_inserter(v))).run();
+
+      check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3,
+            "Something is wrong with LoggerBoolMap");
+    }
+    {
+      std::vector<Node> v(countNodes(gr));
+      dfs(gr).processedMap(loggerBoolMap(v.begin())).run();
+
+      check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3,
+            "Something is wrong with LoggerBoolMap");
+    }
+  }
+
+  // IdMap, RangeIdMap
+  {
+    typedef ListDigraph Graph;
+    DIGRAPH_TYPEDEFS(Graph);
+
+    checkConcept<ReadMap<Node, int>, IdMap<Graph, Node> >();
+    checkConcept<ReadMap<Arc, int>, IdMap<Graph, Arc> >();
+    checkConcept<ReadMap<Node, int>, RangeIdMap<Graph, Node> >();
+    checkConcept<ReadMap<Arc, int>, RangeIdMap<Graph, Arc> >();
+
+    Graph gr;
+    IdMap<Graph, Node> nmap(gr);
+    IdMap<Graph, Arc> amap(gr);
+    RangeIdMap<Graph, Node> nrmap(gr);
+    RangeIdMap<Graph, Arc> armap(gr);
+
+    Node n0 = gr.addNode();
+    Node n1 = gr.addNode();
+    Node n2 = gr.addNode();
+
+    Arc a0 = gr.addArc(n0, n1);
+    Arc a1 = gr.addArc(n0, n2);
+    Arc a2 = gr.addArc(n2, n1);
+    Arc a3 = gr.addArc(n2, n0);
+
+    check(nmap[n0] == gr.id(n0) && nmap(gr.id(n0)) == n0, "Wrong IdMap");
+    check(nmap[n1] == gr.id(n1) && nmap(gr.id(n1)) == n1, "Wrong IdMap");
+    check(nmap[n2] == gr.id(n2) && nmap(gr.id(n2)) == n2, "Wrong IdMap");
+
+    check(amap[a0] == gr.id(a0) && amap(gr.id(a0)) == a0, "Wrong IdMap");
+    check(amap[a1] == gr.id(a1) && amap(gr.id(a1)) == a1, "Wrong IdMap");
+    check(amap[a2] == gr.id(a2) && amap(gr.id(a2)) == a2, "Wrong IdMap");
+    check(amap[a3] == gr.id(a3) && amap(gr.id(a3)) == a3, "Wrong IdMap");
+
+    check(nmap.inverse()[gr.id(n0)] == n0, "Wrong IdMap::InverseMap");
+    check(amap.inverse()[gr.id(a0)] == a0, "Wrong IdMap::InverseMap");
+
+    check(nrmap.size() == 3 && armap.size() == 4,
+          "Wrong RangeIdMap::size()");
+
+    check(nrmap[n0] == 0 && nrmap(0) == n0, "Wrong RangeIdMap");
+    check(nrmap[n1] == 1 && nrmap(1) == n1, "Wrong RangeIdMap");
+    check(nrmap[n2] == 2 && nrmap(2) == n2, "Wrong RangeIdMap");
+
+    check(armap[a0] == 0 && armap(0) == a0, "Wrong RangeIdMap");
+    check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
+    check(armap[a2] == 2 && armap(2) == a2, "Wrong RangeIdMap");
+    check(armap[a3] == 3 && armap(3) == a3, "Wrong RangeIdMap");
+
+    check(nrmap.inverse()[0] == n0, "Wrong RangeIdMap::InverseMap");
+    check(armap.inverse()[0] == a0, "Wrong RangeIdMap::InverseMap");
+
+    gr.erase(n1);
+
+    if (nrmap[n0] == 1) nrmap.swap(n0, n2);
+    nrmap.swap(n2, n0);
+    if (armap[a1] == 1) armap.swap(a1, a3);
+    armap.swap(a3, a1);
+
+    check(nrmap.size() == 2 && armap.size() == 2,
+          "Wrong RangeIdMap::size()");
+
+    check(nrmap[n0] == 1 && nrmap(1) == n0, "Wrong RangeIdMap");
+    check(nrmap[n2] == 0 && nrmap(0) == n2, "Wrong RangeIdMap");
+
+    check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
+    check(armap[a3] == 0 && armap(0) == a3, "Wrong RangeIdMap");
+
+    check(nrmap.inverse()[0] == n2, "Wrong RangeIdMap::InverseMap");
+    check(armap.inverse()[0] == a3, "Wrong RangeIdMap::InverseMap");
+  }
+
+  // SourceMap, TargetMap, ForwardMap, BackwardMap, InDegMap, OutDegMap
+  {
+    typedef ListGraph Graph;
+    GRAPH_TYPEDEFS(Graph);
+
+    checkConcept<ReadMap<Arc, Node>, SourceMap<Graph> >();
+    checkConcept<ReadMap<Arc, Node>, TargetMap<Graph> >();
+    checkConcept<ReadMap<Edge, Arc>, ForwardMap<Graph> >();
+    checkConcept<ReadMap<Edge, Arc>, BackwardMap<Graph> >();
+    checkConcept<ReadMap<Node, int>, InDegMap<Graph> >();
+    checkConcept<ReadMap<Node, int>, OutDegMap<Graph> >();
+
+    Graph gr;
+    Node n0 = gr.addNode();
+    Node n1 = gr.addNode();
+    Node n2 = gr.addNode();
+
+    gr.addEdge(n0,n1);
+    gr.addEdge(n1,n2);
+    gr.addEdge(n0,n2);
+    gr.addEdge(n2,n1);
+    gr.addEdge(n1,n2);
+    gr.addEdge(n0,n1);
+
+    for (EdgeIt e(gr); e != INVALID; ++e) {
+      check(forwardMap(gr)[e] == gr.direct(e, true), "Wrong ForwardMap");
+      check(backwardMap(gr)[e] == gr.direct(e, false), "Wrong BackwardMap");
+    }
+
+    check(mapCompare(gr,
+          sourceMap(orienter(gr, constMap<Edge, bool>(true))),
+          targetMap(orienter(gr, constMap<Edge, bool>(false)))),
+          "Wrong SourceMap or TargetMap");
+
+    typedef Orienter<Graph, const ConstMap<Edge, bool> > Digraph;
+    ConstMap<Edge, bool> true_edge_map(true);
+    Digraph dgr(gr, true_edge_map);
+    OutDegMap<Digraph> odm(dgr);
+    InDegMap<Digraph> idm(dgr);
+
+    check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 1, "Wrong OutDegMap");
+    check(idm[n0] == 0 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
+
+    gr.addEdge(n2, n0);
+
+    check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 2, "Wrong OutDegMap");
+    check(idm[n0] == 1 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
+  }
+
+  // CrossRefMap
+  {
+    typedef ListDigraph Graph;
+    DIGRAPH_TYPEDEFS(Graph);
+
+    checkConcept<ReadWriteMap<Node, int>,
+                 CrossRefMap<Graph, Node, int> >();
+    checkConcept<ReadWriteMap<Node, bool>,
+                 CrossRefMap<Graph, Node, bool> >();
+    checkConcept<ReadWriteMap<Node, double>,
+                 CrossRefMap<Graph, Node, double> >();
+
+    Graph gr;
+    typedef CrossRefMap<Graph, Node, char> CRMap;
+    CRMap map(gr);
+
+    Node n0 = gr.addNode();
+    Node n1 = gr.addNode();
+    Node n2 = gr.addNode();
+
+    map.set(n0, 'A');
+    map.set(n1, 'B');
+    map.set(n2, 'C');
+
+    check(map[n0] == 'A' && map('A') == n0 && map.inverse()['A'] == n0,
+          "Wrong CrossRefMap");
+    check(map[n1] == 'B' && map('B') == n1 && map.inverse()['B'] == n1,
+          "Wrong CrossRefMap");
+    check(map[n2] == 'C' && map('C') == n2 && map.inverse()['C'] == n2,
+          "Wrong CrossRefMap");
+    check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
+          "Wrong CrossRefMap::count()");
+
+    CRMap::ValueIt it = map.beginValue();
+    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
+          it == map.endValue(), "Wrong value iterator");
+
+    map.set(n2, 'A');
+
+    check(map[n0] == 'A' && map[n1] == 'B' && map[n2] == 'A',
+          "Wrong CrossRefMap");
+    check(map('A') == n0 && map.inverse()['A'] == n0, "Wrong CrossRefMap");
+    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
+    check(map('C') == INVALID && map.inverse()['C'] == INVALID,
+          "Wrong CrossRefMap");
+    check(map.count('A') == 2 && map.count('B') == 1 && map.count('C') == 0,
+          "Wrong CrossRefMap::count()");
+
+    it = map.beginValue();
+    check(*it++ == 'A' && *it++ == 'A' && *it++ == 'B' &&
+          it == map.endValue(), "Wrong value iterator");
+
+    map.set(n0, 'C');
+
+    check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
+          "Wrong CrossRefMap");
+    check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
+    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
+    check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
+    check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
+          "Wrong CrossRefMap::count()");
+
+    it = map.beginValue();
+    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
+          it == map.endValue(), "Wrong value iterator");
+  }
+
+  // CrossRefMap
+  {
+    typedef SmartDigraph Graph;
+    DIGRAPH_TYPEDEFS(Graph);
+
+    checkConcept<ReadWriteMap<Node, int>,
+                 CrossRefMap<Graph, Node, int> >();
+
+    Graph gr;
+    typedef CrossRefMap<Graph, Node, char> CRMap;
+    typedef CRMap::ValueIterator ValueIt;
+    CRMap map(gr);
+
+    Node n0 = gr.addNode();
+    Node n1 = gr.addNode();
+    Node n2 = gr.addNode();
+
+    map.set(n0, 'A');
+    map.set(n1, 'B');
+    map.set(n2, 'C');
+    map.set(n2, 'A');
+    map.set(n0, 'C');
+
+    check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
+          "Wrong CrossRefMap");
+    check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
+    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
+    check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
+
+    ValueIt it = map.beginValue();
+    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
+          it == map.endValue(), "Wrong value iterator");
+  }
+
+  // Iterable bool map
+  {
+    typedef SmartGraph Graph;
+    typedef SmartGraph::Node Item;
+
+    typedef IterableBoolMap<SmartGraph, SmartGraph::Node> Ibm;
+    checkConcept<ReferenceMap<Item, bool, bool&, const bool&>, Ibm>();
+
+    const int num = 10;
+    Graph g;
+    Ibm map0(g, true);
+    std::vector<Item> items;
+    for (int i = 0; i < num; ++i) {
+      items.push_back(g.addNode());
+    }
+
+    Ibm map1(g, true);
+    int n = 0;
+    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
+      check(map1[static_cast<Item>(it)], "Wrong TrueIt");
+      ++n;
+    }
+    check(n == num, "Wrong number");
+
+    n = 0;
+    for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
+        check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
+        ++n;
+    }
+    check(n == num, "Wrong number");
+    check(Ibm::FalseIt(map1) == INVALID, "Wrong FalseIt");
+    check(Ibm::ItemIt(map1, false) == INVALID, "Wrong ItemIt for false");
+
+    map1[items[5]] = true;
+
+    n = 0;
+    for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
+        check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
+        ++n;
+    }
+    check(n == num, "Wrong number");
+
+    map1[items[num / 2]] = false;
+    check(map1[items[num / 2]] == false, "Wrong map value");
+
+    n = 0;
+    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
+        check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
+        ++n;
+    }
+    check(n == num - 1, "Wrong number");
+
+    n = 0;
+    for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
+        check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
+        ++n;
+    }
+    check(n == 1, "Wrong number");
+
+    map1[items[0]] = false;
+    check(map1[items[0]] == false, "Wrong map value");
+
+    map1[items[num - 1]] = false;
+    check(map1[items[num - 1]] == false, "Wrong map value");
+
+    n = 0;
+    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
+        check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
+        ++n;
+    }
+    check(n == num - 3, "Wrong number");
+    check(map1.trueNum() == num - 3, "Wrong number");
+
+    n = 0;
+    for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
+        check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
+        ++n;
+    }
+    check(n == 3, "Wrong number");
+    check(map1.falseNum() == 3, "Wrong number");
+  }
+
+  // Iterable int map
+  {
+    typedef SmartGraph Graph;
+    typedef SmartGraph::Node Item;
+    typedef IterableIntMap<SmartGraph, SmartGraph::Node> Iim;
+
+    checkConcept<ReferenceMap<Item, int, int&, const int&>, Iim>();
+
+    const int num = 10;
+    Graph g;
+    Iim map0(g, 0);
+    std::vector<Item> items;
+    for (int i = 0; i < num; ++i) {
+      items.push_back(g.addNode());
+    }
+
+    Iim map1(g);
+    check(map1.size() == 0, "Wrong size");
+
+    for (int i = 0; i < num; ++i) {
+      map1[items[i]] = i;
+    }
+    check(map1.size() == num, "Wrong size");
+
+    for (int i = 0; i < num; ++i) {
+      Iim::ItemIt it(map1, i);
+      check(static_cast<Item>(it) == items[i], "Wrong value");
+      ++it;
+      check(static_cast<Item>(it) == INVALID, "Wrong value");
+    }
+
+    for (int i = 0; i < num; ++i) {
+      map1[items[i]] = i % 2;
+    }
+    check(map1.size() == 2, "Wrong size");
+
+    int n = 0;
+    for (Iim::ItemIt it(map1, 0); it != INVALID; ++it) {
+      check(map1[static_cast<Item>(it)] == 0, "Wrong value");
+      ++n;
+    }
+    check(n == (num + 1) / 2, "Wrong number");
+
+    for (Iim::ItemIt it(map1, 1); it != INVALID; ++it) {
+      check(map1[static_cast<Item>(it)] == 1, "Wrong value");
+      ++n;
+    }
+    check(n == num, "Wrong number");
+
+  }
+
+  // Iterable value map
+  {
+    typedef SmartGraph Graph;
+    typedef SmartGraph::Node Item;
+    typedef IterableValueMap<SmartGraph, SmartGraph::Node, double> Ivm;
+
+    checkConcept<ReadWriteMap<Item, double>, Ivm>();
+
+    const int num = 10;
+    Graph g;
+    Ivm map0(g, 0.0);
+    std::vector<Item> items;
+    for (int i = 0; i < num; ++i) {
+      items.push_back(g.addNode());
+    }
+
+    Ivm map1(g, 0.0);
+    check(distance(map1.beginValue(), map1.endValue()) == 1, "Wrong size");
+    check(*map1.beginValue() == 0.0, "Wrong value");
+
+    for (int i = 0; i < num; ++i) {
+      map1.set(items[i], static_cast<double>(i));
+    }
+    check(distance(map1.beginValue(), map1.endValue()) == num, "Wrong size");
+
+    for (int i = 0; i < num; ++i) {
+      Ivm::ItemIt it(map1, static_cast<double>(i));
+      check(static_cast<Item>(it) == items[i], "Wrong value");
+      ++it;
+      check(static_cast<Item>(it) == INVALID, "Wrong value");
+    }
+
+    for (Ivm::ValueIt vit = map1.beginValue();
+         vit != map1.endValue(); ++vit) {
+      check(map1[static_cast<Item>(Ivm::ItemIt(map1, *vit))] == *vit,
+            "Wrong ValueIt");
+    }
+
+    for (int i = 0; i < num; ++i) {
+      map1.set(items[i], static_cast<double>(i % 2));
+    }
+    check(distance(map1.beginValue(), map1.endValue()) == 2, "Wrong size");
+
+    int n = 0;
+    for (Ivm::ItemIt it(map1, 0.0); it != INVALID; ++it) {
+      check(map1[static_cast<Item>(it)] == 0.0, "Wrong value");
+      ++n;
+    }
+    check(n == (num + 1) / 2, "Wrong number");
+
+    for (Ivm::ItemIt it(map1, 1.0); it != INVALID; ++it) {
+      check(map1[static_cast<Item>(it)] == 1.0, "Wrong value");
+      ++n;
+    }
+    check(n == num, "Wrong number");
+
+  }
+
+  // Graph map utilities:
+  // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
+  // mapFind(), mapFindIf(), mapCount(), mapCountIf()
+  // mapCopy(), mapCompare(), mapFill()
+  {
+    DIGRAPH_TYPEDEFS(SmartDigraph);
+
+    SmartDigraph g;
+    Node n1 = g.addNode();
+    Node n2 = g.addNode();
+    Node n3 = g.addNode();
+
+    SmartDigraph::NodeMap<int> map1(g);
+    SmartDigraph::ArcMap<char> map2(g);
+    ConstMap<Node, A> cmap1 = A();
+    ConstMap<Arc, C> cmap2 = C(0);
+
+    map1[n1] = 10;
+    map1[n2] = 5;
+    map1[n3] = 12;
+
+    // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
+    check(mapMin(g, map1) == n2, "Wrong mapMin()");
+    check(mapMax(g, map1) == n3, "Wrong mapMax()");
+    check(mapMin(g, map1, std::greater<int>()) == n3, "Wrong mapMin()");
+    check(mapMax(g, map1, std::greater<int>()) == n2, "Wrong mapMax()");
+    check(mapMinValue(g, map1) == 5, "Wrong mapMinValue()");
+    check(mapMaxValue(g, map1) == 12, "Wrong mapMaxValue()");
+
+    check(mapMin(g, map2) == INVALID, "Wrong mapMin()");
+    check(mapMax(g, map2) == INVALID, "Wrong mapMax()");
+
+    check(mapMin(g, cmap1) != INVALID, "Wrong mapMin()");
+    check(mapMax(g, cmap2) == INVALID, "Wrong mapMax()");
+
+    Arc a1 = g.addArc(n1, n2);
+    Arc a2 = g.addArc(n1, n3);
+    Arc a3 = g.addArc(n2, n3);
+    Arc a4 = g.addArc(n3, n1);
+
+    map2[a1] = 'b';
+    map2[a2] = 'a';
+    map2[a3] = 'b';
+    map2[a4] = 'c';
+
+    // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
+    check(mapMin(g, map2) == a2, "Wrong mapMin()");
+    check(mapMax(g, map2) == a4, "Wrong mapMax()");
+    check(mapMin(g, map2, std::greater<int>()) == a4, "Wrong mapMin()");
+    check(mapMax(g, map2, std::greater<int>()) == a2, "Wrong mapMax()");
+    check(mapMinValue(g, map2, std::greater<int>()) == 'c',
+          "Wrong mapMinValue()");
+    check(mapMaxValue(g, map2, std::greater<int>()) == 'a',
+          "Wrong mapMaxValue()");
+
+    check(mapMin(g, cmap1) != INVALID, "Wrong mapMin()");
+    check(mapMax(g, cmap2) != INVALID, "Wrong mapMax()");
+    check(mapMaxValue(g, cmap2) == C(0), "Wrong mapMaxValue()");
+
+    check(mapMin(g, composeMap(functorToMap(&createC), map2)) == a2,
+          "Wrong mapMin()");
+    check(mapMax(g, composeMap(functorToMap(&createC), map2)) == a4,
+          "Wrong mapMax()");
+    check(mapMinValue(g, composeMap(functorToMap(&createC), map2)) == C('a'),
+          "Wrong mapMinValue()");
+    check(mapMaxValue(g, composeMap(functorToMap(&createC), map2)) == C('c'),
+          "Wrong mapMaxValue()");
+
+    // mapFind(), mapFindIf()
+    check(mapFind(g, map1, 5) == n2, "Wrong mapFind()");
+    check(mapFind(g, map1, 6) == INVALID, "Wrong mapFind()");
+    check(mapFind(g, map2, 'a') == a2, "Wrong mapFind()");
+    check(mapFind(g, map2, 'e') == INVALID, "Wrong mapFind()");
+    check(mapFind(g, cmap2, C(0)) == ArcIt(g), "Wrong mapFind()");
+    check(mapFind(g, cmap2, C(1)) == INVALID, "Wrong mapFind()");
+
+    check(mapFindIf(g, map1, Less<int>(7)) == n2,
+          "Wrong mapFindIf()");
+    check(mapFindIf(g, map1, Less<int>(5)) == INVALID,
+          "Wrong mapFindIf()");
+    check(mapFindIf(g, map2, Less<char>('d')) == ArcIt(g),
+          "Wrong mapFindIf()");
+    check(mapFindIf(g, map2, Less<char>('a')) == INVALID,
+          "Wrong mapFindIf()");
+
+    // mapCount(), mapCountIf()
+    check(mapCount(g, map1, 5) == 1, "Wrong mapCount()");
+    check(mapCount(g, map1, 6) == 0, "Wrong mapCount()");
+    check(mapCount(g, map2, 'a') == 1, "Wrong mapCount()");
+    check(mapCount(g, map2, 'b') == 2, "Wrong mapCount()");
+    check(mapCount(g, map2, 'e') == 0, "Wrong mapCount()");
+    check(mapCount(g, cmap2, C(0)) == 4, "Wrong mapCount()");
+    check(mapCount(g, cmap2, C(1)) == 0, "Wrong mapCount()");
+
+    check(mapCountIf(g, map1, Less<int>(11)) == 2,
+          "Wrong mapCountIf()");
+    check(mapCountIf(g, map1, Less<int>(13)) == 3,
+          "Wrong mapCountIf()");
+    check(mapCountIf(g, map1, Less<int>(5)) == 0,
+          "Wrong mapCountIf()");
+    check(mapCountIf(g, map2, Less<char>('d')) == 4,
+          "Wrong mapCountIf()");
+    check(mapCountIf(g, map2, Less<char>('c')) == 3,
+          "Wrong mapCountIf()");
+    check(mapCountIf(g, map2, Less<char>('a')) == 0,
+          "Wrong mapCountIf()");
+
+    // MapIt, ConstMapIt
+/*
+These tests can be used after applying bugfix #330
+    typedef SmartDigraph::NodeMap<int>::MapIt MapIt;
+    typedef SmartDigraph::NodeMap<int>::ConstMapIt ConstMapIt;
+    check(*std::min_element(MapIt(map1), MapIt(INVALID)) == 5,
+          "Wrong NodeMap<>::MapIt");
+    check(*std::max_element(ConstMapIt(map1), ConstMapIt(INVALID)) == 12,
+          "Wrong NodeMap<>::MapIt");
+
+    int sum = 0;
+    std::for_each(MapIt(map1), MapIt(INVALID), Sum<int>(sum));
+    check(sum == 27, "Wrong NodeMap<>::MapIt");
+    std::for_each(ConstMapIt(map1), ConstMapIt(INVALID), Sum<int>(sum));
+    check(sum == 54, "Wrong NodeMap<>::ConstMapIt");
+*/
+
+    // mapCopy(), mapCompare(), mapFill()
+    check(mapCompare(g, map1, map1), "Wrong mapCompare()");
+    check(mapCompare(g, cmap2, cmap2), "Wrong mapCompare()");
+    check(mapCompare(g, map1, shiftMap(map1, 0)), "Wrong mapCompare()");
+    check(mapCompare(g, map2, scaleMap(map2, 1)), "Wrong mapCompare()");
+    check(!mapCompare(g, map1, shiftMap(map1, 1)), "Wrong mapCompare()");
+
+    SmartDigraph::NodeMap<int> map3(g, 0);
+    SmartDigraph::ArcMap<char> map4(g, 'a');
+
+    check(!mapCompare(g, map1, map3), "Wrong mapCompare()");
+    check(!mapCompare(g, map2, map4), "Wrong mapCompare()");
+
+    mapCopy(g, map1, map3);
+    mapCopy(g, map2, map4);
+
+    check(mapCompare(g, map1, map3), "Wrong mapCompare() or mapCopy()");
+    check(mapCompare(g, map2, map4), "Wrong mapCompare() or mapCopy()");
+
+    Undirector<SmartDigraph> ug(g);
+    Undirector<SmartDigraph>::EdgeMap<char> umap1(ug, 'x');
+    Undirector<SmartDigraph>::ArcMap<double> umap2(ug, 3.14);
+
+    check(!mapCompare(g, map2, umap1), "Wrong mapCompare() or mapCopy()");
+    check(!mapCompare(g, umap1, map2), "Wrong mapCompare() or mapCopy()");
+    check(!mapCompare(ug, map2, umap1), "Wrong mapCompare() or mapCopy()");
+    check(!mapCompare(ug, umap1, map2), "Wrong mapCompare() or mapCopy()");
+
+    mapCopy(g, map2, umap1);
+
+    check(mapCompare(g, map2, umap1), "Wrong mapCompare() or mapCopy()");
+    check(mapCompare(g, umap1, map2), "Wrong mapCompare() or mapCopy()");
+    check(mapCompare(ug, map2, umap1), "Wrong mapCompare() or mapCopy()");
+    check(mapCompare(ug, umap1, map2), "Wrong mapCompare() or mapCopy()");
+
+    mapCopy(g, map2, umap1);
+    mapCopy(g, umap1, map2);
+    mapCopy(ug, map2, umap1);
+    mapCopy(ug, umap1, map2);
+
+    check(!mapCompare(ug, umap1, umap2), "Wrong mapCompare() or mapCopy()");
+    mapCopy(ug, umap1, umap2);
+    check(mapCompare(ug, umap1, umap2), "Wrong mapCompare() or mapCopy()");
+
+    check(!mapCompare(g, map1, constMap<Node>(2)), "Wrong mapCompare()");
+    mapFill(g, map1, 2);
+    check(mapCompare(g, constMap<Node>(2), map1), "Wrong mapFill()");
+
+    check(!mapCompare(g, map2, constMap<Arc>('z')), "Wrong mapCompare()");
+    mapCopy(g, constMap<Arc>('z'), map2);
+    check(mapCompare(g, constMap<Arc>('z'), map2), "Wrong mapCopy()");
   }
 
Index: test/matching_test.cc
===================================================================
--- test/matching_test.cc	(revision 983)
+++ test/matching_test.cc	(revision 983)
@@ -0,0 +1,449 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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 <cstdlib>
+
+#include <lemon/matching.h>
+#include <lemon/smart_graph.h>
+#include <lemon/concepts/graph.h>
+#include <lemon/concepts/maps.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/math.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 checkMaxMatchingCompile()
+{
+  typedef concepts::Graph Graph;
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+  typedef Graph::EdgeMap<bool> MatMap;
+
+  Graph g;
+  Node n;
+  Edge e;
+  MatMap mat(g);
+
+  MaxMatching<Graph> mat_test(g);
+  const MaxMatching<Graph>&
+    const_mat_test = mat_test;
+
+  mat_test.init();
+  mat_test.greedyInit();
+  mat_test.matchingInit(mat);
+  mat_test.startSparse();
+  mat_test.startDense();
+  mat_test.run();
+
+  const_mat_test.matchingSize();
+  const_mat_test.matching(e);
+  const_mat_test.matching(n);
+  const MaxMatching<Graph>::MatchingMap& mmap =
+    const_mat_test.matchingMap();
+  e = mmap[n];
+  const_mat_test.mate(n);
+
+  MaxMatching<Graph>::Status stat =
+    const_mat_test.status(n);
+  ::lemon::ignore_unused_variable_warning(stat);
+  const MaxMatching<Graph>::StatusMap& smap =
+    const_mat_test.statusMap();
+  stat = smap[n];
+  const_mat_test.barrier(n);
+}
+
+void checkMaxWeightedMatchingCompile()
+{
+  typedef concepts::Graph Graph;
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+  typedef Graph::EdgeMap<int> WeightMap;
+
+  Graph g;
+  Node n;
+  Edge e;
+  WeightMap w(g);
+
+  MaxWeightedMatching<Graph> mat_test(g, w);
+  const MaxWeightedMatching<Graph>&
+    const_mat_test = mat_test;
+
+  mat_test.init();
+  mat_test.start();
+  mat_test.run();
+
+  const_mat_test.matchingWeight();
+  const_mat_test.matchingSize();
+  const_mat_test.matching(e);
+  const_mat_test.matching(n);
+  const MaxWeightedMatching<Graph>::MatchingMap& mmap =
+    const_mat_test.matchingMap();
+  e = mmap[n];
+  const_mat_test.mate(n);
+
+  int k = 0;
+  const_mat_test.dualValue();
+  const_mat_test.nodeValue(n);
+  const_mat_test.blossomNum();
+  const_mat_test.blossomSize(k);
+  const_mat_test.blossomValue(k);
+}
+
+void checkMaxWeightedPerfectMatchingCompile()
+{
+  typedef concepts::Graph Graph;
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+  typedef Graph::EdgeMap<int> WeightMap;
+
+  Graph g;
+  Node n;
+  Edge e;
+  WeightMap w(g);
+
+  MaxWeightedPerfectMatching<Graph> mat_test(g, w);
+  const MaxWeightedPerfectMatching<Graph>&
+    const_mat_test = mat_test;
+
+  mat_test.init();
+  mat_test.start();
+  mat_test.run();
+
+  const_mat_test.matchingWeight();
+  const_mat_test.matching(e);
+  const_mat_test.matching(n);
+  const MaxWeightedPerfectMatching<Graph>::MatchingMap& mmap =
+    const_mat_test.matchingMap();
+  e = mmap[n];
+  const_mat_test.mate(n);
+
+  int k = 0;
+  const_mat_test.dualValue();
+  const_mat_test.nodeValue(n);
+  const_mat_test.blossomNum();
+  const_mat_test.blossomSize(k);
+  const_mat_test.blossomValue(k);
+}
+
+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.status(n) == MaxMatching<SmartGraph>::EVEN ||
+          mm.matching(n) != INVALID, "Wrong Gallai-Edmonds decomposition");
+    if (mm.status(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.status(graph.u(e)) != MaxMatching<SmartGraph>::EVEN ||
+          mm.status(graph.v(e)) != MaxMatching<SmartGraph>::MATCHED,
+          "Wrong Gallai-Edmonds decomposition");
+
+    check(mm.status(graph.v(e)) != MaxMatching<SmartGraph>::EVEN ||
+          mm.status(graph.u(e)) != MaxMatching<SmartGraph>::MATCHED,
+          "Wrong Gallai-Edmonds decomposition");
+
+    if (mm.status(graph.u(e)) != MaxMatching<SmartGraph>::ODD &&
+        mm.status(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.status(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();
+
+    bool perfect;
+    {
+      MaxMatching<SmartGraph> mm(graph);
+      mm.run();
+      checkMatching(graph, mm);
+      perfect = 2 * mm.matchingSize() == countNodes(graph);
+    }
+
+    {
+      MaxWeightedMatching<SmartGraph> mwm(graph, weight);
+      mwm.run();
+      checkWeightedMatching(graph, weight, mwm);
+    }
+
+    {
+      MaxWeightedMatching<SmartGraph> mwm(graph, weight);
+      mwm.init();
+      mwm.start();
+      checkWeightedMatching(graph, weight, mwm);
+    }
+
+    {
+      MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
+      bool result = mwpm.run();
+
+      check(result == perfect, "Perfect matching found");
+      if (perfect) {
+        checkWeightedPerfectMatching(graph, weight, mwpm);
+      }
+    }
+
+    {
+      MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
+      mwpm.init();
+      bool result = mwpm.start();
+
+      check(result == perfect, "Perfect matching found");
+      if (perfect) {
+        checkWeightedPerfectMatching(graph, weight, mwpm);
+      }
+    }
+  }
+
+  return 0;
+}
Index: st/max_matching_test.cc
===================================================================
--- test/max_matching_test.cc	(revision 440)
+++ 	(revision )
@@ -1,310 +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.
- *
- */
-
-#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/min_cost_arborescence_test.cc
===================================================================
--- test/min_cost_arborescence_test.cc	(revision 490)
+++ test/min_cost_arborescence_test.cc	(revision 983)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2008
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -25,4 +25,5 @@
 #include <lemon/min_cost_arborescence.h>
 #include <lemon/lgf_reader.h>
+#include <lemon/concepts/digraph.h>
 
 #include "test_tools.h"
@@ -71,4 +72,64 @@
   "source 0\n";
 
+
+void checkMinCostArborescenceCompile()
+{
+  typedef double VType;
+  typedef concepts::Digraph Digraph;
+  typedef concepts::ReadMap<Digraph::Arc, VType> CostMap;
+  typedef Digraph::Node Node;
+  typedef Digraph::Arc Arc;
+  typedef concepts::WriteMap<Digraph::Arc, bool> ArbMap;
+  typedef concepts::ReadWriteMap<Digraph::Node, Digraph::Arc> PredMap;
+
+  typedef MinCostArborescence<Digraph, CostMap>::
+            SetArborescenceMap<ArbMap>::
+            SetPredMap<PredMap>::Create MinCostArbType;
+
+  Digraph g;
+  Node s, n;
+  Arc e;
+  VType c;
+  bool b;
+  ::lemon::ignore_unused_variable_warning(c,b);
+  int i;
+  CostMap cost;
+  ArbMap arb;
+  PredMap pred;
+
+  MinCostArbType mcarb_test(g, cost);
+  const MinCostArbType& const_mcarb_test = mcarb_test;
+
+  mcarb_test
+    .arborescenceMap(arb)
+    .predMap(pred)
+    .run(s);
+
+  mcarb_test.init();
+  mcarb_test.addSource(s);
+  mcarb_test.start();
+  n = mcarb_test.processNextNode();
+  b = const_mcarb_test.emptyQueue();
+  i = const_mcarb_test.queueSize();
+
+  c = const_mcarb_test.arborescenceCost();
+  b = const_mcarb_test.arborescence(e);
+  e = const_mcarb_test.pred(n);
+  const MinCostArbType::ArborescenceMap &am =
+    const_mcarb_test.arborescenceMap();
+  const MinCostArbType::PredMap &pm =
+    const_mcarb_test.predMap();
+  b = const_mcarb_test.reached(n);
+  b = const_mcarb_test.processed(n);
+
+  i = const_mcarb_test.dualNum();
+  c = const_mcarb_test.dualValue();
+  i = const_mcarb_test.dualSize(i);
+  c = const_mcarb_test.dualValue(i);
+
+  ::lemon::ignore_unused_variable_warning(am);
+  ::lemon::ignore_unused_variable_warning(pm);
+}
+
 int main() {
   typedef SmartDigraph Digraph;
@@ -111,17 +172,17 @@
       }
       if (mca.arborescence(it)) {
-        check(sum == cost[it], "INVALID DUAL");
+        check(sum == cost[it], "Invalid dual solution");
       }
-      check(sum <= cost[it], "INVALID DUAL");
+      check(sum <= cost[it], "Invalid dual solution");
     }
   }
 
 
-  check(mca.dualValue() == mca.arborescenceValue(), "INVALID DUAL");
-
-  check(mca.reached(source), "INVALID ARBORESCENCE");
+  check(mca.dualValue() == mca.arborescenceCost(), "Invalid dual solution");
+
+  check(mca.reached(source), "Invalid arborescence");
   for (ArcIt a(digraph); a != INVALID; ++a) {
     check(!mca.reached(digraph.source(a)) ||
-          mca.reached(digraph.target(a)), "INVALID ARBORESCENCE");
+          mca.reached(digraph.target(a)), "Invalid arborescence");
   }
 
@@ -131,15 +192,15 @@
     for (InArcIt a(digraph, n); a != INVALID; ++a) {
       if (mca.arborescence(a)) {
-        check(mca.pred(n) == a, "INVALID ARBORESCENCE");
+        check(mca.pred(n) == a, "Invalid arborescence");
         ++cnt;
       }
     }
-    check((n == source ? cnt == 0 : cnt == 1), "INVALID ARBORESCENCE");
+    check((n == source ? cnt == 0 : cnt == 1), "Invalid arborescence");
   }
 
   Digraph::ArcMap<bool> arborescence(digraph);
-  check(mca.arborescenceValue() ==
+  check(mca.arborescenceCost() ==
         minCostArborescence(digraph, cost, source, arborescence),
-        "WRONG FUNCTION");
+        "Wrong result of the function interface");
 
   return 0;
Index: test/min_cost_flow_test.cc
===================================================================
--- test/min_cost_flow_test.cc	(revision 877)
+++ test/min_cost_flow_test.cc	(revision 877)
@@ -0,0 +1,542 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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 <fstream>
+#include <limits>
+
+#include <lemon/list_graph.h>
+#include <lemon/lgf_reader.h>
+
+#include <lemon/network_simplex.h>
+#include <lemon/capacity_scaling.h>
+#include <lemon/cost_scaling.h>
+#include <lemon/cycle_canceling.h>
+
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/heap.h>
+#include <lemon/concept_check.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+
+// Test networks
+char test_lgf[] =
+  "@nodes\n"
+  "label  sup1 sup2 sup3 sup4 sup5 sup6\n"
+  "    1    20   27    0   30   20   30\n"
+  "    2    -4    0    0    0   -8   -3\n"
+  "    3     0    0    0    0    0    0\n"
+  "    4     0    0    0    0    0    0\n"
+  "    5     9    0    0    0    6   11\n"
+  "    6    -6    0    0    0   -5   -6\n"
+  "    7     0    0    0    0    0    0\n"
+  "    8     0    0    0    0    0    3\n"
+  "    9     3    0    0    0    0    0\n"
+  "   10    -2    0    0    0   -7   -2\n"
+  "   11     0    0    0    0  -10    0\n"
+  "   12   -20  -27    0  -30  -30  -20\n"
+  "\n"
+  "@arcs\n"
+  "       cost  cap low1 low2 low3\n"
+  " 1  2    70   11    0    8    8\n"
+  " 1  3   150    3    0    1    0\n"
+  " 1  4    80   15    0    2    2\n"
+  " 2  8    80   12    0    0    0\n"
+  " 3  5   140    5    0    3    1\n"
+  " 4  6    60   10    0    1    0\n"
+  " 4  7    80    2    0    0    0\n"
+  " 4  8   110    3    0    0    0\n"
+  " 5  7    60   14    0    0    0\n"
+  " 5 11   120   12    0    0    0\n"
+  " 6  3     0    3    0    0    0\n"
+  " 6  9   140    4    0    0    0\n"
+  " 6 10    90    8    0    0    0\n"
+  " 7  1    30    5    0    0   -5\n"
+  " 8 12    60   16    0    4    3\n"
+  " 9 12    50    6    0    0    0\n"
+  "10 12    70   13    0    5    2\n"
+  "10  2   100    7    0    0    0\n"
+  "10  7    60   10    0    0   -3\n"
+  "11 10    20   14    0    6  -20\n"
+  "12 11    30   10    0    0  -10\n"
+  "\n"
+  "@attributes\n"
+  "source 1\n"
+  "target 12\n";
+
+char test_neg1_lgf[] =
+  "@nodes\n"
+  "label   sup\n"
+  "    1   100\n"
+  "    2     0\n"
+  "    3     0\n"
+  "    4  -100\n"
+  "    5     0\n"
+  "    6     0\n"
+  "    7     0\n"
+  "@arcs\n"
+  "      cost   low1   low2\n"
+  "1 2    100      0      0\n"
+  "1 3     30      0      0\n"
+  "2 4     20      0      0\n"
+  "3 4     80      0      0\n"
+  "3 2     50      0      0\n"
+  "5 3     10      0      0\n"
+  "5 6     80      0   1000\n"
+  "6 7     30      0  -1000\n"
+  "7 5   -120      0      0\n";
+
+char test_neg2_lgf[] =
+  "@nodes\n"
+  "label   sup\n"
+  "    1   100\n"
+  "    2  -300\n"
+  "@arcs\n"
+  "      cost\n"
+  "1 2     -1\n";
+
+
+// Test data
+typedef ListDigraph Digraph;
+DIGRAPH_TYPEDEFS(ListDigraph);
+
+Digraph gr;
+Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), l3(gr), u(gr);
+Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr), s4(gr), s5(gr), s6(gr);
+ConstMap<Arc, int> cc(1), cu(std::numeric_limits<int>::max());
+Node v, w;
+
+Digraph neg1_gr;
+Digraph::ArcMap<int> neg1_c(neg1_gr), neg1_l1(neg1_gr), neg1_l2(neg1_gr);
+ConstMap<Arc, int> neg1_u1(std::numeric_limits<int>::max()), neg1_u2(5000);
+Digraph::NodeMap<int> neg1_s(neg1_gr);
+
+Digraph neg2_gr;
+Digraph::ArcMap<int> neg2_c(neg2_gr);
+ConstMap<Arc, int> neg2_l(0), neg2_u(1000);
+Digraph::NodeMap<int> neg2_s(neg2_gr);
+
+
+enum SupplyType {
+  EQ,
+  GEQ,
+  LEQ
+};
+
+
+// Check the interface of an MCF algorithm
+template <typename GR, typename Value, typename Cost>
+class McfClassConcept
+{
+public:
+
+  template <typename MCF>
+  struct Constraints {
+    void constraints() {
+      checkConcept<concepts::Digraph, GR>();
+
+      const Constraints& me = *this;
+
+      MCF mcf(me.g);
+      const MCF& const_mcf = mcf;
+
+      b = mcf.reset().resetParams()
+             .lowerMap(me.lower)
+             .upperMap(me.upper)
+             .costMap(me.cost)
+             .supplyMap(me.sup)
+             .stSupply(me.n, me.n, me.k)
+             .run();
+
+      c = const_mcf.totalCost();
+      x = const_mcf.template totalCost<double>();
+      v = const_mcf.flow(me.a);
+      c = const_mcf.potential(me.n);
+      const_mcf.flowMap(fm);
+      const_mcf.potentialMap(pm);
+    }
+
+    typedef typename GR::Node Node;
+    typedef typename GR::Arc Arc;
+    typedef concepts::ReadMap<Node, Value> NM;
+    typedef concepts::ReadMap<Arc, Value> VAM;
+    typedef concepts::ReadMap<Arc, Cost> CAM;
+    typedef concepts::WriteMap<Arc, Value> FlowMap;
+    typedef concepts::WriteMap<Node, Cost> PotMap;
+
+    GR g;
+    VAM lower;
+    VAM upper;
+    CAM cost;
+    NM sup;
+    Node n;
+    Arc a;
+    Value k;
+
+    FlowMap fm;
+    PotMap pm;
+    bool b;
+    double x;
+    typename MCF::Value v;
+    typename MCF::Cost c;
+  };
+
+};
+
+
+// Check the feasibility of the given flow (primal soluiton)
+template < typename GR, typename LM, typename UM,
+           typename SM, typename FM >
+bool checkFlow( const GR& gr, const LM& lower, const UM& upper,
+                const SM& supply, const FM& flow,
+                SupplyType type = EQ )
+{
+  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
+
+  for (ArcIt e(gr); e != INVALID; ++e) {
+    if (flow[e] < lower[e] || flow[e] > upper[e]) return false;
+  }
+
+  for (NodeIt n(gr); n != INVALID; ++n) {
+    typename SM::Value sum = 0;
+    for (OutArcIt e(gr, n); e != INVALID; ++e)
+      sum += flow[e];
+    for (InArcIt e(gr, n); e != INVALID; ++e)
+      sum -= flow[e];
+    bool b = (type ==  EQ && sum == supply[n]) ||
+             (type == GEQ && sum >= supply[n]) ||
+             (type == LEQ && sum <= supply[n]);
+    if (!b) return false;
+  }
+
+  return true;
+}
+
+// Check the feasibility of the given potentials (dual soluiton)
+// using the "Complementary Slackness" optimality condition
+template < typename GR, typename LM, typename UM,
+           typename CM, typename SM, typename FM, typename PM >
+bool checkPotential( const GR& gr, const LM& lower, const UM& upper,
+                     const CM& cost, const SM& supply, const FM& flow,
+                     const PM& pi, SupplyType type )
+{
+  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
+
+  bool opt = true;
+  for (ArcIt e(gr); opt && e != INVALID; ++e) {
+    typename CM::Value red_cost =
+      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
+    opt = red_cost == 0 ||
+          (red_cost > 0 && flow[e] == lower[e]) ||
+          (red_cost < 0 && flow[e] == upper[e]);
+  }
+
+  for (NodeIt n(gr); opt && n != INVALID; ++n) {
+    typename SM::Value 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 (type != LEQ) {
+      opt = (pi[n] <= 0) && (sum == supply[n] || pi[n] == 0);
+    } else {
+      opt = (pi[n] >= 0) && (sum == supply[n] || pi[n] == 0);
+    }
+  }
+
+  return opt;
+}
+
+// Check whether the dual cost is equal to the primal cost
+template < typename GR, typename LM, typename UM,
+           typename CM, typename SM, typename PM >
+bool checkDualCost( const GR& gr, const LM& lower, const UM& upper,
+                    const CM& cost, const SM& supply, const PM& pi,
+                    typename CM::Value total )
+{
+  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
+
+  typename CM::Value dual_cost = 0;
+  SM red_supply(gr);
+  for (NodeIt n(gr); n != INVALID; ++n) {
+    red_supply[n] = supply[n];
+  }
+  for (ArcIt a(gr); a != INVALID; ++a) {
+    if (lower[a] != 0) {
+      dual_cost += lower[a] * cost[a];
+      red_supply[gr.source(a)] -= lower[a];
+      red_supply[gr.target(a)] += lower[a];
+    }
+  }
+
+  for (NodeIt n(gr); n != INVALID; ++n) {
+    dual_cost -= red_supply[n] * pi[n];
+  }
+  for (ArcIt a(gr); a != INVALID; ++a) {
+    typename CM::Value red_cost =
+      cost[a] + pi[gr.source(a)] - pi[gr.target(a)];
+    dual_cost -= (upper[a] - lower[a]) * std::max(-red_cost, 0);
+  }
+
+  return dual_cost == total;
+}
+
+// Run a minimum cost flow algorithm and check the results
+template < typename MCF, typename GR,
+           typename LM, typename UM,
+           typename CM, typename SM,
+           typename PT >
+void checkMcf( const MCF& mcf, PT mcf_result,
+               const GR& gr, const LM& lower, const UM& upper,
+               const CM& cost, const SM& supply,
+               PT result, bool optimal, typename CM::Value total,
+               const std::string &test_id = "",
+               SupplyType type = EQ )
+{
+  check(mcf_result == result, "Wrong result " + test_id);
+  if (optimal) {
+    typename GR::template ArcMap<typename SM::Value> flow(gr);
+    typename GR::template NodeMap<typename CM::Value> pi(gr);
+    mcf.flowMap(flow);
+    mcf.potentialMap(pi);
+    check(checkFlow(gr, lower, upper, supply, flow, type),
+          "The flow is not feasible " + test_id);
+    check(mcf.totalCost() == total, "The flow is not optimal " + test_id);
+    check(checkPotential(gr, lower, upper, cost, supply, flow, pi, type),
+          "Wrong potentials " + test_id);
+    check(checkDualCost(gr, lower, upper, cost, supply, pi, total),
+          "Wrong dual cost " + test_id);
+  }
+}
+
+template < typename MCF, typename Param >
+void runMcfGeqTests( Param param,
+                     const std::string &test_str = "",
+                     bool full_neg_cost_support = false )
+{
+  MCF mcf1(gr), mcf2(neg1_gr), mcf3(neg2_gr);
+
+  // Basic tests
+  mcf1.upperMap(u).costMap(c).supplyMap(s1);
+  checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s1,
+           mcf1.OPTIMAL, true,     5240, test_str + "-1");
+  mcf1.stSupply(v, w, 27);
+  checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s2,
+           mcf1.OPTIMAL, true,     7620, test_str + "-2");
+  mcf1.lowerMap(l2).supplyMap(s1);
+  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s1,
+           mcf1.OPTIMAL, true,     5970, test_str + "-3");
+  mcf1.stSupply(v, w, 27);
+  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s2,
+           mcf1.OPTIMAL, true,     8010, test_str + "-4");
+  mcf1.resetParams().supplyMap(s1);
+  checkMcf(mcf1, mcf1.run(param), gr, l1, cu, cc, s1,
+           mcf1.OPTIMAL, true,       74, test_str + "-5");
+  mcf1.lowerMap(l2).stSupply(v, w, 27);
+  checkMcf(mcf1, mcf1.run(param), gr, l2, cu, cc, s2,
+           mcf1.OPTIMAL, true,       94, test_str + "-6");
+  mcf1.reset();
+  checkMcf(mcf1, mcf1.run(param), gr, l1, cu, cc, s3,
+           mcf1.OPTIMAL, true,        0, test_str + "-7");
+  mcf1.lowerMap(l2).upperMap(u);
+  checkMcf(mcf1, mcf1.run(param), gr, l2, u, cc, s3,
+           mcf1.INFEASIBLE, false,    0, test_str + "-8");
+  mcf1.lowerMap(l3).upperMap(u).costMap(c).supplyMap(s4);
+  checkMcf(mcf1, mcf1.run(param), gr, l3, u, c, s4,
+           mcf1.OPTIMAL, true,     6360, test_str + "-9");
+
+  // Tests for the GEQ form
+  mcf1.resetParams().upperMap(u).costMap(c).supplyMap(s5);
+  checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s5,
+           mcf1.OPTIMAL, true,     3530, test_str + "-10", GEQ);
+  mcf1.lowerMap(l2);
+  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s5,
+           mcf1.OPTIMAL, true,     4540, test_str + "-11", GEQ);
+  mcf1.supplyMap(s6);
+  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s6,
+           mcf1.INFEASIBLE, false,    0, test_str + "-12", GEQ);
+
+  // Tests with negative costs
+  mcf2.lowerMap(neg1_l1).costMap(neg1_c).supplyMap(neg1_s);
+  checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l1, neg1_u1, neg1_c, neg1_s,
+           mcf2.UNBOUNDED, false,     0, test_str + "-13");
+  mcf2.upperMap(neg1_u2);
+  checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l1, neg1_u2, neg1_c, neg1_s,
+           mcf2.OPTIMAL, true,   -40000, test_str + "-14");
+  mcf2.resetParams().lowerMap(neg1_l2).costMap(neg1_c).supplyMap(neg1_s);
+  checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l2, neg1_u1, neg1_c, neg1_s,
+           mcf2.UNBOUNDED, false,     0, test_str + "-15");
+
+  mcf3.costMap(neg2_c).supplyMap(neg2_s);
+  if (full_neg_cost_support) {
+    checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
+             mcf3.OPTIMAL, true,   -300, test_str + "-16", GEQ);
+  } else {
+    checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
+             mcf3.UNBOUNDED, false,   0, test_str + "-17", GEQ);
+  }
+  mcf3.upperMap(neg2_u);
+  checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
+           mcf3.OPTIMAL, true,     -300, test_str + "-18", GEQ);
+}
+
+template < typename MCF, typename Param >
+void runMcfLeqTests( Param param,
+                     const std::string &test_str = "" )
+{
+  // Tests for the LEQ form
+  MCF mcf1(gr);
+  mcf1.supplyType(mcf1.LEQ);
+  mcf1.upperMap(u).costMap(c).supplyMap(s6);
+  checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s6,
+           mcf1.OPTIMAL, true,   5080, test_str + "-19", LEQ);
+  mcf1.lowerMap(l2);
+  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s6,
+           mcf1.OPTIMAL, true,   5930, test_str + "-20", LEQ);
+  mcf1.supplyMap(s5);
+  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s5,
+           mcf1.INFEASIBLE, false,  0, test_str + "-21", LEQ);
+}
+
+
+int main()
+{
+  // Read the test networks
+  std::istringstream input(test_lgf);
+  DigraphReader<Digraph>(gr, input)
+    .arcMap("cost", c)
+    .arcMap("cap", u)
+    .arcMap("low1", l1)
+    .arcMap("low2", l2)
+    .arcMap("low3", l3)
+    .nodeMap("sup1", s1)
+    .nodeMap("sup2", s2)
+    .nodeMap("sup3", s3)
+    .nodeMap("sup4", s4)
+    .nodeMap("sup5", s5)
+    .nodeMap("sup6", s6)
+    .node("source", v)
+    .node("target", w)
+    .run();
+
+  std::istringstream neg_inp1(test_neg1_lgf);
+  DigraphReader<Digraph>(neg1_gr, neg_inp1)
+    .arcMap("cost", neg1_c)
+    .arcMap("low1", neg1_l1)
+    .arcMap("low2", neg1_l2)
+    .nodeMap("sup", neg1_s)
+    .run();
+
+  std::istringstream neg_inp2(test_neg2_lgf);
+  DigraphReader<Digraph>(neg2_gr, neg_inp2)
+    .arcMap("cost", neg2_c)
+    .nodeMap("sup", neg2_s)
+    .run();
+
+  // Check the interface of NetworkSimplex
+  {
+    typedef concepts::Digraph GR;
+    checkConcept< McfClassConcept<GR, int, int>,
+                  NetworkSimplex<GR> >();
+    checkConcept< McfClassConcept<GR, double, double>,
+                  NetworkSimplex<GR, double> >();
+    checkConcept< McfClassConcept<GR, int, double>,
+                  NetworkSimplex<GR, int, double> >();
+  }
+
+  // Check the interface of CapacityScaling
+  {
+    typedef concepts::Digraph GR;
+    checkConcept< McfClassConcept<GR, int, int>,
+                  CapacityScaling<GR> >();
+    checkConcept< McfClassConcept<GR, double, double>,
+                  CapacityScaling<GR, double> >();
+    checkConcept< McfClassConcept<GR, int, double>,
+                  CapacityScaling<GR, int, double> >();
+    typedef CapacityScaling<GR>::
+      SetHeap<concepts::Heap<int, RangeMap<int> > >::Create CAS;
+    checkConcept< McfClassConcept<GR, int, int>, CAS >();
+  }
+
+  // Check the interface of CostScaling
+  {
+    typedef concepts::Digraph GR;
+    checkConcept< McfClassConcept<GR, int, int>,
+                  CostScaling<GR> >();
+    checkConcept< McfClassConcept<GR, double, double>,
+                  CostScaling<GR, double> >();
+    checkConcept< McfClassConcept<GR, int, double>,
+                  CostScaling<GR, int, double> >();
+    typedef CostScaling<GR>::
+      SetLargeCost<double>::Create COS;
+    checkConcept< McfClassConcept<GR, int, int>, COS >();
+  }
+
+  // Check the interface of CycleCanceling
+  {
+    typedef concepts::Digraph GR;
+    checkConcept< McfClassConcept<GR, int, int>,
+                  CycleCanceling<GR> >();
+    checkConcept< McfClassConcept<GR, double, double>,
+                  CycleCanceling<GR, double> >();
+    checkConcept< McfClassConcept<GR, int, double>,
+                  CycleCanceling<GR, int, double> >();
+  }
+
+  // Test NetworkSimplex
+  {
+    typedef NetworkSimplex<Digraph> MCF;
+    runMcfGeqTests<MCF>(MCF::FIRST_ELIGIBLE, "NS-FE", true);
+    runMcfLeqTests<MCF>(MCF::FIRST_ELIGIBLE, "NS-FE");
+    runMcfGeqTests<MCF>(MCF::BEST_ELIGIBLE,  "NS-BE", true);
+    runMcfLeqTests<MCF>(MCF::BEST_ELIGIBLE,  "NS-BE");
+    runMcfGeqTests<MCF>(MCF::BLOCK_SEARCH,   "NS-BS", true);
+    runMcfLeqTests<MCF>(MCF::BLOCK_SEARCH,   "NS-BS");
+    runMcfGeqTests<MCF>(MCF::CANDIDATE_LIST, "NS-CL", true);
+    runMcfLeqTests<MCF>(MCF::CANDIDATE_LIST, "NS-CL");
+    runMcfGeqTests<MCF>(MCF::ALTERING_LIST,  "NS-AL", true);
+    runMcfLeqTests<MCF>(MCF::ALTERING_LIST,  "NS-AL");
+  }
+
+  // Test CapacityScaling
+  {
+    typedef CapacityScaling<Digraph> MCF;
+    runMcfGeqTests<MCF>(0, "SSP");
+    runMcfGeqTests<MCF>(2, "CAS");
+  }
+
+  // Test CostScaling
+  {
+    typedef CostScaling<Digraph> MCF;
+    runMcfGeqTests<MCF>(MCF::PUSH, "COS-PR");
+    runMcfGeqTests<MCF>(MCF::AUGMENT, "COS-AR");
+    runMcfGeqTests<MCF>(MCF::PARTIAL_AUGMENT, "COS-PAR");
+  }
+
+  // Test CycleCanceling
+  {
+    typedef CycleCanceling<Digraph> MCF;
+    runMcfGeqTests<MCF>(MCF::SIMPLE_CYCLE_CANCELING, "SCC");
+    runMcfGeqTests<MCF>(MCF::MINIMUM_MEAN_CYCLE_CANCELING, "MMCC");
+    runMcfGeqTests<MCF>(MCF::CANCEL_AND_TIGHTEN, "CAT");
+  }
+
+  return 0;
+}
Index: test/min_mean_cycle_test.cc
===================================================================
--- test/min_mean_cycle_test.cc	(revision 877)
+++ test/min_mean_cycle_test.cc	(revision 877)
@@ -0,0 +1,216 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2010
+ * 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 <lemon/smart_graph.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/path.h>
+#include <lemon/concepts/digraph.h>
+#include <lemon/concept_check.h>
+
+#include <lemon/karp_mmc.h>
+#include <lemon/hartmann_orlin_mmc.h>
+#include <lemon/howard_mmc.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+
+char test_lgf[] =
+  "@nodes\n"
+  "label\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "@arcs\n"
+  "    len1 len2 len3 len4  c1 c2 c3 c4\n"
+  "1 2    1    1    1    1   0  0  0  0\n"
+  "2 4    5    5    5    5   1  0  0  0\n"
+  "2 3    8    8    8    8   0  0  0  0\n"
+  "3 2   -2    0    0    0   1  0  0  0\n"
+  "3 4    4    4    4    4   0  0  0  0\n"
+  "3 7   -4   -4   -4   -4   0  0  0  0\n"
+  "4 1    2    2    2    2   0  0  0  0\n"
+  "4 3    3    3    3    3   1  0  0  0\n"
+  "4 4    3    3    0    0   0  0  1  0\n"
+  "5 2    4    4    4    4   0  0  0  0\n"
+  "5 6    3    3    3    3   0  1  0  0\n"
+  "6 5    2    2    2    2   0  1  0  0\n"
+  "6 4   -1   -1   -1   -1   0  0  0  0\n"
+  "6 7    1    1    1    1   0  0  0  0\n"
+  "7 7    4    4    4   -1   0  0  0  1\n";
+
+
+// Check the interface of an MMC algorithm
+template <typename GR, typename Cost>
+struct MmcClassConcept
+{
+  template <typename MMC>
+  struct Constraints {
+    void constraints() {
+      const Constraints& me = *this;
+
+      typedef typename MMC
+        ::template SetPath<ListPath<GR> >
+        ::template SetLargeCost<Cost>
+        ::Create MmcAlg;
+      MmcAlg mmc(me.g, me.cost);
+      const MmcAlg& const_mmc = mmc;
+
+      typename MmcAlg::Tolerance tol = const_mmc.tolerance();
+      mmc.tolerance(tol);
+
+      b = mmc.cycle(p).run();
+      b = mmc.findCycleMean();
+      b = mmc.findCycle();
+
+      v = const_mmc.cycleCost();
+      i = const_mmc.cycleSize();
+      d = const_mmc.cycleMean();
+      p = const_mmc.cycle();
+    }
+
+    typedef concepts::ReadMap<typename GR::Arc, Cost> CM;
+
+    GR g;
+    CM cost;
+    ListPath<GR> p;
+    Cost v;
+    int i;
+    double d;
+    bool b;
+  };
+};
+
+// Perform a test with the given parameters
+template <typename MMC>
+void checkMmcAlg(const SmartDigraph& gr,
+                 const SmartDigraph::ArcMap<int>& lm,
+                 const SmartDigraph::ArcMap<int>& cm,
+                 int cost, int size) {
+  MMC alg(gr, lm);
+  alg.findCycleMean();
+  check(alg.cycleMean() == static_cast<double>(cost) / size,
+        "Wrong cycle mean");
+  alg.findCycle();
+  check(alg.cycleCost() == cost && alg.cycleSize() == size,
+        "Wrong path");
+  SmartDigraph::ArcMap<int> cycle(gr, 0);
+  for (typename MMC::Path::ArcIt a(alg.cycle()); a != INVALID; ++a) {
+    ++cycle[a];
+  }
+  for (SmartDigraph::ArcIt a(gr); a != INVALID; ++a) {
+    check(cm[a] == cycle[a], "Wrong path");
+  }
+}
+
+// Class for comparing types
+template <typename T1, typename T2>
+struct IsSameType {
+  static const int result = 0;
+};
+
+template <typename T>
+struct IsSameType<T,T> {
+  static const int result = 1;
+};
+
+
+int main() {
+  #ifdef LEMON_HAVE_LONG_LONG
+    typedef long long long_int;
+  #else
+    typedef long long_int;
+  #endif
+
+  // Check the interface
+  {
+    typedef concepts::Digraph GR;
+
+    // KarpMmc
+    checkConcept< MmcClassConcept<GR, int>,
+                  KarpMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
+    checkConcept< MmcClassConcept<GR, float>,
+                  KarpMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
+
+    // HartmannOrlinMmc
+    checkConcept< MmcClassConcept<GR, int>,
+                  HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
+    checkConcept< MmcClassConcept<GR, float>,
+                  HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
+
+    // HowardMmc
+    checkConcept< MmcClassConcept<GR, int>,
+                  HowardMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
+    checkConcept< MmcClassConcept<GR, float>,
+                  HowardMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
+
+    check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, int> >
+           ::LargeCost, long_int>::result == 1), "Wrong LargeCost type");
+    check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, float> >
+           ::LargeCost, double>::result == 1), "Wrong LargeCost type");
+  }
+
+  // Run various tests
+  {
+    typedef SmartDigraph GR;
+    DIGRAPH_TYPEDEFS(GR);
+
+    GR gr;
+    IntArcMap l1(gr), l2(gr), l3(gr), l4(gr);
+    IntArcMap c1(gr), c2(gr), c3(gr), c4(gr);
+
+    std::istringstream input(test_lgf);
+    digraphReader(gr, input).
+      arcMap("len1", l1).
+      arcMap("len2", l2).
+      arcMap("len3", l3).
+      arcMap("len4", l4).
+      arcMap("c1", c1).
+      arcMap("c2", c2).
+      arcMap("c3", c3).
+      arcMap("c4", c4).
+      run();
+
+    // Karp
+    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
+    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
+    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
+    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
+
+    // HartmannOrlin
+    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
+    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
+    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
+    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
+
+    // Howard
+    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
+    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
+    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
+    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
+  }
+
+  return 0;
+}
Index: test/mip_test.cc
===================================================================
--- test/mip_test.cc	(revision 551)
+++ test/mip_test.cc	(revision 748)
@@ -19,15 +19,16 @@
 #include "test_tools.h"
 
+#include <lemon/config.h>
 
-#ifdef HAVE_CONFIG_H
-#include <lemon/config.h>
-#endif
-
-#ifdef HAVE_CPLEX
+#ifdef LEMON_HAVE_CPLEX
 #include <lemon/cplex.h>
 #endif
 
-#ifdef HAVE_GLPK
+#ifdef LEMON_HAVE_GLPK
 #include <lemon/glpk.h>
+#endif
+
+#ifdef LEMON_HAVE_CBC
+#include <lemon/cbc.h>
 #endif
 
@@ -50,5 +51,6 @@
   if (stat ==  MipSolver::OPTIMAL) {
     std::ostringstream sbuf;
-    buf << "Wrong optimal value: the right optimum is " << exp_opt;
+    sbuf << "Wrong optimal value ("<< mip.solValue()
+         <<" instead of " << exp_opt << ")";
     check(std::abs(mip.solValue()-exp_opt) < 1e-3, sbuf.str());
     //+ecvt(exp_opt,2)
@@ -58,10 +60,9 @@
 void aTest(MipSolver& mip)
 {
- //The following example is very simple
+  //The following example is very simple
 
 
   typedef MipSolver::Row Row;
   typedef MipSolver::Col Col;
-
 
 
@@ -75,5 +76,4 @@
   mip.max();
 
-
   //Unconstrained optimization
   mip.solve();
@@ -81,9 +81,10 @@
 
   //Constraints
-  mip.addRow(2*x1+x2 <=2);
-  mip.addRow(x1-2*x2 <=0);
+  mip.addRow(2 * x1 + x2 <= 2);
+  Row y2 = mip.addRow(x1 - 2 * x2 <= 0);
 
   //Nonnegativity of the variable x1
   mip.colLowerBound(x1, 0);
+
 
   //Maximization of x1
@@ -91,4 +92,5 @@
   double expected_opt=4.0/5.0;
   solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
+
 
   //Restrict x2 to integer
@@ -103,7 +105,12 @@
   solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
 
-
+  //Erase a variable
+  mip.erase(x2);
+  mip.rowUpperBound(y2, 8);
+  expected_opt=1;
+  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
 
 }
+
 
 template<class MIP>
@@ -122,5 +129,5 @@
 {
 
-#ifdef HAVE_GLPK
+#ifdef LEMON_HAVE_GLPK
   {
     GlpkMip mip1;
@@ -130,5 +137,5 @@
 #endif
 
-#ifdef HAVE_CPLEX
+#ifdef LEMON_HAVE_CPLEX
   try {
     CplexMip mip2;
@@ -136,10 +143,13 @@
     cloneTest<CplexMip>();
   } 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
+
+#ifdef LEMON_HAVE_CBC
+  {
+    CbcMip mip1;
+    aTest(mip1);
+    cloneTest<CbcMip>();
   }
 #endif
Index: test/path_test.cc
===================================================================
--- test/path_test.cc	(revision 440)
+++ test/path_test.cc	(revision 957)
@@ -39,6 +39,35 @@
 }
 
+// Check if proper copy consructor is called (use valgrind for testing)
+template<class _Path>
+void checkCopy()
+{
+  ListDigraph g;
+  ListDigraph::Arc a  = g.addArc(g.addNode(), g.addNode());
+  
+  _Path p,q;
+  p.addBack(a);
+  q=p;
+  _Path r(p);
+  StaticPath<ListDigraph> s(r);
+}
+  
 int main() {
   check_concepts();
+
+  checkCopy<Path<ListDigraph> >();
+  checkCopy<SimplePath<ListDigraph> >();
+  checkCopy<ListPath<ListDigraph> >();
+
+  ListDigraph g;
+  ListDigraph::Arc a  = g.addArc(g.addNode(), g.addNode());
+  
+  Path<ListDigraph> p;
+  StaticPath<ListDigraph> q,r;
+  p.addBack(a);
+  q=p;
+  r=q;
+  StaticPath<ListDigraph> s(q);
+
   return 0;
 }
Index: test/planarity_test.cc
===================================================================
--- test/planarity_test.cc	(revision 798)
+++ test/planarity_test.cc	(revision 798)
@@ -0,0 +1,262 @@
+/* -*- 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/planarity.h>
+
+#include <lemon/smart_graph.h>
+#include <lemon/lgf_reader.h>
+#include <lemon/connectivity.h>
+#include <lemon/dim2.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+using namespace lemon::dim2;
+
+const int lgfn = 4;
+const std::string lgf[lgfn] = {
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "@edges\n"
+  "     label\n"
+  "0 1  0\n"
+  "0 2  0\n"
+  "0 3  0\n"
+  "0 4  0\n"
+  "1 2  0\n"
+  "1 3  0\n"
+  "1 4  0\n"
+  "2 3  0\n"
+  "2 4  0\n"
+  "3 4  0\n",
+
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "@edges\n"
+  "     label\n"
+  "0 1  0\n"
+  "0 2  0\n"
+  "0 3  0\n"
+  "0 4  0\n"
+  "1 2  0\n"
+  "1 3  0\n"
+  "2 3  0\n"
+  "2 4  0\n"
+  "3 4  0\n",
+
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "@edges\n"
+  "     label\n"
+  "0 3  0\n"
+  "0 4  0\n"
+  "0 5  0\n"
+  "1 3  0\n"
+  "1 4  0\n"
+  "1 5  0\n"
+  "2 3  0\n"
+  "2 4  0\n"
+  "2 5  0\n",
+
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "@edges\n"
+  "     label\n"
+  "0 3  0\n"
+  "0 4  0\n"
+  "0 5  0\n"
+  "1 3  0\n"
+  "1 4  0\n"
+  "1 5  0\n"
+  "2 3  0\n"
+  "2 5  0\n"
+};
+
+
+
+typedef SmartGraph Graph;
+GRAPH_TYPEDEFS(Graph);
+
+typedef PlanarEmbedding<SmartGraph> PE;
+typedef PlanarDrawing<SmartGraph> PD;
+typedef PlanarColoring<SmartGraph> PC;
+
+void checkEmbedding(const Graph& graph, PE& pe) {
+  int face_num = 0;
+
+  Graph::ArcMap<int> face(graph, -1);
+
+  for (ArcIt a(graph); a != INVALID; ++a) {
+    if (face[a] == -1) {
+      Arc b = a;
+      while (face[b] == -1) {
+        face[b] = face_num;
+        b = pe.next(graph.oppositeArc(b));
+      }
+      check(face[b] == face_num, "Wrong face");
+      ++face_num;
+    }
+  }
+  check(face_num + countNodes(graph) - countConnectedComponents(graph) ==
+        countEdges(graph) + 1, "Euler test does not passed");
+}
+
+void checkKuratowski(const Graph& graph, PE& pe) {
+  std::map<int, int> degs;
+  for (NodeIt n(graph); n != INVALID; ++n) {
+    int deg = 0;
+    for (IncEdgeIt e(graph, n); e != INVALID; ++e) {
+      if (pe.kuratowski(e)) {
+        ++deg;
+      }
+    }
+    ++degs[deg];
+  }
+  for (std::map<int, int>::iterator it = degs.begin(); it != degs.end(); ++it) {
+    check(it->first == 0 || it->first == 2 ||
+          (it->first == 3 && it->second == 6) ||
+          (it->first == 4 && it->second == 5),
+          "Wrong degree in Kuratowski graph");
+  }
+
+  // Not full test
+  check((degs[3] == 0) != (degs[4] == 0), "Wrong Kuratowski graph");
+}
+
+bool intersect(Point<int> e1, Point<int> e2, Point<int> f1, Point<int> f2) {
+  int l, r;
+  if (std::min(e1.x, e2.x) > std::max(f1.x, f2.x)) return false;
+  if (std::max(e1.x, e2.x) < std::min(f1.x, f2.x)) return false;
+  if (std::min(e1.y, e2.y) > std::max(f1.y, f2.y)) return false;
+  if (std::max(e1.y, e2.y) < std::min(f1.y, f2.y)) return false;
+
+  l = (e2.x - e1.x) * (f1.y - e1.y) - (e2.y - e1.y) * (f1.x - e1.x);
+  r = (e2.x - e1.x) * (f2.y - e1.y) - (e2.y - e1.y) * (f2.x - e1.x);
+  if (!((l >= 0 && r <= 0) || (l <= 0 && r >= 0))) return false;
+  l = (f2.x - f1.x) * (e1.y - f1.y) - (f2.y - f1.y) * (e1.x - f1.x);
+  r = (f2.x - f1.x) * (e2.y - f1.y) - (f2.y - f1.y) * (e2.x - f1.x);
+  if (!((l >= 0 && r <= 0) || (l <= 0 && r >= 0))) return false;
+  return true;
+}
+
+bool collinear(Point<int> p, Point<int> q, Point<int> r) {
+  int v;
+  v = (q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x);
+  if (v != 0) return false;
+  v = (q.x - p.x) * (r.x - p.x) + (q.y - p.y) * (r.y - p.y);
+  if (v < 0) return false;
+  return true;
+}
+
+void checkDrawing(const Graph& graph, PD& pd) {
+  for (Graph::NodeIt n(graph); n != INVALID; ++n) {
+    Graph::NodeIt m(n);
+    for (++m; m != INVALID; ++m) {
+      check(pd[m] != pd[n], "Two nodes with identical coordinates");
+    }
+  }
+
+  for (Graph::EdgeIt e(graph); e != INVALID; ++e) {
+    for (Graph::EdgeIt f(e); f != e; ++f) {
+      Point<int> e1 = pd[graph.u(e)];
+      Point<int> e2 = pd[graph.v(e)];
+      Point<int> f1 = pd[graph.u(f)];
+      Point<int> f2 = pd[graph.v(f)];
+
+      if (graph.u(e) == graph.u(f)) {
+        check(!collinear(e1, e2, f2), "Wrong drawing");
+      } else if (graph.u(e) == graph.v(f)) {
+        check(!collinear(e1, e2, f1), "Wrong drawing");
+      } else if (graph.v(e) == graph.u(f)) {
+        check(!collinear(e2, e1, f2), "Wrong drawing");
+      } else if (graph.v(e) == graph.v(f)) {
+        check(!collinear(e2, e1, f1), "Wrong drawing");
+      } else {
+        check(!intersect(e1, e2, f1, f2), "Wrong drawing");
+      }
+    }
+  }
+}
+
+void checkColoring(const Graph& graph, PC& pc, int num) {
+  for (NodeIt n(graph); n != INVALID; ++n) {
+    check(pc.colorIndex(n) >= 0 && pc.colorIndex(n) < num,
+          "Wrong coloring");
+  }
+  for (EdgeIt e(graph); e != INVALID; ++e) {
+    check(pc.colorIndex(graph.u(e)) != pc.colorIndex(graph.v(e)),
+          "Wrong coloring");
+  }
+}
+
+int main() {
+
+  for (int i = 0; i < lgfn; ++i) {
+    std::istringstream lgfs(lgf[i]);
+
+    SmartGraph graph;
+    graphReader(graph, lgfs).run();
+
+    check(simpleGraph(graph), "Test graphs must be simple");
+
+    PE pe(graph);
+    bool planar = pe.run();
+    check(checkPlanarity(graph) == planar, "Planarity checking failed");
+
+    if (planar) {
+      checkEmbedding(graph, pe);
+
+      PlanarDrawing<Graph> pd(graph);
+      pd.run(pe.embeddingMap());
+      checkDrawing(graph, pd);
+
+      PlanarColoring<Graph> pc(graph);
+      pc.runFiveColoring(pe.embeddingMap());
+      checkColoring(graph, pc, 5);
+
+    } else {
+      checkKuratowski(graph, pe);
+    }
+  }
+
+  return 0;
+}
Index: test/preflow_test.cc
===================================================================
--- test/preflow_test.cc	(revision 440)
+++ test/preflow_test.cc	(revision 985)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2011
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -85,16 +85,26 @@
   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);
+  VType v;
+  bool b;
+  ::lemon::ignore_unused_variable_warning(v,b);
+
+  typedef Preflow<Digraph, CapMap>
+            ::SetFlowMap<FlowMap>
+            ::SetElevator<Elev>
+            ::SetStandardElevator<LinkedElev>
+            ::Create PreflowType;
+  PreflowType preflow_test(g, cap, n, n);
+  const PreflowType& const_preflow_test = preflow_test;
+
+  const PreflowType::Elevator& elev = const_preflow_test.elevator();
+  preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev));
+  PreflowType::Tolerance tol = const_preflow_test.tolerance();
+  preflow_test.tolerance(tol);
+
+  preflow_test
+    .capacityMap(cap)
+    .flowMap(flow)
+    .source(n)
+    .target(n);
 
   preflow_test.init();
@@ -105,9 +115,11 @@
   preflow_test.runMinCut();
 
-  preflow_test.flowValue();
-  preflow_test.minCut(n);
-  preflow_test.minCutMap(cut);
-  preflow_test.flow(e);
-
+  v = const_preflow_test.flowValue();
+  v = const_preflow_test.flow(e);
+  const FlowMap& fm = const_preflow_test.flowMap();
+  b = const_preflow_test.minCut(n);
+  const_preflow_test.minCutMap(cut);
+
+  ::lemon::ignore_unused_variable_warning(fm);
 }
 
@@ -146,4 +158,28 @@
 }
 
+void initFlowTest()
+{
+  DIGRAPH_TYPEDEFS(SmartDigraph);
+
+  SmartDigraph g;
+  SmartDigraph::ArcMap<int> cap(g),iflow(g);
+  Node s=g.addNode(); Node t=g.addNode();
+  Node n1=g.addNode(); Node n2=g.addNode();
+  Arc a;
+  a=g.addArc(s,n1); cap[a]=20; iflow[a]=20;
+  a=g.addArc(n1,n2); cap[a]=10; iflow[a]=0;
+  a=g.addArc(n2,t); cap[a]=20; iflow[a]=0;
+
+  Preflow<SmartDigraph> pre(g,cap,s,t);
+  pre.init(iflow);
+  pre.startFirstPhase();
+  check(pre.flowValue() == 10, "The incorrect max flow value.");
+  check(pre.minCut(s), "Wrong min cut (Node s).");
+  check(pre.minCut(n1), "Wrong min cut (Node n1).");
+  check(!pre.minCut(n2), "Wrong min cut (Node n2).");
+  check(!pre.minCut(t), "Wrong min cut (Node t).");
+}
+
+
 int main() {
 
@@ -236,4 +272,6 @@
         "The max flow value or the three min cut values are incorrect.");
 
+  initFlowTest();
+
   return 0;
 }
Index: test/suurballe_test.cc
===================================================================
--- test/suurballe_test.cc	(revision 440)
+++ test/suurballe_test.cc	(revision 983)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -23,4 +23,6 @@
 #include <lemon/path.h>
 #include <lemon/suurballe.h>
+#include <lemon/concepts/digraph.h>
+#include <lemon/concepts/heap.h>
 
 #include "test_tools.h"
@@ -30,44 +32,105 @@
 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"
+  "label\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "8\n"
+  "9\n"
+  "10\n"
+  "11\n"
+  "12\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"
+  "      length\n"
+  " 1  2  70\n"
+  " 1  3 150\n"
+  " 1  4  80\n"
+  " 2  8  80\n"
+  " 3  5 140\n"
+  " 4  6  60\n"
+  " 4  7  80\n"
+  " 4  8 110\n"
+  " 5  7  60\n"
+  " 5 11 120\n"
+  " 6  3   0\n"
+  " 6  9 140\n"
+  " 6 10  90\n"
+  " 7  1  30\n"
+  " 8 12  60\n"
+  " 9 12  50\n"
+  "10 12  70\n"
+  "10  2 100\n"
+  "10  7  60\n"
+  "11 10  20\n"
+  "12 11  30\n"
   "@attributes\n"
   "source  1\n"
   "target 12\n"
   "@end\n";
+
+// Check the interface of Suurballe
+void checkSuurballeCompile()
+{
+  typedef int VType;
+  typedef concepts::Digraph Digraph;
+
+  typedef Digraph::Node Node;
+  typedef Digraph::Arc Arc;
+  typedef concepts::ReadMap<Arc, VType> LengthMap;
+
+  typedef Suurballe<Digraph, LengthMap> ST;
+  typedef Suurballe<Digraph, LengthMap>
+    ::SetFlowMap<ST::FlowMap>
+    ::SetPotentialMap<ST::PotentialMap>
+    ::SetPath<SimplePath<Digraph> >
+    ::SetHeap<concepts::Heap<VType, Digraph::NodeMap<int> > >
+    ::Create SuurballeType;
+
+  Digraph g;
+  Node n;
+  Arc e;
+  LengthMap len;
+  SuurballeType::FlowMap flow(g);
+  SuurballeType::PotentialMap pi(g);
+
+  SuurballeType suurb_test(g, len);
+  const SuurballeType& const_suurb_test = suurb_test;
+
+  suurb_test
+    .flowMap(flow)
+    .potentialMap(pi);
+
+  int k;
+  k = suurb_test.run(n, n);
+  k = suurb_test.run(n, n, k);
+  suurb_test.init(n);
+  suurb_test.fullInit(n);
+  suurb_test.start(n);
+  suurb_test.start(n, k);
+  k = suurb_test.findFlow(n);
+  k = suurb_test.findFlow(n, k);
+  suurb_test.findPaths();
+
+  int f;
+  VType c;
+  ::lemon::ignore_unused_variable_warning(f,c);
+
+  c = const_suurb_test.totalLength();
+  f = const_suurb_test.flow(e);
+  const SuurballeType::FlowMap& fm =
+    const_suurb_test.flowMap();
+  c = const_suurb_test.potential(n);
+  const SuurballeType::PotentialMap& pm =
+    const_suurb_test.potentialMap();
+  k = const_suurb_test.pathNum();
+  Path<Digraph> p = const_suurb_test.path(k);
+
+  ::lemon::ignore_unused_variable_warning(fm);
+  ::lemon::ignore_unused_variable_warning(pm);
+}
 
 // Check the feasibility of the flow
@@ -119,5 +182,4 @@
                 typename Digraph::Node s, typename Digraph::Node t)
 {
-  // Check the "Complementary Slackness" optimality condition
   TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
   Node n = s;
@@ -137,18 +199,20 @@
   ListDigraph digraph;
   ListDigraph::ArcMap<int> length(digraph);
-  Node source, target;
+  Node s, t;
 
   std::istringstream input(test_lgf);
   DigraphReader<ListDigraph>(digraph, input).
-    arcMap("cost", length).
-    node("source", source).
-    node("target", target).
+    arcMap("length", length).
+    node("source", s).
+    node("target", t).
     run();
 
-  // Find 2 paths
+  // Check run()
   {
-    Suurballe<ListDigraph> suurballe(digraph, length, source, target);
-    check(suurballe.run(2) == 2, "Wrong number of paths");
-    check(checkFlow(digraph, suurballe.flowMap(), source, target, 2),
+    Suurballe<ListDigraph> suurballe(digraph, length);
+
+    // Find 2 paths
+    check(suurballe.run(s, t) == 2, "Wrong number of paths");
+    check(checkFlow(digraph, suurballe.flowMap(), s, t, 2),
           "The flow is not feasible");
     check(suurballe.totalLength() == 510, "The flow is not optimal");
@@ -157,13 +221,9 @@
           "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),
+      check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
+
+    // Find 3 paths
+    check(suurballe.run(s, t, 3) == 3, "Wrong number of paths");
+    check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
           "The flow is not feasible");
     check(suurballe.totalLength() == 1040, "The flow is not optimal");
@@ -172,13 +232,9 @@
           "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),
+      check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
+
+    // Find 5 paths (only 3 can be found)
+    check(suurballe.run(s, t, 5) == 3, "Wrong number of paths");
+    check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
           "The flow is not feasible");
     check(suurballe.totalLength() == 1040, "The flow is not optimal");
@@ -187,6 +243,23 @@
           "Wrong potentials");
     for (int i = 0; i < suurballe.pathNum(); ++i)
-      check(checkPath(digraph, suurballe.path(i), source, target),
-            "Wrong path");
+      check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
+  }
+
+  // Check fullInit() + start()
+  {
+    Suurballe<ListDigraph> suurballe(digraph, length);
+    suurballe.fullInit(s);
+
+    // Find 2 paths
+    check(suurballe.start(t) == 2, "Wrong number of paths");
+    check(suurballe.totalLength() == 510, "The flow is not optimal");
+
+    // Find 3 paths
+    check(suurballe.start(t, 3) == 3, "Wrong number of paths");
+    check(suurballe.totalLength() == 1040, "The flow is not optimal");
+
+    // Find 5 paths (only 3 can be found)
+    check(suurballe.start(t, 5) == 3, "Wrong number of paths");
+    check(suurballe.totalLength() == 1040, "The flow is not optimal");
   }
 
Index: test/test_tools.h
===================================================================
--- test/test_tools.h	(revision 440)
+++ test/test_tools.h	(revision 877)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -38,9 +38,13 @@
 ///print something like this (and then exits).
 ///\verbatim file_name.cc:123: error: This is obviously false. \endverbatim
-#define check(rc, msg) \
-  if(!(rc)) { \
-    std::cerr << __FILE__ ":" << __LINE__ << ": error: " << msg << std::endl; \
-    abort(); \
-  } else { } \
+#define check(rc, msg)                                                  \
+  {                                                                     \
+    if(!(rc)) {                                                         \
+      std::cerr << __FILE__ ":" << __LINE__ << ": error: "              \
+                << msg << std::endl;                                    \
+      abort();                                                          \
+    } else { }                                                          \
+  }                                                                     \
+
 
 #endif
Index: test/time_measure_test.cc
===================================================================
--- test/time_measure_test.cc	(revision 558)
+++ test/time_measure_test.cc	(revision 982)
@@ -18,4 +18,5 @@
 
 #include <lemon/time_measure.h>
+#include <lemon/concept_check.h>
 
 using namespace lemon;
@@ -33,5 +34,8 @@
 
   for(int i=0;i<1000;i++)
-    TimeStamp x(T);
+    {
+      TimeStamp x(T);
+      ::lemon::ignore_unused_variable_warning(x);
+    }
 }
 
Index: tools/CMakeLists.txt
===================================================================
--- tools/CMakeLists.txt	(revision 549)
+++ tools/CMakeLists.txt	(revision 679)
@@ -4,5 +4,7 @@
 )
 
-LINK_DIRECTORIES(${PROJECT_BINARY_DIR}/lemon)
+LINK_DIRECTORIES(
+  ${PROJECT_BINARY_DIR}/lemon
+)
 
 ADD_EXECUTABLE(lgf-gen lgf-gen.cc)
@@ -25,4 +27,5 @@
     PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/lemon-0.x-to-1.x.sh
     DESTINATION bin
-    COMPONENT bin)
-ENDIF(NOT WIN32)
+    COMPONENT bin
+  )
+ENDIF()
Index: tools/Makefile.am
===================================================================
--- tools/Makefile.am	(revision 526)
+++ tools/Makefile.am	(revision 674)
@@ -1,2 +1,5 @@
+EXTRA_DIST += \
+	tools/CMakeLists.txt
+
 if WANT_TOOLS
 
Index: tools/dimacs-solver.cc
===================================================================
--- tools/dimacs-solver.cc	(revision 561)
+++ tools/dimacs-solver.cc	(revision 968)
@@ -3,5 +3,5 @@
  * This file is a part of LEMON, a generic C++ optimization library.
  *
- * Copyright (C) 2003-2009
+ * Copyright (C) 2003-2010
  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
  * (Egervary Research Group on Combinatorial Optimization, EGRES).
@@ -24,9 +24,8 @@
 ///
 /// See
-/// \verbatim
-///  dimacs-solver --help
-/// \endverbatim
+/// \code
+///   dimacs-solver --help
+/// \endcode
 /// for more info on usage.
-///
 
 #include <iostream>
@@ -44,5 +43,6 @@
 #include <lemon/dijkstra.h>
 #include <lemon/preflow.h>
-#include <lemon/max_matching.h>
+#include <lemon/matching.h>
+#include <lemon/network_simplex.h>
 
 using namespace lemon;
@@ -89,5 +89,47 @@
   pre.run();
   if(report) std::cerr << "Run Preflow: " << ti << '\n';
-  if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';  
+  if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';
+}
+
+template<class Value, class LargeValue>
+void solve_min(ArgParser &ap, std::istream &is, std::ostream &,
+               Value infty, DimacsDescriptor &desc)
+{
+  bool report = !ap.given("q");
+  Digraph g;
+  Digraph::ArcMap<Value> lower(g), cap(g), cost(g);
+  Digraph::NodeMap<Value> sup(g);
+  Timer ti;
+
+  ti.restart();
+  readDimacsMin(is, g, lower, cap, cost, sup, infty, desc);
+  ti.stop();
+  Value sum_sup = 0;
+  for (Digraph::NodeIt n(g); n != INVALID; ++n) {
+    sum_sup += sup[n];
+  }
+  if (report) {
+    std::cerr << "Sum of supply values: " << sum_sup << "\n";
+    if (sum_sup <= 0)
+      std::cerr << "GEQ supply contraints are used for NetworkSimplex\n\n";
+    else
+      std::cerr << "LEQ supply contraints are used for NetworkSimplex\n\n";
+  }
+  if (report) std::cerr << "Read the file: " << ti << '\n';
+
+  typedef NetworkSimplex<Digraph, Value> MCF;
+  ti.restart();
+  MCF ns(g);
+  ns.lowerMap(lower).upperMap(cap).costMap(cost).supplyMap(sup);
+  if (sum_sup > 0) ns.supplyType(ns.LEQ);
+  if (report) std::cerr << "Setup NetworkSimplex class: " << ti << '\n';
+  ti.restart();
+  typename MCF::ProblemType res = ns.run();
+  if (report) {
+    std::cerr << "Run NetworkSimplex: " << ti << "\n\n";
+    std::cerr << "Feasible flow: " << (res == MCF::OPTIMAL ? "found" : "not found") << '\n';
+    if (res) std::cerr << "Min flow cost: "
+                       << ns.template totalCost<LargeValue>() << '\n';
+  }
 }
 
@@ -108,13 +150,13 @@
   if(report) std::cerr << "Run MaxMatching: " << ti << '\n';
   if(report) std::cerr << "\nCardinality of max matching: "
-                       << mat.matchingSize() << '\n';  
-}
-
-
-template<class Value>
+                       << mat.matchingSize() << '\n';
+}
+
+
+template<class Value, class LargeValue>
 void solve(ArgParser &ap, std::istream &is, std::ostream &os,
            DimacsDescriptor &desc)
 {
-  std::stringstream iss(ap["infcap"]);
+  std::stringstream iss(static_cast<std::string>(ap["infcap"]));
   Value infty;
   iss >> infty;
@@ -126,10 +168,9 @@
       exit(1);
     }
-  
+
   switch(desc.type)
     {
     case DimacsDescriptor::MIN:
-      std::cerr <<
-        "\n\n Sorry, the min. cost flow solver is not yet available.\n";
+      solve_min<Value, LargeValue>(ap,is,os,infty,desc);
       break;
     case DimacsDescriptor::MAX:
@@ -148,7 +189,4 @@
 
 int main(int argc, const char *argv[]) {
-  typedef SmartDigraph Digraph;
-
-  typedef Digraph::Arc Arc;
 
   std::string inputName;
@@ -162,5 +200,5 @@
     .boolOption("int","Use 'int' for capacities, costs etc. (default)")
     .optionGroup("datatype","int")
-#ifdef HAVE_LONG_LONG
+#ifdef LEMON_HAVE_LONG_LONG
     .boolOption("long","Use 'long long' for capacities, costs etc.")
     .optionGroup("datatype","long")
@@ -199,5 +237,5 @@
 
   DimacsDescriptor desc = dimacsType(is);
-  
+
   if(!ap.given("q"))
     {
@@ -224,14 +262,16 @@
       std::cout << "\n\n";
     }
-    
+
   if(ap.given("double"))
-    solve<double>(ap,is,os,desc);
+    solve<double, double>(ap,is,os,desc);
   else if(ap.given("ldouble"))
-    solve<long double>(ap,is,os,desc);
-#ifdef HAVE_LONG_LONG
+    solve<long double, long double>(ap,is,os,desc);
+#ifdef LEMON_HAVE_LONG_LONG
   else if(ap.given("long"))
-    solve<long long>(ap,is,os,desc);
+    solve<long long, long long>(ap,is,os,desc);
+  else solve<int, long long>(ap,is,os,desc);
+#else
+  else solve<int, long>(ap,is,os,desc);
 #endif
-  else solve<int>(ap,is,os,desc);
 
   return 0;
Index: tools/dimacs-to-lgf.cc
===================================================================
--- tools/dimacs-to-lgf.cc	(revision 561)
+++ tools/dimacs-to-lgf.cc	(revision 584)
@@ -25,9 +25,8 @@
 ///
 /// See
-/// \verbatim
-///  dimacs-to-lgf --help
-/// \endverbatim
-/// for more info on usage.
-///
+/// \code
+///   dimacs-to-lgf --help
+/// \endcode
+/// for more info on the usage.
 
 #include <iostream>
Index: tools/lemon-0.x-to-1.x.sh
===================================================================
--- tools/lemon-0.x-to-1.x.sh	(revision 555)
+++ tools/lemon-0.x-to-1.x.sh	(revision 691)
@@ -36,8 +36,8 @@
         -e "s/Edge\>/_Ar_c_label_/g"\
         -e "s/\<edge\>/_ar_c_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/_edges\>/_ar_c_label_s/g"\
+        -e "s/_edges\>/__ar_c_label_s/g"\
         -e "s/\([Ee]\)dge\([a-z]\)/_\1d_ge_label_\2/g"\
         -e "s/\([a-z]\)edge/\1_ed_ge_label_/g"\
@@ -69,4 +69,9 @@
         -e "s/_GR_APH_TY_PEDE_FS_label_/GRAPH_TYPEDEFS/g"\
         -e "s/_DIGR_APH_TY_PEDE_FS_label_/DIGRAPH_TYPEDEFS/g"\
+        -e "s/\<digraph_adaptor\.h\>/adaptors.h/g"\
+        -e "s/\<digraph_utils\.h\>/core.h/g"\
+        -e "s/\<digraph_reader\.h\>/lgf_reader.h/g"\
+        -e "s/\<digraph_writer\.h\>/lgf_writer.h/g"\
+        -e "s/\<topology\.h\>/connectivity.h/g"\
         -e "s/DigraphToEps/GraphToEps/g"\
         -e "s/digraphToEps/graphToEps/g"\
@@ -90,4 +95,8 @@
         -e "s/\<StoreBoolMap\>/LoggerBoolMap/g"\
         -e "s/\<storeBoolMap\>/loggerBoolMap/g"\
+        -e "s/\<InvertableMap\>/CrossRefMap/g"\
+        -e "s/\<invertableMap\>/crossRefMap/g"\
+        -e "s/\<DescriptorMap\>/RangeIdMap/g"\
+        -e "s/\<descriptorMap\>/rangeIdMap/g"\
         -e "s/\<BoundingBox\>/Box/g"\
         -e "s/\<readNauty\>/readNautyGraph/g"\
Index: tools/lgf-gen.cc
===================================================================
--- tools/lgf-gen.cc	(revision 524)
+++ tools/lgf-gen.cc	(revision 1001)
@@ -19,18 +19,17 @@
 /// \ingroup tools
 /// \file
-/// \brief Special plane digraph generator.
+/// \brief Special plane graph generator.
 ///
 /// Graph generator application for various types of plane graphs.
 ///
 /// See
-/// \verbatim
-///  lgf-gen --help
-/// \endverbatim
-/// for more info on the usage.
-///
-
+/// \code
+///   lgf-gen --help
+/// \endcode
+/// for more information on the usage.
 
 #include <algorithm>
 #include <set>
+#include <ctime>
 #include <lemon/list_graph.h>
 #include <lemon/random.h>
@@ -67,5 +66,5 @@
   double tlen=0;
   for(EdgeIt e(g);e!=INVALID;++e)
-    tlen+=sqrt((coords[g.v(e)]-coords[g.u(e)]).normSquare());
+    tlen+=std::sqrt((coords[g.v(e)]-coords[g.u(e)]).normSquare());
   return tlen;
 }
@@ -190,5 +189,5 @@
       (r.x * r.x + r.y * r.y) * (p.x * q.y - q.x * p.y);
 
-    return d / (2 * a) + sqrt((d * d + e * e) / (4 * a * a) + f / a);
+    return d / (2 * a) + std::sqrt((d * d + e * e) / (4 * a * a) + f / a);
   }
 
@@ -208,5 +207,5 @@
     double b = (q.x - sx) * p.y - (p.x - sx) * q.y;
     double d = (q.x - sx) * (p.x - sx) * (p - q).normSquare();
-    return (b - sqrt(d)) / a;
+    return (b - std::sqrt(d)) / a;
   }
 
@@ -248,5 +247,5 @@
   struct BeachIt;
 
-  typedef std::multimap<double, BeachIt> SpikeHeap;
+  typedef std::multimap<double, BeachIt*> SpikeHeap;
 
   typedef std::multimap<Part, SpikeHeap::iterator, YLess> Beach;
@@ -331,4 +330,5 @@
 
       if (bit->second != spikeheap.end()) {
+        delete bit->second->second;
         spikeheap.erase(bit->second);
       }
@@ -344,6 +344,6 @@
           circle_form(points[prev], points[curr], points[site])) {
         double x = circle_point(points[prev], points[curr], points[site]);
-        pit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
-        pit->second.it =
+        pit = spikeheap.insert(std::make_pair(x, new BeachIt(beach.end())));
+        pit->second->it =
           beach.insert(std::make_pair(Part(prev, curr, site), pit));
       } else {
@@ -357,6 +357,6 @@
           circle_form(points[site], points[curr],points[next])) {
         double x = circle_point(points[site], points[curr], points[next]);
-        nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
-        nit->second.it =
+        nit = spikeheap.insert(std::make_pair(x, new BeachIt(beach.end())));
+        nit->second->it =
           beach.insert(std::make_pair(Part(site, curr, next), nit));
       } else {
@@ -368,5 +368,5 @@
       sweep = spit->first;
 
-      Beach::iterator bit = spit->second.it;
+      Beach::iterator bit = spit->second->it;
 
       int prev = bit->first.prev;
@@ -401,8 +401,20 @@
       int nnt = nbit->first.next;
 
-      if (bit->second != spikeheap.end()) spikeheap.erase(bit->second);
-      if (pbit->second != spikeheap.end()) spikeheap.erase(pbit->second);
-      if (nbit->second != spikeheap.end()) spikeheap.erase(nbit->second);
-
+      if (bit->second != spikeheap.end())
+        {
+          delete bit->second->second;
+          spikeheap.erase(bit->second);
+        }
+      if (pbit->second != spikeheap.end())
+        {
+          delete pbit->second->second;
+          spikeheap.erase(pbit->second);
+        }
+      if (nbit->second != spikeheap.end())
+        {
+          delete nbit->second->second;
+          spikeheap.erase(nbit->second);
+        }
+      
       beach.erase(nbit);
       beach.erase(bit);
@@ -414,6 +426,6 @@
         double x = circle_point(points[ppv], points[prev], points[next]);
         if (x < sweep) x = sweep;
-        pit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
-        pit->second.it =
+        pit = spikeheap.insert(std::make_pair(x, new BeachIt(beach.end())));
+        pit->second->it =
           beach.insert(std::make_pair(Part(ppv, prev, next), pit));
       } else {
@@ -426,6 +438,6 @@
         double x = circle_point(points[prev], points[next], points[nnt]);
         if (x < sweep) x = sweep;
-        nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
-        nit->second.it =
+        nit = spikeheap.insert(std::make_pair(x, new BeachIt(beach.end())));
+        nit->second->it =
           beach.insert(std::make_pair(Part(prev, next, nnt), nit));
       } else {
@@ -482,6 +494,6 @@
       g.erase(*ei);
       ConstMap<Arc,int> cegy(1);
-      Suurballe<ListGraph,ConstMap<Arc,int> > sur(g,cegy,a,b);
-      int k=sur.run(2);
+      Suurballe<ListGraph,ConstMap<Arc,int> > sur(g,cegy);
+      int k=sur.run(a,b,2);
       if(k<2 || sur.totalLength()>d)
         g.addEdge(a,b);
@@ -513,7 +525,6 @@
       if(e==INVALID) {
         ConstMap<Arc,int> cegy(1);
-        Suurballe<ListGraph,ConstMap<Arc,int> >
-          sur(g,cegy,pi->a,pi->b);
-        int k=sur.run(2);
+        Suurballe<ListGraph,ConstMap<Arc,int> > sur(g,cegy);
+        int k=sur.run(pi->a,pi->b,2);
         if(k<2 || sur.totalLength()>d)
           {
@@ -689,18 +700,19 @@
     .refOption("cities", "Number of cities (default is 1)", num_of_cities)
     .refOption("area", "Full relative area of the cities (default is 1)", area)
-    .refOption("disc", "Nodes are evenly distributed on a unit disc (default)",disc_d)
+    .refOption("disc", "Nodes are evenly distributed on a unit disc (default)",
+               disc_d)
     .optionGroup("dist", "disc")
-    .refOption("square", "Nodes are evenly distributed on a unit square", square_d)
+    .refOption("square", "Nodes are evenly distributed on a unit square",
+               square_d)
     .optionGroup("dist", "square")
-    .refOption("gauss",
-            "Nodes are located according to a two-dim gauss distribution",
-            gauss_d)
+    .refOption("gauss", "Nodes are located according to a two-dim Gauss "
+               "distribution", gauss_d)
     .optionGroup("dist", "gauss")
-//     .mandatoryGroup("dist")
     .onlyOneGroup("dist")
-    .boolOption("eps", "Also generate .eps output (prefix.eps)")
-    .boolOption("nonodes", "Draw the edges only in the generated .eps")
-    .boolOption("dir", "Directed digraph is generated (each arcs are replaced by two directed ones)")
-    .boolOption("2con", "Create a two connected planar digraph")
+    .boolOption("eps", "Also generate .eps output (<prefix>.eps)")
+    .boolOption("nonodes", "Draw only the edges in the generated .eps output")
+    .boolOption("dir", "Directed graph is generated (each edge is replaced by "
+                "two directed arcs)")
+    .boolOption("2con", "Create a two connected planar graph")
     .optionGroup("alg","2con")
     .boolOption("tree", "Create a min. cost spanning tree")
@@ -710,5 +722,5 @@
     .boolOption("tsp2", "Create a TSP tour (tree based)")
     .optionGroup("alg","tsp2")
-    .boolOption("dela", "Delaunay triangulation digraph")
+    .boolOption("dela", "Delaunay triangulation graph")
     .optionGroup("alg","dela")
     .onlyOneGroup("alg")
@@ -722,5 +734,5 @@
 
   if (ap["rand"]) {
-    int seed = time(0);
+    int seed = int(time(0));
     std::cout << "Random number seed: " << seed << std::endl;
     rnd = Random(seed);
@@ -815,5 +827,5 @@
   double tlen=0;
   for(EdgeIt e(g);e!=INVALID;++e)
-    tlen+=sqrt((coords[g.v(e)]-coords[g.u(e)]).normSquare());
+    tlen+=std::sqrt((coords[g.v(e)]-coords[g.u(e)]).normSquare());
   std::cout << "Total arc length  : " << tlen << std::endl;
 
