Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt	(revision 680)
+++ CMakeLists.txt	(revision 744)
@@ -35,4 +35,6 @@
 CHECK_TYPE_SIZE("long long" LONG_LONG)
 SET(LEMON_HAVE_LONG_LONG ${HAVE_LONG_LONG})
+
+INCLUDE(FindPythonInterp)
 
 ENABLE_TESTING()
Index: INSTALL
===================================================================
--- INSTALL	(revision 568)
+++ INSTALL	(revision 824)
@@ -174,2 +174,24 @@
 
    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: Makefile.am
===================================================================
--- Makefile.am	(revision 629)
+++ Makefile.am	(revision 793)
@@ -18,4 +18,5 @@
 	cmake/FindGLPK.cmake \
 	cmake/FindCOIN.cmake \
+	cmake/LEMONConfig.cmake.in \
 	cmake/version.cmake.in \
 	cmake/version.cmake \
@@ -44,4 +45,5 @@
 include doc/Makefile.am
 include tools/Makefile.am
+include scripts/Makefile.am
 
 DIST_SUBDIRS = demo
Index: README
===================================================================
--- README	(revision 658)
+++ README	(revision 848)
@@ -18,4 +18,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: configure.ac
===================================================================
--- configure.ac	(revision 680)
+++ configure.ac	(revision 793)
@@ -42,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])
 
@@ -82,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.
@@ -128,4 +144,5 @@
 echo
 echo Build additional tools........ : $enable_tools
+echo Use valgrind for tests........ : $use_valgrind
 echo
 echo The packace will be installed in
Index: demo/arg_parser_demo.cc
===================================================================
--- demo/arg_parser_demo.cc	(revision 440)
+++ demo/arg_parser_demo.cc	(revision 842)
@@ -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: doc/CMakeLists.txt
===================================================================
--- doc/CMakeLists.txt	(revision 679)
+++ doc/CMakeLists.txt	(revision 827)
@@ -10,5 +10,5 @@
 )
 
-IF(DOXYGEN_EXECUTABLE AND GHOSTSCRIPT_EXECUTABLE)
+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)
@@ -27,6 +27,8 @@
     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}
Index: doc/Doxyfile.in
===================================================================
--- doc/Doxyfile.in	(revision 367)
+++ doc/Doxyfile.in	(revision 756)
@@ -1,3 +1,3 @@
-# Doxyfile 1.5.7.1
+# Doxyfile 1.5.9
 
 #---------------------------------------------------------------------------
@@ -22,5 +22,4 @@
 QT_AUTOBRIEF           = NO
 MULTILINE_CPP_IS_BRIEF = NO
-DETAILS_AT_TOP         = YES
 INHERIT_DOCS           = NO
 SEPARATE_MEMBER_PAGES  = NO
@@ -92,5 +91,6 @@
                          "@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/references.dox"
 INPUT_ENCODING         = UTF-8
 FILE_PATTERNS          = *.h \
@@ -224,5 +224,5 @@
 SKIP_FUNCTION_MACROS   = YES
 #---------------------------------------------------------------------------
-# Configuration::additions related to external references   
+# Options related to the search engine   
 #---------------------------------------------------------------------------
 TAGFILES               = "@abs_top_srcdir@/doc/libstdc++.tag = http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/  "
Index: doc/Makefile.am
===================================================================
--- doc/Makefile.am	(revision 673)
+++ doc/Makefile.am	(revision 827)
@@ -29,4 +29,5 @@
 	edge_biconnected_components.eps \
 	node_biconnected_components.eps \
+	planar.eps \
 	strongly_connected_components.eps
 
@@ -67,5 +68,17 @@
 	fi
 
-html-local: $(DOC_PNG_IMAGES)
+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; \
Index: doc/groups.dox
===================================================================
--- doc/groups.dox	(revision 715)
+++ doc/groups.dox	(revision 813)
@@ -317,5 +317,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.
 */
 
@@ -325,5 +326,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
@@ -347,5 +349,5 @@
 
 This group contains the algorithms for finding minimum cost spanning
-trees and arborescences.
+trees and arborescences \ref clrs01algorithms.
 */
 
@@ -356,5 +358,5 @@
 
 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
@@ -371,10 +373,14 @@
 
 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
+- \ref EdmondsKarp Edmonds-Karp algorithm
+  \ref edmondskarp72theoretical.
+- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm
+  \ref goldberg88newapproach.
+- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees
+  \ref dinic70algorithm, \ref sleator83dynamic.
+- \ref GoldbergTarjan !Preflow push-relabel algorithm with dynamic trees
+  \ref goldberg88newapproach, \ref sleator83dynamic.
+
+In most cases the \ref Preflow algorithm provides the
 fastest method for computing a maximum flow. All implementations
 also provide functions to query the minimum cut, which is the dual
@@ -394,16 +400,18 @@
 
 This group contains the algorithms for finding minimum cost flows and
-circulations. For more information about this problem and its dual
-solution see \ref min_cost_flow "Minimum Cost Flow Problem".
+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 CostScaling Push-Relabel and Augment-Relabel algorithms based on
-   cost scaling.
- - \ref CapacityScaling Successive Shortest %Path algorithm with optional
-   capacity scaling.
- - \ref CancelAndTighten The Cancel and Tighten algorithm.
- - \ref CycleCanceling Cycle-Canceling algorithms.
+   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,
@@ -441,4 +449,41 @@
 If you want to find minimum cut just between two distinict nodes,
 see the \ref max_flow "maximum flow problem".
+*/
+
+/**
+@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 Karp "Karp"'s original algorithm \ref amo93networkflows,
+  \ref dasdan98minmeancycle.
+- \ref HartmannOrlin "Hartmann-Orlin"'s algorithm, which is an improved
+  version of Karp's algorithm \ref dasdan98minmeancycle.
+- \ref Howard "Howard"'s policy iteration algorithm
+  \ref dasdan98minmeancycle.
+
+In practice, the Howard algorithm proved to be by far the most efficient
+one, though the best known theoretical bound on its running time is
+exponential.
+Both Karp and HartmannOrlin 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.
 */
 
@@ -535,11 +580,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.
+\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.
 */
 
@@ -680,6 +728,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.
 */
 
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/mainpage.dox
===================================================================
--- doc/mainpage.dox	(revision 658)
+++ doc/mainpage.dox	(revision 848)
@@ -22,12 +22,9 @@
 \section intro Introduction
 
-\subsection whatis What is LEMON
-
-LEMON stands for <b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
-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</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>
@@ -39,8 +36,21 @@
 </b>
 
-\subsection howtoread How to read the documentation
+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
Index: doc/min_cost_flow.dox
===================================================================
--- doc/min_cost_flow.dox	(revision 663)
+++ doc/min_cost_flow.dox	(revision 788)
@@ -27,5 +27,5 @@
 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.
+and arc costs \ref amo93networkflows.
 
 Formally, let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$,
@@ -79,5 +79,5 @@
    - 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)<=0\f$;
+   - \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$.
@@ -146,5 +146,5 @@
    - 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)>=0\f$;
+   - \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/Makefile.am
===================================================================
--- lemon/Makefile.am	(revision 855)
+++ lemon/Makefile.am	(revision 822)
@@ -61,6 +61,7 @@
 	lemon/bfs.h \
 	lemon/bin_heap.h \
-	lemon/binomial_heap.h \
+	lemon/binom_heap.h \
 	lemon/bucket_heap.h \
+	lemon/capacity_scaling.h \
 	lemon/cbc.h \
 	lemon/circulation.h \
@@ -69,9 +70,10 @@
 	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 \
@@ -82,4 +84,5 @@
 	lemon/euler.h \
 	lemon/fib_heap.h \
+	lemon/fourary_heap.h \
 	lemon/full_graph.h \
 	lemon/glpk.h \
@@ -87,5 +90,9 @@
 	lemon/graph_to_eps.h \
 	lemon/grid_graph.h \
+	lemon/hartmann_orlin.h \
+	lemon/howard.h \
 	lemon/hypercube_graph.h \
+	lemon/karp.h \
+	lemon/kary_heap.h \
 	lemon/kruskal.h \
 	lemon/hao_orlin.h \
@@ -104,6 +111,6 @@
 	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 \
@@ -111,4 +118,5 @@
 	lemon/smart_graph.h \
 	lemon/soplex.h \
+	lemon/static_graph.h \
 	lemon/suurballe.h \
 	lemon/time_measure.h \
Index: lemon/adaptors.h
===================================================================
--- lemon/adaptors.h	(revision 656)
+++ lemon/adaptors.h	(revision 787)
@@ -361,4 +361,7 @@
   /// 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.
   /// It must conform to the \ref concepts::Digraph "Digraph" concept.
@@ -719,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.
@@ -1315,4 +1320,6 @@
   /// 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.
   /// It must conform to the \ref concepts::Graph "Graph" concept.
@@ -1471,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.
@@ -1620,4 +1629,6 @@
   /// 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.
   /// It must conform to the \ref concepts::Digraph "Digraph" concept.
@@ -1729,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.
@@ -2233,4 +2246,7 @@
   /// 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.
   /// It must conform to the \ref concepts::Digraph "Digraph" concept.
@@ -2535,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.
@@ -2678,4 +2697,6 @@
   /// arcs).
   /// 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.
@@ -3326,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.
Index: lemon/arg_parser.cc
===================================================================
--- lemon/arg_parser.cc	(revision 440)
+++ lemon/arg_parser.cc	(revision 842)
@@ -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 842)
@@ -35,4 +35,42 @@
 namespace lemon {
 
+  ///Exception used by ArgParser
+  class ArgParserException : public Exception {
+  public:
+    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
 
@@ -104,5 +142,5 @@
     std::string _command_name;
 
-
+    
   private:
     //Bind a function to an option.
@@ -116,4 +154,8 @@
                     const std::string &help,
                     void (*func)(void *),void *data);
+
+    bool _exit_on_problems;
+    
+    void _terminate(ArgParserException::Reason reason) const;
 
   public:
@@ -381,4 +423,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/bellman_ford.h
===================================================================
--- lemon/bellman_ford.h	(revision 699)
+++ lemon/bellman_ford.h	(revision 844)
@@ -24,8 +24,10 @@
 /// \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/tolerance.h>
 #include <lemon/path.h>
 
@@ -34,5 +36,5 @@
 namespace lemon {
 
-  /// \brief Default OperationTraits for the BellmanFord algorithm class.
+  /// \brief Default operation traits for the BellmanFord algorithm class.
   ///  
   /// This operation traits class defines all computational operations
@@ -41,9 +43,11 @@
   /// If the numeric type does not have infinity value, then the maximum
   /// value is used as extremal infinity value.
+  ///
+  /// \see BellmanFordToleranceOperationTraits
   template <
     typename V, 
     bool has_inf = std::numeric_limits<V>::has_infinity>
   struct BellmanFordDefaultOperationTraits {
-    /// \e
+    /// \brief Value type for the algorithm.
     typedef V Value;
     /// \brief Gives back the zero value of the type.
@@ -84,4 +88,49 @@
   };
   
+  /// \brief Operation traits for the BellmanFord algorithm class
+  /// using tolerance.
+  ///
+  /// This operation traits class defines all computational operations
+  /// and constants that are used in the Bellman-Ford algorithm.
+  /// The only difference between this implementation and
+  /// \ref BellmanFordDefaultOperationTraits is that this class uses
+  /// the \ref Tolerance "tolerance technique" in its \ref less()
+  /// function.
+  ///
+  /// \tparam V The value type.
+  /// \tparam eps The epsilon value for the \ref less() function.
+  /// By default, it is the epsilon value used by \ref Tolerance
+  /// "Tolerance<V>".
+  ///
+  /// \see BellmanFordDefaultOperationTraits
+#ifdef DOXYGEN
+  template <typename V, V eps>
+#else
+  template <
+    typename V,
+    V eps = Tolerance<V>::def_epsilon>
+#endif
+  struct BellmanFordToleranceOperationTraits {
+    /// \brief Value type for the algorithm.
+    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 + eps < right;
+    }
+  };
+
   /// \brief Default traits class of BellmanFord class.
   ///
@@ -107,5 +156,6 @@
     /// It defines the used operations and the infinity value for the
     /// given \c Value type.
-    /// \see BellmanFordDefaultOperationTraits
+    /// \see BellmanFordDefaultOperationTraits,
+    /// BellmanFordToleranceOperationTraits
     typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
  
@@ -171,4 +221,9 @@
   /// 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>
@@ -237,5 +292,7 @@
 	_dist = Traits::createDistMap(*_gr);
       }
-      _mask = new MaskMap(*_gr, false);
+      if(!_mask) {
+        _mask = new MaskMap(*_gr);
+      }
     }
     
@@ -300,5 +357,5 @@
     /// \ref named-templ-param "Named parameter" for setting
     /// \c OperationTraits type.
-    /// For more information see \ref BellmanFordDefaultOperationTraits.
+    /// For more information, see \ref BellmanFordDefaultOperationTraits.
     template <class T>
     struct SetOperationTraits
@@ -403,4 +460,8 @@
 	  _process.push_back(it);
 	  _mask->set(it, true);
+	}
+      } else {
+	for (NodeIt it(*_gr); it != INVALID; ++it) {
+	  _mask->set(it, false);
 	}
       }
@@ -718,5 +779,5 @@
     ///
     /// The shortest path tree used here is equal to the shortest path
-    /// tree used in \ref predNode() and \predMap().
+    /// tree used in \ref predNode() and \ref predMap().
     ///
     /// \pre Either \ref run() or \ref init() must be called before
@@ -733,5 +794,5 @@
     ///
     /// The shortest path tree used here is equal to the shortest path
-    /// tree used in \ref predArc() and \predMap().
+    /// tree used in \ref predArc() and \ref predMap().
     ///
     /// \pre Either \ref run() or \ref init() must be called before
@@ -776,5 +837,5 @@
     /// length if the algorithm has already found one.
     /// Otherwise it gives back an empty path.
-    lemon::Path<Digraph> negativeCycle() {
+    lemon::Path<Digraph> negativeCycle() const {
       typename Digraph::template NodeMap<int> state(*_gr, -1);
       lemon::Path<Digraph> cycle;
@@ -826,5 +887,6 @@
     /// It defines the used operations and the infinity value for the
     /// given \c Value type.
-    /// \see BellmanFordDefaultOperationTraits
+    /// \see BellmanFordDefaultOperationTraits,
+    /// BellmanFordToleranceOperationTraits
     typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
 
@@ -927,4 +989,7 @@
   /// 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 {
Index: lemon/bfs.h
===================================================================
--- lemon/bfs.h	(revision 717)
+++ lemon/bfs.h	(revision 825)
@@ -64,5 +64,5 @@
     ///The type of the map that indicates which nodes are processed.
     ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
-    ///By default it is a NullMap.
+    ///By default, it is a NullMap.
     typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
     ///Instantiates a \c ProcessedMap.
@@ -122,4 +122,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,
@@ -702,10 +707,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.
@@ -853,5 +854,5 @@
     ///The type of the map that indicates which nodes are processed.
     ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
-    ///By default it is a NullMap.
+    ///By default, it is a NullMap.
     typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
     ///Instantiates a ProcessedMap.
@@ -962,4 +963,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
@@ -1047,6 +1051,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()
     {
@@ -1300,9 +1304,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>
@@ -1696,10 +1700,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.
Index: lemon/binom_heap.h
===================================================================
--- lemon/binom_heap.h	(revision 707)
+++ lemon/binom_heap.h	(revision 707)
@@ -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-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_BINOM_HEAP_H
+#define LEMON_BINOM_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 BinomHeap {
+  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 BinomHeap(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.
+    BinomHeap(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 BinomHeap;
+
+      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_BINOM_HEAP_H
+
Index: mon/binomial_heap.h
===================================================================
--- lemon/binomial_heap.h	(revision 855)
+++ 	(revision )
@@ -1,445 +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_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/graph_extender.h
===================================================================
--- lemon/bits/graph_extender.h	(revision 685)
+++ lemon/bits/graph_extender.h	(revision 778)
@@ -57,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);
     }
@@ -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);
     }
Index: lemon/bits/map_extender.h
===================================================================
--- lemon/bits/map_extender.h	(revision 718)
+++ lemon/bits/map_extender.h	(revision 802)
@@ -85,17 +85,57 @@
       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;
       }
@@ -105,46 +145,6 @@
       }
 
-      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() {}
-
-      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;
     };
 
@@ -153,23 +153,23 @@
 
     public:
-
-      ItemIt() {}
-
-      ItemIt(Invalid i) : Parent(i) { }
-
-      explicit ItemIt(Map& _map) : map(_map) {
-        map.notifier()->first(*this);
+      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;
 
     };
@@ -232,34 +232,34 @@
       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;
 
     };
@@ -272,26 +272,26 @@
       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;
     };
 
@@ -300,23 +300,23 @@
 
     public:
-
-      ItemIt() {}
-
-      ItemIt(Invalid i) : Parent(i) { }
-
-      explicit ItemIt(Map& _map) : map(_map) {
-        map.graph.first(*this);
+      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;
 
     };
Index: lemon/capacity_scaling.h
===================================================================
--- lemon/capacity_scaling.h	(revision 840)
+++ lemon/capacity_scaling.h	(revision 840)
@@ -0,0 +1,986 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_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/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;
+    };
+
+    /// @}
+
+  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 576)
+++ lemon/cbc.cc	(revision 746)
@@ -95,4 +95,16 @@
   }
 
+  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) {
Index: lemon/cbc.h
===================================================================
--- lemon/cbc.h	(revision 576)
+++ lemon/cbc.h	(revision 746)
@@ -63,4 +63,5 @@
     virtual int _addCol();
     virtual int _addRow();
+    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
 
     virtual void _eraseCol(int i);
Index: lemon/circulation.h
===================================================================
--- lemon/circulation.h	(revision 715)
+++ lemon/circulation.h	(revision 825)
@@ -174,4 +174,9 @@
      \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
@@ -307,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().
Index: lemon/clp.cc
===================================================================
--- lemon/clp.cc	(revision 576)
+++ lemon/clp.cc	(revision 746)
@@ -79,4 +79,17 @@
   }
 
+  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;
+  }
+
 
   void ClpLp::_eraseCol(int c) {
Index: lemon/clp.h
===================================================================
--- lemon/clp.h	(revision 576)
+++ lemon/clp.h	(revision 746)
@@ -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);
Index: lemon/concepts/digraph.h
===================================================================
--- lemon/concepts/digraph.h	(revision 580)
+++ lemon/concepts/digraph.h	(revision 786)
@@ -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) { 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,43 +391,44 @@
       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 Reference map of the nodes to type \c T.
-      ///
-      /// Reference map of the nodes to type \c T.
+      /// 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 ReferenceMap<Node, T, T&, const T&> {
       public:
 
-        ///\e
-        NodeMap(const Digraph&) { }
-        ///\e
+        /// Constructor
+        explicit NodeMap(const Digraph&) { }
+        /// Constructor with given initial value
         NodeMap(const Digraph&, T) { }
 
@@ -446,15 +445,17 @@
       };
 
-      /// \brief Reference map of the arcs to type \c T.
-      ///
-      /// Reference map of the arcs to type \c T.
+      /// \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 ReferenceMap<Arc, T, T&, const T&> {
       public:
 
-        ///\e
-        ArcMap(const Digraph&) { }
-        ///\e
+        /// Constructor
+        explicit ArcMap(const Digraph&) { }
+        /// Constructor with given initial value
         ArcMap(const Digraph&, T) { }
+
       private:
         ///Copy constructor
Index: lemon/concepts/graph.h
===================================================================
--- lemon/concepts/graph.h	(revision 657)
+++ lemon/concepts/graph.h	(revision 786)
@@ -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
-      /// edge.
+      /// 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
 
-        /// @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.
@@ -324,41 +334,45 @@
         ///
         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 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; }
 
-        /// Converison to Edge
+        /// Converison to \c Edge
+        
+        /// Converison to \c Edge.
+        ///
         operator Edge() const { return Edge(); }
       };
-      /// 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:
+
+      /// 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 {
@@ -366,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.
@@ -374,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) { 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.
@@ -420,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);
         }
-        /// 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
@@ -448,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.
@@ -472,35 +481,33 @@
         ///
         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);
         }
-        /// 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 Reference map of the nodes to type \c T.
-      ///
-      /// Reference map of the nodes to type \c T.
+      /// \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 ReferenceMap<Node, T, T&, const T&>
@@ -508,7 +515,7 @@
       public:
 
-        ///\e
-        NodeMap(const Graph&) { }
-        ///\e
+        /// Constructor
+        explicit NodeMap(const Graph&) { }
+        /// Constructor with given initial value
         NodeMap(const Graph&, T) { }
 
@@ -525,7 +532,8 @@
       };
 
-      /// \brief Reference map of the arcs to type \c T.
-      ///
-      /// Reference map of the arcs to type \c T.
+      /// \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 ReferenceMap<Arc, T, T&, const T&>
@@ -533,8 +541,9 @@
       public:
 
-        ///\e
-        ArcMap(const Graph&) { }
-        ///\e
+        /// Constructor
+        explicit ArcMap(const Graph&) { }
+        /// Constructor with given initial value
         ArcMap(const Graph&, T) { }
+
       private:
         ///Copy constructor
@@ -549,7 +558,8 @@
       };
 
-      /// Reference map of the edges to type \c T.
-
-      /// Reference map of the edges to type \c T.
+      /// \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 ReferenceMap<Edge, T, T&, const T&>
@@ -557,8 +567,9 @@
       public:
 
-        ///\e
-        EdgeMap(const Graph&) { }
-        ///\e
+        /// Constructor
+        explicit EdgeMap(const Graph&) { }
+        /// Constructor with given initial value
         EdgeMap(const Graph&, T) { }
+
       private:
         ///Copy constructor
@@ -573,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 {}
@@ -706,45 +734,37 @@
       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>
Index: lemon/concepts/graph_components.h
===================================================================
--- lemon/concepts/graph_components.h	(revision 666)
+++ lemon/concepts/graph_components.h	(revision 786)
@@ -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
@@ -93,5 +93,5 @@
       /// associative containers (e.g. \c std::map).
       ///
-      /// \note This operator only have to define some strict ordering of
+      /// \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.
Index: lemon/concepts/heap.h
===================================================================
--- lemon/concepts/heap.h	(revision 710)
+++ lemon/concepts/heap.h	(revision 817)
@@ -89,5 +89,9 @@
       /// handle the cross references. The assigned value must be
       /// \c PRE_HEAP (<tt>-1</tt>) for each item.
+#ifdef DOXYGEN
       explicit Heap(ItemIntMap &map) {}
+#else
+      explicit Heap(ItemIntMap&) {}
+#endif      
 
       /// \brief Constructor.
@@ -99,5 +103,9 @@
       /// \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.
@@ -127,5 +135,9 @@
       /// \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) {}
+#else
+      void push(const Item&, const Prio&) {}
+#endif      
 
       /// \brief Return the item having minimum priority.
@@ -133,5 +145,5 @@
       /// 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.
@@ -139,5 +151,5 @@
       /// This function returns the minimum priority.
       /// \pre The heap must be non-empty.
-      Prio prio() const {}
+      Prio prio() const { return Prio(); }
 
       /// \brief Remove the item having minimum priority.
@@ -153,5 +165,9 @@
       /// \param i The item to delete.
       /// \pre \e i must be in the heap.
+#ifdef DOXYGEN
       void erase(const Item &i) {}
+#else
+      void erase(const Item&) {}
+#endif      
 
       /// \brief The priority of the given item.
@@ -160,5 +176,9 @@
       /// \param i The item.
       /// \pre \e i must be in the heap.
+#ifdef DOXYGEN
       Prio operator[](const Item &i) const {}
+#else
+      Prio operator[](const Item&) const { return Prio(); }
+#endif      
 
       /// \brief Set the priority of an item or insert it, if it is
@@ -171,5 +191,9 @@
       /// \param i The item.
       /// \param p The priority.
+#ifdef DOXYGEN
       void set(const Item &i, const Prio &p) {}
+#else
+      void set(const Item&, const Prio&) {}
+#endif      
 
       /// \brief Decrease the priority of an item to the given value.
@@ -179,5 +203,9 @@
       /// \param p The priority.
       /// \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) {}
+#else
+      void decrease(const Item&, const Prio&) {}
+#endif      
 
       /// \brief Increase the priority of an item to the given value.
@@ -187,5 +215,9 @@
       /// \param p The priority.
       /// \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) {}
+#else
+      void increase(const Item&, const Prio&) {}
+#endif      
 
       /// \brief Return the state of an item.
@@ -197,5 +229,9 @@
       /// to the heap again.
       /// \param i The item.
+#ifdef DOXYGEN
       State state(const Item &i) const {}
+#else
+      State state(const Item&) const { return PRE_HEAP; }
+#endif      
 
       /// \brief Set the state of an item in the heap.
@@ -206,5 +242,9 @@
       /// \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      
 
 
Index: lemon/concepts/path.h
===================================================================
--- lemon/concepts/path.h	(revision 559)
+++ lemon/concepts/path.h	(revision 785)
@@ -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,9 +69,9 @@
       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) {
@@ -71,5 +80,5 @@
       }
 
-      /// 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; }
 
@@ -193,22 +202,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 +223,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 +231,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 +245,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 +263,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 +274,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/cost_scaling.h
===================================================================
--- lemon/cost_scaling.h	(revision 840)
+++ lemon/cost_scaling.h	(revision 840)
@@ -0,0 +1,1312 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_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;
+    };
+
+    /// @}
+
+  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();
+          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 = std::numeric_limits<int>::max()) {
+      // 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 576)
+++ lemon/cplex.cc	(revision 746)
@@ -112,4 +112,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) {
Index: lemon/cplex.h
===================================================================
--- lemon/cplex.h	(revision 576)
+++ 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);
Index: lemon/cycle_canceling.h
===================================================================
--- lemon/cycle_canceling.h	(revision 840)
+++ lemon/cycle_canceling.h	(revision 840)
@@ -0,0 +1,1170 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_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.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 Howard<StaticDigraph, CostArcMap>
+        ::template SetPath<SPath>::Create MMC;
+      
+      SPath cycle;
+      MMC mmc(_sgr, _cost_map);
+      mmc.cycle(cycle);
+      buildResidualNetwork();
+      while (mmc.findMinMean() && mmc.cycleLength() < 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 Howard<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.findMinMean();
+          epsilon = -mmc.cycleMean();
+          Cost cycle_cost = mmc.cycleLength();
+          int cycle_size = mmc.cycleArcNum();
+          
+          // 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 717)
+++ lemon/dfs.h	(revision 825)
@@ -64,5 +64,5 @@
     ///The type of the map that indicates which nodes are processed.
     ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
-    ///By default it is a NullMap.
+    ///By default, it is a NullMap.
     typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
     ///Instantiates a \c ProcessedMap.
@@ -122,4 +122,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,
@@ -634,10 +639,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.
@@ -783,5 +784,5 @@
     ///The type of the map that indicates which nodes are processed.
     ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
-    ///By default it is a NullMap.
+    ///By default, it is a NullMap.
     typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
     ///Instantiates a ProcessedMap.
@@ -892,4 +893,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
@@ -977,6 +981,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()
     {
@@ -1242,9 +1246,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>
@@ -1579,10 +1583,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.
Index: mon/dheap.h
===================================================================
--- lemon/dheap.h	(revision 855)
+++ 	(revision )
@@ -1,352 +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_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 717)
+++ lemon/dijkstra.h	(revision 825)
@@ -133,5 +133,5 @@
     ///The type of the map that indicates which nodes are processed.
     ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
-    ///By default it is a NullMap.
+    ///By default, it is a NullMap.
     typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
     ///Instantiates a \c ProcessedMap.
@@ -193,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>
@@ -207,5 +212,5 @@
 
     ///The type of the arc lengths.
-    typedef typename TR::LengthMap::Value Value;
+    typedef typename TR::Value Value;
     ///The type of the map that stores the arc lengths.
     typedef typename TR::LengthMap LengthMap;
@@ -427,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().
@@ -448,5 +453,5 @@
     ///\ref named-templ-param "Named parameter" for setting
     ///\c OperationTraits type.
-    /// For more information see \ref DijkstraDefaultOperationTraits.
+    /// For more information, see \ref DijkstraDefaultOperationTraits.
     template <class T>
     struct SetOperationTraits
@@ -997,5 +1002,5 @@
     ///The type of the map that indicates which nodes are processed.
     ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
-    ///By default it is a NullMap.
+    ///By default, it is a NullMap.
     typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
     ///Instantiates a ProcessedMap.
@@ -1093,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
Index: lemon/edge_set.h
===================================================================
--- lemon/edge_set.h	(revision 670)
+++ lemon/edge_set.h	(revision 787)
@@ -256,11 +256,12 @@
   /// 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> > {
@@ -686,10 +687,11 @@
   /// 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>
@@ -868,5 +870,5 @@
     }
 
-    void next(Arc& arc) const {
+    static void next(Arc& arc) {
       --arc.id;
     }
@@ -955,11 +957,12 @@
   /// 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> > {
@@ -1174,5 +1177,5 @@
     }
 
-    void next(Arc& arc) const {
+    static void next(Arc& arc) {
       --arc.id;
     }
@@ -1182,5 +1185,5 @@
     }
 
-    void next(Edge& arc) const {
+    static void next(Edge& arc) {
       --arc.id;
     }
@@ -1305,11 +1308,12 @@
   /// 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> > {
Index: lemon/fourary_heap.h
===================================================================
--- lemon/fourary_heap.h	(revision 706)
+++ lemon/fourary_heap.h	(revision 706)
@@ -0,0 +1,342 @@
+/* -*- 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_FOURARY_HEAP_H
+#define LEMON_FOURARY_HEAP_H
+
+///\ingroup heaps
+///\file
+///\brief Fourary heap implementation.
+
+#include <vector>
+#include <utility>
+#include <functional>
+
+namespace lemon {
+
+  /// \ingroup heaps
+  ///
+  ///\brief Fourary heap data structure.
+  ///
+  /// This class implements the \e fourary \e heap data structure.
+  /// It fully conforms to the \ref concepts::Heap "heap concept".
+  ///
+  /// The fourary heap is a specialization of the \ref KaryHeap "K-ary heap"
+  /// for <tt>K=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 KaryHeap
+#ifdef DOXYGEN
+  template <typename PR, typename IM, typename CMP>
+#else
+  template <typename PR, typename IM, typename CMP = std::less<PR> >
+#endif
+  class FouraryHeap {
+  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 FouraryHeap(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.
+    FouraryHeap(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 FouraryHeap
+
+} // namespace lemon
+
+#endif // LEMON_FOURARY_HEAP_H
Index: lemon/full_graph.h
===================================================================
--- lemon/full_graph.h	(revision 617)
+++ lemon/full_graph.h	(revision 787)
@@ -25,5 +25,5 @@
 ///\ingroup graphs
 ///\file
-///\brief FullGraph and FullDigraph classes.
+///\brief FullDigraph and FullGraph classes.
 
 namespace lemon {
@@ -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,22 +149,26 @@
   /// \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 fully conforms to the \ref concepts::Digraph
-  /// "Digraph concept".
-  ///
-  /// 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
@@ -174,5 +178,7 @@
   public:
 
-    /// \brief Constructor
+    /// \brief Default constructor.
+    ///
+    /// Default constructor. The number of nodes and arcs will be zero.
     FullDigraph() { construct(0); }
 
@@ -185,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) {
@@ -198,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); }
@@ -206,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);
     }
@@ -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,19 +529,23 @@
   /// \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 fully conforms to the \ref concepts::Graph "Graph concept".
-  ///
-  /// 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
@@ -543,5 +555,7 @@
   public:
 
-    /// \brief Constructor
+    /// \brief Default constructor.
+    ///
+    /// Default constructor. The number of nodes and edges will be zero.
     FullGraph() { construct(0); }
 
@@ -554,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) {
@@ -569,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); }
@@ -577,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 576)
+++ lemon/glpk.cc	(revision 746)
@@ -57,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;
   }
Index: lemon/glpk.h
===================================================================
--- lemon/glpk.h	(revision 650)
+++ lemon/glpk.h	(revision 833)
@@ -26,14 +26,26 @@
 #include <lemon/lp_base.h>
 
-// forward declaration
-#if !defined _GLP_PROB && !defined GLP_PROB
-#define _GLP_PROB
-#define GLP_PROB
-typedef struct { double _opaque_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
@@ -44,6 +56,5 @@
   protected:
 
-    typedef glp_prob LPX;
-    glp_prob* lp;
+    _solver_bits::VoidPtr lp;
 
     GlpkBase();
@@ -55,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);
@@ -123,7 +135,7 @@
 
     ///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.
Index: lemon/gomory_hu.h
===================================================================
--- lemon/gomory_hu.h	(revision 713)
+++ lemon/gomory_hu.h	(revision 786)
@@ -295,9 +295,7 @@
     /// \pre \ref run() must be called before using this function.
     template <typename CutMap>
-    Value minCutMap(const Node& s, ///< 
+    Value minCutMap(const Node& s,
                     const Node& t,
-                    ///< 
                     CutMap& cutMap
-                    ///< 
                     ) const {
       Node sn = s, tn = t;
@@ -395,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);
Index: lemon/graph_to_eps.h
===================================================================
--- lemon/graph_to_eps.h	(revision 617)
+++ lemon/graph_to_eps.h	(revision 838)
@@ -143,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.
@@ -513,5 +513,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.
   ///
@@ -685,7 +685,7 @@
 #else
       os << bits::getWinFormattedDate();
+      os << std::endl;
 #endif
     }
-    os << std::endl;
 
     if (_autoArcWidthScale) {
@@ -1115,5 +1115,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
@@ -1127,5 +1127,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 617)
+++ 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,6 +501,9 @@
   ///\endcode
   ///
-  /// This graph type fully conforms to the \ref concepts::Graph
-  /// "Graph concept".
+  /// 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;
@@ -504,7 +511,9 @@
   public:
 
-    /// \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:
@@ -515,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);
@@ -541,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);
@@ -567,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);
@@ -584,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();
@@ -610,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.
@@ -617,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.
@@ -624,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.
@@ -631,5 +627,5 @@
     }
 
-    /// \brief Gives back the number of the columns.
+    /// \brief The number of the columns.
     ///
     /// Gives back the number of the columns.
@@ -638,5 +634,5 @@
     }
 
-    /// \brief Gives back the number of the rows.
+    /// \brief The number of the rows.
     ///
     /// Gives back the number of the rows.
@@ -645,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
@@ -653,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
@@ -661,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
@@ -669,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/hartmann_orlin.h
===================================================================
--- lemon/hartmann_orlin.h	(revision 841)
+++ lemon/hartmann_orlin.h	(revision 841)
@@ -0,0 +1,646 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_HARTMANN_ORLIN_H
+#define LEMON_HARTMANN_ORLIN_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 HartmannOrlin algorithm.
+  ///
+  /// Default traits class of HartmannOrlin algorithm.
+  /// \tparam GR The type of the digraph.
+  /// \tparam LEN The type of the length map.
+  /// It must conform to the \ref concepts::Rea_data "Rea_data" concept.
+#ifdef DOXYGEN
+  template <typename GR, typename LEN>
+#else
+  template <typename GR, typename LEN,
+    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
+#endif
+  struct HartmannOrlinDefaultTraits
+  {
+    /// The type of the digraph
+    typedef GR Digraph;
+    /// The type of the length map
+    typedef LEN LengthMap;
+    /// The type of the arc lengths
+    typedef typename LengthMap::Value Value;
+
+    /// \brief The large value type used for internal computations
+    ///
+    /// The large value type used for internal computations.
+    /// It is \c long \c long if the \c Value type is integer,
+    /// otherwise it is \c double.
+    /// \c Value must be convertible to \c LargeValue.
+    typedef double LargeValue;
+
+    /// The tolerance type used for internal computations
+    typedef lemon::Tolerance<LargeValue> 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 value types
+  template <typename GR, typename LEN>
+  struct HartmannOrlinDefaultTraits<GR, LEN, true>
+  {
+    typedef GR Digraph;
+    typedef LEN LengthMap;
+    typedef typename LengthMap::Value Value;
+#ifdef LEMON_HAVE_LONG_LONG
+    typedef long long LargeValue;
+#else
+    typedef long LargeValue;
+#endif
+    typedef lemon::Tolerance<LargeValue> 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 length (cost) in a digraph
+  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
+  /// It is an improved version of \ref Karp "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 LEN The type of the length 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 HartmannOrlinDefaultTraits
+  /// "HartmannOrlinDefaultTraits<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,
+             typename LEN = typename GR::template ArcMap<int>,
+             typename TR = HartmannOrlinDefaultTraits<GR, LEN> >
+#endif
+  class HartmannOrlin
+  {
+  public:
+
+    /// The type of the digraph
+    typedef typename TR::Digraph Digraph;
+    /// The type of the length map
+    typedef typename TR::LengthMap LengthMap;
+    /// The type of the arc lengths
+    typedef typename TR::Value Value;
+
+    /// \brief The large value type
+    ///
+    /// The large value type used for internal computations.
+    /// By default, it is \c long \c long if the \c Value type is integer,
+    /// otherwise it is \c double.
+    typedef typename TR::LargeValue LargeValue;
+
+    /// 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 HartmannOrlinDefaultTraits "default traits class",
+    /// it is \ref lemon::Path "Path<Digraph>".
+    typedef typename TR::Path Path;
+
+    /// The \ref HartmannOrlinDefaultTraits "traits class" of the algorithm
+    typedef TR Traits;
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+    // Data sturcture for path data
+    struct PathData
+    {
+      LargeValue dist;
+      Arc pred;
+      PathData(LargeValue 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 length of the arcs
+    const LengthMap &_length;
+
+    // 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;
+    LargeValue _curr_length, _best_length;
+    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 LargeValue INF;
+
+  public:
+
+    /// \name Named Template Parameters
+    /// @{
+
+    template <typename T>
+    struct SetLargeValueTraits : public Traits {
+      typedef T LargeValue;
+      typedef lemon::Tolerance<T> Tolerance;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c LargeValue type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
+    /// type. It is used for internal computations in the algorithm.
+    template <typename T>
+    struct SetLargeValue
+      : public HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > {
+      typedef HartmannOrlin<GR, LEN, SetLargeValueTraits<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 HartmannOrlin<GR, LEN, SetPathTraits<T> > {
+      typedef HartmannOrlin<GR, LEN, SetPathTraits<T> > Create;
+    };
+
+    /// @}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// The constructor of the class.
+    ///
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param length The lengths (costs) of the arcs.
+    HartmannOrlin( const Digraph &digraph,
+                   const LengthMap &length ) :
+      _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
+      _best_found(false), _best_length(0), _best_size(1),
+      _cycle_path(NULL), _local_path(false), _data(digraph),
+      INF(std::numeric_limits<LargeValue>::has_infinity ?
+          std::numeric_limits<LargeValue>::infinity() :
+          std::numeric_limits<LargeValue>::max())
+    {}
+
+    /// Destructor.
+    ~HartmannOrlin() {
+      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 findMinMean(), 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>
+    HartmannOrlin& 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>
+    HartmannOrlin& 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 length, you may call
+    /// \ref findMinMean().
+
+    /// @{
+
+    /// \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 lengths 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.findMinMean() && mmc.findCycle();
+    /// \endcode
+    bool run() {
+      return findMinMean() && findCycle();
+    }
+
+    /// \brief Find the minimum cycle mean.
+    ///
+    /// This function finds the minimum mean length of the directed
+    /// cycles in the digraph.
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    bool findMinMean() {
+      // 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_length * _best_size < _best_length * _curr_size) ) {
+          _best_found = true;
+          _best_length = _curr_length;
+          _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 length
+    /// in the digraph using the data computed by findMinMean().
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    ///
+    /// \pre \ref findMinMean() 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_length = _length[e];
+      _best_size = 1;
+      Node v;
+      while ((v = _gr.source(e)) != u) {
+        e = _data[v][--r].pred;
+        _cycle_path->addFront(e);
+        _best_length += _length[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 length of the found cycle.
+    ///
+    /// This function returns the total length of the found cycle.
+    ///
+    /// \pre \ref run() or \ref findMinMean() must be called before
+    /// using this function.
+    Value cycleLength() const {
+      return static_cast<Value>(_best_length);
+    }
+
+    /// \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 findMinMean() must be called before
+    /// using this function.
+    int cycleArcNum() const {
+      return _best_size;
+    }
+
+    /// \brief Return the mean length of the found cycle.
+    ///
+    /// This function returns the mean length of the found cycle.
+    ///
+    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
+    /// following code.
+    /// \code
+    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
+    /// \endcode
+    ///
+    /// \pre \ref run() or \ref findMinMean() must be called before
+    /// using this function.
+    double cycleMean() const {
+      return static_cast<double>(_best_length) / _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_length = 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 length 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;
+      LargeValue 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 + _length[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;
+      LargeValue 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 + _length[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<LargeValue> pi(_gr);
+      int n = _nodes->size();
+      LargeValue length;
+      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
+            length = _data[u][level[u].second].dist - _data[u][j].dist;
+            size = level[u].second - j;
+            if (!_curr_found || length * _curr_size < _curr_length * size) {
+              _curr_length = length;
+              _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
+      LargeValue 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_length;
+              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(_length[a] * _curr_size - _curr_length,
+                              pi[_gr.target(a)] - pi[_gr.source(a)]) ) {
+            done = false;
+            break;
+          }
+        }
+        return done;
+      }
+      return (k == n);
+    }
+
+  }; //class HartmannOrlin
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_HARTMANN_ORLIN_H
Index: lemon/howard.h
===================================================================
--- lemon/howard.h	(revision 841)
+++ lemon/howard.h	(revision 841)
@@ -0,0 +1,601 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_HOWARD_H
+#define LEMON_HOWARD_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 Howard class.
+  ///
+  /// Default traits class of Howard class.
+  /// \tparam GR The type of the digraph.
+  /// \tparam LEN The type of the length map.
+  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+#ifdef DOXYGEN
+  template <typename GR, typename LEN>
+#else
+  template <typename GR, typename LEN,
+    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
+#endif
+  struct HowardDefaultTraits
+  {
+    /// The type of the digraph
+    typedef GR Digraph;
+    /// The type of the length map
+    typedef LEN LengthMap;
+    /// The type of the arc lengths
+    typedef typename LengthMap::Value Value;
+
+    /// \brief The large value type used for internal computations
+    ///
+    /// The large value type used for internal computations.
+    /// It is \c long \c long if the \c Value type is integer,
+    /// otherwise it is \c double.
+    /// \c Value must be convertible to \c LargeValue.
+    typedef double LargeValue;
+
+    /// The tolerance type used for internal computations
+    typedef lemon::Tolerance<LargeValue> 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 value types
+  template <typename GR, typename LEN>
+  struct HowardDefaultTraits<GR, LEN, true>
+  {
+    typedef GR Digraph;
+    typedef LEN LengthMap;
+    typedef typename LengthMap::Value Value;
+#ifdef LEMON_HAVE_LONG_LONG
+    typedef long long LargeValue;
+#else
+    typedef long LargeValue;
+#endif
+    typedef lemon::Tolerance<LargeValue> 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 length (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 LEN The type of the length 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 HowardDefaultTraits
+  /// "HowardDefaultTraits<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,
+             typename LEN = typename GR::template ArcMap<int>,
+             typename TR = HowardDefaultTraits<GR, LEN> >
+#endif
+  class Howard
+  {
+  public:
+  
+    /// The type of the digraph
+    typedef typename TR::Digraph Digraph;
+    /// The type of the length map
+    typedef typename TR::LengthMap LengthMap;
+    /// The type of the arc lengths
+    typedef typename TR::Value Value;
+
+    /// \brief The large value type
+    ///
+    /// The large value type used for internal computations.
+    /// By default, it is \c long \c long if the \c Value type is integer,
+    /// otherwise it is \c double.
+    typedef typename TR::LargeValue LargeValue;
+
+    /// 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 HowardDefaultTraits "default traits class",
+    /// it is \ref lemon::Path "Path<Digraph>".
+    typedef typename TR::Path Path;
+
+    /// The \ref HowardDefaultTraits "traits class" of the algorithm
+    typedef TR Traits;
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+  
+    // The digraph the algorithm runs on
+    const Digraph &_gr;
+    // The length of the arcs
+    const LengthMap &_length;
+
+    // Data for the found cycles
+    bool _curr_found, _best_found;
+    LargeValue _curr_length, _best_length;
+    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<LargeValue> _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 LargeValue INF;
+
+  public:
+  
+    /// \name Named Template Parameters
+    /// @{
+
+    template <typename T>
+    struct SetLargeValueTraits : public Traits {
+      typedef T LargeValue;
+      typedef lemon::Tolerance<T> Tolerance;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c LargeValue type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
+    /// type. It is used for internal computations in the algorithm.
+    template <typename T>
+    struct SetLargeValue
+      : public Howard<GR, LEN, SetLargeValueTraits<T> > {
+      typedef Howard<GR, LEN, SetLargeValueTraits<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 Howard<GR, LEN, SetPathTraits<T> > {
+      typedef Howard<GR, LEN, SetPathTraits<T> > Create;
+    };
+    
+    /// @}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// The constructor of the class.
+    ///
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param length The lengths (costs) of the arcs.
+    Howard( const Digraph &digraph,
+            const LengthMap &length ) :
+      _gr(digraph), _length(length), _best_found(false),
+      _best_length(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<LargeValue>::has_infinity ?
+          std::numeric_limits<LargeValue>::infinity() :
+          std::numeric_limits<LargeValue>::max())
+    {}
+
+    /// Destructor.
+    ~Howard() {
+      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 findMinMean(), 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>
+    Howard& 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>
+    Howard& 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 length, you may call
+    /// \ref findMinMean().
+
+    /// @{
+
+    /// \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 lengths 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.findMinMean() && mmc.findCycle();
+    /// \endcode
+    bool run() {
+      return findMinMean() && findCycle();
+    }
+
+    /// \brief Find the minimum cycle mean.
+    ///
+    /// This function finds the minimum mean length of the directed
+    /// cycles in the digraph.
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    bool findMinMean() {
+      // 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_length * _best_size < _best_length * _curr_size) ) {
+          _best_found = true;
+          _best_length = _curr_length;
+          _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 length
+    /// in the digraph using the data computed by findMinMean().
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    ///
+    /// \pre \ref findMinMean() 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 length of the found cycle.
+    ///
+    /// This function returns the total length of the found cycle.
+    ///
+    /// \pre \ref run() or \ref findMinMean() must be called before
+    /// using this function.
+    Value cycleLength() const {
+      return static_cast<Value>(_best_length);
+    }
+
+    /// \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 findMinMean() must be called before
+    /// using this function.
+    int cycleArcNum() const {
+      return _best_size;
+    }
+
+    /// \brief Return the mean length of the found cycle.
+    ///
+    /// This function returns the mean length of the found cycle.
+    ///
+    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
+    /// following code.
+    /// \code
+    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
+    /// \endcode
+    ///
+    /// \pre \ref run() or \ref findMinMean() must be called before
+    /// using this function.
+    double cycleMean() const {
+      return static_cast<double>(_best_length) / _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_length = 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 (_length[e] < _dist[u]) {
+            _dist[u] = _length[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;
+      }
+      LargeValue clength;
+      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
+          clength = _length[_policy[u]];
+          csize = 1;
+          for (v = u; (v = _gr.target(_policy[v])) != u; ) {
+            clength += _length[_policy[v]];
+            ++csize;
+          }
+          if ( !_curr_found ||
+               (clength * _curr_size < _curr_length * csize) ) {
+            _curr_found = true;
+            _curr_length = clength;
+            _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] + _length[e] * _curr_size - _curr_length;
+            _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] + _length[e] * _curr_size - _curr_length;
+            _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);
+          LargeValue delta = _dist[v] + _length[e] * _curr_size - _curr_length;
+          if (_tolerance.less(delta, _dist[u])) {
+            _dist[u] = delta;
+            _policy[u] = e;
+            improved = true;
+          }
+        }
+      }
+      return improved;
+    }
+
+  }; //class Howard
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_HOWARD_H
Index: lemon/hypercube_graph.h
===================================================================
--- lemon/hypercube_graph.h	(revision 617)
+++ lemon/hypercube_graph.h	(revision 788)
@@ -263,5 +263,5 @@
     }
 
-    int index(Node node) const {
+    static int index(Node node) {
       return node._id;
     }
@@ -283,15 +283,21 @@
   /// \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".
   class HypercubeGraph : public ExtendedHypercubeGraphBase {
     typedef ExtendedHypercubeGraphBase Parent;
@@ -303,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.
@@ -321,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);
@@ -329,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);
@@ -338,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.h
===================================================================
--- lemon/karp.h	(revision 841)
+++ lemon/karp.h	(revision 841)
@@ -0,0 +1,586 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_KARP_H
+#define LEMON_KARP_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 Karp algorithm.
+  ///
+  /// Default traits class of Karp algorithm.
+  /// \tparam GR The type of the digraph.
+  /// \tparam LEN The type of the length map.
+  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
+#ifdef DOXYGEN
+  template <typename GR, typename LEN>
+#else
+  template <typename GR, typename LEN,
+    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
+#endif
+  struct KarpDefaultTraits
+  {
+    /// The type of the digraph
+    typedef GR Digraph;
+    /// The type of the length map
+    typedef LEN LengthMap;
+    /// The type of the arc lengths
+    typedef typename LengthMap::Value Value;
+
+    /// \brief The large value type used for internal computations
+    ///
+    /// The large value type used for internal computations.
+    /// It is \c long \c long if the \c Value type is integer,
+    /// otherwise it is \c double.
+    /// \c Value must be convertible to \c LargeValue.
+    typedef double LargeValue;
+
+    /// The tolerance type used for internal computations
+    typedef lemon::Tolerance<LargeValue> 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 value types
+  template <typename GR, typename LEN>
+  struct KarpDefaultTraits<GR, LEN, true>
+  {
+    typedef GR Digraph;
+    typedef LEN LengthMap;
+    typedef typename LengthMap::Value Value;
+#ifdef LEMON_HAVE_LONG_LONG
+    typedef long long LargeValue;
+#else
+    typedef long LargeValue;
+#endif
+    typedef lemon::Tolerance<LargeValue> 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 length (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 LEN The type of the length 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 KarpDefaultTraits
+  /// "KarpDefaultTraits<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,
+             typename LEN = typename GR::template ArcMap<int>,
+             typename TR = KarpDefaultTraits<GR, LEN> >
+#endif
+  class Karp
+  {
+  public:
+
+    /// The type of the digraph
+    typedef typename TR::Digraph Digraph;
+    /// The type of the length map
+    typedef typename TR::LengthMap LengthMap;
+    /// The type of the arc lengths
+    typedef typename TR::Value Value;
+
+    /// \brief The large value type
+    ///
+    /// The large value type used for internal computations.
+    /// By default, it is \c long \c long if the \c Value type is integer,
+    /// otherwise it is \c double.
+    typedef typename TR::LargeValue LargeValue;
+
+    /// 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 KarpDefaultTraits "default traits class",
+    /// it is \ref lemon::Path "Path<Digraph>".
+    typedef typename TR::Path Path;
+
+    /// The \ref KarpDefaultTraits "traits class" of the algorithm
+    typedef TR Traits;
+
+  private:
+
+    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
+
+    // Data sturcture for path data
+    struct PathData
+    {
+      LargeValue dist;
+      Arc pred;
+      PathData(LargeValue 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 length of the arcs
+    const LengthMap &_length;
+
+    // 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
+    LargeValue _cycle_length;
+    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 LargeValue INF;
+
+  public:
+
+    /// \name Named Template Parameters
+    /// @{
+
+    template <typename T>
+    struct SetLargeValueTraits : public Traits {
+      typedef T LargeValue;
+      typedef lemon::Tolerance<T> Tolerance;
+    };
+
+    /// \brief \ref named-templ-param "Named parameter" for setting
+    /// \c LargeValue type.
+    ///
+    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
+    /// type. It is used for internal computations in the algorithm.
+    template <typename T>
+    struct SetLargeValue
+      : public Karp<GR, LEN, SetLargeValueTraits<T> > {
+      typedef Karp<GR, LEN, SetLargeValueTraits<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 Karp<GR, LEN, SetPathTraits<T> > {
+      typedef Karp<GR, LEN, SetPathTraits<T> > Create;
+    };
+
+    /// @}
+
+  public:
+
+    /// \brief Constructor.
+    ///
+    /// The constructor of the class.
+    ///
+    /// \param digraph The digraph the algorithm runs on.
+    /// \param length The lengths (costs) of the arcs.
+    Karp( const Digraph &digraph,
+          const LengthMap &length ) :
+      _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
+      _cycle_length(0), _cycle_size(1), _cycle_node(INVALID),
+      _cycle_path(NULL), _local_path(false), _data(digraph),
+      INF(std::numeric_limits<LargeValue>::has_infinity ?
+          std::numeric_limits<LargeValue>::infinity() :
+          std::numeric_limits<LargeValue>::max())
+    {}
+
+    /// Destructor.
+    ~Karp() {
+      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 findMinMean(), 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>
+    Karp& 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>
+    Karp& 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 length, you may call
+    /// \ref findMinMean().
+
+    /// @{
+
+    /// \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 lengths 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.findMinMean() && mmc.findCycle();
+    /// \endcode
+    bool run() {
+      return findMinMean() && findCycle();
+    }
+
+    /// \brief Find the minimum cycle mean.
+    ///
+    /// This function finds the minimum mean length of the directed
+    /// cycles in the digraph.
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    bool findMinMean() {
+      // 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 length
+    /// in the digraph using the data computed by findMinMean().
+    ///
+    /// \return \c true if a directed cycle exists in the digraph.
+    ///
+    /// \pre \ref findMinMean() 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_length = _length[e];
+      _cycle_size = 1;
+      Node v;
+      while ((v = _gr.source(e)) != u) {
+        e = _data[v][--r].pred;
+        _cycle_path->addFront(e);
+        _cycle_length += _length[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 length of the found cycle.
+    ///
+    /// This function returns the total length of the found cycle.
+    ///
+    /// \pre \ref run() or \ref findMinMean() must be called before
+    /// using this function.
+    Value cycleLength() const {
+      return static_cast<Value>(_cycle_length);
+    }
+
+    /// \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 findMinMean() must be called before
+    /// using this function.
+    int cycleArcNum() const {
+      return _cycle_size;
+    }
+
+    /// \brief Return the mean length of the found cycle.
+    ///
+    /// This function returns the mean length of the found cycle.
+    ///
+    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
+    /// following code.
+    /// \code
+    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
+    /// \endcode
+    ///
+    /// \pre \ref run() or \ref findMinMean() must be called before
+    /// using this function.
+    double cycleMean() const {
+      return static_cast<double>(_cycle_length) / _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_length = 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 length 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;
+      LargeValue 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 + _length[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;
+      LargeValue 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 + _length[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;
+        LargeValue length, max_length = 0;
+        int size, max_size = 1;
+        bool found_curr = false;
+        for (int k = 0; k < n; ++k) {
+          if (_data[u][k].dist == INF) continue;
+          length = _data[u][n].dist - _data[u][k].dist;
+          size = n - k;
+          if (!found_curr || length * max_size > max_length * size) {
+            found_curr = true;
+            max_length = length;
+            max_size = size;
+          }
+        }
+        if ( found_curr && (_cycle_node == INVALID ||
+             max_length * _cycle_size < _cycle_length * max_size) ) {
+          _cycle_length = max_length;
+          _cycle_size = max_size;
+          _cycle_node = u;
+        }
+      }
+    }
+
+  }; //class Karp
+
+  ///@}
+
+} //namespace lemon
+
+#endif //LEMON_KARP_H
Index: lemon/kary_heap.h
===================================================================
--- lemon/kary_heap.h	(revision 706)
+++ lemon/kary_heap.h	(revision 706)
@@ -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_KARY_HEAP_H
+#define LEMON_KARY_HEAP_H
+
+///\ingroup heaps
+///\file
+///\brief Fourary heap implementation.
+
+#include <vector>
+#include <utility>
+#include <functional>
+
+namespace lemon {
+
+  /// \ingroup heaps
+  ///
+  ///\brief K-ary heap data structure.
+  ///
+  /// This class implements the \e K-ary \e heap data structure.
+  /// It fully conforms to the \ref concepts::Heap "heap concept".
+  ///
+  /// The \ref KaryHeap "K-ary heap" is a generalization of the
+  /// \ref BinHeap "binary heap" structure, its nodes have at most
+  /// \c K children, instead of two.
+  /// \ref BinHeap and \ref FouraryHeap are specialized implementations
+  /// of this structure for <tt>K=2</tt> and <tt>K=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 K The degree of the heap, each node have at most \e K
+  /// 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 K, typename CMP>
+#else
+  template <typename PR, typename IM, int K = 16,
+            typename CMP = std::less<PR> >
+#endif
+  class KaryHeap {
+  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 KaryHeap(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.
+    KaryHeap(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)/K; }
+    int firstChild(int i) { return K*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+K<=length ) {
+          int min=child;
+          for (int i=1; i<K; ++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 KaryHeap
+
+} // namespace lemon
+
+#endif // LEMON_KARY_HEAP_H
Index: lemon/lgf_reader.h
===================================================================
--- lemon/lgf_reader.h	(revision 599)
+++ lemon/lgf_reader.h	(revision 786)
@@ -428,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
@@ -2222,5 +2222,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
Index: lemon/list_graph.h
===================================================================
--- lemon/list_graph.h	(revision 617)
+++ lemon/list_graph.h	(revision 788)
@@ -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,29 +316,25 @@
   ///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.
   ///
+  ///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:
@@ -348,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(); }
@@ -354,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);
     }
@@ -363,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
@@ -406,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
@@ -420,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);
@@ -515,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
@@ -538,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:
@@ -710,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),
@@ -717,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();
@@ -756,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();
@@ -795,8 +817,4 @@
 
     typedef ListGraphBase Graph;
-
-    class Node;
-    class Arc;
-    class Edge;
 
     class Node {
@@ -848,6 +866,4 @@
       bool operator<(const Arc& arc) const {return id < arc.id;}
     };
-
-
 
     ListGraphBase()
@@ -1165,29 +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.
   ///
+  ///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,5 +1214,5 @@
     /// \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(); }
@@ -1208,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
@@ -1267,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
@@ -1280,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
@@ -1308,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
@@ -1317,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:
@@ -1489,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),
@@ -1496,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();
@@ -1535,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_base.h
===================================================================
--- lemon/lp_base.h	(revision 584)
+++ lemon/lp_base.h	(revision 834)
@@ -147,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
@@ -242,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
@@ -944,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;
@@ -1208,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;
     }
@@ -1218,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;
     }
Index: lemon/lp_skeleton.cc
===================================================================
--- lemon/lp_skeleton.cc	(revision 576)
+++ lemon/lp_skeleton.cc	(revision 746)
@@ -29,4 +29,9 @@
 
   int SkeletonSolverBase::_addRow()
+  {
+    return ++row_num;
+  }
+
+  int SkeletonSolverBase::_addRow(Value, ExprIterator, ExprIterator, Value)
   {
     return ++row_num;
Index: lemon/lp_skeleton.h
===================================================================
--- lemon/lp_skeleton.h	(revision 576)
+++ lemon/lp_skeleton.h	(revision 746)
@@ -45,4 +45,6 @@
     /// \e
     virtual int _addRow();
+    /// \e
+    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
     /// \e
     virtual void _eraseCol(int i);
Index: lemon/maps.h
===================================================================
--- lemon/maps.h	(revision 726)
+++ lemon/maps.h	(revision 792)
@@ -231,8 +231,8 @@
   /// 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
+  /// 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.
+  /// "ReferenceMap" concept. 
   ///
   /// The simplest way of using this map is through the rangeMap()
@@ -349,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.
   ///
@@ -1786,5 +1786,5 @@
   /// 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
@@ -1801,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.
   ///
@@ -1923,5 +1923,5 @@
   /// 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, however
+  /// to traverse the items with the same associated value, but
   /// it does not have \c InverseMap.
   ///
@@ -3467,5 +3467,5 @@
   /// 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
@@ -3597,5 +3597,5 @@
   /// 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
@@ -3765,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/min_cost_arborescence.h
===================================================================
--- lemon/min_cost_arborescence.h	(revision 713)
+++ lemon/min_cost_arborescence.h	(revision 825)
@@ -113,8 +113,9 @@
   /// 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
+  /// \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,
@@ -123,5 +124,5 @@
               MinCostArborescenceDefaultTraits<GR, CM> >
 #else
-  template <typename GR, typename CM, typedef TR>
+  template <typename GR, typename CM, typename TR>
 #endif
   class MinCostArborescence {
Index: lemon/network_simplex.h
===================================================================
--- lemon/network_simplex.h	(revision 730)
+++ lemon/network_simplex.h	(revision 840)
@@ -41,13 +41,15 @@
   ///
   /// \ref NetworkSimplex implements the primal Network Simplex algorithm
-  /// for finding a \ref min_cost_flow "minimum cost flow".
-  /// This algorithm is a specialized version of the linear programming
-  /// simplex method directly for the minimum cost flow problem.
-  /// It is one of the most efficient solution methods.
+  /// 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 this class is the fastest implementation available
-  /// in LEMON for the minimum cost flow problem.
-  /// Moreover it supports both directions of the supply/demand inequality
-  /// constraints. For more information see \ref SupplyType.
+  /// 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)
@@ -57,15 +59,15 @@
   ///
   /// \tparam GR The digraph type the algorithm runs on.
-  /// \tparam V The value type used for flow amounts, capacity bounds
-  /// and supply values in the algorithm. By default it is \c int.
-  /// \tparam C The value type used for costs and potentials in the
-  /// algorithm. By default it is the same as \c V.
+  /// \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 value types must be signed and all input data must
+  /// \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.
+  /// by default. For more information, see \ref PivotRule.
   template <typename GR, typename V = int, typename C = V>
   class NetworkSimplex
@@ -123,21 +125,21 @@
     /// implementations that significantly affect the running time
     /// of the algorithm.
-    /// By default \ref BLOCK_SEARCH "Block Search" is used, which
+    /// By default, \ref BLOCK_SEARCH "Block Search" is used, which
     /// proved to be the most efficient and the most robust on various
-    /// test inputs according to our benchmark tests.
-    /// However another pivot rule can be selected using the \ref run()
+    /// test inputs.
+    /// However, another pivot rule can be selected using the \ref run()
     /// function with the proper parameter.
     enum PivotRule {
 
-      /// The First Eligible pivot rule.
+      /// The \e First \e Eligible pivot rule.
       /// The next eligible arc is selected in a wraparound fashion
       /// in every iteration.
       FIRST_ELIGIBLE,
 
-      /// The Best Eligible pivot rule.
+      /// The \e Best \e Eligible pivot rule.
       /// The best eligible arc is selected in every iteration.
       BEST_ELIGIBLE,
 
-      /// The Block Search pivot rule.
+      /// 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
@@ -145,5 +147,5 @@
       BLOCK_SEARCH,
 
-      /// The Candidate List pivot rule.
+      /// 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
@@ -151,5 +153,5 @@
       CANDIDATE_LIST,
 
-      /// The Altering Candidate List pivot rule.
+      /// 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
@@ -163,7 +165,8 @@
 
     typedef std::vector<int> IntVector;
-    typedef std::vector<bool> BoolVector;
     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
@@ -193,4 +196,5 @@
     IntVector _source;
     IntVector _target;
+    bool _arc_mixing;
 
     // Node and arc data
@@ -212,5 +216,5 @@
     IntVector _dirty_revs;
     BoolVector _forward;
-    IntVector _state;
+    BoolVector _state;
     int _root;
 
@@ -220,4 +224,6 @@
     int stem, par_stem, new_stem;
     Value delta;
+    
+    const Value MAX;
 
   public:
@@ -241,5 +247,5 @@
       const IntVector  &_target;
       const CostVector &_cost;
-      const IntVector  &_state;
+      const BoolVector &_state;
       const CostVector &_pi;
       int &_in_arc;
@@ -262,5 +268,5 @@
       bool findEnteringArc() {
         Cost c;
-        for (int e = _next_arc; e < _search_arc_num; ++e) {
+        for (int e = _next_arc; e != _search_arc_num; ++e) {
           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
           if (c < 0) {
@@ -270,5 +276,5 @@
           }
         }
-        for (int e = 0; e < _next_arc; ++e) {
+        for (int e = 0; e != _next_arc; ++e) {
           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
           if (c < 0) {
@@ -293,5 +299,5 @@
       const IntVector  &_target;
       const CostVector &_cost;
-      const IntVector  &_state;
+      const BoolVector &_state;
       const CostVector &_pi;
       int &_in_arc;
@@ -310,5 +316,5 @@
       bool findEnteringArc() {
         Cost c, min = 0;
-        for (int e = 0; e < _search_arc_num; ++e) {
+        for (int e = 0; e != _search_arc_num; ++e) {
           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
           if (c < min) {
@@ -332,5 +338,5 @@
       const IntVector  &_target;
       const CostVector &_cost;
-      const IntVector  &_state;
+      const BoolVector &_state;
       const CostVector &_pi;
       int &_in_arc;
@@ -351,5 +357,5 @@
       {
         // The main parameters of the pivot rule
-        const double BLOCK_SIZE_FACTOR = 0.5;
+        const double BLOCK_SIZE_FACTOR = 1.0;
         const int MIN_BLOCK_SIZE = 10;
 
@@ -364,5 +370,5 @@
         int cnt = _block_size;
         int e;
-        for (e = _next_arc; e < _search_arc_num; ++e) {
+        for (e = _next_arc; e != _search_arc_num; ++e) {
           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
           if (c < min) {
@@ -375,5 +381,5 @@
           }
         }
-        for (e = 0; e < _next_arc; ++e) {
+        for (e = 0; e != _next_arc; ++e) {
           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
           if (c < min) {
@@ -405,5 +411,5 @@
       const IntVector  &_target;
       const CostVector &_cost;
-      const IntVector  &_state;
+      const BoolVector &_state;
       const CostVector &_pi;
       int &_in_arc;
@@ -466,5 +472,5 @@
         min = 0;
         _curr_length = 0;
-        for (e = _next_arc; e < _search_arc_num; ++e) {
+        for (e = _next_arc; e != _search_arc_num; ++e) {
           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
           if (c < 0) {
@@ -477,5 +483,5 @@
           }
         }
-        for (e = 0; e < _next_arc; ++e) {
+        for (e = 0; e != _next_arc; ++e) {
           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
           if (c < 0) {
@@ -508,5 +514,5 @@
       const IntVector  &_target;
       const CostVector &_cost;
-      const IntVector  &_state;
+      const BoolVector &_state;
       const CostVector &_pi;
       int &_in_arc;
@@ -561,5 +567,5 @@
         // Check the current candidate list
         int e;
-        for (int i = 0; i < _curr_length; ++i) {
+        for (int i = 0; i != _curr_length; ++i) {
           e = _candidates[i];
           _cand_cost[e] = _state[e] *
@@ -574,5 +580,5 @@
         int limit = _head_length;
 
-        for (e = _next_arc; e < _search_arc_num; ++e) {
+        for (e = _next_arc; e != _search_arc_num; ++e) {
           _cand_cost[e] = _state[e] *
             (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
@@ -586,5 +592,5 @@
           }
         }
-        for (e = 0; e < _next_arc; ++e) {
+        for (e = 0; e != _next_arc; ++e) {
           _cand_cost[e] = _state[e] *
             (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
@@ -630,9 +636,10 @@
     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() :
-          std::numeric_limits<Value>::max())
+          std::numeric_limits<Value>::infinity() : MAX)
     {
-      // Check the value types
+      // Check the number types
       LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
         "The flow type of NetworkSimplex must be signed");
@@ -640,56 +647,5 @@
         "The cost type of NetworkSimplex must be signed");
         
-      // 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
+      // Reset data structures
       reset();
     }
@@ -726,5 +682,5 @@
     /// 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 on each arc).
+    /// unbounded from above).
     ///
     /// \param map An arc map storing the upper bounds.
@@ -811,5 +767,5 @@
     /// type will be used.
     ///
-    /// For more information see \ref SupplyType.
+    /// For more information, see \ref SupplyType.
     ///
     /// \return <tt>(*this)</tt>
@@ -839,13 +795,13 @@
     /// \endcode
     ///
-    /// This function can be called more than once. All the parameters
-    /// that have been given are kept for the next call, unless
-    /// \ref reset() is called, thus only the modified parameters
-    /// have to be set again. See \ref reset() for examples.
-    /// However the underlying digraph must not be modified after this
-    /// class have been constructed, since it copies and extends the graph.
+    /// 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.
+    /// algorithm. For more information, see \ref PivotRule.
     ///
     /// \return \c INFEASIBLE if no feasible flow exists,
@@ -858,4 +814,5 @@
     ///
     /// \see ProblemType, PivotRule
+    /// \see resetParams(), reset()
     ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH) {
       if (!init()) return INFEASIBLE;
@@ -869,9 +826,10 @@
     /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType().
     ///
-    /// 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.
+    /// 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,
@@ -883,12 +841,12 @@
     ///     .supplyMap(sup).run();
     ///
-    ///   // Run again with modified cost map (reset() is not called,
+    ///   // 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 reset()
+    ///   // Run again from scratch using resetParams()
     ///   // (the lower bounds will be set to zero on all arcs)
-    ///   ns.reset();
+    ///   ns.resetParams();
     ///   ns.upperMap(capacity).costMap(cost)
     ///     .supplyMap(sup).run();
@@ -896,5 +854,7 @@
     ///
     /// \return <tt>(*this)</tt>
-    NetworkSimplex& reset() {
+    ///
+    /// \see reset(), run()
+    NetworkSimplex& resetParams() {
       for (int i = 0; i != _node_num; ++i) {
         _supply[i] = 0;
@@ -910,4 +870,81 @@
     }
 
+    /// \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;
+    }
+    
     /// @}
 
@@ -1019,7 +1056,7 @@
           Value c = _lower[i];
           if (c >= 0) {
-            _cap[i] = _upper[i] < INF ? _upper[i] - c : INF;
+            _cap[i] = _upper[i] < MAX ? _upper[i] - c : INF;
           } else {
-            _cap[i] = _upper[i] < INF + c ? _upper[i] - c : INF;
+            _cap[i] = _upper[i] < MAX + c ? _upper[i] - c : INF;
           }
           _supply[_source[i]] -= c;
@@ -1213,5 +1250,5 @@
         e = _pred[u];
         d = _forward[u] ?
-          _flow[e] : (_cap[e] == INF ? INF : _cap[e] - _flow[e]);
+          _flow[e] : (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]);
         if (d < delta) {
           delta = d;
@@ -1224,5 +1261,5 @@
         e = _pred[u];
         d = _forward[u] ? 
-          (_cap[e] == INF ? INF : _cap[e] - _flow[e]) : _flow[e];
+          (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]) : _flow[e];
         if (d <= delta) {
           delta = d;
@@ -1325,5 +1362,5 @@
 
       // Update _rev_thread using the new _thread values
-      for (int i = 0; i < int(_dirty_revs.size()); ++i) {
+      for (int i = 0; i != int(_dirty_revs.size()); ++i) {
         u = _dirty_revs[i];
         _rev_thread[_thread[u]] = u;
@@ -1395,4 +1432,98 @@
         _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;
     }
 
@@ -1419,9 +1550,12 @@
       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 >= INF) return UNBOUNDED;
+        if (delta >= MAX) return UNBOUNDED;
         changeFlow(change);
         if (change) {
Index: lemon/path.h
===================================================================
--- lemon/path.h	(revision 559)
+++ lemon/path.h	(revision 803)
@@ -71,5 +71,5 @@
     template <typename CPath>
     Path(const CPath& cpath) {
-      copyPath(*this, cpath);
+      pathCopy(cpath, *this);
     }
 
@@ -79,5 +79,5 @@
     template <typename CPath>
     Path& operator=(const CPath& cpath) {
-      copyPath(*this, cpath);
+      pathCopy(cpath, *this);
       return *this;
     }
@@ -259,5 +259,5 @@
     template <typename CPath>
     SimplePath(const CPath& cpath) {
-      copyPath(*this, cpath);
+      pathCopy(cpath, *this);
     }
 
@@ -268,5 +268,5 @@
     template <typename CPath>
     SimplePath& operator=(const CPath& cpath) {
-      copyPath(*this, cpath);
+      pathCopy(cpath, *this);
       return *this;
     }
@@ -438,5 +438,5 @@
     template <typename CPath>
     ListPath(const CPath& cpath) : first(0), last(0) {
-      copyPath(*this, cpath);
+      pathCopy(cpath, *this);
     }
 
@@ -454,5 +454,5 @@
     template <typename CPath>
     ListPath& operator=(const CPath& cpath) {
-      copyPath(*this, cpath);
+      pathCopy(cpath, *this);
       return *this;
     }
@@ -764,5 +764,5 @@
     template <typename CPath>
     StaticPath(const CPath& cpath) : arcs(0) {
-      copyPath(*this, cpath);
+      pathCopy(cpath, *this);
     }
 
@@ -780,5 +780,5 @@
     template <typename CPath>
     StaticPath& operator=(const CPath& cpath) {
-      copyPath(*this, cpath);
+      pathCopy(cpath, *this);
       return *this;
     }
@@ -929,55 +929,55 @@
     };
 
-    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 From, typename To>
+    struct PathCopySelectorBackward<From, To, true> {
+      static void copy(const From& from, To& to) {
+        to.clear();
+        to.buildRev(from);
       }
     };
 
     
-    template <typename Target, typename Source,
-              bool revEnable = RevPathTagIndicator<Source>::value>
+    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);
+      static void copy(const From& from, To& to) {
+        PathCopySelectorForward<From, To>::copy(from, to);
       }      
     };
 
-    template <typename Target, typename Source>
-    struct PathCopySelector<Target, Source, true> {
-      static void copy(Target& target, const Source& source) {
-        PathCopySelectorBackward<Target, Source>::copy(target, source);
+    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 +988,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 +1024,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 828)
+++ lemon/planarity.h	(revision 828)
@@ -0,0 +1,2755 @@
+/* -*- 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_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 source = _graph.source(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 715)
+++ lemon/preflow.h	(revision 825)
@@ -103,5 +103,6 @@
   /// 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 uses a mixture of the
@@ -113,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>
@@ -265,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().
Index: mon/quad_heap.h
===================================================================
--- lemon/quad_heap.h	(revision 855)
+++ 	(revision )
@@ -1,343 +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_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/smart_graph.h
===================================================================
--- lemon/smart_graph.h	(revision 617)
+++ lemon/smart_graph.h	(revision 787)
@@ -33,8 +33,5 @@
 
   class SmartDigraph;
-  ///Base of SmartDigraph
-
-  ///Base of SmartDigraph
-  ///
+
   class SmartDigraphBase {
   protected:
@@ -188,26 +185,26 @@
   ///\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 fully conforms to the \ref concepts::Digraph "Digraph concept".
-  ///
-  ///\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:
-
-    ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
-
-    ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
-    ///
+    /// Digraphs are \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.
+    /// \brief Assignment of a digraph to another one is \e not allowed.
+    /// Use DigraphCopy instead.
     void operator=(const SmartDigraph &) {}
 
@@ -222,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.
@@ -309,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:
 
@@ -333,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
     {
@@ -358,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();
@@ -372,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();
@@ -386,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()
       {
@@ -509,5 +500,5 @@
     }
 
-    void next(Node& node) const {
+    static void next(Node& node) {
       --node._id;
     }
@@ -517,5 +508,5 @@
     }
 
-    void next(Arc& arc) const {
+    static void next(Arc& arc) {
       --arc._id;
     }
@@ -525,5 +516,5 @@
     }
 
-    void next(Edge& arc) const {
+    static void next(Edge& arc) {
       --arc._id;
     }
@@ -622,27 +613,26 @@
   /// \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>.
-  /// It fully conforms to the \ref concepts::Graph "Graph concept".
-  ///
-  /// \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 &) {}
 
@@ -655,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:
@@ -743,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
     {
@@ -769,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 576)
+++ lemon/soplex.cc	(revision 746)
@@ -92,4 +92,17 @@
   }
 
+  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);
+
+    _row_names.push_back(std::string());
+
+    return soplex->nRows() - 1;
+  }
+
 
   void SoplexLp::_eraseCol(int i) {
Index: lemon/soplex.h
===================================================================
--- lemon/soplex.h	(revision 576)
+++ lemon/soplex.h	(revision 746)
@@ -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);
Index: lemon/static_graph.h
===================================================================
--- lemon/static_graph.h	(revision 787)
+++ lemon/static_graph.h	(revision 787)
@@ -0,0 +1,476 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_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 623)
+++ lemon/suurballe.h	(revision 854)
@@ -30,4 +30,5 @@
 #include <lemon/path.h>
 #include <lemon/list_graph.h>
+#include <lemon/dijkstra.h>
 #include <lemon/maps.h>
 
@@ -47,5 +48,5 @@
   /// "minimum cost flow problem". This implementation is actually an
   /// efficient specialized version of the \ref CapacityScaling
-  /// "Successive Shortest Path" algorithm directly for this problem.
+  /// "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
@@ -56,7 +57,7 @@
   /// 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
+  /// \note For finding \e node-disjoint paths, this algorithm can be used
   /// along with the \ref SplitNodes adaptor.
 #ifdef DOXYGEN
@@ -98,4 +99,7 @@
   private:
 
+    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
+    typedef BinHeap<Length, HeapCrossRef> Heap;
+
     // ResidualDijkstra is a special implementation of the
     // Dijkstra algorithm for finding shortest paths in the
@@ -105,42 +109,36 @@
     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 &graph,
-                        const FlowMap &flow,
-                        const LengthMap &length,
-                        PotentialMap &potential,
-                        PredMap &pred,
-                        Node s, Node t ) :
-        _graph(graph), _flow(flow), _length(length), _potential(potential),
-        _dist(graph), _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);
@@ -152,8 +150,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
@@ -162,17 +205,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;
               }
             }
@@ -184,17 +227,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;
               }
             }
@@ -206,5 +249,5 @@
         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;
       }
@@ -227,17 +270,19 @@
 
     // 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;
 
   public:
@@ -252,9 +297,7 @@
                const LengthMap &length ) :
       _graph(graph), _length(length), _flow(0), _local_flow(false),
-      _potential(0), _local_potential(false), _pred(graph)
-    {
-      LEMON_ASSERT(std::numeric_limits<Length>::is_integer,
-        "The length type of Suurballe must be integer");
-    }
+      _potential(0), _local_potential(false), _pred(graph),
+      _init_dist(0), _init_pred(0)
+    {}
 
     /// Destructor.
@@ -262,5 +305,6 @@
       if (_local_flow) delete _flow;
       if (_local_potential) delete _potential;
-      delete _dijkstra;
+      delete _init_dist;
+      delete _init_pred;
     }
 
@@ -307,8 +351,11 @@
     /// \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().
 
     /// @{
@@ -330,11 +377,9 @@
     /// \code
     ///   s.init(s);
-    ///   s.findFlow(t, k);
-    ///   s.findPaths();
+    ///   s.start(t, k);
     /// \endcode
     int run(const Node& s, const Node& t, int k = 2) {
       init(s);
-      findFlow(t, k);
-      findPaths();
+      start(t, k);
       return _path_num;
     }
@@ -342,9 +387,9 @@
     /// \brief Initialize the algorithm.
     ///
-    /// This function initializes the algorithm.
+    /// This function initializes the algorithm with the given source node.
     ///
     /// \param s The source node.
     void init(const Node& s) {
-      _source = s;
+      _s = s;
 
       // Initialize maps
@@ -357,6 +402,61 @@
         _local_potential = true;
       }
-      for (ArcIt e(_graph); e != INVALID; ++e) (*_flow)[e] = 0;
-      for (NodeIt n(_graph); n != INVALID; ++n) (*_potential)[n] = 0;
+      _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
+    /// \c s to \c t in the digraph. Otherwise it returns the number of
+    /// arc-disjoint paths found.
+    ///
+    /// \note Apart from the return value, <tt>s.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;
     }
 
@@ -376,18 +476,37 @@
     /// \pre \ref init() must be called before using this function.
     int findFlow(const Node& t, int k = 2) {
-      _target = t;
-      _dijkstra =
-        new ResidualDijkstra( _graph, *_flow, _length, *_potential, _pred,
-                              _source, _target );
+      _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) {
@@ -406,6 +525,6 @@
     /// \brief Compute the paths from the flow.
     ///
-    /// This function computes the paths from the found minimum cost flow,
-    /// which is the union of some arc-disjoint paths.
+    /// 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
@@ -415,13 +534,13 @@
       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;
         }
@@ -521,6 +640,6 @@
     /// \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 584)
+++ lemon/time_measure.h	(revision 786)
@@ -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
Index: lemon/unionfind.h
===================================================================
--- lemon/unionfind.h	(revision 559)
+++ lemon/unionfind.h	(revision 800)
@@ -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;
     }
Index: m4/lx_check_coin.m4
===================================================================
--- m4/lx_check_coin.m4	(revision 627)
+++ m4/lx_check_coin.m4	(revision 749)
@@ -89,5 +89,5 @@
         CBC_LDFLAGS="-L$with_coin/lib"
       fi
-      CBC_LIBS="-lOsi -lCbc -lOsiCbc -lCbcSolver -lClp -lOsiClp -lCoinUtils -lVol -lOsiVol -lCgl -lm -llapack -lblas"
+      CBC_LIBS="-lOsi -lCbc -lCbcSolver -lClp -lOsiClp -lCoinUtils -lVol -lOsiVol -lCgl -lm -llapack -lblas"
 
       lx_save_cxxflags="$CXXFLAGS"
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 564)
+++ scripts/mk-release.sh	(revision 733)
@@ -1,3 +1,17 @@
 #!/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
Index: scripts/unify-sources.sh
===================================================================
--- scripts/unify-sources.sh	(revision 655)
+++ scripts/unify-sources.sh	(revision 733)
@@ -1,3 +1,17 @@
 #!/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.
 
 YEAR=`date +%Y`
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 698)
+++ test/CMakeLists.txt	(revision 799)
@@ -33,5 +33,7 @@
   min_cost_arborescence_test
   min_cost_flow_test
+  min_mean_cycle_test
   path_test
+  planarity_test
   preflow_test
   radix_sort_test
Index: test/Makefile.am
===================================================================
--- test/Makefile.am	(revision 698)
+++ test/Makefile.am	(revision 799)
@@ -1,2 +1,6 @@
+if USE_VALGRIND
+TESTS_ENVIRONMENT=$(top_srcdir)/scripts/valgrind-wrapper.sh
+endif
+
 EXTRA_DIST += \
 	test/CMakeLists.txt
@@ -31,5 +35,7 @@
 	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 \
@@ -79,5 +85,7 @@
 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 504)
@@ -1372,26 +1372,18 @@
 
   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 SplitNodes<Orienter< const GridGraph, GridGraph::EdgeMap<bool> > >
+    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);
+
+  SplitGridGraph adaptor = splitNodes(orienter(graph, dir_map));
   USplitGridGraph uadaptor = undirector(adaptor);
-  UUSplitGridGraph uuadaptor = undirector(uadaptor);
 
   // Check adaptor
@@ -1400,21 +1392,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 +1431,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/bellman_ford_test.cc
===================================================================
--- test/bellman_ford_test.cc	(revision 699)
+++ test/bellman_ford_test.cc	(revision 844)
@@ -66,5 +66,5 @@
   Arc e;
   Value l;
-  int k;
+  int k=3;
   bool b;
   BF::DistMap d(gr);
@@ -97,4 +97,5 @@
     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) {}
@@ -104,4 +105,5 @@
       ::SetDistMap<concepts::ReadWriteMap<Node,Value> >
       ::SetOperationTraits<BellmanFordDefaultOperationTraits<Value> >
+      ::SetOperationTraits<BellmanFordToleranceOperationTraits<Value, 0> >
       ::Create bf_test(gr,length);
 
@@ -133,4 +135,5 @@
     b  = bf_test.reached(t);
     pp = bf_test.path(t);
+    pp = bf_test.negativeCycle();
   }
 }
Index: test/digraph_test.cc
===================================================================
--- test/digraph_test.cc	(revision 440)
+++ test/digraph_test.cc	(revision 780)
@@ -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
@@ -284,4 +288,12 @@
 
   snapshot.restore();
+  snapshot.save(G);
+
+  checkGraphNodeList(G, 4);
+  checkGraphArcList(G, 4);
+
+  G.addArc(G.addNode(), G.addNode());
+
+  snapshot.restore();
 
   checkGraphNodeList(G, 4);
@@ -318,4 +330,8 @@
     checkConcept<ClearableDigraphComponent<>, SmartDigraph>();
   }
+  { // Checking StaticDigraph
+    checkConcept<Digraph, StaticDigraph>();
+    checkConcept<ClearableDigraphComponent<>, StaticDigraph>();
+  }
   { // Checking FullDigraph
     checkConcept<Digraph, FullDigraph>();
@@ -373,8 +389,120 @@
 }
 
+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);
+
+  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 +548,7 @@
     checkDigraphValidity<SmartDigraph>();
   }
+  { // Checking StaticDigraph
+    checkStaticDigraph();
+  }
   { // Checking FullDigraph
     checkFullDigraph(8);
Index: test/graph_test.cc
===================================================================
--- test/graph_test.cc	(revision 440)
+++ test/graph_test.cc	(revision 740)
@@ -39,4 +39,7 @@
   checkGraphArcList(G, 0);
 
+  G.reserveNode(3);
+  G.reserveEdge(3);
+
   Node
     n1 = G.addNode(),
@@ -257,4 +260,13 @@
 
   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);
@@ -268,4 +280,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);
@@ -412,4 +431,8 @@
   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");
+
   for (int i = 0; i < width; ++i) {
     for (int j = 0; j < height; ++j) {
@@ -487,4 +510,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)));
Index: test/heap_test.cc
===================================================================
--- test/heap_test.cc	(revision 855)
+++ test/heap_test.cc	(revision 702)
@@ -31,10 +31,10 @@
 
 #include <lemon/bin_heap.h>
-#include <lemon/quad_heap.h>
-#include <lemon/dheap.h>
+#include <lemon/fourary_heap.h>
+#include <lemon/kary_heap.h>
 #include <lemon/fib_heap.h>
 #include <lemon/pairing_heap.h>
 #include <lemon/radix_heap.h>
-#include <lemon/binomial_heap.h>
+#include <lemon/binom_heap.h>
 #include <lemon/bucket_heap.h>
 
@@ -186,24 +186,24 @@
   }
 
-  // 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;
+  // FouraryHeap
+  {
+    typedef FouraryHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef FouraryHeap<Prio, IntNodeMap > NodeHeap;
+    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
+    dijkstraHeapTest<NodeHeap>(digraph, length, source);
+  }
+
+  // KaryHeap
+  {
+    typedef KaryHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef KaryHeap<Prio, IntNodeMap > NodeHeap;
     checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
     dijkstraHeapTest<NodeHeap>(digraph, length, source);
@@ -246,12 +246,12 @@
   }
 
-  // BinomialHeap
-  {
-    typedef BinomialHeap<Prio, ItemIntMap> IntHeap;
-    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
-    heapSortTest<IntHeap>();
-    heapIncreaseTest<IntHeap>();
-
-    typedef BinomialHeap<Prio, IntNodeMap > NodeHeap;
+  // BinomHeap
+  {
+    typedef BinomHeap<Prio, ItemIntMap> IntHeap;
+    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
+    heapSortTest<IntHeap>();
+    heapIncreaseTest<IntHeap>();
+
+    typedef BinomHeap<Prio, IntNodeMap > NodeHeap;
     checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
     dijkstraHeapTest<NodeHeap>(digraph, length, source);
Index: test/maps_test.cc
===================================================================
--- test/maps_test.cc	(revision 726)
+++ test/maps_test.cc	(revision 789)
@@ -27,4 +27,5 @@
 #include <lemon/adaptors.h>
 #include <lemon/dfs.h>
+#include <algorithm>
 
 #include "test_tools.h"
@@ -38,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; }
 };
 
@@ -57,4 +71,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;
 typedef ReadWriteMap<A, double> DoubleWriteMap;
@@ -64,10 +86,4 @@
 typedef ReadWriteMap<A, bool> BoolWriteMap;
 typedef ReferenceMap<A, bool, bool&, const bool&> BoolRefMap;
-
-template<typename Map1, typename Map2, typename ItemIt>
-void compareMap(const Map1& map1, const Map2& map2, ItemIt it) {
-  for (; it != INVALID; ++it)
-    check(map1[it] == map2[it], "The maps are not equal");
-}
 
 int main()
@@ -495,7 +511,8 @@
     }
     
-    compareMap(sourceMap(orienter(gr, constMap<Edge, bool>(true))),
-               targetMap(orienter(gr, constMap<Edge, bool>(false))),
-               EdgeIt(gr));
+    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;
@@ -801,4 +818,182 @@
 
   }
+  
+  // 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()");
+  }
+  
   return 0;
 }
Index: test/min_cost_flow_test.cc
===================================================================
--- test/min_cost_flow_test.cc	(revision 669)
+++ test/min_cost_flow_test.cc	(revision 830)
@@ -25,6 +25,10 @@
 
 #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>
 
@@ -33,4 +37,5 @@
 using namespace lemon;
 
+// Test networks
 char test_lgf[] =
   "@nodes\n"
@@ -77,4 +82,56 @@
   "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 {
@@ -83,4 +140,5 @@
   LEQ
 };
+
 
 // Check the interface of an MCF algorithm
@@ -100,5 +158,5 @@
       const MCF& const_mcf = mcf;
 
-      b = mcf.reset()
+      b = mcf.reset().resetParams()
              .lowerMap(me.lower)
              .upperMap(me.upper)
@@ -269,28 +327,97 @@
 }
 
+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()
 {
-  // Check the interfaces
-  {
-    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> >();
-  }
-
-  // Run various MCF tests
-  typedef ListDigraph Digraph;
-  DIGRAPH_TYPEDEFS(ListDigraph);
-
-  // Read the test digraph
-  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;
-
+  // Read the test networks
   std::istringstream input(test_lgf);
   DigraphReader<Digraph>(gr, input)
@@ -310,139 +437,104 @@
     .run();
   
-  // Build test digraphs with negative costs
-  Digraph neg_gr;
-  Node n1 = neg_gr.addNode();
-  Node n2 = neg_gr.addNode();
-  Node n3 = neg_gr.addNode();
-  Node n4 = neg_gr.addNode();
-  Node n5 = neg_gr.addNode();
-  Node n6 = neg_gr.addNode();
-  Node n7 = neg_gr.addNode();
-  
-  Arc a1 = neg_gr.addArc(n1, n2);
-  Arc a2 = neg_gr.addArc(n1, n3);
-  Arc a3 = neg_gr.addArc(n2, n4);
-  Arc a4 = neg_gr.addArc(n3, n4);
-  Arc a5 = neg_gr.addArc(n3, n2);
-  Arc a6 = neg_gr.addArc(n5, n3);
-  Arc a7 = neg_gr.addArc(n5, n6);
-  Arc a8 = neg_gr.addArc(n6, n7);
-  Arc a9 = neg_gr.addArc(n7, n5);
-  
-  Digraph::ArcMap<int> neg_c(neg_gr), neg_l1(neg_gr, 0), neg_l2(neg_gr, 0);
-  ConstMap<Arc, int> neg_u1(std::numeric_limits<int>::max()), neg_u2(5000);
-  Digraph::NodeMap<int> neg_s(neg_gr, 0);
-  
-  neg_l2[a7] =  1000;
-  neg_l2[a8] = -1000;
-  
-  neg_s[n1] =  100;
-  neg_s[n4] = -100;
-  
-  neg_c[a1] =  100;
-  neg_c[a2] =   30;
-  neg_c[a3] =   20;
-  neg_c[a4] =   80;
-  neg_c[a5] =   50;
-  neg_c[a6] =   10;
-  neg_c[a7] =   80;
-  neg_c[a8] =   30;
-  neg_c[a9] = -120;
-
-  Digraph negs_gr;
-  Digraph::NodeMap<int> negs_s(negs_gr);
-  Digraph::ArcMap<int> negs_c(negs_gr);
-  ConstMap<Arc, int> negs_l(0), negs_u(1000);
-  n1 = negs_gr.addNode();
-  n2 = negs_gr.addNode();
-  negs_s[n1] = 100;
-  negs_s[n2] = -300;
-  negs_c[negs_gr.addArc(n1, n2)] = -1;
-
-
-  // A. Test NetworkSimplex with the default pivot rule
-  {
-    NetworkSimplex<Digraph> mcf(gr);
-
-    // Check the equality form
-    mcf.upperMap(u).costMap(c);
-    checkMcf(mcf, mcf.supplyMap(s1).run(),
-             gr, l1, u, c, s1, mcf.OPTIMAL, true,   5240, "#A1");
-    checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
-             gr, l1, u, c, s2, mcf.OPTIMAL, true,   7620, "#A2");
-    mcf.lowerMap(l2);
-    checkMcf(mcf, mcf.supplyMap(s1).run(),
-             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#A3");
-    checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
-             gr, l2, u, c, s2, mcf.OPTIMAL, true,   8010, "#A4");
-    mcf.reset();
-    checkMcf(mcf, mcf.supplyMap(s1).run(),
-             gr, l1, cu, cc, s1, mcf.OPTIMAL, true,   74, "#A5");
-    checkMcf(mcf, mcf.lowerMap(l2).stSupply(v, w, 27).run(),
-             gr, l2, cu, cc, s2, mcf.OPTIMAL, true,   94, "#A6");
-    mcf.reset();
-    checkMcf(mcf, mcf.run(),
-             gr, l1, cu, cc, s3, mcf.OPTIMAL, true,    0, "#A7");
-    checkMcf(mcf, mcf.lowerMap(l2).upperMap(u).run(),
-             gr, l2, u, cc, s3, mcf.INFEASIBLE, false, 0, "#A8");
-    mcf.reset().lowerMap(l3).upperMap(u).costMap(c).supplyMap(s4);
-    checkMcf(mcf, mcf.run(),
-             gr, l3, u, c, s4, mcf.OPTIMAL, true,   6360, "#A9");
-
-    // Check the GEQ form
-    mcf.reset().upperMap(u).costMap(c).supplyMap(s5);
-    checkMcf(mcf, mcf.run(),
-             gr, l1, u, c, s5, mcf.OPTIMAL, true,   3530, "#A10", GEQ);
-    mcf.supplyType(mcf.GEQ);
-    checkMcf(mcf, mcf.lowerMap(l2).run(),
-             gr, l2, u, c, s5, mcf.OPTIMAL, true,   4540, "#A11", GEQ);
-    mcf.supplyMap(s6);
-    checkMcf(mcf, mcf.run(),
-             gr, l2, u, c, s6, mcf.INFEASIBLE, false,  0, "#A12", GEQ);
-
-    // Check the LEQ form
-    mcf.reset().supplyType(mcf.LEQ);
-    mcf.upperMap(u).costMap(c).supplyMap(s6);
-    checkMcf(mcf, mcf.run(),
-             gr, l1, u, c, s6, mcf.OPTIMAL, true,   5080, "#A13", LEQ);
-    checkMcf(mcf, mcf.lowerMap(l2).run(),
-             gr, l2, u, c, s6, mcf.OPTIMAL, true,   5930, "#A14", LEQ);
-    mcf.supplyMap(s5);
-    checkMcf(mcf, mcf.run(),
-             gr, l2, u, c, s5, mcf.INFEASIBLE, false,  0, "#A15", LEQ);
-
-    // Check negative costs
-    NetworkSimplex<Digraph> neg_mcf(neg_gr);
-    neg_mcf.lowerMap(neg_l1).costMap(neg_c).supplyMap(neg_s);
-    checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l1, neg_u1,
-      neg_c, neg_s, neg_mcf.UNBOUNDED, false,    0, "#A16");
-    neg_mcf.upperMap(neg_u2);
-    checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l1, neg_u2,
-      neg_c, neg_s, neg_mcf.OPTIMAL, true,  -40000, "#A17");
-    neg_mcf.reset().lowerMap(neg_l2).costMap(neg_c).supplyMap(neg_s);
-    checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l2, neg_u1,
-      neg_c, neg_s, neg_mcf.UNBOUNDED, false,    0, "#A18");
-      
-    NetworkSimplex<Digraph> negs_mcf(negs_gr);
-    negs_mcf.costMap(negs_c).supplyMap(negs_s);
-    checkMcf(negs_mcf, negs_mcf.run(), negs_gr, negs_l, negs_u,
-      negs_c, negs_s, negs_mcf.OPTIMAL, true, -300, "#A19", GEQ);
-  }
-
-  // B. Test NetworkSimplex with each pivot rule
-  {
-    NetworkSimplex<Digraph> mcf(gr);
-    mcf.supplyMap(s1).costMap(c).upperMap(u).lowerMap(l2);
-
-    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::FIRST_ELIGIBLE),
-             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B1");
-    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BEST_ELIGIBLE),
-             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B2");
-    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BLOCK_SEARCH),
-             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B3");
-    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::CANDIDATE_LIST),
-             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B4");
-    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::ALTERING_LIST),
-             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B5");
+  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");
   }
 
Index: test/min_mean_cycle_test.cc
===================================================================
--- test/min_mean_cycle_test.cc	(revision 769)
+++ test/min_mean_cycle_test.cc	(revision 769)
@@ -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-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 <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.h>
+#include <lemon/hartmann_orlin.h>
+#include <lemon/howard.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 Value>
+struct MmcClassConcept
+{
+  template <typename MMC>
+  struct Constraints {
+    void constraints() {
+      const Constraints& me = *this;
+
+      typedef typename MMC
+        ::template SetPath<ListPath<GR> >
+        ::template SetLargeValue<Value>
+        ::Create MmcAlg;
+      MmcAlg mmc(me.g, me.length);
+      const MmcAlg& const_mmc = mmc;
+      
+      typename MmcAlg::Tolerance tol = const_mmc.tolerance();
+      mmc.tolerance(tol);
+      
+      b = mmc.cycle(p).run();
+      b = mmc.findMinMean();
+      b = mmc.findCycle();
+
+      v = const_mmc.cycleLength();
+      i = const_mmc.cycleArcNum();
+      d = const_mmc.cycleMean();
+      p = const_mmc.cycle();
+    }
+
+    typedef concepts::ReadMap<typename GR::Arc, Value> LM;
+  
+    GR g;
+    LM length;
+    ListPath<GR> p;
+    Value 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 length, int size) {
+  MMC alg(gr, lm);
+  alg.findMinMean();
+  check(alg.cycleMean() == static_cast<double>(length) / size,
+        "Wrong cycle mean");
+  alg.findCycle();
+  check(alg.cycleLength() == length && alg.cycleArcNum() == 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;
+
+    // Karp
+    checkConcept< MmcClassConcept<GR, int>,
+                  Karp<GR, concepts::ReadMap<GR::Arc, int> > >();
+    checkConcept< MmcClassConcept<GR, float>,
+                  Karp<GR, concepts::ReadMap<GR::Arc, float> > >();
+    
+    // HartmannOrlin
+    checkConcept< MmcClassConcept<GR, int>,
+                  HartmannOrlin<GR, concepts::ReadMap<GR::Arc, int> > >();
+    checkConcept< MmcClassConcept<GR, float>,
+                  HartmannOrlin<GR, concepts::ReadMap<GR::Arc, float> > >();
+    
+    // Howard
+    checkConcept< MmcClassConcept<GR, int>,
+                  Howard<GR, concepts::ReadMap<GR::Arc, int> > >();
+    checkConcept< MmcClassConcept<GR, float>,
+                  Howard<GR, concepts::ReadMap<GR::Arc, float> > >();
+
+    if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, int> >::LargeValue,
+          long_int>::result == 0) check(false, "Wrong LargeValue type");
+    if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, float> >::LargeValue,
+          double>::result == 0) check(false, "Wrong LargeValue 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<Karp<GR, IntArcMap> >(gr, l1, c1,  6, 3);
+    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l2, c2,  5, 2);
+    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l3, c3,  0, 1);
+    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l4, c4, -1, 1);
+
+    // HartmannOrlin
+    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l1, c1,  6, 3);
+    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l2, c2,  5, 2);
+    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l3, c3,  0, 1);
+    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l4, c4, -1, 1);
+
+    // Howard
+    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l1, c1,  6, 3);
+    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l2, c2,  5, 2);
+    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l3, c3,  0, 1);
+    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l4, c4, -1, 1);
+  }
+
+  return 0;
+}
Index: test/mip_test.cc
===================================================================
--- test/mip_test.cc	(revision 631)
+++ test/mip_test.cc	(revision 748)
@@ -51,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)
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/suurballe_test.cc
===================================================================
--- test/suurballe_test.cc	(revision 623)
+++ test/suurballe_test.cc	(revision 854)
@@ -102,4 +102,7 @@
   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);
Index: test/test_tools.h
===================================================================
--- test/test_tools.h	(revision 440)
+++ test/test_tools.h	(revision 763)
@@ -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: tools/dimacs-solver.cc
===================================================================
--- tools/dimacs-solver.cc	(revision 644)
+++ tools/dimacs-solver.cc	(revision 846)
@@ -92,5 +92,5 @@
 }
 
-template<class Value>
+template<class Value, class LargeValue>
 void solve_min(ArgParser &ap, std::istream &is, std::ostream &,
                Value infty, DimacsDescriptor &desc)
@@ -128,5 +128,6 @@
     std::cerr << "Run NetworkSimplex: " << ti << "\n\n";
     std::cerr << "Feasible flow: " << (res ? "found" : "not found") << '\n';
-    if (res) std::cerr << "Min flow cost: " << ns.totalCost() << '\n';
+    if (res) std::cerr << "Min flow cost: "
+                       << ns.template totalCost<LargeValue>() << '\n';
   }
 }
@@ -152,5 +153,5 @@
 
 
-template<class Value>
+template<class Value, class LargeValue>
 void solve(ArgParser &ap, std::istream &is, std::ostream &os,
            DimacsDescriptor &desc)
@@ -170,5 +171,5 @@
     {
     case DimacsDescriptor::MIN:
-      solve_min<Value>(ap,is,os,infty,desc);
+      solve_min<Value, LargeValue>(ap,is,os,infty,desc);
       break;
     case DimacsDescriptor::MAX:
@@ -265,12 +266,14 @@
     
   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);
+    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;
